diff -Nru cargo-0.33.0/appveyor.yml cargo-0.35.0/appveyor.yml --- cargo-0.33.0/appveyor.yml 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/appveyor.yml 2019-04-01 21:32:07.000000000 +0000 @@ -2,9 +2,6 @@ matrix: - TARGET: x86_64-pc-windows-msvc OTHER_TARGET: i686-pc-windows-msvc - - TARGET: x86_64-pc-windows-msvc - MINIMAL_VERSIONS: true - CFG_DISABLE_CROSS_TESTS: 1 install: - if NOT defined APPVEYOR_PULL_REQUEST_NUMBER if "%APPVEYOR_REPO_BRANCH%" == "master" appveyor exit @@ -25,5 +22,5 @@ # we don't have ci time to run the full `cargo test` with `minimal-versions` like # - if defined MINIMAL_VERSIONS cargo +nightly generate-lockfile -Z minimal-versions && cargo +stable test # so we just run `cargo check --tests` like - - if defined MINIMAL_VERSIONS cargo +nightly generate-lockfile -Z minimal-versions && cargo +1.31.0 check --tests - - if NOT defined MINIMAL_VERSIONS cargo test + - if defined MINIMAL_VERSIONS cargo +nightly generate-lockfile -Z minimal-versions && cargo +1.31.0 check --tests --features=deny-warnings + - if NOT defined MINIMAL_VERSIONS cargo test --features=deny-warnings diff -Nru cargo-0.33.0/ARCHITECTURE.md cargo-0.35.0/ARCHITECTURE.md --- cargo-0.33.0/ARCHITECTURE.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/ARCHITECTURE.md 2019-04-01 21:32:07.000000000 +0000 @@ -5,7 +5,7 @@ interested in the inner workings of Cargo. The purpose of Cargo is to formalize a canonical Rust workflow, by automating -the standard tasks associated with distributing software. Cargo simplifies +the standard tasks associated with distributing software. Cargo simplifies structuring a new project, adding dependencies, writing and running unit tests, and more. @@ -58,7 +58,7 @@ `Resolve` is the representation of a directed acyclic graph of package dependencies, which uses `PackageId`s for nodes. This is the data -structure that is saved to the lock file. If there is no lockfile, +structure that is saved to the lock file. If there is no lock file, Cargo constructs a resolve by finding a graph of packages which matches declared dependency specification according to semver. @@ -114,22 +114,18 @@ /target/debug/cargo ..`) (or set the `RUSTC` env var to point to nightly rustc). -Because the test suite has `#![deny(warnings)]` at times you might find it -convenient to override this with `RUSTFLAGS`, for example -`RUSTFLAGS="--cap-lints warn" cargo build`. - ## Logging Cargo uses [`env_logger`](https://docs.rs/env_logger/*/env_logger/), so you can set `RUST_LOG` environment variable to get the logs. This is useful both for diagnosing -bugs in stable Cargo and for local development. Cargo also has internal hierarchical -profiling infrastructure, which is activated via `CARGO_PROFILE` variable +bugs in stable Cargo and for local development. Cargo also has internal hierarchical +profiling infrastructure, which is activated via `CARGO_PROFILE` variable ``` -# Outputs all logs with levels debug and higher +# Outputs all logs with levels debug and higher $ RUST_LOG=debug cargo generate-lockfile -# Don't forget that you can filter by module as well +# Don't forget that you can filter by module as well $ RUST_LOG=cargo::core::resolver=trace cargo generate-lockfile # Output first three levels of profiling info diff -Nru cargo-0.33.0/Cargo.toml cargo-0.35.0/Cargo.toml --- cargo-0.33.0/Cargo.toml 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/Cargo.toml 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,7 @@ [package] name = "cargo" -version = "0.33.0" +version = "0.35.0" +edition = "2018" authors = ["Yehuda Katz ", "Carl Lerche ", "Alex Crichton "] @@ -18,37 +19,37 @@ [dependencies] atty = "0.2" +byteorder = "1.2" bytesize = "1.0" -crates-io = { path = "src/crates-io", version = "0.21" } +crates-io = { path = "src/crates-io", version = "0.23" } crossbeam-utils = "0.6" crypto-hash = "0.3.1" curl = { version = "0.4.19", features = ['http2'] } curl-sys = "0.4.15" env_logger = "0.6.0" -pretty_env_logger = { version = "0.2", optional = true } -failure = "0.1.2" +pretty_env_logger = { version = "0.3", optional = true } +failure = "0.1.5" filetime = "0.2" flate2 = { version = "1.0.3", features = ['zlib'] } fs2 = "0.4" -git2 = "0.7.5" -git2-curl = "0.8.1" +git2 = "0.8.0" +git2-curl = "0.9.0" glob = "0.2.11" hex = "0.3" home = "0.3" ignore = "0.4" -lazy_static = "1.0.0" +lazy_static = "1.2.0" jobserver = "0.1.11" lazycell = "1.2.0" libc = "0.2" -log = "0.4" +log = "0.4.6" libgit2-sys = "0.7.9" num_cpus = "1.0" opener = "0.3.0" -rustfix = "0.4.2" +rustfix = "0.4.4" same-file = "1" semver = { version = "0.9.0", features = ["serde"] } -serde = "1.0" -serde_derive = "1.0" +serde = { version = "1.0.82", features = ['derive'] } serde_ignored = "0.0.4" serde_json = { version = "1.0.30", features = ["raw_value"] } shell-escape = "0.1.4" @@ -57,6 +58,7 @@ termcolor = "1.0" toml = "0.4.2" url = "1.1" +url_serde = "0.2.0" clap = "2.31.2" unicode-width = "0.1.5" openssl = { version = '0.10.11', optional = true } @@ -105,5 +107,6 @@ doc = false [features] +deny-warnings = [] vendored-openssl = ['openssl/vendored'] pretty-env-logger = ['pretty_env_logger'] diff -Nru cargo-0.33.0/CONTRIBUTING.md cargo-0.35.0/CONTRIBUTING.md --- cargo-0.33.0/CONTRIBUTING.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/CONTRIBUTING.md 2019-04-01 21:32:07.000000000 +0000 @@ -6,7 +6,7 @@ issue tracker. If you have a general question about Cargo or it's internals, feel free to ask -on [IRC]. +on [Discord]. ## Code of Conduct @@ -54,7 +54,7 @@ If you're looking for somewhere to start, check out the [E-easy][E-Easy] and [E-mentor][E-mentor] tags. -Feel free to ask for guidelines on how to tackle a problem on [IRC] or open a +Feel free to ask for guidelines on how to tackle a problem on [Discord] or open a [new issue][new-issues]. This is especially important if you want to add new features to Cargo or make large changes to the already existing code-base. Cargo's core developers will do their best to provide help. @@ -85,8 +85,8 @@ * [Commit as you go][githelp]. * Include tests that cover all non-trivial code. The existing tests in `test/` provide templates on how to test Cargo's behavior in a -sandbox-environment. The internal crate `cargotest` provides a vast amount -of helpers to minimize boilerplate. See [`cargotest/mod.rs`] for an +sandbox-environment. The internal module `testsuite/support` provides a vast amount +of helpers to minimize boilerplate. See [`testsuite/support/mod.rs`] for an introduction to writing tests. * Make sure `cargo test` passes. If you do not have the cross-compilers installed locally, install them using the instructions returned by @@ -106,11 +106,11 @@ After the pull request is made, a friendly bot will automatically assign a reviewer; the review-process will make sure that the proposed changes are sound. Please give the assigned reviewer sufficient time, especially during -weekends. If you don't get a reply, you may poke the core developers on [IRC]. +weekends. If you don't get a reply, you may poke the core developers on [Discord]. A merge of Cargo's master-branch and your changes is immediately queued to be tested after the pull request is made. In case unforeseen -problems are discovered during this step (e.g. a failure on a platform you +problems are discovered during this step (e.g., a failure on a platform you originally did not develop on), you may ask for guidance. Push additional commits to your branch to tackle these problems. @@ -196,7 +196,7 @@ [E-mentor]: https://github.com/rust-lang/cargo/labels/E-mentor [I-nominated]: https://github.com/rust-lang/cargo/labels/I-nominated [Code of Conduct]: https://www.rust-lang.org/conduct.html -[IRC]: https://kiwiirc.com/client/irc.mozilla.org/cargo -[`cargotest/mod.rs`]: https://github.com/rust-lang/cargo/blob/master/tests/testsuite/cargotest/mod.rs +[Discord]: https://discordapp.com/invite/rust-lang +[`testsuite/support/mod.rs`]: https://github.com/rust-lang/cargo/blob/master/tests/testsuite/support/mod.rs [irlo]: https://internals.rust-lang.org/ [subcommands]: https://doc.rust-lang.org/cargo/reference/external-tools.html#custom-subcommands diff -Nru cargo-0.33.0/debian/changelog cargo-0.35.0/debian/changelog --- cargo-0.33.0/debian/changelog 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/changelog 2019-05-16 23:30:15.000000000 +0000 @@ -1,4 +1,4 @@ -cargo (0.33.0-1ubuntu1~18.04.1) bionic; urgency=medium +cargo (0.35.0-0ubuntu1~18.04.1) bionic; urgency=medium * Backport to Bionic. * Embed libgit2 0.27.0 to avoid a dependency on a version which is newer @@ -15,7 +15,31 @@ - add debian/patches/use-system-libhttp-parser.patch - update debian/patches/series - -- Michael Hudson-Doyle Wed, 27 Feb 2019 16:09:16 +1300 + -- Michael Hudson-Doyle Fri, 17 May 2019 11:30:15 +1200 + +cargo (0.35.0-0ubuntu1) eoan; urgency=medium + + * New upstream version. + - Refresh patches. + - Remove d/patches/1003_increase_timeout_for_slow_arches_like_mips.patch, + no longer needed. + + -- Michael Hudson-Doyle Fri, 17 May 2019 11:25:23 +1200 + +cargo (0.34.0-0ubuntu1) eoan; urgency=medium + + * New upstream version. + - Refresh patches. + + -- Michael Hudson-Doyle Tue, 14 May 2019 11:14:06 +1200 + +cargo (0.33.0-1ubuntu2) disco; urgency=medium + + * Fix a rounding issue in vendor/typenum. + - add debian/patches/typenum-rounding.patch + - update debian/patches/series + + -- Michael Hudson-Doyle Thu, 14 Mar 2019 10:00:18 +1300 cargo (0.33.0-1ubuntu1) disco; urgency=medium diff -Nru cargo-0.33.0/debian/patches/1003_increase_timeout_for_slow_arches_like_mips.patch cargo-0.35.0/debian/patches/1003_increase_timeout_for_slow_arches_like_mips.patch --- cargo-0.33.0/debian/patches/1003_increase_timeout_for_slow_arches_like_mips.patch 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/1003_increase_timeout_for_slow_arches_like_mips.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -Description: Increase timeout for slow arches like mips -Author: Ximin Luo -Bug: https://github.com/rust-lang/cargo/issues/6491 ---- a/tests/testsuite/support/resolver.rs -+++ b/tests/testsuite/support/resolver.rs -@@ -118,7 +118,7 @@ - - // The largest test in our suite takes less then 30 sec. - // So lets fail the test if we have ben running for two long. -- assert!(start.elapsed() < Duration::from_secs(60)); -+ assert!(start.elapsed() < Duration::from_secs(240)); - resolve - } - ---- a/tests/testsuite/concurrent.rs -+++ b/tests/testsuite/concurrent.rs -@@ -511,7 +511,7 @@ - } - - for _ in 0..n_concurrent_builds { -- let result = rx.recv_timeout(Duration::from_secs(30)).expect("Deadlock!"); -+ let result = rx.recv_timeout(Duration::from_secs(120)).expect("Deadlock!"); - execs().run_output(&result); - } - } ---- a/src/cargo/core/resolver/types.rs -+++ b/src/cargo/core/resolver/types.rs -@@ -57,7 +57,7 @@ - // If any of them are removed then it takes more than I am willing to measure. - // So lets fail the test fast if we have ben running for two long. - if cfg!(debug_assertions) && (self.ticks % 1000 == 0) { -- assert!(self.start.elapsed() - self.deps_time < Duration::from_secs(90)); -+ assert!(self.start.elapsed() - self.deps_time < Duration::from_secs(360)); - } - Ok(()) - } diff -Nru cargo-0.33.0/debian/patches/2002_disable-net-tests.patch cargo-0.35.0/debian/patches/2002_disable-net-tests.patch --- cargo-0.33.0/debian/patches/2002_disable-net-tests.patch 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/2002_disable-net-tests.patch 2019-05-16 01:51:02.000000000 +0000 @@ -6,15 +6,15 @@ --- a/tests/testsuite/build_auth.rs +++ b/tests/testsuite/build_auth.rs @@ -10,7 +10,7 @@ - use support::{basic_manifest, project}; + use git2; - // Test that HTTP auth is offered from `credential.helper` + // Tests that HTTP auth is offered from `credential.helper`. -#[test] +#[allow(dead_code)] fn http_auth_offered() { let server = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = server.local_addr().unwrap(); -@@ -141,7 +141,7 @@ +@@ -149,7 +149,7 @@ } // Boy, sure would be nice to have a TLS implementation in rust! @@ -26,15 +26,15 @@ --- a/tests/testsuite/net_config.rs +++ b/tests/testsuite/net_config.rs @@ -1,6 +1,6 @@ - use support::project; + use crate::support::project; -#[test] +#[allow(dead_code)] fn net_retry_loads_from_config() { let p = project() .file( -@@ -33,7 +33,7 @@ - ).run(); +@@ -36,7 +36,7 @@ + .run(); } -#[test] diff -Nru cargo-0.33.0/debian/patches/2005_disable_fetch_cross_tests.patch cargo-0.35.0/debian/patches/2005_disable_fetch_cross_tests.patch --- cargo-0.33.0/debian/patches/2005_disable_fetch_cross_tests.patch 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/2005_disable_fetch_cross_tests.patch 2019-05-14 01:14:16.000000000 +0000 @@ -17,7 +17,7 @@ if cross_compile::disabled() { return; } -@@ -58,8 +58,8 @@ +@@ -59,8 +59,8 @@ .run(); } diff -Nru cargo-0.33.0/debian/patches/disable-fetch-tests-on-non-x86.patch cargo-0.35.0/debian/patches/disable-fetch-tests-on-non-x86.patch --- cargo-0.33.0/debian/patches/disable-fetch-tests-on-non-x86.patch 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/disable-fetch-tests-on-non-x86.patch 2019-05-14 01:14:16.000000000 +0000 @@ -1,10 +1,10 @@ --- a/tests/testsuite/fetch.rs +++ b/tests/testsuite/fetch.rs @@ -1,6 +1,4 @@ --use support::registry::Package; --use support::rustc_host; --use support::{basic_manifest, cross_compile, project}; -+use support::project; +-use crate::support::registry::Package; +-use crate::support::rustc_host; +-use crate::support::{basic_manifest, cross_compile, project}; ++use crate::support::project; #[test] fn no_deps() { @@ -14,22 +14,22 @@ #[test] +#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] fn fetch_all_platform_dependencies_when_no_target_is_given() { -+ use support::rustc_host; -+ use support::registry::Package; -+ use support::{basic_manifest, cross_compile}; ++ use crate::support::rustc_host; ++ use crate::support::registry::Package; ++ use crate::support::{basic_manifest, cross_compile}; + if cross_compile::disabled() { return; } -@@ -59,7 +62,12 @@ +@@ -60,7 +63,12 @@ } #[test] +#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] fn fetch_platform_specific_dependencies() { -+ use support::rustc_host; -+ use support::registry::Package; -+ use support::{basic_manifest, cross_compile}; ++ use crate::support::rustc_host; ++ use crate::support::registry::Package; ++ use crate::support::{basic_manifest, cross_compile}; + if cross_compile::disabled() { return; diff -Nru cargo-0.33.0/debian/patches/disable-tool_paths-custom_runner.patch cargo-0.35.0/debian/patches/disable-tool_paths-custom_runner.patch --- cargo-0.33.0/debian/patches/disable-tool_paths-custom_runner.patch 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/disable-tool_paths-custom_runner.patch 2019-05-14 01:14:16.000000000 +0000 @@ -8,7 +8,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/tests/testsuite/tool_paths.rs +++ b/tests/testsuite/tool_paths.rs -@@ -115,135 +115,139 @@ +@@ -115,145 +115,149 @@ )).run(); } @@ -29,7 +29,8 @@ - "#, - target - ), -- ).build(); +- ) +- .build(); - - p.cargo("run -- --param") - .with_status(101) @@ -39,7 +40,8 @@ -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` -", -- ).run(); +- ) +- .run(); - - p.cargo("test --test test --verbose -- --param") - .with_status(101) @@ -50,7 +52,8 @@ -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -[RUNNING] `nonexistent-runner -r [..]/target/debug/deps/test-[..][EXE] --param` -", -- ).run(); +- ) +- .run(); - - p.cargo("bench --bench bench --verbose -- --param") - .with_status(101) @@ -62,7 +65,8 @@ -[FINISHED] release [optimized] target(s) in [..] -[RUNNING] `nonexistent-runner -r [..]/target/release/deps/bench-[..][EXE] --param --bench` -", -- ).run(); +- ) +- .run(); -} - -// can set a custom runner via `target.'cfg(..)'.runner` @@ -76,7 +80,8 @@ - [target.'cfg(not(target_os = "none"))'] - runner = "nonexistent-runner -r" - "#, -- ).build(); +- ) +- .build(); - - p.cargo("run -- --param") - .with_status(101) @@ -86,7 +91,8 @@ -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` -", -- )).run(); +- )) +- .run(); -} - -// custom runner set via `target.$triple.runner` have precende over `target.'cfg(..)'.runner` @@ -108,7 +114,8 @@ - "#, - target - ), -- ).build(); +- ) +- .build(); - - p.cargo("run -- --param") - .with_status(101) @@ -118,7 +125,8 @@ -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -[RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` -", -- )).run(); +- )) +- .run(); -} - -#[test] @@ -134,7 +142,8 @@ - [target.'cfg(not(target_os = "none"))'] - runner = "false" - "#, -- ).build(); +- ) +- .build(); - - p.cargo("run -- --param") - .with_status(101) @@ -142,7 +151,8 @@ - "\ -[ERROR] several matching instances of `target.'cfg(..)'.runner` in `.cargo/config` -", -- )).run(); +- )) +- .run(); -} +// These tests sometimes fail because of +// https://github.com/rust-lang/rust/issues/55242 ("failed call to @@ -165,7 +175,8 @@ +// "#, +// target +// ), -+// ).build(); ++// ) ++// .build(); + +// p.cargo("run -- --param") +// .with_status(101) @@ -175,7 +186,8 @@ +// [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +// [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` +// ", -+// ).run(); ++// ) ++// .run(); + +// p.cargo("test --test test --verbose -- --param") +// .with_status(101) @@ -186,7 +198,8 @@ +// [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +// [RUNNING] `nonexistent-runner -r [..]/target/debug/deps/test-[..][EXE] --param` +// ", -+// ).run(); ++// ) ++// .run(); + +// p.cargo("bench --bench bench --verbose -- --param") +// .with_status(101) @@ -198,7 +211,8 @@ +// [FINISHED] release [optimized] target(s) in [..] +// [RUNNING] `nonexistent-runner -r [..]/target/release/deps/bench-[..][EXE] --param --bench` +// ", -+// ).run(); ++// ) ++// .run(); +// } + +// // can set a custom runner via `target.'cfg(..)'.runner` @@ -212,7 +226,8 @@ +// [target.'cfg(not(target_os = "none"))'] +// runner = "nonexistent-runner -r" +// "#, -+// ).build(); ++// ) ++// .build(); + +// p.cargo("run -- --param") +// .with_status(101) @@ -222,7 +237,8 @@ +// [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +// [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` +// ", -+// )).run(); ++// )) ++// .run(); +// } + +// // custom runner set via `target.$triple.runner` have precende over `target.'cfg(..)'.runner` @@ -244,7 +260,8 @@ +// "#, +// target +// ), -+// ).build(); ++// ) ++// .build(); + +// p.cargo("run -- --param") +// .with_status(101) @@ -254,7 +271,8 @@ +// [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +// [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` +// ", -+// )).run(); ++// )) ++// .run(); +// } + +// #[test] @@ -270,7 +288,8 @@ +// [target.'cfg(not(target_os = "none"))'] +// runner = "false" +// "#, -+// ).build(); ++// ) ++// .build(); + +// p.cargo("run -- --param") +// .with_status(101) @@ -278,5 +297,6 @@ +// "\ +// [ERROR] several matching instances of `target.'cfg(..)'.runner` in `.cargo/config` +// ", -+// )).run(); ++// )) ++// .run(); +// } diff -Nru cargo-0.33.0/debian/patches/series cargo-0.35.0/debian/patches/series --- cargo-0.33.0/debian/patches/series 2019-02-27 03:09:16.000000000 +0000 +++ cargo-0.35.0/debian/patches/series 2019-05-16 23:29:53.000000000 +0000 @@ -1,7 +1,7 @@ -1003_increase_timeout_for_slow_arches_like_mips.patch 2002_disable-net-tests.patch #2005_disable_fetch_cross_tests.patch disable-fetch-tests-on-non-x86.patch disable-tool_paths-custom_runner.patch +typenum-rounding.patch do-not-use-system-libgit2.patch use-system-libhttp-parser.patch diff -Nru cargo-0.33.0/debian/patches/typenum-rounding.patch cargo-0.35.0/debian/patches/typenum-rounding.patch --- cargo-0.33.0/debian/patches/typenum-rounding.patch 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/debian/patches/typenum-rounding.patch 2019-05-14 01:14:16.000000000 +0000 @@ -0,0 +1,18 @@ +Description: fix rounding issue in typenum +Author: Michael Hudson-Doyle +Origin: vendor +Bug: https://github.com/paholg/typenum/pull/115 +Last-Update: 2019-03-13 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/vendor/typenum/build/main.rs ++++ b/vendor/typenum/build/main.rs +@@ -77,7 +77,7 @@ + fn main() { + let highest: u64 = 1024; + +- let first2: u32 = (highest as f64).log(2.0) as u32 + 1; ++ let first2: u32 = (highest as f64).log(2.0).round() as u32 + 1; + let first10: u32 = (highest as f64).log(10.0) as u32 + 1; + let uints = (0..(highest + 1)) + .chain((first2..64).map(|i| 2u64.pow(i))) diff -Nru cargo-0.33.0/.github/ISSUE_TEMPLATE/bug_report.md cargo-0.35.0/.github/ISSUE_TEMPLATE/bug_report.md --- cargo-0.33.0/.github/ISSUE_TEMPLATE/bug_report.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/.github/ISSUE_TEMPLATE/bug_report.md 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,7 @@ --- name: Bug report about: Create a report to help us improve +labels: C-bug --- diff -Nru cargo-0.33.0/.github/ISSUE_TEMPLATE/feature_request.md cargo-0.35.0/.github/ISSUE_TEMPLATE/feature_request.md --- cargo-0.33.0/.github/ISSUE_TEMPLATE/feature_request.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/.github/ISSUE_TEMPLATE/feature_request.md 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,7 @@ --- name: Feature request about: Suggest an idea for this project +labels: C-feature-request --- diff -Nru cargo-0.33.0/.github/stale.yml cargo-0.35.0/.github/stale.yml --- cargo-0.33.0/.github/stale.yml 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/.github/stale.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# Default values: https://probot.github.io/apps/stale/#installation - -daysUntilStale: 1160 # ~3 yrs 2 months -daysUntilClose: 30 - -exemptLabels: - - C-tracking-issue # keep tracking issues open - - C-feature-request # keep feature requests open (at least for now) - - "Feature accepted" # keep accepted features - -staleLabel: stale - -markComment: > - As there hasn't been any activity here in a while would someone (the author, a - team member, or any interested party) be able to summarise the current state, - perhaps making explicit: - * Is this still relevant? - * If so, what is blocking it? - * Is it known what could be done to help move this forward? - - Thank you! - - - (The cargo team is currently evaluating the use of Stale bot, and using #6035 - as the tracking issue to gather feedback.) - - - If you're reading this comment from the distant future, fear not if this - was closed automatically. If you believe it's still an issue please leave a - comment and a team member can reopen this issue. Opening a new issue is also - acceptable! - -closeComment: > - As I didn't see any updates in 30 days I'm going to close this. - Please see the previous comment for more information! - -limitPerRun: 1 # 1 per hour, so 24 per day diff -Nru cargo-0.33.0/README.md cargo-0.35.0/README.md --- cargo-0.33.0/README.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/README.md 2019-04-01 21:32:07.000000000 +0000 @@ -6,7 +6,7 @@ ## Code Status -[![Build Status](https://travis-ci.org/rust-lang/cargo.svg?branch=master)](https://travis-ci.org/rust-lang/cargo) +[![Build Status](https://travis-ci.com/rust-lang/cargo.svg?branch=master)](https://travis-ci.com/rust-lang/cargo) [![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-lang/cargo?branch=master&svg=true)](https://ci.appveyor.com/project/rust-lang-libs/cargo) Code documentation: https://docs.rs/cargo/ @@ -20,6 +20,7 @@ Cargo requires the following tools and packages to build: +* `git` * `python` * `curl` (on Unix) * OpenSSL headers (only for Unix, this is the `libssl-dev` package on ubuntu) diff -Nru cargo-0.33.0/src/bin/cargo/cli.rs cargo-0.35.0/src/bin/cargo/cli.rs --- cargo-0.33.0/src/bin/cargo/cli.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/cli.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -extern crate clap; +use clap; use clap::{AppSettings, Arg, ArgMatches}; @@ -6,7 +6,7 @@ use super::commands; use super::list_commands; -use command_prelude::*; +use crate::command_prelude::*; pub fn main(config: &mut Config) -> CliResult { let args = match cli().get_matches_safe() { @@ -132,7 +132,7 @@ Ok(args) } -fn execute_subcommand(config: &mut Config, args: &ArgMatches) -> CliResult { +fn execute_subcommand(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let (cmd, subcommand_args) = match args.subcommand() { (cmd, Some(args)) => (cmd, args), _ => { @@ -194,7 +194,7 @@ doc Build this package's and its dependencies' documentation new Create a new cargo package init Create a new cargo package in an existing directory - run Build and execute src/main.rs + run Run a binary or example of the local package test Run the tests bench Run the benchmarks update Update dependencies listed in Cargo.lock diff -Nru cargo-0.33.0/src/bin/cargo/commands/bench.rs cargo-0.35.0/src/bin/cargo/commands/bench.rs --- cargo-0.33.0/src/bin/cargo/commands/bench.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/bench.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, TestOptions}; @@ -46,14 +46,14 @@ )) .after_help( "\ -The benchmark filtering argument `BENCHNAME` and all the arguments following the +The benchmark filtering argument BENCHNAME and all the arguments following the two dashes (`--`) are passed to the benchmark binaries and thus to libtest -(rustc's built in unit-test and micro-benchmarking framework). If you're +(rustc's built in unit-test and micro-benchmarking framework). If you're passing arguments to both Cargo and the binary, the ones after `--` go to the -binary, the ones before go to Cargo. For details about libtest's arguments see +binary, the ones before go to Cargo. For details about libtest's arguments see the output of `cargo bench -- --help`. -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package should be benchmarked. If it is not given, then the current package is benchmarked. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -62,7 +62,7 @@ `--all` flag is automatically assumed for a virtual manifest. Note that `--exclude` has to be specified in conjunction with the `--all` flag. -The --jobs argument affects the building of the benchmark executable but does +The `--jobs` argument affects the building of the benchmark executable but does not affect how many jobs are used when running the benchmarks. Compilation can be customized with the `bench` profile in the manifest. @@ -70,9 +70,10 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - let mut compile_opts = args.compile_options(config, CompileMode::Bench)?; + let mut compile_opts = args.compile_options(config, CompileMode::Bench, Some(&ws))?; + compile_opts.build_config.release = true; let ops = TestOptions { @@ -97,7 +98,7 @@ match err { None => Ok(()), Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) { - Some(i) => CliError::new(format_err!("bench failed"), i), + Some(i) => CliError::new(failure::format_err!("bench failed"), i), None => CliError::new(err.into(), 101), }), } diff -Nru cargo-0.33.0/src/bin/cargo/commands/build.rs cargo-0.35.0/src/bin/cargo/commands/build.rs --- cargo-0.33.0/src/bin/cargo/commands/build.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/build.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -46,12 +46,13 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - let mut compile_opts = args.compile_options(config, CompileMode::Build)?; + let mut compile_opts = args.compile_options(config, CompileMode::Build, Some(&ws))?; + compile_opts.export_dir = args.value_of_path("out-dir", config); if compile_opts.export_dir.is_some() && !config.cli_unstable().unstable_options { - Err(format_err!( + Err(failure::format_err!( "`--out-dir` flag is unstable, pass `-Z unstable-options` to enable it" ))?; }; diff -Nru cargo-0.33.0/src/bin/cargo/commands/check.rs cargo-0.35.0/src/bin/cargo/commands/check.rs --- cargo-0.33.0/src/bin/cargo/commands/check.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/check.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -34,7 +34,7 @@ .arg_message_format() .after_help( "\ -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package should be built. If it is not given, then the current package is built. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -45,7 +45,7 @@ Compilation can be configured via the use of profiles which are configured in the manifest. The default profile for this command is `dev`, but passing -the --release flag will use the `release` profile instead. +the `--release` flag will use the `release` profile instead. The `--profile test` flag can be used to check unit tests with the `#[cfg(test)]` attribute. @@ -53,13 +53,13 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let test = match args.value_of("profile") { Some("test") => true, None => false, Some(profile) => { - let err = format_err!( + let err = failure::format_err!( "unknown profile: `{}`, only `test` is \ currently supported", profile @@ -68,7 +68,8 @@ } }; let mode = CompileMode::Check { test }; - let compile_opts = args.compile_options(config, mode)?; + let compile_opts = args.compile_options(config, mode, Some(&ws))?; + ops::compile(&ws, &compile_opts)?; Ok(()) } diff -Nru cargo-0.33.0/src/bin/cargo/commands/clean.rs cargo-0.35.0/src/bin/cargo/commands/clean.rs --- cargo-0.33.0/src/bin/cargo/commands/clean.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/clean.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, CleanOptions}; @@ -7,13 +7,13 @@ .about("Remove artifacts that cargo has generated in the past") .arg_package_spec_simple("Package to clean artifacts for") .arg_manifest_path() - .arg_target_triple("Target triple to clean output for (default all)") + .arg_target_triple("Target triple to clean output for") .arg_target_dir() .arg_release("Whether or not to clean release artifacts") .arg_doc("Whether or not to clean just the documentation directory") .after_help( "\ -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package's artifacts should be cleaned out. If it is not given, then all packages' artifacts are removed. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -21,7 +21,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let opts = CleanOptions { config, diff -Nru cargo-0.33.0/src/bin/cargo/commands/doc.rs cargo-0.35.0/src/bin/cargo/commands/doc.rs --- cargo-0.33.0/src/bin/cargo/commands/doc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/doc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, DocOptions}; @@ -37,7 +37,7 @@ `--all` flag is automatically assumed for a virtual manifest. Note that `--exclude` has to be specified in conjunction with the `--all` flag. -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package should be documented. If it is not given, then the current package is documented. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -45,12 +45,12 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let mode = CompileMode::Doc { deps: !args.is_present("no-deps"), }; - let mut compile_opts = args.compile_options(config, mode)?; + let mut compile_opts = args.compile_options(config, mode, Some(&ws))?; compile_opts.local_rustdoc_args = if args.is_present("document-private-items") { Some(vec!["--document-private-items".to_string()]) } else { diff -Nru cargo-0.33.0/src/bin/cargo/commands/fetch.rs cargo-0.35.0/src/bin/cargo/commands/fetch.rs --- cargo-0.33.0/src/bin/cargo/commands/fetch.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/fetch.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; use cargo::ops::FetchOptions; @@ -10,19 +10,19 @@ .arg_target_triple("Fetch dependencies for the target triple") .after_help( "\ -If a lockfile is available, this command will ensure that all of the git +If a lock file is available, this command will ensure that all of the Git dependencies and/or registries dependencies are downloaded and locally available. The network is never touched after a `cargo fetch` unless -the lockfile changes. +the lock file changes. -If the lockfile is not available, then this is the equivalent of -`cargo generate-lockfile`. A lockfile is generated and dependencies are also +If the lock file is not available, then this is the equivalent of +`cargo generate-lockfile`. A lock file is generated and dependencies are also all updated. ", ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let opts = FetchOptions { diff -Nru cargo-0.33.0/src/bin/cargo/commands/fix.rs cargo-0.35.0/src/bin/cargo/commands/fix.rs --- cargo-0.33.0/src/bin/cargo/commands/fix.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/fix.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, CompileFilter, FilterRule}; @@ -54,7 +54,7 @@ .arg( Arg::with_name("idioms") .long("edition-idioms") - .help("Fix warnings to migrate to the idioms of an edition") + .help("Fix warnings to migrate to the idioms of an edition"), ) .arg( Arg::with_name("allow-no-vcs") @@ -104,13 +104,13 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let test = match args.value_of("profile") { Some("test") => true, None => false, Some(profile) => { - let err = format_err!( + let err = failure::format_err!( "unknown profile: `{}`, only `test` is \ currently supported", profile @@ -122,7 +122,8 @@ // Unlike other commands default `cargo fix` to all targets to fix as much // code as we can. - let mut opts = args.compile_options(config, mode)?; + let mut opts = args.compile_options(config, mode, Some(&ws))?; + if let CompileFilter::Default { .. } = opts.filter { opts.filter = CompileFilter::Only { all_targets: true, @@ -133,15 +134,18 @@ tests: FilterRule::All, } } - ops::fix(&ws, &mut ops::FixOptions { - edition: args.is_present("edition"), - prepare_for: args.value_of("prepare-for"), - idioms: args.is_present("idioms"), - compile_opts: opts, - allow_dirty: args.is_present("allow-dirty"), - allow_no_vcs: args.is_present("allow-no-vcs"), - allow_staged: args.is_present("allow-staged"), - broken_code: args.is_present("broken-code"), - })?; + ops::fix( + &ws, + &mut ops::FixOptions { + edition: args.is_present("edition"), + prepare_for: args.value_of("prepare-for"), + idioms: args.is_present("idioms"), + compile_opts: opts, + allow_dirty: args.is_present("allow-dirty"), + allow_no_vcs: args.is_present("allow-no-vcs"), + allow_staged: args.is_present("allow-staged"), + broken_code: args.is_present("broken-code"), + }, + )?; Ok(()) } diff -Nru cargo-0.33.0/src/bin/cargo/commands/generate_lockfile.rs cargo-0.35.0/src/bin/cargo/commands/generate_lockfile.rs --- cargo-0.33.0/src/bin/cargo/commands/generate_lockfile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/generate_lockfile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -8,7 +8,7 @@ .arg_manifest_path() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; ops::generate_lockfile(&ws)?; Ok(()) diff -Nru cargo-0.33.0/src/bin/cargo/commands/git_checkout.rs cargo-0.35.0/src/bin/cargo/commands/git_checkout.rs --- cargo-0.33.0/src/bin/cargo/commands/git_checkout.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/git_checkout.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::core::{GitReference, Source, SourceId}; use cargo::sources::GitSource; @@ -21,7 +21,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let url = args.value_of("url").unwrap().to_url()?; let reference = args.value_of("reference").unwrap(); diff -Nru cargo-0.33.0/src/bin/cargo/commands/init.rs cargo-0.35.0/src/bin/cargo/commands/init.rs --- cargo-0.33.0/src/bin/cargo/commands/init.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/init.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -10,7 +10,7 @@ .arg_new_opts() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let opts = args.new_options(config)?; ops::init(&opts, config)?; config diff -Nru cargo-0.33.0/src/bin/cargo/commands/install.rs cargo-0.35.0/src/bin/cargo/commands/install.rs --- cargo-0.33.0/src/bin/cargo/commands/install.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/install.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::core::{GitReference, SourceId}; use cargo::ops; @@ -51,7 +51,7 @@ which crate should be installed. Crates from crates.io can optionally specify the version they wish to install -via the `--vers` flags, and similarly packages from git repositories can +via the `--version` flags, and similarly packages from git repositories can optionally specify the branch, tag, or revision that should be installed. If a crate has multiple binaries, the `--bin` argument can selectively install only one of them, and if you'd rather install examples the `--example` argument can @@ -63,22 +63,24 @@ Omitting the specification entirely will install the crate in the current directory. That is, `install` is equivalent to -the more explicit `install --path .`. This behaviour is deprecated, and no +the more explicit `install --path .`. This behaviour is deprecated, and no longer supported as of the Rust 2018 edition. If the source is crates.io or `--git` then by default the crate will be built -in a temporary target directory. To avoid this, the target directory can be +in a temporary target directory. To avoid this, the target directory can be specified by setting the `CARGO_TARGET_DIR` environment variable to a relative -path. In particular, this can be useful for caching build artifacts on +path. In particular, this can be useful for caching build artifacts on continuous integration systems.", ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let registry = args.registry(config)?; config.reload_rooted_at_cargo_home()?; - let mut compile_opts = args.compile_options(config, CompileMode::Build)?; + + let workspace = args.workspace(config).ok(); + let mut compile_opts = args.compile_options(config, CompileMode::Build, workspace.as_ref())?; compile_opts.build_config.release = !args.is_present("debug"); diff -Nru cargo-0.33.0/src/bin/cargo/commands/locate_project.rs cargo-0.35.0/src/bin/cargo/commands/locate_project.rs --- cargo-0.33.0/src/bin/cargo/commands/locate_project.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/locate_project.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,7 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::print_json; +use serde::Serialize; pub fn cli() -> App { subcommand("locate-project") @@ -13,12 +14,13 @@ root: &'a str, } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let root = args.root_manifest(config)?; - let root = root.to_str() + let root = root + .to_str() .ok_or_else(|| { - format_err!( + failure::format_err!( "your package path contains characters \ not representable in Unicode" ) diff -Nru cargo-0.33.0/src/bin/cargo/commands/login.rs cargo-0.35.0/src/bin/cargo/commands/login.rs --- cargo-0.33.0/src/bin/cargo/commands/login.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/login.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,6 @@ -use command_prelude::*; +use crate::command_prelude::*; -use std::io::{self, BufRead}; - -use cargo::core::{Source, SourceId}; use cargo::ops; -use cargo::sources::RegistrySource; -use cargo::util::{CargoError, CargoResultExt}; pub fn cli() -> App { subcommand("login") @@ -14,46 +9,19 @@ If token is not specified, it will be read from stdin.", ) .arg(Arg::with_name("token")) - .arg(opt("host", "Host to set the token for").value_name("HOST")) + .arg( + opt("host", "Host to set the token for") + .value_name("HOST") + .hidden(true), + ) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { - let registry = args.registry(config)?; - - let token = match args.value_of("token") { - Some(token) => token.to_string(), - None => { - let host = match registry { - Some(ref _registry) => { - return Err(format_err!( - "token must be provided when \ - --registry is provided." - ) - .into()); - } - None => { - let src = SourceId::crates_io(config)?; - let mut src = RegistrySource::remote(src, config); - src.update()?; - let config = src.config()?.unwrap(); - args.value_of("host") - .map(|s| s.to_string()) - .unwrap_or_else(|| config.api.unwrap()) - } - }; - println!("please visit {}/me and paste the API Token below", host); - let mut line = String::new(); - let input = io::stdin(); - input - .lock() - .read_line(&mut line) - .chain_err(|| "failed to read stdin") - .map_err(CargoError::from)?; - line.trim().to_string() - } - }; - - ops::registry_login(config, token, registry)?; +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { + ops::registry_login( + config, + args.value_of("token").map(String::from), + args.value_of("registry").map(String::from), + )?; Ok(()) } diff -Nru cargo-0.33.0/src/bin/cargo/commands/metadata.rs cargo-0.35.0/src/bin/cargo/commands/metadata.rs --- cargo-0.33.0/src/bin/cargo/commands/metadata.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/metadata.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, OutputMetadataOptions}; use cargo::print_json; @@ -24,7 +24,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let version = match args.value_of("format-version") { diff -Nru cargo-0.33.0/src/bin/cargo/commands/mod.rs cargo-0.35.0/src/bin/cargo/commands/mod.rs --- cargo-0.33.0/src/bin/cargo/commands/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; pub fn builtin() -> Vec { vec![ @@ -35,8 +35,8 @@ ] } - pub fn builtin_exec(cmd: &str) -> Option CliResult> { - let f = match cmd { +pub fn builtin_exec(cmd: &str) -> Option) -> CliResult> { + let f = match cmd { "bench" => bench::exec, "build" => build::exec, "check" => check::exec, diff -Nru cargo-0.33.0/src/bin/cargo/commands/new.rs cargo-0.35.0/src/bin/cargo/commands/new.rs --- cargo-0.33.0/src/bin/cargo/commands/new.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/new.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -10,7 +10,7 @@ .arg_new_opts() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let opts = args.new_options(config)?; ops::new(&opts, config)?; @@ -20,8 +20,9 @@ } else { path }; - config - .shell() - .status("Created", format!("{} `{}` package", opts.kind, package_name))?; + config.shell().status( + "Created", + format!("{} `{}` package", opts.kind, package_name), + )?; Ok(()) } diff -Nru cargo-0.33.0/src/bin/cargo/commands/owner.rs cargo-0.35.0/src/bin/cargo/commands/owner.rs --- cargo-0.33.0/src/bin/cargo/commands/owner.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/owner.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, OwnersOptions}; @@ -6,19 +6,21 @@ subcommand("owner") .about("Manage the owners of a crate on the registry") .arg(Arg::with_name("crate")) - .arg(multi_opt("add", "LOGIN", "Name of a user or team to add as an owner").short("a")) + .arg(multi_opt("add", "LOGIN", "Name of a user or team to invite as an owner").short("a")) .arg( multi_opt( "remove", "LOGIN", "Name of a user or team to remove as an owner", - ).short("r"), + ) + .short("r"), ) .arg(opt("list", "List owners of a crate").short("l")) .arg(opt("index", "Registry index to modify owners for").value_name("INDEX")) .arg(opt("token", "API token to use when authenticating").value_name("TOKEN")) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) - .after_help("\ + .after_help( + "\ This command will modify the owners for a crate on the specified registry (or default). Owners of a crate can upload new versions and yank old versions. Explicitly named owners can also modify the set of owners, so take care! @@ -28,15 +30,17 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let registry = args.registry(config)?; let opts = OwnersOptions { krate: args.value_of("crate").map(|s| s.to_string()), token: args.value_of("token").map(|s| s.to_string()), index: args.value_of("index").map(|s| s.to_string()), - to_add: args.values_of("add") + to_add: args + .values_of("add") .map(|xs| xs.map(|s| s.to_string()).collect()), - to_remove: args.values_of("remove") + to_remove: args + .values_of("remove") .map(|xs| xs.map(|s| s.to_string()).collect()), list: args.is_present("list"), registry, diff -Nru cargo-0.33.0/src/bin/cargo/commands/package.rs cargo-0.35.0/src/bin/cargo/commands/package.rs --- cargo-0.33.0/src/bin/cargo/commands/package.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/package.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, PackageOpts}; @@ -9,7 +9,8 @@ opt( "list", "Print files included in a package without making one", - ).short("l"), + ) + .short("l"), ) .arg(opt( "no-verify", @@ -25,11 +26,12 @@ )) .arg_target_triple("Build for the target triple") .arg_target_dir() + .arg_features() .arg_manifest_path() .arg_jobs() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; ops::package( &ws, @@ -41,7 +43,9 @@ allow_dirty: args.is_present("allow-dirty"), target: args.target(), jobs: args.jobs()?, - registry: None, + features: args._values_of("features"), + all_features: args.is_present("all-features"), + no_default_features: args.is_present("no-default-features"), }, )?; Ok(()) diff -Nru cargo-0.33.0/src/bin/cargo/commands/pkgid.rs cargo-0.35.0/src/bin/cargo/commands/pkgid.rs --- cargo-0.33.0/src/bin/cargo/commands/pkgid.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/pkgid.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -6,11 +6,11 @@ subcommand("pkgid") .about("Print a fully qualified package specification") .arg(Arg::with_name("spec")) - .arg_package("Argument to get the package id specifier for") + .arg_package("Argument to get the package ID specifier for") .arg_manifest_path() .after_help( "\ -Given a argument, print out the fully qualified package id specifier. +Given a argument, print out the fully qualified package ID specifier. This command will generate an error if is ambiguous as to which package it refers to in the dependency graph. If no is given, then the pkgid for the local package is printed. @@ -32,7 +32,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let spec = args.value_of("spec").or_else(|| args.value_of("package")); let spec = ops::pkgid(&ws, spec)?; diff -Nru cargo-0.33.0/src/bin/cargo/commands/publish.rs cargo-0.35.0/src/bin/cargo/commands/publish.rs --- cargo-0.33.0/src/bin/cargo/commands/publish.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/publish.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, PublishOpts}; @@ -18,12 +18,13 @@ .arg_target_triple("Build for the target triple") .arg_target_dir() .arg_manifest_path() + .arg_features() .arg_jobs() - .arg(opt("dry-run", "Perform all checks without uploading")) + .arg_dry_run("Perform all checks without uploading") .arg(opt("registry", "Registry to publish to").value_name("REGISTRY")) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let registry = args.registry(config)?; let ws = args.workspace(config)?; let index = args.index(config)?; @@ -40,6 +41,9 @@ jobs: args.jobs()?, dry_run: args.is_present("dry-run"), registry, + features: args._values_of("features"), + all_features: args.is_present("all-features"), + no_default_features: args.is_present("no-default-features"), }, )?; Ok(()) diff -Nru cargo-0.33.0/src/bin/cargo/commands/read_manifest.rs cargo-0.35.0/src/bin/cargo/commands/read_manifest.rs --- cargo-0.33.0/src/bin/cargo/commands/read_manifest.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/read_manifest.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::print_json; @@ -14,7 +14,7 @@ .arg_manifest_path() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; print_json(&ws.current()?); Ok(()) diff -Nru cargo-0.33.0/src/bin/cargo/commands/run.rs cargo-0.35.0/src/bin/cargo/commands/run.rs --- cargo-0.33.0/src/bin/cargo/commands/run.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/run.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::core::Verbosity; use cargo::ops::{self, CompileFilter}; @@ -8,7 +8,7 @@ // subcommand aliases are handled in aliased_command() // .alias("r") .setting(AppSettings::TrailingVarArg) - .about("Run the main binary of the local package (src/main.rs)") + .about("Run a binary or example of the local package") .arg(Arg::with_name("args").multiple(true)) .arg_targets_bin_example( "Name of the bin target to run", @@ -36,10 +36,11 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - let mut compile_opts = args.compile_options(config, CompileMode::Build)?; + let mut compile_opts = args.compile_options(config, CompileMode::Build, Some(&ws))?; + if !args.is_present("example") && !args.is_present("bin") { let default_runs: Vec<_> = compile_opts .spec diff -Nru cargo-0.33.0/src/bin/cargo/commands/rustc.rs cargo-0.35.0/src/bin/cargo/commands/rustc.rs --- cargo-0.33.0/src/bin/cargo/commands/rustc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/rustc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -46,7 +46,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let mode = match args.value_of("profile") { Some("dev") | None => CompileMode::Build, @@ -54,7 +54,7 @@ Some("bench") => CompileMode::Bench, Some("check") => CompileMode::Check { test: false }, Some(mode) => { - let err = format_err!( + let err = failure::format_err!( "unknown profile: `{}`, use dev, test, or bench", mode @@ -62,7 +62,7 @@ return Err(CliError::new(err, 101)); } }; - let mut compile_opts = args.compile_options_for_single_package(config, mode)?; + let mut compile_opts = args.compile_options_for_single_package(config, mode, Some(&ws))?; let target_args = values(args, "args"); compile_opts.target_rustc_args = if target_args.is_empty() { None diff -Nru cargo-0.33.0/src/bin/cargo/commands/rustdoc.rs cargo-0.35.0/src/bin/cargo/commands/rustdoc.rs --- cargo-0.33.0/src/bin/cargo/commands/rustdoc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/rustdoc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ -use command_prelude::*; - use cargo::ops::{self, DocOptions}; +use crate::command_prelude::*; + pub fn cli() -> App { subcommand("rustdoc") .setting(AppSettings::TrailingVarArg) @@ -34,13 +34,13 @@ .after_help( "\ The specified target for the current package (or package specified by SPEC if -provided) will be documented with the specified ... being passed to the +provided) will be documented with the specified `...` being passed to the final rustdoc invocation. Dependencies will not be documented as part of this -command. Note that rustdoc will still unconditionally receive arguments such -as -L, --extern, and --crate-type, and the specified ... will simply be -added to the rustdoc invocation. +command. Note that rustdoc will still unconditionally receive arguments such +as `-L`, `--extern`, and `--crate-type`, and the specified `...` will +simply be added to the rustdoc invocation. -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package should be documented. If it is not given, then the current package is documented. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -48,10 +48,13 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - let mut compile_opts = - args.compile_options_for_single_package(config, CompileMode::Doc { deps: false })?; + let mut compile_opts = args.compile_options_for_single_package( + config, + CompileMode::Doc { deps: false }, + Some(&ws), + )?; let target_args = values(args, "args"); compile_opts.target_rustdoc_args = if target_args.is_empty() { None diff -Nru cargo-0.33.0/src/bin/cargo/commands/search.rs cargo-0.35.0/src/bin/cargo/commands/search.rs --- cargo-0.33.0/src/bin/cargo/commands/search.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/search.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use std::cmp::min; @@ -13,12 +13,13 @@ opt( "limit", "Limit the number of results (default: 10, max: 100)", - ).value_name("LIMIT"), + ) + .value_name("LIMIT"), ) .arg(opt("registry", "Registry to use").value_name("REGISTRY")) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let registry = args.registry(config)?; let index = args.index(config)?; let limit = args.value_of_u32("limit")?; diff -Nru cargo-0.33.0/src/bin/cargo/commands/test.rs cargo-0.35.0/src/bin/cargo/commands/test.rs --- cargo-0.33.0/src/bin/cargo/commands/test.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/test.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,13 +1,13 @@ -use command_prelude::*; - use cargo::ops::{self, CompileFilter}; +use crate::command_prelude::*; + pub fn cli() -> App { subcommand("test") - // subcommand aliases are handled in aliased_command() + // Subcommand aliases are handled in `aliased_command()`. // .alias("t") .setting(AppSettings::TrailingVarArg) - .about("Execute all unit and integration tests of a local package") + .about("Execute all unit and integration tests and build examples of a local package") .arg( Arg::with_name("TESTNAME") .help("If specified, only run tests containing this string in their names"), @@ -19,7 +19,7 @@ .last(true), ) .arg_targets_all( - "Test only this package's library", + "Test only this package's library unit tests", "Test only the specified binary", "Test all binaries", "Test only the specified example", @@ -47,17 +47,17 @@ .arg_message_format() .after_help( "\ -The test filtering argument `TESTNAME` and all the arguments following the +The test filtering argument TESTNAME and all the arguments following the two dashes (`--`) are passed to the test binaries and thus to libtest -(rustc's built in unit-test and micro-benchmarking framework). If you're +(rustc's built in unit-test and micro-benchmarking framework). If you're passing arguments to both Cargo and the binary, the ones after `--` go to the -binary, the ones before go to Cargo. For details about libtest's arguments see -the output of `cargo test -- --help`. As an example, this will run all +binary, the ones before go to Cargo. For details about libtest's arguments see +the output of `cargo test -- --help`. As an example, this will run all tests with `foo` in their name on 3 threads in parallel: cargo test foo -- --test-threads 3 -If the --package argument is given, then SPEC is a package id specification +If the `--package` argument is given, then SPEC is a package ID specification which indicates which package should be tested. If it is not given, then the current package is tested. For more information on SPEC and its format, see the `cargo help pkgid` command. @@ -66,9 +66,9 @@ `--all` flag is automatically assumed for a virtual manifest. Note that `--exclude` has to be specified in conjunction with the `--all` flag. -The --jobs argument affects the building of the test executable but does +The `--jobs` argument affects the building of the test executable but does not affect how many jobs are used when running the tests. The default value -for the --jobs argument is the number of CPUs. If you want to control the +for the `--jobs` argument is the number of CPUs. If you want to control the number of simultaneous running test cases, pass the `--test-threads` option to the test binaries: @@ -77,7 +77,7 @@ Compilation can be configured via the `test` profile in the manifest. By default the rust test harness hides output from test execution to -keep results readable. Test output can be recovered (e.g. for debugging) +keep results readable. Test output can be recovered (e.g., for debugging) by passing `--nocapture` to the test binaries: cargo test -- --nocapture @@ -89,15 +89,25 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; - let mut compile_opts = args.compile_options(config, CompileMode::Test)?; + let mut compile_opts = args.compile_options(config, CompileMode::Test, Some(&ws))?; + let no_run = args.is_present("no-run"); let doc = args.is_present("doc"); if doc { if let CompileFilter::Only { .. } = compile_opts.filter { - return Err(CliError::new(format_err!("Can't mix --doc with other target selecting options"), 101)) + return Err(CliError::new( + failure::format_err!("Can't mix --doc with other target selecting options"), + 101, + )); + } + if no_run { + return Err(CliError::new( + failure::format_err!("Can't skip running doc tests with --no-run"), + 101, + )); } compile_opts.build_config.mode = CompileMode::Doctest; compile_opts.filter = ops::CompileFilter::new( @@ -115,13 +125,13 @@ } let ops = ops::TestOptions { - no_run: args.is_present("no-run"), + no_run, no_fail_fast: args.is_present("no-fail-fast"), compile_opts, }; - // TESTNAME is actually an argument of the test binary, but it's - // important so we explicitly mention it and reconfigure + // `TESTNAME` is actually an argument of the test binary, but it's + // important, so we explicitly mention it and reconfigure. let mut test_args = vec![]; test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string())); test_args.extend( @@ -134,7 +144,7 @@ match err { None => Ok(()), Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) { - Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i), + Some(i) => CliError::new(failure::format_err!("{}", err.hint(&ws)), i), None => CliError::new(err.into(), 101), }), } diff -Nru cargo-0.33.0/src/bin/cargo/commands/uninstall.rs cargo-0.35.0/src/bin/cargo/commands/uninstall.rs --- cargo-0.33.0/src/bin/cargo/commands/uninstall.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/uninstall.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -11,7 +11,7 @@ .arg(opt("root", "Directory to uninstall packages from").value_name("DIR")) .after_help( "\ -The argument SPEC is a package id specification (see `cargo help pkgid`) to +The argument SPEC is a package ID specification (see `cargo help pkgid`) to specify which crate should be uninstalled. By default all binaries are uninstalled for a crate but the `--bin` and `--example` flags can be used to only uninstall particular binaries. @@ -19,7 +19,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let root = args.value_of("root"); let specs = args .values_of("spec") diff -Nru cargo-0.33.0/src/bin/cargo/commands/update.rs cargo-0.35.0/src/bin/cargo/commands/update.rs --- cargo-0.33.0/src/bin/cargo/commands/update.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/update.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops::{self, UpdateOptions}; @@ -10,6 +10,7 @@ "aggressive", "Force updating all dependencies of as well", )) + .arg_dry_run("Don't actually write the lockfile") .arg(opt("precise", "Update a single dependency to exactly PRECISE").value_name("PRECISE")) .arg_manifest_path() .after_help( @@ -20,10 +21,10 @@ If SPEC is given, then a conservative update of the lockfile will be performed. This means that only the dependency specified by SPEC will be updated. Its transitive dependencies will be updated only if SPEC cannot be -updated without updating dependencies. All other dependencies will remain +updated without updating dependencies. All other dependencies will remain locked at their currently recorded versions. -If PRECISE is specified, then --aggressive must not also be specified. The +If PRECISE is specified, then `--aggressive` must not also be specified. The argument PRECISE is a string representing a precise revision that the package being updated should be updated to. For example, if the package comes from a git repository, then PRECISE would be the exact revision that the repository should @@ -32,18 +33,19 @@ If SPEC is not given, then all dependencies will be re-resolved and updated. -For more information about package id specifications, see `cargo help pkgid`. +For more information about package ID specifications, see `cargo help pkgid`. ", ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let ws = args.workspace(config)?; let update_opts = UpdateOptions { aggressive: args.is_present("aggressive"), precise: args.value_of("precise"), to_update: values(args, "package"), + dry_run: args.is_present("dry-run"), config, }; ops::update_lockfile(&ws, &update_opts)?; diff -Nru cargo-0.33.0/src/bin/cargo/commands/verify_project.rs cargo-0.35.0/src/bin/cargo/commands/verify_project.rs --- cargo-0.33.0/src/bin/cargo/commands/verify_project.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/verify_project.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use std::collections::HashMap; use std::process; @@ -11,7 +11,7 @@ .arg_manifest_path() } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { fn fail(reason: &str, value: &str) -> ! { let mut h = HashMap::new(); h.insert(reason.to_string(), value.to_string()); diff -Nru cargo-0.33.0/src/bin/cargo/commands/version.rs cargo-0.35.0/src/bin/cargo/commands/version.rs --- cargo-0.33.0/src/bin/cargo/commands/version.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/version.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,12 +1,12 @@ -use command_prelude::*; +use crate::command_prelude::*; -use cli; +use crate::cli; pub fn cli() -> App { subcommand("version").about("Show version information") } -pub fn exec(_config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(_config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let verbose = args.occurrences_of("verbose") > 0; let version = cli::get_version_string(verbose); print!("{}", version); diff -Nru cargo-0.33.0/src/bin/cargo/commands/yank.rs cargo-0.35.0/src/bin/cargo/commands/yank.rs --- cargo-0.33.0/src/bin/cargo/commands/yank.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/commands/yank.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use command_prelude::*; +use crate::command_prelude::*; use cargo::ops; @@ -27,7 +27,7 @@ ) } -pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { +pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let registry = args.registry(config)?; ops::yank( diff -Nru cargo-0.33.0/src/bin/cargo/main.rs cargo-0.35.0/src/bin/cargo/main.rs --- cargo-0.33.0/src/bin/cargo/main.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/bin/cargo/main.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,20 +1,6 @@ -#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] // large project -#![cfg_attr(feature = "cargo-clippy", allow(clippy::redundant_closure))] // there's a false positive - -extern crate cargo; -extern crate clap; -#[cfg(feature = "pretty-env-logger")] -extern crate pretty_env_logger; -#[cfg(not(feature = "pretty-env-logger"))] -extern crate env_logger; -#[macro_use] -extern crate failure; -extern crate git2_curl; -extern crate log; -#[macro_use] -extern crate serde_derive; -extern crate serde_json; -extern crate toml; +#![warn(rust_2018_idioms)] // while we're getting used to 2018 +#![allow(clippy::too_many_arguments)] // large project +#![allow(clippy::redundant_closure)] // there's a false positive use std::collections::BTreeSet; use std::env; @@ -28,7 +14,7 @@ mod cli; mod commands; -use command_prelude::*; +use crate::command_prelude::*; fn main() { #[cfg(feature = "pretty-env-logger")] @@ -147,12 +133,12 @@ Some(command) => command, None => { let err = match find_closest(config, cmd) { - Some(closest) => format_err!( + Some(closest) => failure::format_err!( "no such subcommand: `{}`\n\n\tDid you mean `{}`?\n", cmd, closest ), - None => format_err!("no such subcommand: `{}`", cmd), + None => failure::format_err!("no such subcommand: `{}`", cmd), }; return Err(CliError::new(err, 101)); } diff -Nru cargo-0.33.0/src/cargo/core/compiler/build_config.rs cargo-0.35.0/src/cargo/core/compiler/build_config.rs --- cargo-0.33.0/src/cargo/core/compiler/build_config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/build_config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,43 +3,44 @@ use serde::ser; -use util::{CargoResult, CargoResultExt, Config, RustfixDiagnosticServer}; +use crate::util::{CargoResult, CargoResultExt, Config, RustfixDiagnosticServer}; /// Configuration information for a rustc build. #[derive(Debug)] pub struct BuildConfig { - /// The target arch triple, defaults to host arch + /// The target arch triple. + /// Default: host arch. pub requested_target: Option, - /// How many rustc jobs to run in parallel + /// Number of rustc jobs to run in parallel. pub jobs: u32, - /// Whether we are building for release + /// `true` if we are building for release. pub release: bool, - /// In what mode we are compiling + /// The mode we are compiling in. pub mode: CompileMode, - /// Whether to print std output in json format (for machine reading) + /// `true` to print stdout in JSON format (for machine reading). pub message_format: MessageFormat, - /// Force cargo to do a full rebuild and treat each target as changed. + /// Force Cargo to do a full rebuild and treat each target as changed. pub force_rebuild: bool, /// Output a build plan to stdout instead of actually compiling. pub build_plan: bool, - /// Use Cargo itself as the wrapper around rustc, only used for `cargo fix` + /// Use Cargo itself as the wrapper around rustc, only used for `cargo fix`. pub cargo_as_rustc_wrapper: bool, - /// Extra env vars to inject into rustc commands + /// Extra env vars to inject into rustc commands. pub extra_rustc_env: Vec<(String, String)>, - /// Extra args to inject into rustc commands + /// Extra args to inject into rustc commands. pub extra_rustc_args: Vec, pub rustfix_diagnostic_server: RefCell>, } impl BuildConfig { - /// Parse all config files to learn about build configuration. Currently + /// Parses all config files to learn about build configuration. Currently /// configured options are: /// - /// * build.jobs - /// * build.target - /// * target.$target.ar - /// * target.$target.linker - /// * target.$target.libfoo.metadata + /// * `build.jobs` + /// * `build.target` + /// * `target.$target.ar` + /// * `target.$target.linker` + /// * `target.$target.libfoo.metadata` pub fn new( config: &Config, jobs: Option, @@ -48,27 +49,27 @@ ) -> CargoResult { let requested_target = match requested_target { &Some(ref target) if target.ends_with(".json") => { - let path = Path::new(target) - .canonicalize() - .chain_err(|| format_err!("Target path {:?} is not a valid file", target))?; + let path = Path::new(target).canonicalize().chain_err(|| { + failure::format_err!("Target path {:?} is not a valid file", target) + })?; Some( path.into_os_string() .into_string() - .map_err(|_| format_err!("Target path is not valid unicode"))?, + .map_err(|_| failure::format_err!("Target path is not valid unicode"))?, ) } other => other.clone(), }; if let Some(ref s) = requested_target { if s.trim().is_empty() { - bail!("target was empty") + failure::bail!("target was empty") } } let cfg_target = config.get_string("build.target")?.map(|s| s.val); - let target = requested_target.clone().or(cfg_target); + let target = requested_target.or(cfg_target); if jobs == Some(0) { - bail!("jobs must be at least 1") + failure::bail!("jobs must be at least 1") } if jobs.is_some() && config.jobserver_from_env().is_some() { config.shell().warn( @@ -110,10 +111,10 @@ Short, } -/// The general "mode" of what to do. -/// This is used for two purposes. The commands themselves pass this in to -/// `compile_ws` to tell it the general execution strategy. This influences -/// the default targets selected. The other use is in the `Unit` struct +/// The general "mode" for what to do. +/// This is used for two purposes. The commands themselves pass this in to +/// `compile_ws` to tell it the general execution strategy. This influences +/// the default targets selected. The other use is in the `Unit` struct /// to indicate what is being done with a specific target. #[derive(Clone, Copy, PartialEq, Debug, Eq, Hash, PartialOrd, Ord)] pub enum CompileMode { @@ -125,8 +126,8 @@ /// `test` is true, then it is also compiled with `--test` to check it like /// a test. Check { test: bool }, - /// Used to indicate benchmarks should be built. This is not used in - /// `Target` because it is essentially the same as `Test` (indicating + /// Used to indicate benchmarks should be built. This is not used in + /// `Target`, because it is essentially the same as `Test` (indicating /// `--test` should be passed to rustc) and by using `Test` instead it /// allows some de-duping of Units to occur. Bench, @@ -135,8 +136,7 @@ Doc { deps: bool }, /// A target that will be tested with `rustdoc`. Doctest, - /// A marker for Units that represent the execution of a `build.rs` - /// script. + /// A marker for Units that represent the execution of a `build.rs` script. RunCustomBuild, } @@ -159,7 +159,7 @@ } impl CompileMode { - /// Returns true if the unit is being checked. + /// Returns `true` if the unit is being checked. pub fn is_check(self) -> bool { match self { CompileMode::Check { .. } => true, @@ -167,7 +167,7 @@ } } - /// Returns true if this is a doc or doctest. Be careful using this. + /// Returns `true` if this is a doc or doc test. Be careful using this. /// Although both run rustdoc, the dependencies for those two modes are /// very different. pub fn is_doc(self) -> bool { @@ -177,8 +177,8 @@ } } - /// Returns true if this is any type of test (test, benchmark, doctest, or - /// check-test). + /// Returns `true` if this is any type of test (test, benchmark, doc test, or + /// check test). pub fn is_any_test(self) -> bool { match self { CompileMode::Test @@ -189,7 +189,7 @@ } } - /// Returns true if this is the *execution* of a `build.rs` script. + /// Returns `true` if this is the *execution* of a `build.rs` script. pub fn is_run_custom_build(self) -> bool { self == CompileMode::RunCustomBuild } diff -Nru cargo-0.33.0/src/cargo/core/compiler/build_context/mod.rs cargo-0.35.0/src/cargo/core/compiler/build_context/mod.rs --- cargo-0.33.0/src/cargo/core/compiler/build_context/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/build_context/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,24 +3,26 @@ use std::path::{Path, PathBuf}; use std::str; -use core::profiles::Profiles; -use core::{Dependency, Workspace}; -use core::{PackageId, PackageSet, Resolve}; -use util::errors::CargoResult; -use util::{profile, Cfg, CfgExpr, Config, Rustc}; +use log::debug; + +use crate::core::profiles::Profiles; +use crate::core::{Dependency, Workspace}; +use crate::core::{PackageId, PackageSet, Resolve}; +use crate::util::errors::CargoResult; +use crate::util::{profile, Cfg, CfgExpr, Config, Rustc}; use super::{BuildConfig, BuildOutput, Kind, Unit}; mod target_info; pub use self::target_info::{FileFlavor, TargetInfo}; -/// The build context, containing all information about a build task +/// The build context, containing all information about a build task. pub struct BuildContext<'a, 'cfg: 'a> { - /// The workspace the build is for + /// The workspace the build is for. pub ws: &'a Workspace<'cfg>, - /// The cargo configuration + /// The cargo configuration. pub config: &'cfg Config, - /// The dependency graph for our build + /// The dependency graph for our build. pub resolve: &'a Resolve, pub profiles: &'a Profiles, pub build_config: &'a BuildConfig, @@ -28,15 +30,14 @@ pub extra_compiler_args: HashMap, Vec>, pub packages: &'a PackageSet<'cfg>, - /// Information about the compiler + /// Information about the compiler. pub rustc: Rustc, - /// Build information for the host arch + /// Build information for the host arch. pub host_config: TargetConfig, - /// Build information for the target + /// Build information for the target. pub target_config: TargetConfig, pub target_info: TargetInfo, pub host_info: TargetInfo, - pub incremental_env: Option, } impl<'a, 'cfg> BuildContext<'a, 'cfg> { @@ -49,11 +50,6 @@ profiles: &'a Profiles, extra_compiler_args: HashMap, Vec>, ) -> CargoResult> { - let incremental_env = match env::var("CARGO_INCREMENTAL") { - Ok(v) => Some(v == "1"), - Err(_) => None, - }; - let rustc = config.rustc(Some(ws))?; let host_config = TargetConfig::new(config, &rustc.host)?; let target_config = match build_config.requested_target.as_ref() { @@ -82,7 +78,6 @@ host_info, build_config, profiles, - incremental_env, extra_compiler_args, }) } @@ -108,17 +103,17 @@ platform.matches(name, info.cfg()) } - /// Get the user-specified linker for a particular host or target + /// Gets the user-specified linker for a particular host or target. pub fn linker(&self, kind: Kind) -> Option<&Path> { self.target_config(kind).linker.as_ref().map(|s| s.as_ref()) } - /// Get the user-specified `ar` program for a particular host or target + /// Gets the user-specified `ar` program for a particular host or target. pub fn ar(&self, kind: Kind) -> Option<&Path> { self.target_config(kind).ar.as_ref().map(|s| s.as_ref()) } - /// Get the list of cfg printed out from the compiler for the specified kind + /// Gets the list of `cfg`s printed out from the compiler for the specified kind. pub fn cfg(&self, kind: Kind) -> &[Cfg] { let info = match kind { Kind::Host => &self.host_info, @@ -127,12 +122,12 @@ info.cfg().unwrap_or(&[]) } - /// The host arch triple + /// Gets the host architecture triple. /// - /// e.g. x86_64-unknown-linux-gnu, would be - /// - machine: x86_64 - /// - hardware-platform: unknown - /// - operating system: linux-gnu + /// For example, x86_64-unknown-linux-gnu, would be + /// - machine: x86_64, + /// - hardware-platform: unknown, + /// - operating system: linux-gnu. pub fn host_triple(&self) -> &str { &self.rustc.host } @@ -145,7 +140,7 @@ .unwrap_or_else(|| self.host_triple()) } - /// Get the target configuration for a particular host or target + /// Gets the target configuration for a particular host or target. fn target_config(&self, kind: Kind) -> &TargetConfig { match kind { Kind::Host => &self.host_config, @@ -153,12 +148,12 @@ } } - /// Number of jobs specified for this build + /// Gets the number of jobs specified for this build. pub fn jobs(&self) -> u32 { self.build_config.jobs } - pub fn rustflags_args(&self, unit: &Unit) -> CargoResult> { + pub fn rustflags_args(&self, unit: &Unit<'_>) -> CargoResult> { env_args( self.config, &self.build_config.requested_target, @@ -169,7 +164,7 @@ ) } - pub fn rustdocflags_args(&self, unit: &Unit) -> CargoResult> { + pub fn rustdocflags_args(&self, unit: &Unit<'_>) -> CargoResult> { env_args( self.config, &self.build_config.requested_target, @@ -196,14 +191,14 @@ } } -/// Information required to build for a target +/// Information required to build for a target. #[derive(Clone, Default)] pub struct TargetConfig { /// The path of archiver (lib builder) for this target. pub ar: Option, /// The path of the linker for this target. pub linker: Option, - /// Special build options for any necessary input files (filename -> options) + /// Special build options for any necessary input files (filename -> options). pub overrides: HashMap, } @@ -274,7 +269,7 @@ } } "warning" | "rerun-if-changed" | "rerun-if-env-changed" => { - bail!("`{}` is not supported in build script overrides", k); + failure::bail!("`{}` is not supported in build script overrides", k); } _ => { let val = value.string(k)?.0; @@ -330,7 +325,7 @@ // to compilation units with the Target kind, which indicates // it was chosen by the --target flag. // - // This means that, e.g. even if the specified --target is the + // This means that, e.g., even if the specified --target is the // same as the host, build scripts in plugins won't get // RUSTFLAGS. let compiling_with_target = requested_target.is_some(); @@ -400,7 +395,7 @@ return Ok(rustflags); } - // Then the build.rustflags value + // Then the `build.rustflags` value. let key = format!("build.{}", name); if let Some(args) = config.get_list_or_split_string(&key)? { let args = args.val.into_iter(); diff -Nru cargo-0.33.0/src/cargo/core/compiler/build_context/target_info.rs cargo-0.35.0/src/cargo/core/compiler/build_context/target_info.rs --- cargo-0.33.0/src/cargo/core/compiler/build_context/target_info.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/build_context/target_info.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,8 +5,8 @@ use super::env_args; use super::Kind; -use core::TargetKind; -use util::{CargoResult, CargoResultExt, Cfg, Config, ProcessBuilder, Rustc}; +use crate::core::TargetKind; +use crate::util::{CargoResult, CargoResultExt, Cfg, Config, ProcessBuilder, Rustc}; #[derive(Clone)] pub struct TargetInfo { @@ -21,9 +21,9 @@ pub enum FileFlavor { /// Not a special file type. Normal, - /// It is something you can link against (e.g. a library) + /// Something you can link against (e.g., a library). Linkable, - /// It is a piece of external debug information (e.g. *.dSYM and *.pdb) + /// Piece of external debug information (e.g., `.dSYM`/`.pdb` file). DebugInfo, } @@ -31,7 +31,7 @@ pub flavor: FileFlavor, suffix: String, prefix: String, - // wasm bin target will generate two files in deps such as + // Wasm bin target will generate two files in deps such as // "web-stuff.js" and "web_stuff.wasm". Note the different usages of // "-" and "_". should_replace_hyphens is a flag to indicate that // we need to convert the stem "web-stuff" to "web_stuff", so we @@ -113,7 +113,7 @@ if has_cfg_and_sysroot { let line = match lines.next() { Some(line) => line, - None => bail!( + None => failure::bail!( "output of --print=sysroot missing when learning about \ target-specific information from rustc" ), @@ -180,7 +180,7 @@ should_replace_hyphens: false, }]; - // rust-lang/cargo#4500 + // See rust-lang/cargo#4500. if target_triple.ends_with("pc-windows-msvc") && crate_type.ends_with("dylib") && suffix == ".dll" @@ -193,7 +193,7 @@ }) } - // rust-lang/cargo#4535 + // See rust-lang/cargo#4535. if target_triple.starts_with("wasm32-") && crate_type == "bin" && suffix == ".js" { ret.push(FileType { suffix: ".wasm".to_string(), @@ -203,10 +203,10 @@ }) } - // rust-lang/cargo#4490, rust-lang/cargo#4960 - // - only uplift debuginfo for binaries. - // tests are run directly from target/debug/deps/ - // and examples are inside target/debug/examples/ which already have symbols next to them + // See rust-lang/cargo#4490, rust-lang/cargo#4960. + // - Only uplift debuginfo for binaries. + // Tests are run directly from `target/debug/deps/` + // and examples are inside target/debug/examples/ which already have symbols next to them, // so no need to do anything. if *kind == TargetKind::Bin { if target_triple.contains("-apple-") { @@ -249,17 +249,18 @@ } /// Takes rustc output (using specialized command line args), and calculates the file prefix and -/// suffix for the given crate type, or returns None if the type is not supported. (e.g. for a -/// rust library like libcargo.rlib, prefix = "lib", suffix = "rlib"). +/// suffix for the given crate type, or returns `None` if the type is not supported. (e.g., for a +/// Rust library like `libcargo.rlib`, we have prefix "lib" and suffix "rlib"). /// /// The caller needs to ensure that the lines object is at the correct line for the given crate /// type: this is not checked. -// This function can not handle more than 1 file per type (with wasm32-unknown-emscripten, there -// are 2 files for bin (.wasm and .js)) +// +// This function can not handle more than one file per type (with wasm32-unknown-emscripten, there +// are two files for bin (`.wasm` and `.js`)). fn parse_crate_type( crate_type: &str, error: &str, - lines: &mut str::Lines, + lines: &mut str::Lines<'_>, ) -> CargoResult> { let not_supported = error.lines().any(|line| { (line.contains("unsupported crate type") || line.contains("unknown crate type")) @@ -270,7 +271,7 @@ } let line = match lines.next() { Some(line) => line, - None => bail!( + None => failure::bail!( "malformed output when learning about \ crate-type {} information", crate_type @@ -280,7 +281,7 @@ let prefix = parts.next().unwrap(); let suffix = match parts.next() { Some(part) => part, - None => bail!( + None => failure::bail!( "output of --print=file-names has changed in \ the compiler, cannot parse" ), diff -Nru cargo-0.33.0/src/cargo/core/compiler/build_plan.rs cargo-0.35.0/src/cargo/core/compiler/build_plan.rs --- cargo-0.33.0/src/cargo/core/compiler/build_plan.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/build_plan.rs 2019-04-01 21:32:07.000000000 +0000 @@ -7,14 +7,14 @@ //! dependencies on other Invocations. use std::collections::BTreeMap; +use std::path::PathBuf; + +use serde::Serialize; use super::context::OutputFile; use super::{CompileMode, Context, Kind, Unit}; -use core::TargetKind; -use semver; -use serde_json; -use std::path::PathBuf; -use util::{internal, CargoResult, ProcessBuilder}; +use crate::core::TargetKind; +use crate::util::{internal, CargoResult, ProcessBuilder}; #[derive(Debug, Serialize)] struct Invocation { @@ -45,7 +45,7 @@ } impl Invocation { - pub fn new(unit: &Unit, deps: Vec) -> Invocation { + pub fn new(unit: &Unit<'_>, deps: Vec) -> Invocation { let id = unit.pkg.package_id(); Invocation { package_name: id.name().to_string(), @@ -74,13 +74,13 @@ self.program = cmd .get_program() .to_str() - .ok_or_else(|| format_err!("unicode program string required"))? + .ok_or_else(|| failure::format_err!("unicode program string required"))? .to_string(); self.cwd = Some(cmd.get_cwd().unwrap().to_path_buf()); for arg in cmd.get_args().iter() { self.args.push( arg.to_str() - .ok_or_else(|| format_err!("unicode argument string required"))? + .ok_or_else(|| failure::format_err!("unicode argument string required"))? .to_string(), ); } @@ -93,7 +93,7 @@ var.clone(), value .to_str() - .ok_or_else(|| format_err!("unicode environment value required"))? + .ok_or_else(|| failure::format_err!("unicode environment value required"))? .to_string(), ); } @@ -109,7 +109,7 @@ } } - pub fn add(&mut self, cx: &Context, unit: &Unit) -> CargoResult<()> { + pub fn add(&mut self, cx: &Context<'_, '_>, unit: &Unit<'_>) -> CargoResult<()> { let id = self.plan.invocations.len(); self.invocation_map.insert(unit.buildkey(), id); let deps = cx diff -Nru cargo-0.33.0/src/cargo/core/compiler/compilation.rs cargo-0.35.0/src/cargo/core/compiler/compilation.rs --- cargo-0.33.0/src/cargo/core/compiler/compilation.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/compilation.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,11 +6,11 @@ use semver::Version; use super::BuildContext; -use core::{Edition, Package, PackageId, Target, TargetKind}; -use util::{self, join_paths, process, CargoResult, CfgExpr, Config, ProcessBuilder}; +use crate::core::{Edition, Package, PackageId, Target, TargetKind}; +use crate::util::{self, join_paths, process, CargoResult, CfgExpr, Config, ProcessBuilder}; pub struct Doctest { - /// The package being doctested. + /// The package being doc-tested. pub package: Package, /// The target being tested (currently always the package's lib). pub target: Target, @@ -89,6 +89,9 @@ } else { bcx.rustc.process() }; + if bcx.config.extra_verbose() { + rustc.display_env_vars(); + } for (k, v) in bcx.build_config.extra_rustc_env.iter() { rustc.env(k, v); } @@ -100,7 +103,8 @@ server.configure(&mut rustc); } Ok(Compilation { - native_dirs: BTreeSet::new(), // TODO: deprecated, remove + // TODO: deprecated; remove. + native_dirs: BTreeSet::new(), root_output: PathBuf::from("/"), deps_output: PathBuf::from("/"), host_deps_output: PathBuf::from("/"), @@ -193,6 +197,17 @@ }; search_path.extend(util::dylib_path().into_iter()); + if cfg!(target_os = "macos") { + // These are the defaults when DYLD_FALLBACK_LIBRARY_PATH isn't + // set. Since Cargo is explicitly setting the value, make sure the + // defaults still work. + if let Ok(home) = env::var("HOME") { + search_path.push(PathBuf::from(home).join("lib")); + } + search_path.push(PathBuf::from("/usr/local/lib")); + search_path.push(PathBuf::from("/lib")); + search_path.push(PathBuf::from("/usr/lib")); + } let search_path = join_paths(&search_path, util::dylib_path_envvar())?; cmd.env(util::dylib_path_envvar(), &search_path); @@ -205,7 +220,7 @@ let metadata = pkg.manifest().metadata(); let cargo_exe = self.config.cargo_exe()?; - cmd.env(::CARGO_ENV, cargo_exe); + cmd.env(crate::CARGO_ENV, cargo_exe); // When adding new environment variables depending on // crate properties which might require rebuild upon change @@ -256,7 +271,7 @@ ret } -fn target_runner(bcx: &BuildContext) -> CargoResult)>> { +fn target_runner(bcx: &BuildContext<'_, '_>) -> CargoResult)>> { let target = bcx.target_triple(); // try target.{}.runner @@ -276,7 +291,7 @@ if let Some(runner) = bcx.config.get_path_and_args(&key)? { // more than one match, error out if matching_runner.is_some() { - bail!( + failure::bail!( "several matching instances of `target.'cfg(..)'.runner` \ in `.cargo/config`" ) diff -Nru cargo-0.33.0/src/cargo/core/compiler/context/compilation_files.rs cargo-0.35.0/src/cargo/core/compiler/context/compilation_files.rs --- cargo-0.33.0/src/cargo/core/compiler/context/compilation_files.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/context/compilation_files.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,24 +6,53 @@ use std::sync::Arc; use lazycell::LazyCell; +use log::info; use super::{BuildContext, Context, FileFlavor, Kind, Layout, Unit}; -use core::{TargetKind, Workspace}; -use util::{self, CargoResult}; +use crate::core::{TargetKind, Workspace}; +use crate::util::{self, CargoResult}; +/// The `Metadata` is a hash used to make unique file names for each unit in a build. +/// For example: +/// - A project may depend on crate `A` and crate `B`, so the package name must be in the file name. +/// - Similarly a project may depend on two versions of `A`, so the version must be in the file name. +/// In general this must include all things that need to be distinguished in different parts of +/// the same build. This is absolutely required or we override things before +/// we get chance to use them. +/// +/// We use a hash because it is an easy way to guarantee +/// that all the inputs can be converted to a valid path. +/// +/// This also acts as the main layer of caching provided by Cargo. +/// For example, we want to cache `cargo build` and `cargo doc` separately, so that running one +/// does not invalidate the artifacts for the other. We do this by including `CompileMode` in the +/// hash, thus the artifacts go in different folders and do not override each other. +/// If we don't add something that we should have, for this reason, we get the +/// correct output but rebuild more than is needed. +/// +/// Some things that need to be tracked to ensure the correct output should definitely *not* +/// go in the `Metadata`. For example, the modification time of a file, should be tracked to make a +/// rebuild when the file changes. However, it would be wasteful to include in the `Metadata`. The +/// old artifacts are never going to be needed again. We can save space by just overwriting them. +/// If we add something that we should not have, for this reason, we get the correct output but take +/// more space than needed. This makes not including something in `Metadata` +/// a form of cache invalidation. +/// +/// Note that the `Fingerprint` is in charge of tracking everything needed to determine if a +/// rebuild is needed. #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Metadata(u64); impl fmt::Display for Metadata { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:016x}", self.0) } } pub struct CompilationFiles<'a, 'cfg: 'a> { - /// The target directory layout for the host (and target if it is the same as host) + /// The target directory layout for the host (and target if it is the same as host). pub(super) host: Layout, - /// The target directory layout for the target (if different from then host) + /// The target directory layout for the target (if different from then host). pub(super) target: Option, /// Additional directory to include a copy of the outputs. export_dir: Option, @@ -41,7 +70,7 @@ /// Absolute path to the file that will be produced by the build process. pub path: PathBuf, /// If it should be linked into `target`, and what it should be called - /// (e.g. without metadata). + /// (e.g., without metadata). pub hardlink: Option, /// If `--out-dir` is specified, the absolute path to the exported file. pub export_path: Option, @@ -49,6 +78,16 @@ pub flavor: FileFlavor, } +impl OutputFile { + /// Gets the hard link if present; otherwise, returns the path. + pub fn bin_dst(&self) -> &PathBuf { + match self.hardlink { + Some(ref link_dst) => link_dst, + None => &self.path, + } + } +} + impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { pub(super) fn new( roots: &[Unit<'a>], @@ -86,17 +125,17 @@ } } - /// Get the metadata for a target in a specific profile - /// We build to the path: "{filename}-{target_metadata}" + /// Gets the metadata for a target in a specific profile. + /// We build to the path `"{filename}-{target_metadata}"`. /// We use a linking step to link/copy to a predictable filename /// like `target/debug/libfoo.{a,so,rlib}` and such. pub fn metadata(&self, unit: &Unit<'a>) -> Option { self.metas[unit].clone() } - /// Get the short hash based only on the PackageId - /// Used for the metadata when target_metadata returns None - pub fn target_short_hash(&self, unit: &Unit) -> String { + /// Gets the short hash based only on the `PackageId`. + /// Used for the metadata when `target_metadata` returns `None`. + pub fn target_short_hash(&self, unit: &Unit<'_>) -> String { let hashable = unit.pkg.package_id().stable_hash(self.ws.root()); util::short_hash(&hashable) } @@ -127,7 +166,7 @@ } } - /// Return the root of the build output tree + /// Returns the root of the build output tree. pub fn target_root(&self) -> &Path { self.host.dest() } @@ -138,7 +177,7 @@ /// Returns the directories where Rust crate dependencies are found for the /// specified unit. - pub fn deps_dir(&self, unit: &Unit) -> &Path { + pub fn deps_dir(&self, unit: &Unit<'_>) -> &Path { self.layout(unit.kind).deps() } @@ -163,7 +202,7 @@ self.layout(unit.kind).build().join(dir).join("out") } - /// Returns the file stem for a given target/profile combo (with metadata) + /// Returns the file stem for a given target/profile combo (with metadata). pub fn file_stem(&self, unit: &Unit<'a>) -> String { match self.metas[unit] { Some(ref metadata) => format!("{}-{}", unit.target.crate_name(), metadata), @@ -181,8 +220,8 @@ .map(Arc::clone) } - /// Returns the bin stem for a given target (without metadata) - fn bin_stem(&self, unit: &Unit) -> String { + /// Returns the bin stem for a given target (without metadata). + fn bin_stem(&self, unit: &Unit<'_>) -> String { if unit.target.allows_underscores() { unit.target.name().to_string() } else { @@ -194,10 +233,10 @@ /// our target to be copied to. Eg, file_stem may be out_dir/deps/foo-abcdef /// and link_stem would be out_dir/foo /// This function returns it in two parts so the caller can add prefix/suffix - /// to filename separately + /// to filename separately. /// - /// Returns an Option because in some cases we don't want to link - /// (eg a dependent lib) + /// Returns an `Option` because in some cases we don't want to link + /// (eg a dependent lib). fn link_stem(&self, unit: &Unit<'a>) -> Option<(PathBuf, String)> { let out_dir = self.out_dir(unit); let bin_stem = self.bin_stem(unit); @@ -207,7 +246,7 @@ // it was compiled into something like `example/` or `doc/` then // we don't want to link it up. if out_dir.ends_with("deps") { - // Don't lift up library dependencies + // Don't lift up library dependencies. if unit.target.is_bin() || self.roots.contains(unit) { Some(( out_dir.parent().unwrap().to_owned(), @@ -237,7 +276,7 @@ let out_dir = self.out_dir(unit); let file_stem = self.file_stem(unit); let link_stem = self.link_stem(unit); - let info = if unit.target.for_host() { + let info = if unit.kind == Kind::Host { &bcx.host_info } else { &bcx.target_info @@ -294,14 +333,14 @@ }); } } - // not supported, don't worry about it + // Not supported; don't worry about it. None => { unsupported.push(crate_type.to_string()); } } Ok(()) }; - //info!("{:?}", unit); + // info!("{:?}", unit); match *unit.target.kind() { TargetKind::Bin | TargetKind::CustomBuild @@ -330,7 +369,7 @@ } if ret.is_empty() { if !unsupported.is_empty() { - bail!( + failure::bail!( "cannot produce {} for `{}` as the target `{}` \ does not support these crate types", unsupported.join(", "), @@ -338,7 +377,7 @@ bcx.target_triple() ) } - bail!( + failure::bail!( "cannot compile `{}` as the target `{}` does not \ support any of the output crate types", unit.pkg, @@ -371,18 +410,18 @@ cx: &Context<'a, 'cfg>, metas: &mut HashMap, Option>, ) -> Option { - // No metadata for dylibs because of a couple issues - // - OSX encodes the dylib name in the executable - // - Windows rustc multiple files of which we can't easily link all of them + // No metadata for dylibs because of a couple issues: + // - macOS encodes the dylib name in the executable, + // - Windows rustc multiple files of which we can't easily link all of them. // - // No metadata for bin because of an issue - // - wasm32 rustc/emcc encodes the .wasm name in the .js (rust-lang/cargo#4535) + // No metadata for bin because of an issue: + // - wasm32 rustc/emcc encodes the `.wasm` name in the `.js` (rust-lang/cargo#4535). // - // Two exceptions - // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict) - // 2) __CARGO_DEFAULT_LIB_METADATA env var + // Two exceptions: + // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict), + // 2) `__CARGO_DEFAULT_LIB_METADATA` env var. // - // Note, though, that the compiler's build system at least wants + // Note, however, that the compiler's build system at least wants // path dependencies (eg libstd) to have hashes in filenames. To account for // that we have an extra hack here which reads the // `__CARGO_DEFAULT_LIB_METADATA` environment variable and creates a @@ -415,14 +454,14 @@ 1.hash(&mut hasher); // Unique metadata per (name, source, version) triple. This'll allow us - // to pull crates from anywhere w/o worrying about conflicts + // to pull crates from anywhere without worrying about conflicts. unit.pkg .package_id() .stable_hash(bcx.ws.root()) .hash(&mut hasher); // Add package properties which map to environment variables - // exposed by Cargo + // exposed by Cargo. let manifest_metadata = unit.pkg.manifest().metadata(); manifest_metadata.authors.hash(&mut hasher); manifest_metadata.description.hash(&mut hasher); @@ -434,7 +473,7 @@ .features_sorted(unit.pkg.package_id()) .hash(&mut hasher); - // Mix in the target-metadata of all the dependencies of this target + // Mix in the target-metadata of all the dependencies of this target. { let mut deps_metadata = cx .dep_targets(unit) @@ -446,7 +485,7 @@ } // Throw in the profile we're compiling with. This helps caching - // panic=abort and panic=unwind artifacts, additionally with various + // `panic=abort` and `panic=unwind` artifacts, additionally with various // settings like debuginfo and whatnot. unit.profile.hash(&mut hasher); unit.mode.hash(&mut hasher); @@ -454,6 +493,15 @@ args.hash(&mut hasher); } + // Throw in the rustflags we're compiling with. + // This helps when the target directory is a shared cache for projects with different cargo configs, + // or if the user is experimenting with different rustflags manually. + if unit.mode.is_doc() { + cx.bcx.rustdocflags_args(unit).ok().hash(&mut hasher); + } else { + cx.bcx.rustflags_args(unit).ok().hash(&mut hasher); + } + // Artifacts compiled for the host should have a different metadata // piece than those compiled for the target, so make sure we throw in // the unit's `kind` as well @@ -466,7 +514,7 @@ bcx.rustc.verbose_version.hash(&mut hasher); - // Seed the contents of __CARGO_DEFAULT_LIB_METADATA to the hasher if present. + // Seed the contents of `__CARGO_DEFAULT_LIB_METADATA` to the hasher if present. // This should be the release channel, to get a different hash for each channel. if let Ok(ref channel) = __cargo_default_lib_metadata { channel.hash(&mut hasher); diff -Nru cargo-0.33.0/src/cargo/core/compiler/context/mod.rs cargo-0.35.0/src/cargo/core/compiler/context/mod.rs --- cargo-0.33.0/src/cargo/core/compiler/context/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/context/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -7,11 +7,11 @@ use jobserver::Client; -use core::compiler::compilation; -use core::profiles::Profile; -use core::{Package, PackageId, Resolve, Target}; -use util::errors::{CargoResult, CargoResultExt}; -use util::{internal, profile, short_hash, Config}; +use crate::core::compiler::compilation; +use crate::core::profiles::Profile; +use crate::core::{Package, PackageId, Resolve, Target}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{internal, profile, short_hash, Config}; use super::build_plan::BuildPlan; use super::custom_build::{self, BuildDeps, BuildScripts, BuildState}; @@ -27,7 +27,7 @@ use self::compilation_files::CompilationFiles; pub use self::compilation_files::{Metadata, OutputFile}; -/// All information needed to define a Unit. +/// All information needed to define a unit. /// /// A unit is an object that has enough information so that cargo knows how to build it. /// For example, if your package has dependencies, then every dependency will be built as a library @@ -60,8 +60,7 @@ /// the host architecture so the host rustc can use it (when compiling to the target /// architecture). pub kind: Kind, - /// The "mode" this unit is being compiled for. See `CompileMode` for - /// more details. + /// The "mode" this unit is being compiled for. See [`CompileMode`] for more details. pub mode: CompileMode, } @@ -129,7 +128,7 @@ mut self, units: &[Unit<'a>], export_dir: Option, - exec: &Arc, + exec: &Arc, ) -> CargoResult> { let mut queue = JobQueue::new(self.bcx); let mut plan = BuildPlan::new(); @@ -163,10 +162,7 @@ continue; } - let bindst = match output.hardlink { - Some(ref link_dst) => link_dst, - None => &output.path, - }; + let bindst = output.bin_dst(); if unit.mode == CompileMode::Test { self.compilation.tests.push(( @@ -196,7 +192,7 @@ } if unit.mode == CompileMode::Doctest { - // Note that we can *only* doctest rlib outputs here. A + // Note that we can *only* doc-test rlib outputs here. A // staticlib output cannot be linked by the compiler (it just // doesn't do that). A dylib output, however, can be linked by // the compiler, but will always fail. Currently all dylibs are @@ -274,6 +270,23 @@ Ok(self.compilation) } + /// Returns the executable for the specified unit (if any). + pub fn get_executable(&mut self, unit: &Unit<'a>) -> CargoResult> { + for output in self.outputs(unit)?.iter() { + if output.flavor == FileFlavor::DebugInfo { + continue; + } + + let is_binary = unit.target.is_bin() || unit.target.is_bin_example(); + let is_test = unit.mode.is_any_test() && !unit.mode.is_check(); + + if is_binary || is_test { + return Ok(Option::Some(output.bin_dst().clone())); + } + } + Ok(None) + } + pub fn prepare_units( &mut self, export_dir: Option, @@ -342,14 +355,15 @@ self.files.as_mut().unwrap() } - /// Return the filenames that the given unit will generate. + /// Returns the filenames that the given unit will generate. pub fn outputs(&self, unit: &Unit<'a>) -> CargoResult>> { self.files.as_ref().unwrap().outputs(unit, self.bcx) } /// For a package, return all targets which are registered as dependencies /// for that package. - // TODO: this ideally should be `-> &[Unit<'a>]` + // + // TODO: this ideally should be `-> &[Unit<'a>]`. pub fn dep_targets(&self, unit: &Unit<'a>) -> Vec> { // If this build script's execution has been overridden then we don't // actually depend on anything, we've reached the end of the dependency @@ -372,82 +386,27 @@ deps } - pub fn incremental_args(&self, unit: &Unit) -> CargoResult> { - // There's a number of ways to configure incremental compilation right - // now. In order of descending priority (first is highest priority) we - // have: - // - // * `CARGO_INCREMENTAL` - this is blanket used unconditionally to turn - // on/off incremental compilation for any cargo subcommand. We'll - // respect this if set. - // * `build.incremental` - in `.cargo/config` this blanket key can - // globally for a system configure whether incremental compilation is - // enabled. Note that setting this to `true` will not actually affect - // all builds though. For example a `true` value doesn't enable - // release incremental builds, only dev incremental builds. This can - // be useful to globally disable incremental compilation like - // `CARGO_INCREMENTAL`. - // * `profile.dev.incremental` - in `Cargo.toml` specific profiles can - // be configured to enable/disable incremental compilation. This can - // be primarily used to disable incremental when buggy for a package. - // * Finally, each profile has a default for whether it will enable - // incremental compilation or not. Primarily development profiles - // have it enabled by default while release profiles have it disabled - // by default. - let global_cfg = self - .bcx - .config - .get_bool("build.incremental")? - .map(|c| c.val); - let incremental = match ( - self.bcx.incremental_env, - global_cfg, - unit.profile.incremental, - ) { - (Some(v), _, _) => v, - (None, Some(false), _) => false, - (None, _, other) => other, - }; - - if !incremental { - return Ok(Vec::new()); - } - - // Only enable incremental compilation for sources the user can - // modify (aka path sources). For things that change infrequently, - // non-incremental builds yield better performance in the compiler - // itself (aka crates.io / git dependencies) - // - // (see also https://github.com/rust-lang/cargo/issues/3972) - if !unit.pkg.package_id().source_id().is_path() { - return Ok(Vec::new()); - } - - let dir = self.files().layout(unit.kind).incremental().display(); - Ok(vec!["-C".to_string(), format!("incremental={}", dir)]) - } - pub fn is_primary_package(&self, unit: &Unit<'a>) -> bool { self.primary_packages.contains(&unit.pkg.package_id()) } - /// Gets a package for the given package id. + /// Gets a package for the given package ID. pub fn get_package(&self, id: PackageId) -> CargoResult<&'a Package> { self.package_cache .get(&id) .cloned() - .ok_or_else(|| format_err!("failed to find {}", id)) + .ok_or_else(|| failure::format_err!("failed to find {}", id)) } - /// Return the list of filenames read by cargo to generate the BuildContext - /// (all Cargo.toml, etc). + /// Returns the list of filenames read by cargo to generate the `BuildContext` + /// (all `Cargo.toml`, etc.). pub fn build_plan_inputs(&self) -> CargoResult> { let mut inputs = Vec::new(); // Note that we're using the `package_cache`, which should have been // populated by `build_unit_dependencies`, and only those packages are // considered as all the inputs. // - // (notably we skip dev-deps here if they aren't present) + // (Notably, we skip dev-deps here if they aren't present.) for pkg in self.package_cache.values() { inputs.push(pkg.manifest_path().to_path_buf()); } @@ -457,24 +416,26 @@ fn check_collistions(&self) -> CargoResult<()> { let mut output_collisions = HashMap::new(); - let describe_collision = |unit: &Unit, other_unit: &Unit, path: &PathBuf| -> String { - format!( - "The {} target `{}` in package `{}` has the same output \ - filename as the {} target `{}` in package `{}`.\n\ - Colliding filename is: {}\n", - unit.target.kind().description(), - unit.target.name(), - unit.pkg.package_id(), - other_unit.target.kind().description(), - other_unit.target.name(), - other_unit.pkg.package_id(), - path.display() - ) - }; + let describe_collision = + |unit: &Unit<'_>, other_unit: &Unit<'_>, path: &PathBuf| -> String { + format!( + "The {} target `{}` in package `{}` has the same output \ + filename as the {} target `{}` in package `{}`.\n\ + Colliding filename is: {}\n", + unit.target.kind().description(), + unit.target.name(), + unit.pkg.package_id(), + other_unit.target.kind().description(), + other_unit.target.name(), + other_unit.pkg.package_id(), + path.display() + ) + }; let suggestion = "Consider changing their names to be unique or compiling them separately.\n\ - This may become a hard error in the future, see https://github.com/rust-lang/cargo/issues/6313"; - let report_collision = |unit: &Unit, - other_unit: &Unit, + This may become a hard error in the future; see \ + ."; + let report_collision = |unit: &Unit<'_>, + other_unit: &Unit<'_>, path: &PathBuf| -> CargoResult<()> { if unit.target.name() == other_unit.target.name() { @@ -500,7 +461,7 @@ Second unit: {:?}", describe_collision(unit, other_unit, path), suggestion, - ::version(), self.bcx.host_triple(), self.bcx.target_triple(), + crate::version(), self.bcx.host_triple(), self.bcx.target_triple(), unit, other_unit)) } }; @@ -553,7 +514,7 @@ } } - pub fn validate(&mut self, resolve: &Resolve, unit: &Unit) -> CargoResult<()> { + pub fn validate(&mut self, resolve: &Resolve, unit: &Unit<'_>) -> CargoResult<()> { if !self.validated.insert(unit.pkg.package_id()) { return Ok(()); } @@ -573,7 +534,7 @@ dep_path_desc }; - bail!( + failure::bail!( "multiple packages link to native library `{}`, \ but a native library can be linked only once\n\ \n\ @@ -594,7 +555,7 @@ .iter() .any(|t| t.is_custom_build()) { - bail!( + failure::bail!( "package `{}` specifies that it links to `{}` but does not \ have a custom build script", unit.pkg.package_id(), diff -Nru cargo-0.33.0/src/cargo/core/compiler/context/unit_dependencies.rs cargo-0.35.0/src/cargo/core/compiler/context/unit_dependencies.rs --- cargo-0.33.0/src/cargo/core/compiler/context/unit_dependencies.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/context/unit_dependencies.rs 2019-04-01 21:32:07.000000000 +0000 @@ -18,12 +18,14 @@ use std::cell::RefCell; use std::collections::{HashMap, HashSet}; +use log::trace; + use super::{BuildContext, CompileMode, Kind, Unit}; -use core::dependency::Kind as DepKind; -use core::package::Downloads; -use core::profiles::UnitFor; -use core::{Package, PackageId, Target}; -use CargoResult; +use crate::core::dependency::Kind as DepKind; +use crate::core::package::Downloads; +use crate::core::profiles::UnitFor; +use crate::core::{Package, PackageId, Target}; +use crate::CargoResult; struct State<'a: 'tmp, 'cfg: 'a, 'tmp> { bcx: &'tmp BuildContext<'a, 'cfg>, @@ -57,8 +59,8 @@ // We check the global test mode to see if we are running in `cargo // test` in which case we ensure all dependencies have `panic` // cleared, and avoid building the lib thrice (once with `panic`, once - // without, once for --test). In particular, the lib included for - // doctests and examples are `Build` mode here. + // without, once for `--test`). In particular, the lib included for + // Doc tests and examples are `Build` mode here. let unit_for = if unit.mode.is_any_test() || bcx.build_config.test() { UnitFor::new_test() } else if unit.target.is_custom_build() { @@ -66,7 +68,7 @@ // generates all units. UnitFor::new_build() } else if unit.target.for_host() { - // proc-macro/plugin should never have panic set. + // Proc macro / plugin should never have panic set. UnitFor::new_compiler() } else { UnitFor::new_normal() @@ -93,10 +95,10 @@ state: &mut State<'a, 'cfg, 'tmp>, unit_for: UnitFor, ) -> CargoResult<()> { - // Currently the `deps` map does not include `unit_for`. This should - // be safe for now. `TestDependency` only exists to clear the `panic` + // Currently the `deps` map does not include `unit_for`. This should + // be safe for now. `TestDependency` only exists to clear the `panic` // flag, and you'll never ask for a `unit` with `panic` set as a - // `TestDependency`. `CustomBuild` should also be fine since if the + // `TestDependency`. `CustomBuild` should also be fine since if the // requested unit's settings are the same as `Any`, `CustomBuild` can't // affect anything else in the hierarchy. if !state.deps.contains_key(unit) { @@ -110,9 +112,9 @@ Ok(()) } -/// For a package, return all targets which are registered as dependencies +/// For a package, returns all targets that are registered as dependencies /// for that package. -/// This returns a vec of `(Unit, UnitFor)` pairs. The `UnitFor` +/// This returns a `Vec` of `(Unit, UnitFor)` pairs. The `UnitFor` /// is the profile type that should be used for dependencies of the unit. fn compute_deps<'a, 'cfg, 'tmp>( unit: &Unit<'a>, @@ -122,7 +124,7 @@ if unit.mode.is_run_custom_build() { return compute_deps_custom_build(unit, state.bcx); } else if unit.mode.is_doc() && !unit.mode.is_any_test() { - // Note: This does not include Doctest. + // Note: this does not include doc test. return compute_deps_doc(unit, state); } @@ -138,8 +140,8 @@ return false; } - // If this dependency is *not* a transitive dependency, then it - // only applies to test/example targets + // If this dependency is **not** a transitive dependency, then it + // only applies to test/example targets. if !dep.is_transitive() && !unit.target.is_test() && !unit.target.is_example() @@ -178,8 +180,19 @@ }; let mode = check_or_build_mode(unit.mode, lib); let dep_unit_for = unit_for.with_for_host(lib.for_host()); - let unit = new_unit(bcx, pkg, lib, dep_unit_for, unit.kind.for_target(lib), mode); - ret.push((unit, dep_unit_for)); + + if bcx.config.cli_unstable().dual_proc_macros + && lib.proc_macro() + && unit.kind == Kind::Target + { + let unit = new_unit(bcx, pkg, lib, dep_unit_for, Kind::Target, mode); + ret.push((unit, dep_unit_for)); + let unit = new_unit(bcx, pkg, lib, dep_unit_for, Kind::Host, mode); + ret.push((unit, dep_unit_for)); + } else { + let unit = new_unit(bcx, pkg, lib, dep_unit_for, unit.kind.for_target(lib), mode); + ret.push((unit, dep_unit_for)); + } } // If this target is a build script, then what we've collected so far is @@ -247,7 +260,7 @@ ) -> CargoResult, UnitFor)>> { // When not overridden, then the dependencies to run a build script are: // - // 1. Compiling the build script itself + // 1. Compiling the build script itself. // 2. For each immediate dependency of our package which has a `links` // key, the execution of that build script. // @@ -259,7 +272,8 @@ unit.pkg, unit.target, UnitFor::new_build(), - Kind::Host, // build scripts always compiled for the host + // Build scripts always compiled for the host. + Kind::Host, CompileMode::Build, ); // All dependencies of this unit should use profiles for custom @@ -267,7 +281,7 @@ Ok(vec![(unit, UnitFor::new_build())]) } -/// Returns the dependencies necessary to document a package +/// Returns the dependencies necessary to document a package. fn compute_deps_doc<'a, 'cfg, 'tmp>( unit: &Unit<'a>, state: &mut State<'a, 'cfg, 'tmp>, @@ -296,8 +310,8 @@ Some(lib) => lib, None => continue, }; - // rustdoc only needs rmeta files for regular dependencies. - // However, for plugins/proc-macros, deps should be built like normal. + // Rustdoc only needs rmeta files for regular dependencies. + // However, for plugins/proc macros, deps should be built like normal. let mode = check_or_build_mode(unit.mode, lib); let dep_unit_for = UnitFor::new_normal().with_for_host(lib.for_host()); let lib_unit = new_unit(bcx, dep, lib, dep_unit_for, unit.kind.for_target(lib), mode); @@ -316,10 +330,10 @@ } } - // Be sure to build/run the build script for documented libraries as + // Be sure to build/run the build script for documented libraries. ret.extend(dep_build_script(unit, bcx)); - // If we document a binary, we need the library available + // If we document a binary, we need the library available. if unit.target.is_bin() { ret.extend(maybe_lib(unit, bcx, UnitFor::new_normal())); } @@ -328,7 +342,7 @@ fn maybe_lib<'a>( unit: &Unit<'a>, - bcx: &BuildContext, + bcx: &BuildContext<'_, '_>, unit_for: UnitFor, ) -> Option<(Unit<'a>, UnitFor)> { unit.pkg.targets().iter().find(|t| t.linkable()).map(|t| { @@ -345,7 +359,10 @@ /// script itself doesn't have any dependencies, so even in that case a unit /// of work is still returned. `None` is only returned if the package has no /// build script. -fn dep_build_script<'a>(unit: &Unit<'a>, bcx: &BuildContext) -> Option<(Unit<'a>, UnitFor)> { +fn dep_build_script<'a>( + unit: &Unit<'a>, + bcx: &BuildContext<'_, '_>, +) -> Option<(Unit<'a>, UnitFor)> { unit.pkg .targets() .iter() @@ -371,7 +388,7 @@ match mode { CompileMode::Check { .. } | CompileMode::Doc { .. } => { if target.for_host() { - // Plugin and proc-macro targets should be compiled like + // Plugin and proc macro targets should be compiled like // normal. CompileMode::Build } else { @@ -385,7 +402,7 @@ } fn new_unit<'a>( - bcx: &BuildContext, + bcx: &BuildContext<'_, '_>, pkg: &'a Package, target: &'a Target, unit_for: UnitFor, @@ -418,7 +435,7 @@ /// /// Here we take the entire `deps` map and add more dependencies from execution /// of one build script to execution of another build script. -fn connect_run_custom_build_deps(state: &mut State) { +fn connect_run_custom_build_deps(state: &mut State<'_, '_, '_>) { let mut new_deps = Vec::new(); { @@ -439,7 +456,7 @@ } } - // And next we take a look at all build scripts executions listed in the + // Next, we take a look at all build scripts executions listed in the // dependency map. Our job here is to take everything that depends on // this build script (from our reverse map above) and look at the other // package dependencies of these parents. diff -Nru cargo-0.33.0/src/cargo/core/compiler/custom_build.rs cargo-0.35.0/src/cargo/core/compiler/custom_build.rs --- cargo-0.33.0/src/cargo/core/compiler/custom_build.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/custom_build.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,11 +5,11 @@ use std::str; use std::sync::{Arc, Mutex}; -use core::PackageId; -use util::errors::{CargoResult, CargoResultExt}; -use util::machine_message; -use util::{self, internal, paths, profile}; -use util::{Cfg, Freshness}; +use crate::core::PackageId; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::machine_message; +use crate::util::{self, internal, paths, profile}; +use crate::util::{Cfg, Freshness}; use super::job::Work; use super::{fingerprint, Context, Kind, TargetConfig, Unit}; @@ -17,29 +17,29 @@ /// Contains the parsed output of a custom build script. #[derive(Clone, Debug, Hash)] pub struct BuildOutput { - /// Paths to pass to rustc with the `-L` flag + /// Paths to pass to rustc with the `-L` flag. pub library_paths: Vec, - /// Names and link kinds of libraries, suitable for the `-l` flag + /// Names and link kinds of libraries, suitable for the `-l` flag. pub library_links: Vec, - /// Various `--cfg` flags to pass to the compiler + /// Various `--cfg` flags to pass to the compiler. pub cfgs: Vec, /// Additional environment variables to run the compiler with. pub env: Vec<(String, String)>, - /// Metadata to pass to the immediate dependencies + /// Metadata to pass to the immediate dependencies. pub metadata: Vec<(String, String)>, /// Paths to trigger a rerun of this build script. /// May be absolute or relative paths (relative to package root). pub rerun_if_changed: Vec, /// Environment variables which, when changed, will cause a rebuild. pub rerun_if_env_changed: Vec, - /// Warnings generated by this build, + /// Warnings generated by this build. pub warnings: Vec, } -/// Map of packages to build info +/// Map of packages to build info. pub type BuildMap = HashMap<(PackageId, Kind), BuildOutput>; -/// Build info and overrides +/// Build info and overrides. pub struct BuildState { pub outputs: Mutex, overrides: HashMap<(String, Kind), BuildOutput>, @@ -47,7 +47,7 @@ #[derive(Default)] pub struct BuildScripts { - // Cargo will use this `to_link` vector to add -L flags to compiles as we + // Cargo will use this `to_link` vector to add `-L` flags to compiles as we // propagate them upwards towards the final build. Note, however, that we // need to preserve the ordering of `to_link` to be topologically sorted. // This will ensure that build scripts which print their paths properly will @@ -59,7 +59,7 @@ // this as we're building interactively below to ensure that the memory // usage here doesn't blow up too much. // - // For more information, see #2354 + // For more information, see #2354. pub to_link: Vec<(PackageId, Kind)>, seen_to_link: HashSet<(PackageId, Kind)>, pub plugins: BTreeSet, @@ -146,7 +146,7 @@ // environment variables. Note that the profile-related environment // variables are not set with this the build script's profile but rather the // package's library profile. - // NOTE: If you add any profile flags, be sure to update + // NOTE: if you add any profile flags, be sure to update // `Profiles::get_profile_run_custom_build` so that those flags get // carried over. let to_exec = to_exec.into_os_string(); @@ -261,8 +261,8 @@ let json_messages = bcx.build_config.json_messages(); let extra_verbose = bcx.config.extra_verbose(); - // Check to see if the build script has already run, and if it has keep - // track of whether it has told us about some explicit dependencies + // Check to see if the build script has already run, and if it has, keep + // track of whether it has told us about some explicit dependencies. let prev_script_out_dir = paths::read_bytes(&root_output_file) .and_then(|bytes| util::bytes2path(&bytes)) .unwrap_or_else(|_| script_out_dir.clone()); @@ -332,6 +332,7 @@ state.build_plan(invocation_name, cmd.clone(), Arc::new(Vec::new())); } else { state.running(&cmd); + let timestamp = paths::get_current_filesystem_time(&output_file)?; let output = if extra_verbose { let prefix = format!("[{} {}] ", id.name(), id.version()); state.capture_output(&cmd, Some(prefix), true) @@ -339,7 +340,7 @@ cmd.exec_with_output() }; let output = output.map_err(|e| { - format_err!( + failure::format_err!( "failed to run custom build command for `{}`\n{}", pkg_name, e @@ -354,6 +355,7 @@ // state informing what variables were discovered via our script as // well. paths::write(&output_file, &output.stdout)?; + filetime::set_file_times(output_file, timestamp, timestamp)?; paths::write(&err_file, &output.stderr)?; paths::write(&root_output_file, util::path2bytes(&script_out_dir)?)?; let parsed_output = @@ -467,8 +469,8 @@ let value = iter.next(); let (key, value) = match (key, value) { (Some(a), Some(b)) => (a, b.trim_end()), - // line started with `cargo:` but didn't match `key=value` - _ => bail!("Wrong output in {}: `{}`", whence, line), + // Line started with `cargo:` but didn't match `key=value`. + _ => failure::bail!("Wrong output in {}: `{}`", whence, line), }; // This will rewrite paths if the target directory has been moved. @@ -517,7 +519,7 @@ let (mut library_paths, mut library_links) = (Vec::new(), Vec::new()); while let Some(flag) = flags_iter.next() { if flag != "-l" && flag != "-L" { - bail!( + failure::bail!( "Only `-l` and `-L` flags are allowed in {}: `{}`", whence, value @@ -525,7 +527,7 @@ } let value = match flags_iter.next() { Some(v) => v, - None => bail!( + None => failure::bail!( "Flag in rustc-flags has no value in {}: `{}`", whence, value @@ -536,7 +538,7 @@ "-L" => library_paths.push(PathBuf::from(value)), // was already checked above - _ => bail!("only -l and -L flags are allowed"), + _ => failure::bail!("only -l and -L flags are allowed"), }; } Ok((library_paths, library_links)) @@ -548,7 +550,7 @@ let val = iter.next(); match (name, val) { (Some(n), Some(v)) => Ok((n.to_owned(), v.to_owned())), - _ => bail!("Variable rustc-env has no value in {}: {}", whence, value), + _ => failure::bail!("Variable rustc-env has no value in {}: {}", whence, value), } } } @@ -571,7 +573,7 @@ }) .collect(); for dep in &meta_deps { - output.push(format!("extern crate {};\n", dep)); + output.push(format!("use {};\n", dep)); } output.push("fn main() {\n".to_string()); for dep in &meta_deps { @@ -601,7 +603,7 @@ } } -/// Compute the `build_scripts` map in the `Context` which tracks what build +/// Computes the `build_scripts` map in the `Context` which tracks what build /// scripts each package depends on. /// /// The global `build_scripts` map lists for all (package, kind) tuples what set @@ -683,7 +685,7 @@ } // When adding an entry to 'to_link' we only actually push it on if the - // script hasn't seen it yet (e.g. we don't push on duplicates). + // script hasn't seen it yet (e.g., we don't push on duplicates). fn add_to_link(scripts: &mut BuildScripts, pkg: PackageId, kind: Kind) { if scripts.seen_to_link.insert((pkg, kind)) { scripts.to_link.push((pkg, kind)); diff -Nru cargo-0.33.0/src/cargo/core/compiler/fingerprint.rs cargo-0.35.0/src/cargo/core/compiler/fingerprint.rs --- cargo-0.33.0/src/cargo/core/compiler/fingerprint.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/fingerprint.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,17 +3,19 @@ use std::hash::{self, Hasher}; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; +use std::time::SystemTime; use filetime::FileTime; -use serde::de::{self, Deserialize}; +use log::{debug, info}; +use serde::de; use serde::ser; -use serde_json; +use serde::{Deserialize, Serialize}; -use core::{Edition, Package}; -use util; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::{internal, profile, Dirty, Fresh, Freshness}; +use crate::core::{Edition, Package}; +use crate::util; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::{internal, profile, Dirty, Fresh, Freshness}; use super::custom_build::BuildDeps; use super::job::Work; @@ -63,10 +65,11 @@ debug!("fingerprint at: {}", loc.display()); let fingerprint = calculate(cx, unit)?; - let compare = compare_old_fingerprint(&loc, &*fingerprint); + let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use; + let compare = compare_old_fingerprint(&loc, &*fingerprint, mtime_on_use); log_compare(unit, &compare); - // If our comparison failed (e.g. we're going to trigger a rebuild of this + // If our comparison failed (e.g., we're going to trigger a rebuild of this // crate), then we also ensure the source of the crate passes all // verification checks before we build it. // @@ -87,6 +90,7 @@ let root = cx.files().out_dir(unit); let missing_outputs = { + let t = FileTime::from_system_time(SystemTime::now()); if unit.mode.is_doc() { !root .join(unit.target.crate_name()) @@ -97,8 +101,17 @@ .outputs(unit)? .iter() .filter(|output| output.flavor != FileFlavor::DebugInfo) - .find(|output| !output.path.exists()) - { + .find(|output| { + if output.path.exists() { + if mtime_on_use { + // update the mtime so other cleaners know we used it + let _ = filetime::set_file_times(&output.path, t, t); + } + false + } else { + true + } + }) { None => false, Some(output) => { info!("missing output path {:?}", output.path); @@ -128,10 +141,14 @@ } /// A compilation unit dependency has a fingerprint that is comprised of: -/// * its package id +/// * its package ID /// * its extern crate name /// * its calculated fingerprint for the dependency -type DepFingerprint = (String, String, Arc); +struct DepFingerprint { + pkg_id: String, + name: String, + fingerprint: Arc, +} /// A fingerprint can be considered to be a "short string" representing the /// state of a world for a package. @@ -161,10 +178,6 @@ target: u64, profile: u64, path: u64, - #[serde( - serialize_with = "serialize_deps", - deserialize_with = "deserialize_deps" - )] deps: Vec, local: Vec, #[serde(skip_serializing, skip_deserializing)] @@ -173,39 +186,31 @@ edition: Edition, } -fn serialize_deps(deps: &[DepFingerprint], ser: S) -> Result -where - S: ser::Serializer, -{ - ser.collect_seq(deps.iter().map(|&(ref a, ref b, ref c)| (a, b, c.hash()))) +impl Serialize for DepFingerprint { + fn serialize(&self, ser: S) -> Result + where + S: ser::Serializer, + { + (&self.pkg_id, &self.name, &self.fingerprint.hash()).serialize(ser) + } } -fn deserialize_deps<'de, D>(d: D) -> Result, D::Error> -where - D: de::Deserializer<'de>, -{ - let decoded = >::deserialize(d)?; - Ok(decoded - .into_iter() - .map(|(pkg_id, name, hash)| { - ( - pkg_id, - name, - Arc::new(Fingerprint { - rustc: 0, - target: 0, - profile: 0, - path: 0, - local: vec![LocalFingerprint::Precalculated(String::new())], - features: String::new(), - deps: Vec::new(), - memoized_hash: Mutex::new(Some(hash)), - edition: Edition::Edition2015, - rustflags: Vec::new(), - }), - ) +impl<'de> Deserialize<'de> for DepFingerprint { + fn deserialize(d: D) -> Result + where + D: de::Deserializer<'de>, + { + let (pkg_id, name, hash) = <(String, String, u64)>::deserialize(d)?; + Ok(DepFingerprint { + pkg_id, + name, + fingerprint: Arc::new(Fingerprint { + local: vec![LocalFingerprint::Precalculated(String::new())], + memoized_hash: Mutex::new(Some(hash)), + ..Fingerprint::new() + }), }) - .collect()) + } } #[derive(Serialize, Deserialize, Hash)] @@ -227,6 +232,21 @@ struct MtimeSlot(Mutex>); impl Fingerprint { + fn new() -> Fingerprint { + Fingerprint { + rustc: 0, + target: 0, + profile: 0, + path: 0, + features: String::new(), + deps: Vec::new(), + local: Vec::new(), + memoized_hash: Mutex::new(None), + edition: Edition::Edition2015, + rustflags: Vec::new(), + } + } + fn update_local(&self, root: &Path) -> CargoResult<()> { for local in self.local.iter() { match *local { @@ -254,32 +274,32 @@ fn compare(&self, old: &Fingerprint) -> CargoResult<()> { if self.rustc != old.rustc { - bail!("rust compiler has changed") + failure::bail!("rust compiler has changed") } if self.features != old.features { - bail!( + failure::bail!( "features have changed: {} != {}", self.features, old.features ) } if self.target != old.target { - bail!("target configuration has changed") + failure::bail!("target configuration has changed") } if self.path != old.path { - bail!("path to the compiler has changed") + failure::bail!("path to the compiler has changed") } if self.profile != old.profile { - bail!("profile configuration has changed") + failure::bail!("profile configuration has changed") } if self.rustflags != old.rustflags { - bail!("RUSTFLAGS has changed") + failure::bail!("RUSTFLAGS has changed") } if self.local.len() != old.local.len() { - bail!("local lens changed"); + failure::bail!("local lens changed"); } if self.edition != old.edition { - bail!("edition changed") + failure::bail!("edition changed") } for (new, old) in self.local.iter().zip(&old.local) { match (new, old) { @@ -288,7 +308,7 @@ &LocalFingerprint::Precalculated(ref b), ) => { if a != b { - bail!("precalculated components have changed: {} != {}", a, b) + failure::bail!("precalculated components have changed: {} != {}", a, b) } } ( @@ -305,7 +325,7 @@ }; if should_rebuild { - bail!( + failure::bail!( "mtime based components have changed: previously {:?} now {:?}, \ paths are {:?} and {:?}", *previously_built_mtime, @@ -320,10 +340,10 @@ &LocalFingerprint::EnvBased(ref bkey, ref bvalue), ) => { if *akey != *bkey { - bail!("env vars changed: {} != {}", akey, bkey); + failure::bail!("env vars changed: {} != {}", akey, bkey); } if *avalue != *bvalue { - bail!( + failure::bail!( "env var `{}` changed: previously {:?} now {:?}", akey, bvalue, @@ -331,16 +351,16 @@ ) } } - _ => bail!("local fingerprint type has changed"), + _ => failure::bail!("local fingerprint type has changed"), } } if self.deps.len() != old.deps.len() { - bail!("number of dependencies has changed") + failure::bail!("number of dependencies has changed") } for (a, b) in self.deps.iter().zip(old.deps.iter()) { - if a.1 != b.1 || a.2.hash() != b.2.hash() { - bail!("new ({}) != old ({})", a.0, b.0) + if a.name != b.name || a.fingerprint.hash() != b.fingerprint.hash() { + failure::bail!("new ({}) != old ({})", a.pkg_id, b.pkg_id) } } Ok(()) @@ -367,7 +387,12 @@ .hash(h); h.write_usize(deps.len()); - for &(ref pkg_id, ref name, ref fingerprint) in deps { + for DepFingerprint { + pkg_id, + name, + fingerprint, + } in deps + { pkg_id.hash(h); name.hash(h); // use memoized dep hashes to avoid exponential blowup @@ -415,7 +440,7 @@ /// * Any dependency changes /// * The compiler changes /// * The set of features a package is built with changes -/// * The profile a target is compiled with changes (e.g. opt-level changes) +/// * The profile a target is compiled with changes (e.g., opt-level changes) /// /// Information like file modification time is only calculated for path /// dependencies and is calculated in `calculate_target_fresh`. @@ -442,7 +467,11 @@ .map(|dep| { calculate(cx, dep).and_then(|fingerprint| { let name = cx.bcx.extern_crate_name(unit, dep)?; - Ok((dep.pkg.package_id().to_string(), name, fingerprint)) + Ok(DepFingerprint { + pkg_id: dep.pkg.package_id().to_string(), + name, + fingerprint, + }) }) }) .collect::>>()?; @@ -457,18 +486,13 @@ LocalFingerprint::Precalculated(fingerprint) }; let mut deps = deps; - deps.sort_by(|&(ref a, _, _), &(ref b, _, _)| a.cmp(b)); + deps.sort_by(|a, b| a.pkg_id.cmp(&b.pkg_id)); let extra_flags = if unit.mode.is_doc() { bcx.rustdocflags_args(unit)? } else { bcx.rustflags_args(unit)? }; - let profile_hash = util::hash_u64(&( - &unit.profile, - unit.mode, - bcx.extra_args_for(unit), - cx.incremental_args(unit)?, - )); + let profile_hash = util::hash_u64(&(&unit.profile, unit.mode, bcx.extra_args_for(unit))); let fingerprint = Arc::new(Fingerprint { rustc: util::hash_u64(&bcx.rustc.verbose_version), target: util::hash_u64(&unit.target), @@ -491,7 +515,7 @@ // git/registry source, then the mtime of files may fluctuate, but they won't // change so long as the source itself remains constant (which is the // responsibility of the source) -fn use_dep_info(unit: &Unit) -> bool { +fn use_dep_info(unit: &Unit<'_>) -> bool { let path = unit.pkg.summary().source_id().is_path(); !unit.mode.is_doc() && path } @@ -525,18 +549,12 @@ let (local, output_path) = build_script_local_fingerprints(cx, unit)?; let mut fingerprint = Fingerprint { - rustc: 0, - target: 0, - profile: 0, - path: 0, - features: String::new(), - deps: Vec::new(), local, - memoized_hash: Mutex::new(None), - edition: Edition::Edition2015, - rustflags: Vec::new(), + rustc: util::hash_u64(&cx.bcx.rustc.verbose_version), + ..Fingerprint::new() }; - let compare = compare_old_fingerprint(&loc, &fingerprint); + let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use; + let compare = compare_old_fingerprint(&loc, &fingerprint, mtime_on_use); log_compare(unit, &compare); // When we write out the fingerprint, we may want to actually change the @@ -638,6 +656,10 @@ } fn write_fingerprint(loc: &Path, fingerprint: &Fingerprint) -> CargoResult<()> { + debug_assert_ne!(fingerprint.rustc, 0); + // fingerprint::new().rustc == 0, make sure it doesn't make it to the file system. + // This is mostly so outside tools can reliably find out what rust version this file is for, + // as we can use the full hash. let hash = fingerprint.hash(); debug!("write fingerprint: {}", loc.display()); paths::write(loc, util::to_hex(hash).as_bytes())?; @@ -665,8 +687,19 @@ .join(&format!("dep-{}", filename(cx, unit))) } -fn compare_old_fingerprint(loc: &Path, new_fingerprint: &Fingerprint) -> CargoResult<()> { +fn compare_old_fingerprint( + loc: &Path, + new_fingerprint: &Fingerprint, + mtime_on_use: bool, +) -> CargoResult<()> { let old_fingerprint_short = paths::read(loc)?; + + if mtime_on_use { + // update the mtime so other cleaners know we used it + let t = FileTime::from_system_time(SystemTime::now()); + filetime::set_file_times(loc, t, t)?; + } + let new_hash = new_fingerprint.hash(); if util::to_hex(new_hash) == old_fingerprint_short { @@ -679,7 +712,7 @@ new_fingerprint.compare(&old_fingerprint) } -fn log_compare(unit: &Unit, compare: &CargoResult<()>) { +fn log_compare(unit: &Unit<'_>, compare: &CargoResult<()>) { let ce = match *compare { Ok(..) => return, Err(ref e) => e, @@ -717,7 +750,7 @@ } } -fn pkg_fingerprint(bcx: &BuildContext, pkg: &Package) -> CargoResult { +fn pkg_fingerprint(bcx: &BuildContext<'_, '_>, pkg: &Package) -> CargoResult { let source_id = pkg.package_id().source_id(); let sources = bcx.packages.sources(); @@ -747,23 +780,25 @@ } }; - // Note that equal mtimes are considered "stale". For filesystems with - // not much timestamp precision like 1s this is a conservative approximation + // TODO: fix #5918. + // Note that equal mtimes should be considered "stale". For filesystems with + // not much timestamp precision like 1s this is would be a conservative approximation // to handle the case where a file is modified within the same second after - // a build finishes. We want to make sure that incremental rebuilds pick that up! + // a build starts. We want to make sure that incremental rebuilds pick that up! // // For filesystems with nanosecond precision it's been seen in the wild that // its "nanosecond precision" isn't really nanosecond-accurate. It turns out that // kernels may cache the current time so files created at different times actually // list the same nanosecond precision. Some digging on #5919 picked up that the // kernel caches the current time between timer ticks, which could mean that if - // a file is updated at most 10ms after a build finishes then Cargo may not + // a file is updated at most 10ms after a build starts then Cargo may not // pick up the build changes. // - // All in all, the equality check here is a conservative assumption that, + // All in all, an equality check here would be a conservative assumption that, // if equal, files were changed just after a previous build finished. - // It's hoped this doesn't cause too many issues in practice! - if mtime2 >= mtime { + // Unfortunately this became problematic when (in #6484) cargo switch to more accurately + // measuring the start time of builds. + if mtime2 > mtime { info!("stale: {} -- {} vs {}", path.display(), mtime2, mtime); true } else { diff -Nru cargo-0.33.0/src/cargo/core/compiler/job_queue.rs cargo-0.35.0/src/cargo/core/compiler/job_queue.rs --- cargo-0.33.0/src/cargo/core/compiler/job_queue.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/job_queue.rs 2019-04-01 21:32:07.000000000 +0000 @@ -7,19 +7,18 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::Arc; -use crossbeam_utils; use crossbeam_utils::thread::Scope; use jobserver::{Acquired, HelperThread}; +use log::{debug, info, trace}; -use core::profiles::Profile; -use core::{PackageId, Target, TargetKind}; -use handle_error; -use util; -use util::diagnostic_server::{self, DiagnosticPrinter}; -use util::{internal, profile, CargoResult, CargoResultExt, ProcessBuilder}; -use util::{Config, DependencyQueue, Dirty, Fresh, Freshness}; -use util::{Progress, ProgressStyle}; - +use crate::core::profiles::Profile; +use crate::core::{PackageId, Target, TargetKind}; +use crate::handle_error; +use crate::util; +use crate::util::diagnostic_server::{self, DiagnosticPrinter}; +use crate::util::{internal, profile, CargoResult, CargoResultExt, ProcessBuilder}; +use crate::util::{Config, DependencyQueue, Dirty, Fresh, Freshness}; +use crate::util::{Progress, ProgressStyle}; use super::context::OutputFile; use super::job::Job; use super::{BuildContext, BuildPlan, CompileMode, Context, Kind, Unit}; @@ -29,7 +28,7 @@ /// This structure is backed by the `DependencyQueue` type and manages the /// actual compilation step of each package. Packages enqueue units of work and /// then later on the entire graph is processed and compiled. -pub struct JobQueue<'a> { +pub struct JobQueue<'a, 'cfg> { queue: DependencyQueue, Vec<(Job, Freshness)>>, tx: Sender>, rx: Receiver>, @@ -39,13 +38,14 @@ documented: HashSet, counts: HashMap, is_release: bool, + progress: Progress<'cfg>, } /// A helper structure for metadata about the state of a building package. struct PendingBuild { - /// Number of jobs currently active + /// The number of jobs currently active. amt: usize, - /// Current freshness state of this package. Any dirty target within a + /// The current freshness state of this package. Any dirty target within a /// package will cause the entire package to become dirty. fresh: Freshness, } @@ -131,9 +131,10 @@ } } -impl<'a> JobQueue<'a> { - pub fn new<'cfg>(bcx: &BuildContext<'a, 'cfg>) -> JobQueue<'a> { +impl<'a, 'cfg> JobQueue<'a, 'cfg> { + pub fn new(bcx: &BuildContext<'a, 'cfg>) -> JobQueue<'a, 'cfg> { let (tx, rx) = channel(); + let progress = Progress::with_style("Building", ProgressStyle::Ratio, bcx.config); JobQueue { queue: DependencyQueue::new(), tx, @@ -144,10 +145,11 @@ documented: HashSet::new(), counts: HashMap::new(), is_release: bcx.build_config.release, + progress, } } - pub fn enqueue<'cfg>( + pub fn enqueue( &mut self, cx: &Context<'a, 'cfg>, unit: &Unit<'a>, @@ -163,12 +165,12 @@ Ok(()) } - /// Execute all jobs necessary to build the dependency graph. + /// Executes all jobs necessary to build the dependency graph. /// /// This function will spawn off `config.jobs()` workers to build all of the /// necessary dependencies, in order. Freshness is propagated as far as /// possible along each dependency chain. - pub fn execute(&mut self, cx: &mut Context, plan: &mut BuildPlan) -> CargoResult<()> { + pub fn execute(&mut self, cx: &mut Context<'_, '_>, plan: &mut BuildPlan) -> CargoResult<()> { let _p = profile::start("executing the job graph"); self.queue.queue_finished(); @@ -209,7 +211,7 @@ fn drain_the_queue( &mut self, - cx: &mut Context, + cx: &mut Context<'_, '_>, plan: &mut BuildPlan, scope: &Scope<'a>, jobserver_helper: &HelperThread, @@ -224,14 +226,13 @@ // loop starts out by scheduling as much work as possible (up to the // maximum number of parallel jobs we have tokens for). A local queue // is maintained separately from the main dependency queue as one - // dequeue may actually dequeue quite a bit of work (e.g. 10 binaries + // dequeue may actually dequeue quite a bit of work (e.g., 10 binaries // in one package). // // After a job has finished we update our internal state if it was // successful and otherwise wait for pending work to finish if it failed // and then immediately return. let mut error = None; - let mut progress = Progress::with_style("Building", ProgressStyle::Ratio, cx.bcx.config); let total = self.queue.len(); loop { // Dequeue as much work as we can, learning about everything @@ -276,84 +277,90 @@ // to the jobserver itself. tokens.truncate(self.active.len() - 1); - let count = total - self.queue.len(); - let active_names = self - .active - .iter() - .map(Key::name_for_progress) - .collect::>(); - drop(progress.tick_now(count, total, &format!(": {}", active_names.join(", ")))); - let event = self.rx.recv().unwrap(); - progress.clear(); - - match event { - Message::Run(cmd) => { - cx.bcx - .config - .shell() - .verbose(|c| c.status("Running", &cmd))?; - } - Message::BuildPlanMsg(module_name, cmd, filenames) => { - plan.update(&module_name, &cmd, &filenames)?; - } - Message::Stdout(out) => { - println!("{}", out); - } - Message::Stderr(err) => { - let mut shell = cx.bcx.config.shell(); - shell.print_ansi(err.as_bytes())?; - shell.err().write_all(b"\n")?; - } - Message::FixDiagnostic(msg) => { - print.print(&msg)?; - } - Message::Finish(key, result) => { - info!("end: {:?}", key); - - // self.active.remove_item(&key); // <- switch to this when stabilized. - let pos = self - .active - .iter() - .position(|k| *k == key) - .expect("an unrecorded package has finished compiling"); - self.active.remove(pos); - if !self.active.is_empty() { - assert!(!tokens.is_empty()); - drop(tokens.pop()); + // Drain all events at once to avoid displaying the progress bar + // unnecessarily. + let events: Vec<_> = self.rx.try_iter().collect(); + let events = if events.is_empty() { + self.show_progress(total); + vec![self.rx.recv().unwrap()] + } else { + events + }; + + for event in events { + match event { + Message::Run(cmd) => { + cx.bcx + .config + .shell() + .verbose(|c| c.status("Running", &cmd))?; } - match result { - Ok(()) => self.finish(key, cx)?, - Err(e) => { - let msg = "The following warnings were emitted during compilation:"; - self.emit_warnings(Some(msg), &key, cx)?; - - if !self.active.is_empty() { - error = Some(format_err!("build failed")); - handle_error(&e, &mut *cx.bcx.config.shell()); - cx.bcx.config.shell().warn( - "build failed, waiting for other \ - jobs to finish...", - )?; - } else { - error = Some(e); + Message::BuildPlanMsg(module_name, cmd, filenames) => { + plan.update(&module_name, &cmd, &filenames)?; + } + Message::Stdout(out) => { + self.progress.clear(); + println!("{}", out); + } + Message::Stderr(err) => { + let mut shell = cx.bcx.config.shell(); + shell.print_ansi(err.as_bytes())?; + shell.err().write_all(b"\n")?; + } + Message::FixDiagnostic(msg) => { + print.print(&msg)?; + } + Message::Finish(key, result) => { + info!("end: {:?}", key); + + // FIXME: switch to this when stabilized. + // self.active.remove_item(&key); + let pos = self + .active + .iter() + .position(|k| *k == key) + .expect("an unrecorded package has finished compiling"); + self.active.remove(pos); + if !self.active.is_empty() { + assert!(!tokens.is_empty()); + drop(tokens.pop()); + } + match result { + Ok(()) => self.finish(key, cx)?, + Err(e) => { + let msg = "The following warnings were emitted during compilation:"; + self.emit_warnings(Some(msg), &key, cx)?; + + if !self.active.is_empty() { + error = Some(failure::format_err!("build failed")); + handle_error(&e, &mut *cx.bcx.config.shell()); + cx.bcx.config.shell().warn( + "build failed, waiting for other \ + jobs to finish...", + )?; + } else { + error = Some(e); + } } } } - } - Message::Token(acquired_token) => { - tokens.push(acquired_token.chain_err(|| "failed to acquire jobserver token")?); + Message::Token(acquired_token) => { + tokens.push( + acquired_token.chain_err(|| "failed to acquire jobserver token")?, + ); + } } } } - drop(progress); + self.progress.clear(); let build_type = if self.is_release { "release" } else { "dev" }; - // NOTE: This may be a bit inaccurate, since this may not display the - // profile for what was actually built. Profile overrides can change + // NOTE: this may be a bit inaccurate, since this may not display the + // profile for what was actually built. Profile overrides can change // these settings, and in some cases different targets are built with - // different profiles. To be accurate, it would need to collect a + // different profiles. To be accurate, it would need to collect a // list of Units built, and maybe display a list of the different - // profiles used. However, to keep it simple and compatible with old + // profiles used. However, to keep it simple and compatible with old // behavior, we just display what the base profile is. let profile = cx.bcx.profiles.base_profile(self.is_release); let mut opt_type = String::from(if profile.opt_level.as_str() == "0" { @@ -384,6 +391,19 @@ } } + fn show_progress(&mut self, total: usize) { + let count = total - self.queue.len(); + let active_names = self + .active + .iter() + .map(Key::name_for_progress) + .collect::>(); + drop( + self.progress + .tick_now(count, total, &format!(": {}", active_names.join(", "))), + ); + } + /// Executes a job in the `scope` given, pushing the spawned thread's /// handled onto `threads`. fn run( @@ -407,7 +427,7 @@ }; if !build_plan { - // Print out some nice progress information + // Print out some nice progress information. self.note_working_on(config, &key, fresh)?; } @@ -421,30 +441,35 @@ Ok(()) } - fn emit_warnings(&self, msg: Option<&str>, key: &Key<'a>, cx: &mut Context) -> CargoResult<()> { + fn emit_warnings( + &mut self, + msg: Option<&str>, + key: &Key<'a>, + cx: &mut Context<'_, '_>, + ) -> CargoResult<()> { let output = cx.build_state.outputs.lock().unwrap(); let bcx = &mut cx.bcx; if let Some(output) = output.get(&(key.pkg, key.kind)) { - if let Some(msg) = msg { - if !output.warnings.is_empty() { + if !output.warnings.is_empty() { + if let Some(msg) = msg { writeln!(bcx.config.shell().err(), "{}\n", msg)?; } - } - for warning in output.warnings.iter() { - bcx.config.shell().warn(warning)?; - } + for warning in output.warnings.iter() { + bcx.config.shell().warn(warning)?; + } - if !output.warnings.is_empty() && msg.is_some() { - // Output an empty line. - writeln!(bcx.config.shell().err())?; + if msg.is_some() { + // Output an empty line. + writeln!(bcx.config.shell().err())?; + } } } Ok(()) } - fn finish(&mut self, key: Key<'a>, cx: &mut Context) -> CargoResult<()> { + fn finish(&mut self, key: Key<'a>, cx: &mut Context<'_, '_>) -> CargoResult<()> { if key.mode.is_run_custom_build() && cx.bcx.show_warnings(key.pkg) { self.emit_warnings(None, &key, cx)?; } @@ -480,10 +505,10 @@ match fresh { // Any dirty stage which runs at least one command gets printed as - // being a compiled package + // being a compiled package. Dirty => { if key.mode.is_doc() { - // Skip Doctest + // Skip doc test. if !key.mode.is_any_test() { self.documented.insert(key.pkg); config.shell().status("Documenting", key.pkg)?; @@ -498,7 +523,7 @@ } } Fresh => { - // If doctest is last, only print "Fresh" if nothing has been printed. + // If doc test are last, only print "Fresh" if nothing has been printed. if self.counts[&key.pkg] == 0 && !(key.mode == CompileMode::Doctest && self.compiled.contains(&key.pkg)) { @@ -547,7 +572,7 @@ } impl<'a> fmt::Debug for Key<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{} => {}/{} => {:?}", diff -Nru cargo-0.33.0/src/cargo/core/compiler/job.rs cargo-0.35.0/src/cargo/core/compiler/job.rs --- cargo-0.33.0/src/cargo/core/compiler/job.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/job.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ use std::fmt; use super::job_queue::JobState; -use util::{CargoResult, Dirty, Fresh, Freshness}; +use crate::util::{CargoResult, Dirty, Fresh, Freshness}; pub struct Job { dirty: Work, @@ -11,7 +11,7 @@ /// Each proc should send its description before starting. /// It should send either once or close immediately. pub struct Work { - inner: Box FnBox<&'a JobState<'b>, CargoResult<()>> + Send>, + inner: Box FnBox<&'a JobState<'b>, CargoResult<()>> + Send>, } trait FnBox { @@ -27,7 +27,7 @@ impl Work { pub fn new(f: F) -> Work where - F: FnOnce(&JobState) -> CargoResult<()> + Send + 'static, + F: FnOnce(&JobState<'_>) -> CargoResult<()> + Send + 'static, { Work { inner: Box::new(f) } } @@ -36,7 +36,7 @@ Work::new(|_| Ok(())) } - pub fn call(self, tx: &JobState) -> CargoResult<()> { + pub fn call(self, tx: &JobState<'_>) -> CargoResult<()> { self.inner.call_box(tx) } @@ -49,14 +49,14 @@ } impl Job { - /// Create a new job representing a unit of work. + /// Creates a new job representing a unit of work. pub fn new(dirty: Work, fresh: Work) -> Job { Job { dirty, fresh } } /// Consumes this job by running it, returning the result of the /// computation. - pub fn run(self, fresh: Freshness, state: &JobState) -> CargoResult<()> { + pub fn run(self, fresh: Freshness, state: &JobState<'_>) -> CargoResult<()> { match fresh { Fresh => self.fresh.call(state), Dirty => self.dirty.call(state), @@ -65,7 +65,7 @@ } impl fmt::Debug for Job { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Job {{ ... }}") } } diff -Nru cargo-0.33.0/src/cargo/core/compiler/layout.rs cargo-0.35.0/src/cargo/core/compiler/layout.rs --- cargo-0.33.0/src/cargo/core/compiler/layout.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/layout.rs 2019-04-01 21:32:07.000000000 +0000 @@ -53,8 +53,8 @@ use std::io; use std::path::{Path, PathBuf}; -use core::Workspace; -use util::{CargoResult, Config, FileLock, Filesystem}; +use crate::core::Workspace; +use crate::util::{CargoResult, Config, FileLock, Filesystem}; /// Contains the paths of all target output locations. /// @@ -67,7 +67,7 @@ incremental: PathBuf, fingerprint: PathBuf, examples: PathBuf, - /// The lockfile for a build, will be unlocked when this struct is `drop`ped. + /// The lock file for a build, will be unlocked when this struct is `drop`ped. _lock: FileLock, } @@ -84,7 +84,7 @@ /// /// Differs from `at` in that this calculates the root path from the workspace target directory, /// adding the target triple and the profile (debug, release, ...). - pub fn new(ws: &Workspace, triple: Option<&str>, dest: &str) -> CargoResult { + pub fn new(ws: &Workspace<'_>, triple: Option<&str>, dest: &str) -> CargoResult { let mut path = ws.target_dir(); // Flexible target specifications often point at json files, so interpret // the target triple as a Path and then just use the file stem as the @@ -95,7 +95,7 @@ path.push( triple .file_stem() - .ok_or_else(|| format_err!("invalid target"))?, + .ok_or_else(|| failure::format_err!("invalid target"))?, ); } else { path.push(triple); @@ -156,7 +156,7 @@ // doesn't prevent Cargo from working } - /// Make sure all directories stored in the Layout exist on the filesystem. + /// Makes sure all directories stored in the Layout exist on the filesystem. pub fn prepare(&mut self) -> io::Result<()> { if fs::metadata(&self.root).is_err() { fs::create_dir_all(&self.root)?; diff -Nru cargo-0.33.0/src/cargo/core/compiler/mod.rs cargo-0.35.0/src/cargo/core/compiler/mod.rs --- cargo-0.33.0/src/cargo/core/compiler/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,3 +1,15 @@ +mod build_config; +mod build_context; +mod build_plan; +mod compilation; +mod context; +mod custom_build; +mod fingerprint; +mod job; +mod job_queue; +mod layout; +mod output_depinfo; + use std::env; use std::ffi::{OsStr, OsString}; use std::fs; @@ -6,43 +18,29 @@ use std::sync::Arc; use failure::Error; +use log::debug; use same_file::is_same_file; -use serde_json; - -use core::manifest::TargetSourcePath; -use core::profiles::{Lto, Profile}; -use core::{PackageId, Target}; -use util::errors::{CargoResult, CargoResultExt, Internal, ProcessError}; -use util::paths; -use util::{self, machine_message, process, Freshness, ProcessBuilder}; -use util::{internal, join_paths, profile}; - -use self::build_plan::BuildPlan; -use self::job::{Job, Work}; -use self::job_queue::JobQueue; - -use self::output_depinfo::output_depinfo; +use serde::Serialize; +use crate::core::manifest::TargetSourcePath; +use crate::core::profiles::{Lto, Profile}; +use crate::core::{PackageId, Target}; +use crate::util::errors::{CargoResult, CargoResultExt, Internal, ProcessError}; +use crate::util::paths; +use crate::util::{self, machine_message, process, Freshness, ProcessBuilder}; +use crate::util::{internal, join_paths, profile}; pub use self::build_config::{BuildConfig, CompileMode, MessageFormat}; pub use self::build_context::{BuildContext, FileFlavor, TargetConfig, TargetInfo}; +use self::build_plan::BuildPlan; pub use self::compilation::{Compilation, Doctest}; pub use self::context::{Context, Unit}; pub use self::custom_build::{BuildMap, BuildOutput, BuildScripts}; +use self::job::{Job, Work}; +use self::job_queue::JobQueue; pub use self::layout::is_bad_artifact_name; +use self::output_depinfo::output_depinfo; -mod build_config; -mod build_context; -mod build_plan; -mod compilation; -mod context; -mod custom_build; -mod fingerprint; -mod job; -mod job_queue; -mod layout; -mod output_depinfo; - -/// Whether an object is for the host arch, or the target arch. +/// Indicates whether an object is for the host architcture or the target architecture. /// /// These will be the same unless cross-compiling. #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord, Serialize)] @@ -52,13 +50,13 @@ } /// A glorified callback for executing calls to rustc. Rather than calling rustc -/// directly, we'll use an Executor, giving clients an opportunity to intercept +/// directly, we'll use an `Executor`, giving clients an opportunity to intercept /// the build calls. pub trait Executor: Send + Sync + 'static { /// Called after a rustc process invocation is prepared up-front for a given /// unit of work (may still be modified for runtime-known dependencies, when /// the work is actually executed). - fn init(&self, _cx: &Context, _unit: &Unit) {} + fn init(&self, _cx: &Context<'_, '_>, _unit: &Unit<'_>) {} /// In case of an `Err`, Cargo will not continue with the build process for /// this package. @@ -81,7 +79,7 @@ mode: CompileMode, _state: &job_queue::JobState<'_>, ) -> CargoResult<()> { - // we forward to exec() to keep RLS working. + // We forward to `exec()` to keep RLS working. self.exec(cmd, id, target, mode) } @@ -91,8 +89,8 @@ _id: PackageId, _target: &Target, _mode: CompileMode, - handle_stdout: &mut FnMut(&str) -> CargoResult<()>, - handle_stderr: &mut FnMut(&str) -> CargoResult<()>, + handle_stdout: &mut dyn FnMut(&str) -> CargoResult<()>, + handle_stderr: &mut dyn FnMut(&str) -> CargoResult<()>, ) -> CargoResult<()> { cmd.exec_with_streaming(handle_stdout, handle_stderr, false)?; Ok(()) @@ -100,7 +98,7 @@ /// Queried when queuing each unit of work. If it returns true, then the /// unit will always be rebuilt, independent of whether it needs to be. - fn force_rebuild(&self, _unit: &Unit) -> bool { + fn force_rebuild(&self, _unit: &Unit<'_>) -> bool { false } } @@ -125,10 +123,10 @@ fn compile<'a, 'cfg: 'a>( cx: &mut Context<'a, 'cfg>, - jobs: &mut JobQueue<'a>, + jobs: &mut JobQueue<'a, 'cfg>, plan: &mut BuildPlan, unit: &Unit<'a>, - exec: &Arc, + exec: &Arc, force_rebuild: bool, ) -> CargoResult<()> { let bcx = cx.bcx; @@ -146,7 +144,7 @@ let (dirty, fresh, freshness) = if unit.mode.is_run_custom_build() { custom_build::prepare(cx, unit)? } else if unit.mode == CompileMode::Doctest { - // we run these targets later, so this is just a noop for now + // We run these targets later, so this is just a no-op for now. (Work::noop(), Work::noop(), Freshness::Fresh) } else if build_plan { ( @@ -161,7 +159,7 @@ } else { rustc(cx, unit, exec)? }; - // Need to link targets on both the dirty and fresh + // Need to link targets on both the dirty and fresh. let dirty = work.then(link_targets(cx, unit, false)?).then(dirty); let fresh = link_targets(cx, unit, true)?.then(fresh); @@ -188,7 +186,7 @@ fn rustc<'a, 'cfg>( cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>, - exec: &Arc, + exec: &Arc, ) -> CargoResult { let mut rustc = prepare_rustc(cx, &unit.target.rustc_crate_types(), unit)?; if cx.is_primary_package(unit) { @@ -205,7 +203,7 @@ let root = cx.files().out_dir(unit); let kind = unit.kind; - // Prepare the native lib state (extra -L and -l flags) + // Prepare the native lib state (extra `-L` and `-l` flags). let build_state = cx.build_state.clone(); let current_id = unit.pkg.package_id(); let build_deps = load_build_deps(cx, unit); @@ -217,7 +215,7 @@ let real_name = unit.target.name().to_string(); let crate_name = unit.target.crate_name(); - // XXX(Rely on target_filenames iterator as source of truth rather than rederiving filestem) + // Rely on `target_filenames` iterator as source of truth rather than rederiving filestem. let rustc_dep_info_loc = if do_rename && cx.files().metadata(unit).is_none() { root.join(&crate_name) } else { @@ -278,8 +276,8 @@ } fn internal_if_simple_exit_code(err: Error) -> Error { - // If a signal on unix (code == None) or an abnormal termination - // on Windows (codes like 0xC0000409), don't hide the error details. + // If a signal on unix (`code == None`) or an abnormal termination + // on Windows (codes like `0xC0000409`), don't hide the error details. match err .downcast_ref::() .as_ref() @@ -291,6 +289,7 @@ } state.running(&rustc); + let timestamp = paths::get_current_filesystem_time(&dep_info_loc)?; if json_messages { exec.exec_json( rustc, @@ -333,13 +332,14 @@ rustc_dep_info_loc.display() )) })?; + filetime::set_file_times(dep_info_loc, timestamp, timestamp)?; } Ok(()) })); - // Add all relevant -L and -l flags from dependencies (now calculated and - // present in `state`) to the command provided + // Add all relevant `-L` and `-l` flags from dependencies (now calculated and + // present in `state`) to the command provided. fn add_native_deps( rustc: &mut ProcessBuilder, build_state: &BuildMap, @@ -390,7 +390,7 @@ } /// Link the compiled target (often of form `foo-{metadata_hash}`) to the -/// final target. This must happen during both "Fresh" and "Compile" +/// final target. This must happen during both "Fresh" and "Compile". fn link_targets<'a, 'cfg>( cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>, @@ -409,6 +409,7 @@ .map(|s| s.to_owned()) .collect(); let json_messages = bcx.build_config.json_messages(); + let executable = cx.get_executable(unit)?; let mut target = unit.target.clone(); if let TargetSourcePath::Metabuild = target.src_path() { // Give it something to serialize. @@ -417,7 +418,7 @@ } Ok(Work::new(move |_| { - // If we're a "root crate", e.g. the target of this compilation, then we + // If we're a "root crate", e.g., the target of this compilation, then we // hard link our outputs out of the `deps` directory into the directory // above. This means that `cargo build` will produce binaries in // `target/debug` which one probably expects. @@ -432,11 +433,11 @@ let dst = match output.hardlink.as_ref() { Some(dst) => dst, None => { - destinations.push(src.display().to_string()); + destinations.push(src.clone()); continue; } }; - destinations.push(dst.display().to_string()); + destinations.push(dst.clone()); hardlink_or_copy(src, dst)?; if let Some(ref path) = output.export_path { let export_dir = export_dir.as_ref().unwrap(); @@ -463,6 +464,7 @@ profile: art_profile, features, filenames: destinations, + executable, fresh, }); } @@ -512,7 +514,7 @@ Ok(()) } -fn load_build_deps(cx: &Context, unit: &Unit) -> Option> { +fn load_build_deps(cx: &Context<'_, '_>, unit: &Unit<'_>) -> Option> { cx.build_scripts.get(unit).cloned() } @@ -545,7 +547,7 @@ // Determine paths to add to the dynamic search path from -L entries // // Strip off prefixes like "native=" or "framework=" and filter out directories -// *not* inside our output directory since they are likely spurious and can cause +// **not** inside our output directory since they are likely spurious and can cause // clashes with system shared libraries (issue #3366). fn filter_dynamic_search_path<'a, I>(paths: I, root_output: &PathBuf) -> Vec where @@ -684,12 +686,11 @@ // // The first returned value here is the argument to pass to rustc, and the // second is the cwd that rustc should operate in. -fn path_args(bcx: &BuildContext, unit: &Unit) -> (PathBuf, PathBuf) { +fn path_args(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>) -> (PathBuf, PathBuf) { let ws_root = bcx.ws.root(); - let src = if unit.target.is_custom_build() && unit.pkg.manifest().metabuild().is_some() { - unit.pkg.manifest().metabuild_path(bcx.ws.target_dir()) - } else { - unit.target.src_path().path().to_path_buf() + let src = match unit.target.src_path() { + TargetSourcePath::Path(path) => path.to_path_buf(), + TargetSourcePath::Metabuild => unit.pkg.manifest().metabuild_path(bcx.ws.target_dir()), }; assert!(src.is_absolute()); if unit.pkg.package_id().source_id().is_path() { @@ -700,13 +701,13 @@ (src, unit.pkg.root().to_path_buf()) } -fn add_path_args(bcx: &BuildContext, unit: &Unit, cmd: &mut ProcessBuilder) { +fn add_path_args(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>, cmd: &mut ProcessBuilder) { let (arg, cwd) = path_args(bcx, unit); cmd.arg(arg); cmd.cwd(cwd); } -fn add_cap_lints(bcx: &BuildContext, unit: &Unit, cmd: &mut ProcessBuilder) { +fn add_cap_lints(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>, cmd: &mut ProcessBuilder) { // If this is an upstream dep we don't want warnings from, turn off all // lints. if !bcx.show_warnings(unit.pkg.package_id()) { @@ -719,7 +720,7 @@ } } -fn add_color(bcx: &BuildContext, cmd: &mut ProcessBuilder) { +fn add_color(bcx: &BuildContext<'_, '_>, cmd: &mut ProcessBuilder) { let shell = bcx.config.shell(); let color = if shell.supports_color() { "always" @@ -729,7 +730,7 @@ cmd.args(&["--color", color]); } -fn add_error_format(bcx: &BuildContext, cmd: &mut ProcessBuilder) { +fn add_error_format(bcx: &BuildContext<'_, '_>, cmd: &mut ProcessBuilder) { match bcx.build_config.message_format { MessageFormat::Human => (), MessageFormat::Json => { @@ -759,6 +760,7 @@ overflow_checks, rpath, ref panic, + incremental, .. } = unit.profile; let test = unit.mode.is_any_test(); @@ -823,9 +825,9 @@ cmd.args(args); } - // -C overflow-checks is implied by the setting of -C debug-assertions, - // so we only need to provide -C overflow-checks if it differs from - // the value of -C debug-assertions we would provide. + // `-C overflow-checks` is implied by the setting of `-C debug-assertions`, + // so we only need to provide `-C overflow-checks` if it differs from + // the value of `-C debug-assertions` we would provide. if opt_level.as_str() != "0" { if debug_assertions { cmd.args(&["-C", "debug-assertions=on"]); @@ -901,8 +903,10 @@ "linker=", bcx.linker(unit.kind).map(|s| s.as_ref()), ); - cmd.args(&cx.incremental_args(unit)?); - + if incremental { + let dir = cx.files().layout(unit.kind).incremental().as_os_str(); + opt(cmd, "-C", "incremental=", Some(dir)); + } Ok(()) } @@ -918,7 +922,7 @@ deps }); - // Be sure that the host path is also listed. This'll ensure that proc-macro + // Be sure that the host path is also listed. This'll ensure that proc macro // dependencies are correctly found (for reexported macros). if let Kind::Target = unit.kind { cmd.arg("-L").arg(&{ @@ -932,7 +936,7 @@ // If there is not one linkable target but should, rustc fails later // on if there is an `extern crate` for it. This may turn into a hard - // error in the future, see PR #4797 + // error in the future (see PR #4797). if !dep_targets .iter() .any(|u| !u.mode.is_doc() && u.target.linkable()) @@ -999,7 +1003,7 @@ fn for_target(self, target: &Target) -> Kind { // Once we start compiling for the `Host` kind we continue doing so, but // if we are a `Target` kind and then we start compiling for a target - // that needs to be on the host we lift ourselves up to `Host` + // that needs to be on the host we lift ourselves up to `Host`. match self { Kind::Host => Kind::Host, Kind::Target if target.for_host() => Kind::Host, @@ -1020,9 +1024,9 @@ } fn json_stderr(line: &str, package_id: PackageId, target: &Target) -> CargoResult<()> { - // stderr from rustc/rustdoc can have a mix of JSON and non-JSON output + // Stderr from rustc/rustdoc can have a mix of JSON and non-JSON output. if line.starts_with('{') { - // Handle JSON lines + // Handle JSON lines. let compiler_message = serde_json::from_str(line) .map_err(|_| internal(&format!("compiler produced invalid json: `{}`", line)))?; @@ -1032,7 +1036,7 @@ message: compiler_message, }); } else { - // Forward non-JSON to stderr + // Forward non-JSON to stderr. writeln!(io::stderr(), "{}", line)?; } Ok(()) diff -Nru cargo-0.33.0/src/cargo/core/compiler/output_depinfo.rs cargo-0.35.0/src/cargo/core/compiler/output_depinfo.rs --- cargo-0.33.0/src/cargo/core/compiler/output_depinfo.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/compiler/output_depinfo.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,9 +3,11 @@ use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; +use log::debug; + use super::{fingerprint, Context, Unit}; -use util::paths; -use util::{internal, CargoResult}; +use crate::util::paths; +use crate::util::{internal, CargoResult}; fn render_filename>(path: P, basedir: Option<&str>) -> CargoResult { let path = path.as_ref(); diff -Nru cargo-0.33.0/src/cargo/core/dependency.rs cargo-0.35.0/src/cargo/core/dependency.rs --- cargo-0.33.0/src/cargo/core/dependency.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/dependency.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,14 +2,17 @@ use std::rc::Rc; use std::str::FromStr; +use log::trace; use semver::ReqParseError; use semver::VersionReq; use serde::ser; +use serde::Serialize; +use url::Url; -use core::interning::InternedString; -use core::{PackageId, SourceId, Summary}; -use util::errors::{CargoError, CargoResult, CargoResultExt}; -use util::{Cfg, CfgExpr, Config}; +use crate::core::interning::InternedString; +use crate::core::{PackageId, SourceId, Summary}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{Cfg, CfgExpr, Config}; /// Information about a dependency requested by a Cargo manifest. /// Cheap to copy. @@ -18,11 +21,17 @@ inner: Rc, } -/// The data underlying a Dependency. +/// The data underlying a `Dependency`. #[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Clone, Debug)] struct Inner { name: InternedString, source_id: SourceId, + /// Source ID for the registry as specified in the manifest. + /// + /// This will be None if it is not specified (crates.io dependency). + /// This is different from `source_id` for example when both a `path` and + /// `registry` is specified. Or in the case of a crates.io dependency, + /// `source_id` will be crates.io and this will be None. registry_id: Option, req: VersionReq, specified_req: bool, @@ -57,6 +66,10 @@ uses_default_features: bool, features: &'a [InternedString], target: Option<&'a Platform>, + /// The registry URL this dependency is from. + /// If None, then it comes from the default registry (crates.io). + #[serde(with = "url_serde")] + registry: Option, } impl ser::Serialize for Dependency { @@ -74,6 +87,7 @@ features: self.features(), target: self.platform(), rename: self.explicit_name_in_toml().map(|s| s.as_str()), + registry: self.registry_id().map(|sid| sid.url().clone()), } .serialize(s) } @@ -219,7 +233,7 @@ /// This is the name of this `Dependency` as listed in `Cargo.toml`. /// /// Or in other words, this is what shows up in the `[dependencies]` section - /// on the left hand side. This is **not** the name of the package that's + /// on the left hand side. This is *not* the name of the package that's /// being depended on as the dependency can be renamed. For that use /// `package_name` below. /// @@ -326,13 +340,13 @@ self } - /// Set the source id for this dependency + /// Sets the source ID for this dependency. pub fn set_source_id(&mut self, id: SourceId) -> &mut Dependency { Rc::make_mut(&mut self.inner).source_id = id; self } - /// Set the version requirement for this dependency + /// Sets the version requirement for this dependency. pub fn set_version_req(&mut self, req: VersionReq) -> &mut Dependency { Rc::make_mut(&mut self.inner).req = req; self @@ -348,7 +362,7 @@ self } - /// Lock this dependency to depending on the specified package id + /// Locks this dependency to depending on the specified package ID. pub fn lock_to(&mut self, id: PackageId) -> &mut Dependency { assert_eq!(self.inner.source_id, id.source_id()); assert!(self.inner.req.matches(id.version())); @@ -363,14 +377,14 @@ .set_source_id(id.source_id()) } - /// Returns whether this is a "locked" dependency, basically whether it has + /// Returns `true` if this is a "locked" dependency, basically whether it has /// an exact version req. pub fn is_locked(&self) -> bool { // Kind of a hack to figure this out, but it works! self.inner.req.to_string().starts_with('=') } - /// Returns false if the dependency is only used to build the local package. + /// Returns `false` if the dependency is only used to build the local package. pub fn is_transitive(&self) -> bool { match self.inner.kind { Kind::Normal | Kind::Build => true, @@ -389,7 +403,7 @@ self.inner.optional } - /// Returns true if the default features of the dependency are requested. + /// Returns `true` if the default features of the dependency are requested. pub fn uses_default_features(&self) -> bool { self.inner.default_features } @@ -398,17 +412,17 @@ &self.inner.features } - /// Returns true if the package (`sum`) can fulfill this dependency request. + /// Returns `true` if the package (`sum`) can fulfill this dependency request. pub fn matches(&self, sum: &Summary) -> bool { self.matches_id(sum.package_id()) } - /// Returns true if the package (`sum`) can fulfill this dependency request. + /// Returns `true` if the package (`sum`) can fulfill this dependency request. pub fn matches_ignoring_source(&self, id: PackageId) -> bool { self.package_name() == id.name() && self.version_req().matches(id.version()) } - /// Returns true if the package (`id`) can fulfill this dependency request. + /// Returns `true` if the package (`id`) can fulfill this dependency request. pub fn matches_id(&self, id: PackageId) -> bool { self.inner.name == id.name() && (self.inner.only_match_name @@ -447,15 +461,14 @@ } impl FromStr for Platform { - type Err = CargoError; + type Err = failure::Error; fn from_str(s: &str) -> CargoResult { if s.starts_with("cfg(") && s.ends_with(')') { let s = &s[4..s.len() - 1]; - let p = s - .parse() - .map(Platform::Cfg) - .chain_err(|| format_err!("failed to parse `{}` as a cfg expression", s))?; + let p = s.parse().map(Platform::Cfg).chain_err(|| { + failure::format_err!("failed to parse `{}` as a cfg expression", s) + })?; Ok(p) } else { Ok(Platform::Name(s.to_string())) @@ -464,7 +477,7 @@ } impl fmt::Display for Platform { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Platform::Name(ref n) => n.fmt(f), Platform::Cfg(ref e) => write!(f, "cfg({})", e), diff -Nru cargo-0.33.0/src/cargo/core/features.rs cargo-0.35.0/src/cargo/core/features.rs --- cargo-0.33.0/src/cargo/core/features.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/features.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -//! Support for nightly features in Cargo itself +//! Support for nightly features in Cargo itself. //! //! This file is the version of `feature_gate.rs` in upstream Rust for Cargo //! itself and is intended to be the avenue for which new features in Cargo are @@ -37,7 +37,7 @@ //! //! 4. Update the unstable documentation at //! `src/doc/src/reference/unstable.md` to include a short description of -//! how to use your new feature. When the feature is stabilized, be sure +//! how to use your new feature. When the feature is stabilized, be sure //! that the Cargo Guide or Reference is updated to fully document the //! feature and remove the entry from the Unstable section. //! @@ -51,8 +51,9 @@ use std::str::FromStr; use failure::Error; +use serde::{Deserialize, Serialize}; -use util::errors::CargoResult; +use crate::util::errors::CargoResult; /// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize)] @@ -64,7 +65,7 @@ } impl fmt::Display for Edition { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Edition::Edition2015 => f.write_str("2015"), Edition::Edition2018 => f.write_str("2018"), @@ -77,10 +78,11 @@ match s { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), - s => { - bail!("supported edition values are `2015` or `2018`, but `{}` \ - is unknown", s) - } + s => failure::bail!( + "supported edition values are `2015` or `2018`, but `{}` \ + is unknown", + s + ), } } } @@ -148,17 +150,17 @@ }; } -/// A listing of all features in Cargo -/// -/// "look here" -/// -/// This is the macro that lists all stable and unstable features in Cargo. -/// You'll want to add to this macro whenever you add a feature to Cargo, also -/// following the directions above. -/// -/// Note that all feature names here are valid Rust identifiers, but the `_` -/// character is translated to `-` when specified in the `cargo-features` -/// manifest entry in `Cargo.toml`. +// A listing of all features in Cargo. +// +// "look here" +// +// This is the macro that lists all stable and unstable features in Cargo. +// You'll want to add to this macro whenever you add a feature to Cargo, also +// following the directions above. +// +// Note that all feature names here are valid Rust identifiers, but the `_` +// character is translated to `-` when specified in the `cargo-features` +// manifest entry in `Cargo.toml`. features! { pub struct Features { @@ -171,7 +173,7 @@ [unstable] test_dummy_unstable: bool, // Downloading packages from alternative registry indexes. - [unstable] alternative_registries: bool, + [stable] alternative_registries: bool, // Using editions [stable] edition: bool, @@ -214,11 +216,11 @@ fn add(&mut self, feature: &str, warnings: &mut Vec) -> CargoResult<()> { let (slot, status) = match self.status(feature) { Some(p) => p, - None => bail!("unknown cargo feature `{}`", feature), + None => failure::bail!("unknown cargo feature `{}`", feature), }; if *slot { - bail!("the cargo feature `{}` has already been activated", feature); + failure::bail!("the cargo feature `{}` has already been activated", feature); } match status { @@ -231,7 +233,7 @@ ); warnings.push(warning); } - Status::Unstable if !nightly_features_allowed() => bail!( + Status::Unstable if !nightly_features_allowed() => failure::bail!( "the cargo feature `{}` requires a nightly version of \ Cargo, but this is the `{}` channel", feature, @@ -273,7 +275,7 @@ ); msg.push_str(&s); } - bail!("{}", msg); + failure::bail!("{}", msg); } } @@ -318,12 +320,14 @@ pub package_features: bool, pub advanced_env: bool, pub config_profile: bool, + pub dual_proc_macros: bool, + pub mtime_on_use: bool, } impl CliUnstable { pub fn parse(&mut self, flags: &[String]) -> CargoResult<()> { if !flags.is_empty() && !nightly_features_allowed() { - bail!("the `-Z` flag is only accepted on the nightly channel of Cargo") + failure::bail!("the `-Z` flag is only accepted on the nightly channel of Cargo") } for flag in flags { self.add(flag)?; @@ -340,7 +344,7 @@ match value { None | Some("yes") => Ok(true), Some("no") => Ok(false), - Some(s) => bail!("expected `no` or `yes`, found: {}", s), + Some(s) => failure::bail!("expected `no` or `yes`, found: {}", s), } } @@ -354,7 +358,9 @@ "package-features" => self.package_features = true, "advanced-env" => self.advanced_env = true, "config-profile" => self.config_profile = true, - _ => bail!("unknown `-Z` flag specified: {}", k), + "dual-proc-macros" => self.dual_proc_macros = true, + "mtime-on-use" => self.mtime_on_use = true, + _ => failure::bail!("unknown `-Z` flag specified: {}", k), } Ok(()) @@ -370,7 +376,7 @@ return "dev".to_string(); } } - ::version() + crate::version() .cfg_info .map(|c| c.release_channel) .unwrap_or_else(|| String::from("dev")) @@ -396,9 +402,9 @@ /// that called `masquerade_as_nightly_cargo` pub fn nightly_features_allowed() -> bool { if ENABLE_NIGHTLY_FEATURES.with(|c| c.get()) { - return true + return true; } - match &channel()[..] { + match &channel()[..] { "nightly" | "dev" => NIGHTLY_FEATURES_ALLOWED.with(|c| c.get()), _ => false, } diff -Nru cargo-0.33.0/src/cargo/core/interning.rs cargo-0.35.0/src/cargo/core/interning.rs --- cargo-0.33.0/src/cargo/core/interning.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/interning.rs 2019-04-01 21:32:07.000000000 +0000 @@ -14,7 +14,7 @@ Box::leak(s.into_boxed_str()) } -lazy_static! { +lazy_static::lazy_static! { static ref STRING_CACHE: Mutex> = Mutex::new(HashSet::new()); } @@ -57,7 +57,7 @@ } impl Hash for InternedString { - // NB: we can't implement this as `identity(self).hash(state)`, + // N.B., we can't implement this as `identity(self).hash(state)`, // because we use this for on-disk fingerprints and so need // stability across Cargo invocations. fn hash(&self, state: &mut H) { @@ -66,7 +66,7 @@ } impl Borrow for InternedString { - // if we implement Hash as `identity(self).hash(state)`, + // If we implement Hash as `identity(self).hash(state)`, // then this will nead to be removed. fn borrow(&self) -> &str { self.as_str() @@ -74,13 +74,13 @@ } impl fmt::Debug for InternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(self.as_str(), f) } } impl fmt::Display for InternedString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self.as_str(), f) } } diff -Nru cargo-0.33.0/src/cargo/core/manifest.rs cargo-0.35.0/src/cargo/core/manifest.rs --- cargo-0.33.0/src/cargo/core/manifest.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/manifest.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,23 +6,23 @@ use semver::Version; use serde::ser; -use toml; +use serde::Serialize; use url::Url; -use core::interning::InternedString; -use core::profiles::Profiles; -use core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary}; -use core::{Edition, Feature, Features, WorkspaceConfig}; -use util::errors::*; -use util::toml::TomlManifest; -use util::{short_hash, Config, Filesystem}; +use crate::core::interning::InternedString; +use crate::core::profiles::Profiles; +use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary}; +use crate::core::{Edition, Feature, Features, WorkspaceConfig}; +use crate::util::errors::*; +use crate::util::toml::TomlManifest; +use crate::util::{short_hash, Config, Filesystem}; pub enum EitherManifest { Real(Manifest), Virtual(VirtualManifest), } -/// Contains all the information about a package, as loaded from a Cargo.toml. +/// Contains all the information about a package, as loaded from a `Cargo.toml`. #[derive(Clone, Debug)] pub struct Manifest { summary: Summary, @@ -66,6 +66,7 @@ workspace: WorkspaceConfig, profiles: Profiles, warnings: Warnings, + features: Features, } /// General metadata about a package which is just blindly uploaded to the @@ -83,11 +84,11 @@ pub categories: Vec, pub license: Option, pub license_file: Option, - pub description: Option, // not markdown - pub readme: Option, // file, not contents - pub homepage: Option, // url - pub repository: Option, // url - pub documentation: Option, // url + pub description: Option, // Not in Markdown + pub readme: Option, // File, not contents + pub homepage: Option, // URL + pub repository: Option, // URL + pub documentation: Option, // URL pub badges: BTreeMap>, pub links: Option, } @@ -122,7 +123,7 @@ } impl fmt::Debug for LibKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.crate_type().fmt(f) } } @@ -168,7 +169,7 @@ } impl fmt::Debug for TargetKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use self::TargetKind::*; match *self { Lib(ref kinds) => kinds.fmt(f), @@ -212,6 +213,7 @@ doctest: bool, harness: bool, // whether to use the test harness (--test) for_host: bool, + proc_macro: bool, edition: Edition, } @@ -222,10 +224,10 @@ } impl TargetSourcePath { - pub fn path(&self) -> &Path { + pub fn path(&self) -> Option<&Path> { match self { - TargetSourcePath::Path(path) => path.as_ref(), - TargetSourcePath::Metabuild => panic!("metabuild not expected"), + TargetSourcePath::Path(path) => Some(path.as_ref()), + TargetSourcePath::Metabuild => None, } } @@ -244,7 +246,7 @@ } impl fmt::Debug for TargetSourcePath { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { TargetSourcePath::Path(path) => path.fmt(f), TargetSourcePath::Metabuild => "metabuild".fmt(f), @@ -268,7 +270,7 @@ /// See https://doc.rust-lang.org/reference/linkage.html crate_types: Vec<&'a str>, name: &'a str, - src_path: &'a PathBuf, + src_path: Option<&'a PathBuf>, edition: &'a str, #[serde(rename = "required-features", skip_serializing_if = "Option::is_none")] required_features: Option>, @@ -276,11 +278,17 @@ impl ser::Serialize for Target { fn serialize(&self, s: S) -> Result { + let src_path = match &self.src_path { + TargetSourcePath::Path(p) => Some(p), + // Unfortunately getting the correct path would require access to + // target_dir, which is not available here. + TargetSourcePath::Metabuild => None, + }; SerializedTarget { kind: &self.kind, crate_types: self.rustc_crate_types(), name: &self.name, - src_path: &self.src_path.path().to_path_buf(), + src_path, edition: &self.edition.to_string(), required_features: self .required_features @@ -301,7 +309,7 @@ Target::lib_target( &self.name, kinds.clone(), - self.src_path().path().to_path_buf(), + self.src_path().path().unwrap().to_path_buf(), self.edition, ), format!("lib_target({:?}, {:?}, {:?}, {:?})", @@ -346,6 +354,7 @@ doctest harness for_host + proc_macro edition )] } @@ -477,7 +486,7 @@ self.features .require(Feature::test_dummy_unstable()) .chain_err(|| { - format_err!( + failure::format_err!( "the `im-a-teapot` manifest key is unstable and may \ not work properly in England" ) @@ -487,7 +496,7 @@ if self.default_run.is_some() { self.features .require(Feature::default_run()) - .chain_err(|| format_err!("the `default-run` manifest key is unstable"))?; + .chain_err(|| failure::format_err!("the `default-run` manifest key is unstable"))?; } Ok(()) @@ -533,6 +542,7 @@ patch: HashMap>, workspace: WorkspaceConfig, profiles: Profiles, + features: Features, ) -> VirtualManifest { VirtualManifest { replace, @@ -540,6 +550,7 @@ workspace, profiles, warnings: Warnings::new(), + features, } } @@ -566,6 +577,10 @@ pub fn warnings(&self) -> &Warnings { &self.warnings } + + pub fn features(&self) -> &Features { + &self.features + } } impl Target { @@ -579,6 +594,7 @@ doctest: false, harness: true, for_host: false, + proc_macro: false, edition, tested: true, benched: true, @@ -638,7 +654,7 @@ for_host: true, benched: false, tested: false, - ..Target::new(TargetSourcePath::Metabuild, Edition::Edition2015) + ..Target::new(TargetSourcePath::Metabuild, Edition::Edition2018) } } @@ -729,6 +745,9 @@ pub fn for_host(&self) -> bool { self.for_host } + pub fn proc_macro(&self) -> bool { + self.proc_macro + } pub fn edition(&self) -> Edition { self.edition } @@ -854,6 +873,10 @@ self.for_host = for_host; self } + pub fn set_proc_macro(&mut self, proc_macro: bool) -> &mut Target { + self.proc_macro = proc_macro; + self + } pub fn set_edition(&mut self, edition: Edition) -> &mut Target { self.edition = edition; self @@ -869,7 +892,7 @@ } impl fmt::Display for Target { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.kind { TargetKind::Lib(..) => write!(f, "Target(lib)"), TargetKind::Bin => write!(f, "Target(bin: {})", self.name), diff -Nru cargo-0.33.0/src/cargo/core/mod.rs cargo-0.35.0/src/cargo/core/mod.rs --- cargo-0.33.0/src/cargo/core/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,8 @@ pub use self::dependency::Dependency; -pub use self::features::{CliUnstable, Edition, Feature, Features}; pub use self::features::{ - maybe_allow_nightly_features, - enable_nightly_features, - nightly_features_allowed + enable_nightly_features, maybe_allow_nightly_features, nightly_features_allowed, }; +pub use self::features::{CliUnstable, Edition, Feature, Features}; pub use self::manifest::{EitherManifest, VirtualManifest}; pub use self::manifest::{LibKind, Manifest, Target, TargetKind}; pub use self::package::{Package, PackageSet}; diff -Nru cargo-0.33.0/src/cargo/core/package_id.rs cargo-0.35.0/src/cargo/core/package_id.rs --- cargo-0.33.0/src/cargo/core/package_id.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/package_id.rs 2019-04-01 21:32:07.000000000 +0000 @@ -10,11 +10,11 @@ use serde::de; use serde::ser; -use core::interning::InternedString; -use core::source::SourceId; -use util::{CargoResult, ToSemver}; +use crate::core::interning::InternedString; +use crate::core::source::SourceId; +use crate::util::{CargoResult, ToSemver}; -lazy_static! { +lazy_static::lazy_static! { static ref PACKAGE_ID_CACHE: Mutex> = Mutex::new(HashSet::new()); } @@ -72,11 +72,12 @@ let string = String::deserialize(d)?; let mut s = string.splitn(3, ' '); let name = s.next().unwrap(); + let name = InternedString::new(name); let version = match s.next() { Some(s) => s, None => return Err(de::Error::custom("invalid serialized PackageId")), }; - let version = semver::Version::parse(version).map_err(de::Error::custom)?; + let version = version.to_semver().map_err(de::Error::custom)?; let url = match s.next() { Some(s) => s, None => return Err(de::Error::custom("invalid serialized PackageId")), @@ -88,11 +89,7 @@ }; let source_id = SourceId::from_url(url).map_err(de::Error::custom)?; - Ok(PackageId::wrap(PackageIdInner { - name: InternedString::new(name), - version, - source_id, - })) + Ok(PackageId::pure(name, version, source_id)) } } @@ -118,15 +115,15 @@ impl PackageId { pub fn new(name: &str, version: T, sid: SourceId) -> CargoResult { let v = version.to_semver()?; - - Ok(PackageId::wrap(PackageIdInner { - name: InternedString::new(name), - version: v, - source_id: sid, - })) + Ok(PackageId::pure(InternedString::new(name), v, sid)) } - fn wrap(inner: PackageIdInner) -> PackageId { + pub fn pure(name: InternedString, version: semver::Version, source_id: SourceId) -> PackageId { + let inner = PackageIdInner { + name, + version, + source_id, + }; let mut cache = PACKAGE_ID_CACHE.lock().unwrap(); let inner = cache.get(&inner).cloned().unwrap_or_else(|| { let inner = Box::leak(Box::new(inner)); @@ -147,22 +144,26 @@ } pub fn with_precise(self, precise: Option) -> PackageId { - PackageId::wrap(PackageIdInner { - name: self.inner.name, - version: self.inner.version.clone(), - source_id: self.inner.source_id.with_precise(precise), - }) + PackageId::pure( + self.inner.name, + self.inner.version.clone(), + self.inner.source_id.with_precise(precise), + ) } pub fn with_source_id(self, source: SourceId) -> PackageId { - PackageId::wrap(PackageIdInner { - name: self.inner.name, - version: self.inner.version.clone(), - source_id: source, - }) + PackageId::pure(self.inner.name, self.inner.version.clone(), source) + } + + pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Self { + if self.source_id() == to_replace { + self.with_source_id(replace_with) + } else { + self + } } - pub fn stable_hash(self, workspace: &Path) -> PackageIdStableHash { + pub fn stable_hash(self, workspace: &Path) -> PackageIdStableHash<'_> { PackageIdStableHash(self, workspace) } } @@ -178,7 +179,7 @@ } impl fmt::Display for PackageId { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{} v{}", self.inner.name, self.inner.version)?; if !self.inner.source_id.is_default_registry() { @@ -190,7 +191,7 @@ } impl fmt::Debug for PackageId { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("PackageId") .field("name", &self.inner.name) .field("version", &self.inner.version.to_string()) @@ -202,9 +203,9 @@ #[cfg(test)] mod tests { use super::PackageId; - use core::source::SourceId; - use sources::CRATES_IO_INDEX; - use util::ToUrl; + use crate::core::source::SourceId; + use crate::sources::CRATES_IO_INDEX; + use crate::util::ToUrl; #[test] fn invalid_version_handled_nicely() { diff -Nru cargo-0.33.0/src/cargo/core/package_id_spec.rs cargo-0.35.0/src/cargo/core/package_id_spec.rs --- cargo-0.33.0/src/cargo/core/package_id_spec.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/package_id_spec.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,9 +5,9 @@ use serde::{de, ser}; use url::Url; -use core::PackageId; -use util::errors::{CargoResult, CargoResultExt}; -use util::{ToSemver, ToUrl}; +use crate::core::PackageId; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{validate_package_name, ToSemver, ToUrl}; /// Some or all of the data required to identify a package: /// @@ -15,9 +15,9 @@ /// 2. the package version (a `Version`, optional) /// 3. the package source (a `Url`, optional) /// -/// If any of the optional fields are omitted, then the package id may be ambiguous, there may be +/// If any of the optional fields are omitted, then the package ID may be ambiguous, there may be /// more than one package/version/url combo that will match. However, often just the name is -/// sufficient to uniquely define a package id. +/// sufficient to uniquely define a package ID. #[derive(Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)] pub struct PackageIdSpec { name: String, @@ -61,14 +61,10 @@ let mut parts = spec.splitn(2, ':'); let name = parts.next().unwrap(); let version = match parts.next() { - Some(version) => Some(Version::parse(version)?), + Some(version) => Some(version.to_semver()?), None => None, }; - for ch in name.chars() { - if !ch.is_alphanumeric() && ch != '_' && ch != '-' { - bail!("invalid character in pkgid `{}`: `{}`", spec, ch) - } - } + validate_package_name(name, "pkgid", "")?; Ok(PackageIdSpec { name: name.to_string(), version, @@ -82,7 +78,7 @@ I: IntoIterator, { let spec = PackageIdSpec::parse(spec) - .chain_err(|| format_err!("invalid package id specification: `{}`", spec))?; + .chain_err(|| failure::format_err!("invalid package ID specification: `{}`", spec))?; spec.query(i) } @@ -99,16 +95,16 @@ /// Tries to convert a valid `Url` to a `PackageIdSpec`. fn from_url(mut url: Url) -> CargoResult { if url.query().is_some() { - bail!("cannot have a query string in a pkgid: {}", url) + failure::bail!("cannot have a query string in a pkgid: {}", url) } let frag = url.fragment().map(|s| s.to_owned()); url.set_fragment(None); let (name, version) = { let mut path = url .path_segments() - .ok_or_else(|| format_err!("pkgid urls must have a path: {}", url))?; + .ok_or_else(|| failure::format_err!("pkgid urls must have a path: {}", url))?; let path_name = path.next_back().ok_or_else(|| { - format_err!( + failure::format_err!( "pkgid urls must have at least one path \ component: {}", url @@ -186,8 +182,8 @@ let mut ids = i.into_iter().filter(|p| self.matches(*p)); let ret = match ids.next() { Some(id) => id, - None => bail!( - "package id specification `{}` \ + None => failure::bail!( + "package ID specification `{}` \ matched no packages", self ), @@ -207,7 +203,7 @@ let mut vec = vec![ret, other]; vec.extend(ids); minimize(&mut msg, &vec, self); - Err(format_err!("{}", msg)) + Err(failure::format_err!("{}", msg)) } None => Ok(ret), }; @@ -229,7 +225,7 @@ } impl fmt::Display for PackageIdSpec { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut printed_name = false; match self.url { Some(ref url) => { @@ -277,8 +273,8 @@ #[cfg(test)] mod tests { use super::PackageIdSpec; - use core::{PackageId, SourceId}; - use semver::Version; + use crate::core::{PackageId, SourceId}; + use crate::util::ToSemver; use url::Url; #[test] @@ -293,7 +289,7 @@ "http://crates.io/foo#1.2.3", PackageIdSpec { name: "foo".to_string(), - version: Some(Version::parse("1.2.3").unwrap()), + version: Some("1.2.3".to_semver().unwrap()), url: Some(Url::parse("http://crates.io/foo").unwrap()), }, ); @@ -301,7 +297,7 @@ "http://crates.io/foo#bar:1.2.3", PackageIdSpec { name: "bar".to_string(), - version: Some(Version::parse("1.2.3").unwrap()), + version: Some("1.2.3".to_semver().unwrap()), url: Some(Url::parse("http://crates.io/foo").unwrap()), }, ); @@ -317,7 +313,7 @@ "crates.io/foo#1.2.3", PackageIdSpec { name: "foo".to_string(), - version: Some(Version::parse("1.2.3").unwrap()), + version: Some("1.2.3".to_semver().unwrap()), url: Some(Url::parse("cargo://crates.io/foo").unwrap()), }, ); @@ -333,7 +329,7 @@ "crates.io/foo#bar:1.2.3", PackageIdSpec { name: "bar".to_string(), - version: Some(Version::parse("1.2.3").unwrap()), + version: Some("1.2.3".to_semver().unwrap()), url: Some(Url::parse("cargo://crates.io/foo").unwrap()), }, ); @@ -349,7 +345,7 @@ "foo:1.2.3", PackageIdSpec { name: "foo".to_string(), - version: Some(Version::parse("1.2.3").unwrap()), + version: Some("1.2.3".to_semver().unwrap()), url: None, }, ); diff -Nru cargo-0.33.0/src/cargo/core/package.rs cargo-0.35.0/src/cargo/core/package.rs --- cargo-0.33.0/src/cargo/core/package.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/package.rs 2019-04-01 21:32:07.000000000 +0000 @@ -8,34 +8,34 @@ use std::time::{Duration, Instant}; use bytesize::ByteSize; -use curl; use curl::easy::{Easy, HttpVersion}; use curl::multi::{EasyHandle, Multi}; -use curl_sys; use failure::ResultExt; use lazycell::LazyCell; +use log::{debug, warn}; use semver::Version; use serde::ser; -use toml; +use serde::Serialize; -use core::interning::InternedString; -use core::source::MaybePackage; -use core::{Dependency, Manifest, PackageId, SourceId, Target}; -use core::{FeatureMap, SourceMap, Summary}; -use ops; -use util::errors::{CargoResult, CargoResultExt, HttpNot200}; -use util::network::Retry; -use util::{self, internal, lev_distance, Config, Progress, ProgressStyle}; +use crate::core::interning::InternedString; +use crate::core::source::MaybePackage; +use crate::core::{Dependency, Manifest, PackageId, SourceId, Target}; +use crate::core::{FeatureMap, SourceMap, Summary}; +use crate::ops; +use crate::util::errors::{CargoResult, CargoResultExt, HttpNot200}; +use crate::util::network::Retry; +use crate::util::{self, internal, lev_distance, Config, Progress, ProgressStyle}; /// Information about a package that is available somewhere in the file system. /// /// A package is a `Cargo.toml` file plus all the files that are part of it. -// TODO: Is manifest_path a relic? +// +// TODO: is `manifest_path` a relic? #[derive(Clone)] pub struct Package { - /// The package's manifest + /// The package's manifest. manifest: Manifest, - /// The root of the package + /// The root of the package. manifest_path: PathBuf, } @@ -55,7 +55,7 @@ #[derive(Serialize)] struct SerializedPackage<'a> { name: &'a str, - version: &'a str, + version: &'a Version, id: PackageId, license: Option<&'a str>, license_file: Option<&'a str>, @@ -64,7 +64,7 @@ dependencies: &'a [Dependency], targets: Vec<&'a Target>, features: &'a FeatureMap, - manifest_path: &'a str, + manifest_path: &'a Path, metadata: Option<&'a toml::Value>, authors: &'a [String], categories: &'a [String], @@ -72,6 +72,7 @@ readme: Option<&'a str>, repository: Option<&'a str>, edition: &'a str, + links: Option<&'a str>, #[serde(skip_serializing_if = "Option::is_none")] metabuild: Option<&'a Vec>, } @@ -104,7 +105,7 @@ SerializedPackage { name: &*package_id.name(), - version: &package_id.version().to_string(), + version: &package_id.version(), id: package_id, license, license_file, @@ -113,7 +114,7 @@ dependencies: summary.dependencies(), targets, features: summary.features(), - manifest_path: &self.manifest_path.display().to_string(), + manifest_path: &self.manifest_path, metadata: self.manifest.custom_metadata(), authors, categories, @@ -121,6 +122,7 @@ readme, repository, edition: &self.manifest.edition().to_string(), + links: self.manifest.links(), metabuild: self.manifest.metabuild(), } .serialize(s) @@ -128,7 +130,7 @@ } impl Package { - /// Create a package from a manifest and its location + /// Creates a package from a manifest and its location. pub fn new(manifest: Manifest, manifest_path: &Path) -> Package { Package { manifest, @@ -136,52 +138,52 @@ } } - /// Get the manifest dependencies + /// Gets the manifest dependencies. pub fn dependencies(&self) -> &[Dependency] { self.manifest.dependencies() } - /// Get the manifest + /// Gets the manifest. pub fn manifest(&self) -> &Manifest { &self.manifest } - /// Get the path to the manifest + /// Gets the path to the manifest. pub fn manifest_path(&self) -> &Path { &self.manifest_path } - /// Get the name of the package + /// Gets the name of the package. pub fn name(&self) -> InternedString { self.package_id().name() } - /// Get the PackageId object for the package (fully defines a package) + /// Gets the `PackageId` object for the package (fully defines a package). pub fn package_id(&self) -> PackageId { self.manifest.package_id() } - /// Get the root folder of the package + /// Gets the root folder of the package. pub fn root(&self) -> &Path { self.manifest_path.parent().unwrap() } - /// Get the summary for the package + /// Gets the summary for the package. pub fn summary(&self) -> &Summary { self.manifest.summary() } - /// Get the targets specified in the manifest + /// Gets the targets specified in the manifest. pub fn targets(&self) -> &[Target] { self.manifest.targets() } - /// Get the current package version + /// Gets the current package version. pub fn version(&self) -> &Version { self.package_id().version() } - /// Get the package authors + /// Gets the package authors. pub fn authors(&self) -> &Vec { &self.manifest.metadata().authors } - /// Whether the package is set to publish + /// Returns `true` if the package is set to publish. pub fn publish(&self) -> &Option> { self.manifest.publish() } - /// Whether the package uses a custom build script for any target + /// Returns `true` if the package uses a custom build script for any target. pub fn has_custom_build(&self) -> bool { self.targets().iter().any(|t| t.is_custom_build()) } @@ -218,7 +220,7 @@ # When uploading crates to the registry Cargo will automatically\n\ # \"normalize\" Cargo.toml files for maximal compatibility\n\ # with all versions of Cargo and also rewrite `path` dependencies\n\ - # to registry (e.g. crates.io) dependencies\n\ + # to registry (e.g., crates.io) dependencies\n\ #\n\ # If you believe there's an error in this file please file an\n\ # issue against the rust-lang/cargo repository. If you're\n\ @@ -233,13 +235,13 @@ } impl fmt::Display for Package { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.summary().package_id()) } } impl fmt::Debug for Package { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Package") .field("id", &self.summary().package_id()) .field("..", &"..") @@ -288,36 +290,36 @@ /// /// Note that timeout management is done manually here instead of in libcurl /// because we want to apply timeouts to an entire batch of operations, not - /// any one particular single operatino - timeout: ops::HttpTimeout, // timeout configuration + /// any one particular single operation. + timeout: ops::HttpTimeout, // timeout configuration updated_at: Cell, // last time we received bytes next_speed_check: Cell, // if threshold isn't 0 by this time, error next_speed_check_bytes_threshold: Cell, // decremented when we receive bytes } struct Download<'cfg> { - /// Token for this download, used as the key of the `Downloads::pending` map + /// The token for this download, used as the key of the `Downloads::pending` map /// and stored in `EasyHandle` as well. token: usize, - /// Package that we're downloading + /// The package that we're downloading. id: PackageId, - /// Actual downloaded data, updated throughout the lifetime of this download + /// Actual downloaded data, updated throughout the lifetime of this download. data: RefCell>, /// The URL that we're downloading from, cached here for error messages and /// reenqueuing. url: String, - /// A descriptive string to print when we've finished downloading this crate + /// A descriptive string to print when we've finished downloading this crate. descriptor: String, - /// Statistics updated from the progress callback in libcurl + /// Statistics updated from the progress callback in libcurl. total: Cell, current: Cell, - /// The moment we started this transfer at + /// The moment we started this transfer at. start: Instant, timed_out: Cell>, @@ -411,7 +413,7 @@ Ok(pkgs) } - pub fn sources(&self) -> Ref> { + pub fn sources(&self) -> Ref<'_, SourceMap<'cfg>> { self.sources.borrow() } } @@ -427,7 +429,7 @@ } } else { result.with_context(|_| { - format_err!("failed to enable {}, is curl not built right?", $msg) + failure::format_err!("failed to enable {}, is curl not built right?", $msg) })?; } }; @@ -460,7 +462,7 @@ .ok_or_else(|| internal(format!("couldn't find source for `{}`", id)))?; let pkg = source .download(id) - .chain_err(|| format_err!("unable to get packages from source"))?; + .chain_err(|| failure::format_err!("unable to get packages from source"))?; let (url, descriptor) = match pkg { MaybePackage::Ready(pkg) => { debug!("{} doesn't need a download", id); @@ -564,7 +566,7 @@ Ok(None) } - /// Returns the number of crates that are still downloading + /// Returns the number of crates that are still downloading. pub fn remaining(&self) -> usize { self.pending.len() } @@ -598,7 +600,7 @@ let timed_out = &dl.timed_out; let url = &dl.url; dl.retry - .try(|| { + .r#try(|| { if let Err(e) = result { // If this error is "aborted by callback" then that's // probably because our progress callback aborted due to @@ -716,7 +718,7 @@ // a few anyway. // // Here we start off by asking the `multi` handle to do some work via - // the `perform` method. This will actually do I/O work (nonblocking) + // the `perform` method. This will actually do I/O work (non-blocking) // and attempt to make progress. Afterwards we ask about the `messages` // contained in the handle which will inform us if anything has finished // transferring. @@ -817,7 +819,7 @@ true } - fn tick(&self, why: WhyTick) -> CargoResult<()> { + fn tick(&self, why: WhyTick<'_>) -> CargoResult<()> { let mut progress = self.progress.borrow_mut(); let progress = progress.as_mut().unwrap(); @@ -874,11 +876,11 @@ if !progress.is_enabled() { return; } - // If we didn't download anything, no need for a summary + // If we didn't download anything, no need for a summary. if self.downloads_finished == 0 { return; } - // If an error happened, let's not clutter up the output + // If an error happened, let's not clutter up the output. if !self.success { return; } @@ -908,17 +910,17 @@ thread_local!(static PTR: Cell = Cell::new(0)); - pub(crate) fn with(f: impl FnOnce(Option<&Downloads>) -> R) -> R { + pub(crate) fn with(f: impl FnOnce(Option<&Downloads<'_, '_>>) -> R) -> R { let ptr = PTR.with(|p| p.get()); if ptr == 0 { f(None) } else { - unsafe { f(Some(&*(ptr as *const Downloads))) } + unsafe { f(Some(&*(ptr as *const Downloads<'_, '_>))) } } } - pub(crate) fn set(dl: &Downloads, f: impl FnOnce() -> R) -> R { - struct Reset<'a, T: Copy + 'a>(&'a Cell, T); + pub(crate) fn set(dl: &Downloads<'_, '_>, f: impl FnOnce() -> R) -> R { + struct Reset<'a, T: Copy>(&'a Cell, T); impl<'a, T: Copy> Drop for Reset<'a, T> { fn drop(&mut self) { @@ -928,7 +930,7 @@ PTR.with(|p| { let _reset = Reset(p, p.get()); - p.set(dl as *const Downloads as usize); + p.set(dl as *const Downloads<'_, '_> as usize); f() }) } diff -Nru cargo-0.33.0/src/cargo/core/profiles.rs cargo-0.35.0/src/cargo/core/profiles.rs --- cargo-0.33.0/src/cargo/core/profiles.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/profiles.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,13 +1,15 @@ use std::collections::HashSet; -use std::{cmp, fmt, hash}; +use std::{cmp, env, fmt, hash}; -use core::compiler::CompileMode; -use core::interning::InternedString; -use core::{Features, PackageId, PackageIdSpec, PackageSet, Shell}; -use util::errors::CargoResultExt; -use util::lev_distance::lev_distance; -use util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool}; -use util::{CargoResult, Config}; +use serde::Deserialize; + +use crate::core::compiler::CompileMode; +use crate::core::interning::InternedString; +use crate::core::{Features, PackageId, PackageIdSpec, PackageSet, Shell}; +use crate::util::errors::CargoResultExt; +use crate::util::lev_distance::lev_distance; +use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool}; +use crate::util::{CargoResult, Config}; /// Collection of all user profiles. #[derive(Clone, Debug)] @@ -17,6 +19,10 @@ test: ProfileMaker, bench: ProfileMaker, doc: ProfileMaker, + /// Incremental compilation can be overridden globally via: + /// - `CARGO_INCREMENTAL` environment variable. + /// - `build.incremental` config value. + incremental: Option, } impl Profiles { @@ -31,7 +37,11 @@ } let config_profiles = config.profiles()?; - config_profiles.validate(features, warnings)?; + + let incremental = match env::var_os("CARGO_INCREMENTAL") { + Some(v) => Some(v == "1"), + None => config.get::>("build.incremental")?, + }; Ok(Profiles { dev: ProfileMaker { @@ -59,10 +69,11 @@ toml: profiles.and_then(|p| p.doc.clone()), config: None, }, + incremental, }) } - /// Retrieve the profile for a target. + /// Retrieves the profile for a target. /// `is_member` is whether or not this package is a member of the /// workspace. pub fn get_profile( @@ -85,9 +96,9 @@ | CompileMode::Check { .. } | CompileMode::Doctest | CompileMode::RunCustomBuild => { - // Note: RunCustomBuild doesn't normally use this code path. + // Note: `RunCustomBuild` doesn't normally use this code path. // `build_unit_profiles` normally ensures that it selects the - // ancestor's profile. However `cargo clean -p` can hit this + // ancestor's profile. However, `cargo clean -p` can hit this // path. if release { &self.release @@ -103,11 +114,25 @@ if !unit_for.is_panic_ok() || mode.is_any_test() { profile.panic = None; } + + // Incremental can be globally overridden. + if let Some(v) = self.incremental { + profile.incremental = v; + } + // Only enable incremental compilation for sources the user can + // modify (aka path sources). For things that change infrequently, + // non-incremental builds yield better performance in the compiler + // itself (aka crates.io / git dependencies) + // + // (see also https://github.com/rust-lang/cargo/issues/3972) + if !pkg_id.source_id().is_path() { + profile.incremental = false; + } profile } /// The profile for *running* a `build.rs` script is only used for setting - /// a few environment variables. To ensure proper de-duplication of the + /// a few environment variables. To ensure proper de-duplication of the /// running `Unit`, this uses a stripped-down profile (so that unrelated /// profile flags don't cause `build.rs` to needlessly run multiple /// times). @@ -119,7 +144,7 @@ } /// This returns a generic base profile. This is currently used for the - /// `[Finished]` line. It is not entirely accurate, since it doesn't + /// `[Finished]` line. It is not entirely accurate, since it doesn't /// select for the package that was actually built. pub fn base_profile(&self, release: bool) -> Profile { if release { @@ -130,7 +155,11 @@ } /// Used to check for overrides for non-existing packages. - pub fn validate_packages(&self, shell: &mut Shell, packages: &PackageSet) -> CargoResult<()> { + pub fn validate_packages( + &self, + shell: &mut Shell, + packages: &PackageSet<'_>, + ) -> CargoResult<()> { self.dev.validate_packages(shell, packages)?; self.release.validate_packages(shell, packages)?; self.test.validate_packages(shell, packages)?; @@ -143,10 +172,10 @@ /// An object used for handling the profile override hierarchy. /// /// The precedence of profiles are (first one wins): -/// - Profiles in .cargo/config files (using same order as below). -/// - [profile.dev.overrides.name] - A named package. -/// - [profile.dev.overrides."*"] - This cannot apply to workspace members. -/// - [profile.dev.build-override] - This can only apply to `build.rs` scripts +/// - Profiles in `.cargo/config` files (using same order as below). +/// - [profile.dev.overrides.name] -- a named package. +/// - [profile.dev.overrides."*"] -- this cannot apply to workspace members. +/// - [profile.dev.build-override] -- this can only apply to `build.rs` scripts /// and their dependencies. /// - [profile.dev] /// - Default (hard-coded) values. @@ -177,7 +206,7 @@ profile } - fn validate_packages(&self, shell: &mut Shell, packages: &PackageSet) -> CargoResult<()> { + fn validate_packages(&self, shell: &mut Shell, packages: &PackageSet<'_>) -> CargoResult<()> { self.validate_packages_toml(shell, packages, &self.toml, true)?; self.validate_packages_toml(shell, packages, &self.config, false)?; Ok(()) @@ -186,7 +215,7 @@ fn validate_packages_toml( &self, shell: &mut Shell, - packages: &PackageSet, + packages: &PackageSet<'_>, toml: &Option, warn_unmatched: bool, ) -> CargoResult<()> { @@ -225,7 +254,7 @@ .map(|spec| spec.to_string()) .collect::>() .join(", "); - bail!( + failure::bail!( "multiple profile overrides in profile `{}` match package `{}`\n\ found profile override specs: {}", self.default.name, @@ -379,7 +408,7 @@ pub name: &'static str, pub opt_level: InternedString, pub lto: Lto, - // None = use rustc default + // `None` means use rustc default. pub codegen_units: Option, pub debuginfo: Option, pub debug_assertions: bool, @@ -434,7 +463,7 @@ } impl fmt::Display for Profile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Profile({})", self.name) } } @@ -495,7 +524,7 @@ } } - /// Compare all fields except `name`, which doesn't affect compilation. + /// Compares all fields except `name`, which doesn't affect compilation. /// This is necessary for `Unit` deduplication for things like "test" and /// "dev" which are essentially the same. fn comparable( @@ -539,19 +568,19 @@ /// to ensure the target's dependencies have the correct settings. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct UnitFor { - /// A target for `build.rs` or any of its dependencies. This enables + /// A target for `build.rs` or any of its dependencies. This enables /// `build-override` profiles for these targets. custom_build: bool, /// This is true if it is *allowed* to set the `panic` flag. Currently /// this is false for test/bench targets and all their dependencies, and - /// "for_host" units such as proc-macro and custom build scripts and their + /// "for_host" units such as proc macro and custom build scripts and their /// dependencies. panic_ok: bool, } impl UnitFor { - /// A unit for a normal target/dependency (i.e. not custom build, - /// proc-macro/plugin, or test/bench). + /// A unit for a normal target/dependency (i.e., not custom build, + /// proc macro/plugin, or test/bench). pub fn new_normal() -> UnitFor { UnitFor { custom_build: false, @@ -567,7 +596,7 @@ } } - /// A unit for a proc-macro or compiler plugin or their dependencies. + /// A unit for a proc macro or compiler plugin or their dependencies. pub fn new_compiler() -> UnitFor { UnitFor { custom_build: false, @@ -583,7 +612,7 @@ } } - /// Create a variant based on `for_host` setting. + /// Creates a variant based on `for_host` setting. /// /// When `for_host` is true, this clears `panic_ok` in a sticky fashion so /// that all its dependencies also have `panic_ok=false`. @@ -594,13 +623,13 @@ } } - /// Returns true if this unit is for a custom build script or one of its + /// Returns `true` if this unit is for a custom build script or one of its /// dependencies. pub fn is_custom_build(self) -> bool { self.custom_build } - /// Returns true if this unit is allowed to set the `panic` compiler flag. + /// Returns `true` if this unit is allowed to set the `panic` compiler flag. pub fn is_panic_ok(self) -> bool { self.panic_ok } @@ -625,7 +654,7 @@ } } -/// Profiles loaded from .cargo/config files. +/// Profiles loaded from `.cargo/config` files. #[derive(Clone, Debug, Deserialize, Default)] pub struct ConfigProfiles { dev: Option, @@ -637,12 +666,14 @@ if let Some(ref profile) = self.dev { profile .validate("dev", features, warnings) - .chain_err(|| format_err!("config profile `profile.dev` is not valid"))?; + .chain_err(|| failure::format_err!("config profile `profile.dev` is not valid"))?; } if let Some(ref profile) = self.release { profile .validate("release", features, warnings) - .chain_err(|| format_err!("config profile `profile.release` is not valid"))?; + .chain_err(|| { + failure::format_err!("config profile `profile.release` is not valid") + })?; } Ok(()) } diff -Nru cargo-0.33.0/src/cargo/core/registry.rs cargo-0.35.0/src/cargo/core/registry.rs --- cargo-0.33.0/src/cargo/core/registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,20 +1,26 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use log::{debug, trace}; use semver::VersionReq; use url::Url; -use core::PackageSet; -use core::{Dependency, PackageId, Source, SourceId, SourceMap, Summary}; -use sources::config::SourceConfigMap; -use util::errors::{CargoResult, CargoResultExt}; -use util::{profile, Config}; +use crate::core::PackageSet; +use crate::core::{Dependency, PackageId, Source, SourceId, SourceMap, Summary}; +use crate::sources::config::SourceConfigMap; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{profile, Config}; /// Source of information about a group of packages. /// /// See also `core::Source`. pub trait Registry { /// Attempt to find the packages that match a dependency request. - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary), fuzzy: bool) -> CargoResult<()>; + fn query( + &mut self, + dep: &Dependency, + f: &mut dyn FnMut(Summary), + fuzzy: bool, + ) -> CargoResult<()>; fn query_vec(&mut self, dep: &Dependency, fuzzy: bool) -> CargoResult> { let mut ret = Vec::new(); @@ -32,7 +38,7 @@ /// /// The resolution phase of Cargo uses this to drive knowledge about new /// packages as well as querying for lists of new packages. It is here that -/// sources are updated (e.g. network operations) and overrides are +/// sources are updated (e.g., network operations) and overrides are /// handled. /// /// The general idea behind this registry is that it is centered around the @@ -65,6 +71,7 @@ source_ids: HashMap, locked: LockedMap, + yanked_whitelist: HashSet, source_config: SourceConfigMap<'cfg>, patches: HashMap>, @@ -91,6 +98,7 @@ overrides: Vec::new(), source_config, locked: HashMap::new(), + yanked_whitelist: HashSet::new(), patches: HashMap::new(), patches_locked: false, patches_available: HashMap::new(), @@ -145,21 +153,29 @@ Ok(()) } - pub fn add_preloaded(&mut self, source: Box) { + pub fn add_preloaded(&mut self, source: Box) { self.add_source(source, Kind::Locked); } - fn add_source(&mut self, source: Box, kind: Kind) { + fn add_source(&mut self, source: Box, kind: Kind) { let id = source.source_id(); self.sources.insert(source); self.source_ids.insert(id, (id, kind)); } - pub fn add_override(&mut self, source: Box) { + pub fn add_override(&mut self, source: Box) { self.overrides.push(source.source_id()); self.add_source(source, Kind::Override); } + pub fn add_to_yanked_whitelist(&mut self, iter: impl Iterator) { + let pkgs = iter.collect::>(); + for (_, source) in self.sources.sources_mut() { + source.add_to_yanked_whitelist(&pkgs); + } + self.yanked_whitelist.extend(pkgs); + } + pub fn register_lock(&mut self, id: PackageId, deps: Vec) { trace!("register_lock: {}", id); for dep in deps.iter() { @@ -185,7 +201,7 @@ /// /// Here the `deps` will be resolved to a precise version and stored /// internally for future calls to `query` below. It's expected that `deps` - /// have had `lock_to` call already, if applicable. (e.g. if a lock file was + /// have had `lock_to` call already, if applicable. (e.g., if a lock file was /// already present). /// /// Note that the patch list specified here *will not* be available to @@ -215,7 +231,7 @@ // corresponding to this `dep`. self.ensure_loaded(dep.source_id(), Kind::Normal) .chain_err(|| { - format_err!( + failure::format_err!( "failed to load source for a dependency \ on `{}`", dep.package_name() @@ -231,7 +247,7 @@ let summary = match summaries.next() { Some(summary) => summary, - None => bail!( + None => failure::bail!( "patch for `{}` in `{}` did not resolve to any crates. If this is \ unexpected, you may wish to consult: \ https://github.com/rust-lang/cargo/issues/4678", @@ -240,14 +256,14 @@ ), }; if summaries.next().is_some() { - bail!( + failure::bail!( "patch for `{}` in `{}` resolved to more than one candidate", dep.package_name(), url ) } if summary.package_id().source_id().url() == url { - bail!( + failure::bail!( "patch for `{}` in `{}` points to the same source, but \ patches must point to different sources", dep.package_name(), @@ -257,7 +273,7 @@ Ok(summary) }) .collect::>>() - .chain_err(|| format_err!("failed to resolve patches for `{}`", url))?; + .chain_err(|| failure::format_err!("failed to resolve patches for `{}`", url))?; // Note that we do not use `lock` here to lock summaries! That step // happens later once `lock_patches` is invoked. In the meantime though @@ -295,7 +311,7 @@ fn load(&mut self, source_id: SourceId, kind: Kind) -> CargoResult<()> { (|| { debug!("loading source {}", source_id); - let source = self.source_config.load(source_id)?; + let source = self.source_config.load(source_id, &self.yanked_whitelist)?; assert_eq!(source.source_id(), source_id); if kind == Kind::Override { @@ -307,7 +323,7 @@ let _p = profile::start(format!("updating: {}", source_id)); self.sources.get_mut(source_id).unwrap().update() })() - .chain_err(|| format_err!("Unable to update {}", source_id))?; + .chain_err(|| failure::format_err!("Unable to update {}", source_id))?; Ok(()) } @@ -324,16 +340,16 @@ } /// This function is used to transform a summary to another locked summary - /// if possible. This is where the concept of a lockfile comes into play. + /// if possible. This is where the concept of a lock file comes into play. /// - /// If a summary points at a package id which was previously locked, then we - /// override the summary's id itself, as well as all dependencies, to be + /// If a summary points at a package ID which was previously locked, then we + /// override the summary's ID itself, as well as all dependencies, to be /// rewritten to the locked versions. This will transform the summary's /// source to a precise source (listed in the locked version) as well as /// transforming all of the dependencies from range requirements on /// imprecise sources to exact requirements on precise sources. /// - /// If a summary does not point at a package id which was previously locked, + /// If a summary does not point at a package ID which was previously locked, /// or if any dependencies were added and don't have a previously listed /// version, we still want to avoid updating as many dependencies as /// possible to keep the graph stable. In this case we map all of the @@ -403,7 +419,12 @@ } impl<'cfg> Registry for PackageRegistry<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary), fuzzy: bool) -> CargoResult<()> { + fn query( + &mut self, + dep: &Dependency, + f: &mut dyn FnMut(Summary), + fuzzy: bool, + ) -> CargoResult<()> { assert!(self.patches_locked); let (override_summary, n, to_warn) = { // Look for an override and get ready to query the real source. @@ -456,7 +477,7 @@ // Ensure the requested source_id is loaded self.ensure_loaded(dep.source_id(), Kind::Normal) .chain_err(|| { - format_err!( + failure::format_err!( "failed to load source for a dependency \ on `{}`", dep.package_name() @@ -465,7 +486,7 @@ let source = self.sources.get_mut(dep.source_id()); match (override_summary, source) { - (Some(_), None) => bail!("override found but no real ones"), + (Some(_), None) => failure::bail!("override found but no real ones"), (None, None) => return Ok(()), // If we don't have an override then we just ship @@ -505,7 +526,7 @@ // the summaries it gives us though. (Some(override_summary), Some(source)) => { if !patches.is_empty() { - bail!("found patches and a path override") + failure::bail!("found patches and a path override") } let mut n = 0; let mut to_warn = None; @@ -527,7 +548,7 @@ }; if n > 1 { - bail!("found an override with a non-locked list"); + failure::bail!("found an override with a non-locked list"); } else if let Some(summary) = to_warn { self.warn_bad_override(&override_summary, &summary)?; } @@ -558,7 +579,7 @@ trace!("locking summary of {}", summary.package_id()); - // Lock the summary's id if possible + // Lock the summary's ID if possible let summary = match pair { Some(&(ref precise, _)) => summary.override_id(precise.clone()), None => summary, @@ -576,7 +597,7 @@ // // 1. We have a lock entry for this dependency from the same // source as it's listed as coming from. In this case we make - // sure to lock to precisely the given package id. + // sure to lock to precisely the given package ID. // // 2. We have a lock entry for this dependency, but it's from a // different source than what's listed, or the version @@ -594,7 +615,7 @@ let locked = locked_deps.iter().find(|&&id| dep.matches_id(id)); if let Some(&locked) = locked { trace!("\tfirst hit on {}", locked); - let mut dep = dep.clone(); + let mut dep = dep; dep.lock_to(locked); return dep; } @@ -609,7 +630,7 @@ .and_then(|vec| vec.iter().find(|&&(id, _)| dep.matches_id(id))); if let Some(&(id, _)) = v { trace!("\tsecond hit on {}", id); - let mut dep = dep.clone(); + let mut dep = dep; dep.lock_to(id); return dep; } @@ -635,7 +656,7 @@ if patch_locked { trace!("\tthird hit on {}", patch_id); let req = VersionReq::exact(patch_id.version()); - let mut dep = dep.clone(); + let mut dep = dep; dep.set_version_req(req); return dep; } diff -Nru cargo-0.33.0/src/cargo/core/resolver/conflict_cache.rs cargo-0.35.0/src/cargo/core/resolver/conflict_cache.rs --- cargo-0.33.0/src/cargo/core/resolver/conflict_cache.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/conflict_cache.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,16 +1,18 @@ use std::collections::{BTreeMap, HashMap, HashSet}; +use log::trace; + use super::types::ConflictReason; -use core::resolver::Context; -use core::{Dependency, PackageId}; +use crate::core::resolver::Context; +use crate::core::{Dependency, PackageId}; -/// This is a Trie for storing a large number of Sets designed to -/// efficiently see if any of the stored Sets are a subset of a search Set. +/// This is a trie for storing a large number of sets designed to +/// efficiently see if any of the stored sets are a subset of a search set. enum ConflictStoreTrie { - /// a Leaf is one of the stored Sets. + /// One of the stored sets. Leaf(BTreeMap), - /// a Node is a map from an element to a subTrie where - /// all the Sets in the subTrie contains that element. + /// A map from an element to a subtrie where + /// all the sets in the subtrie contains that element. Node(BTreeMap), } @@ -25,12 +27,12 @@ match self { ConflictStoreTrie::Leaf(c) => { if must_contain.is_none() { - // is_conflicting checks that all the elements are active, + // `is_conflicting` checks that all the elements are active, // but we have checked each one by the recursion of this function. debug_assert!(cx.is_conflicting(None, c)); Some(c) } else { - // we did not find `must_contain` so we need to keep looking. + // We did not find `must_contain`, so we need to keep looking. None } } @@ -39,15 +41,16 @@ .map(|f| m.range(..=f)) .unwrap_or_else(|| m.range(..)) { - // if the key is active then we need to check all of the corresponding subTrie. + // If the key is active, then we need to check all of the corresponding subtrie. if cx.is_active(pid) { if let Some(o) = store.find_conflicting(cx, must_contain.filter(|&f| f != pid)) { return Some(o); } - } // else, if it is not active then there is no way any of the corresponding - // subTrie will be conflicting. + } + // Else, if it is not active then there is no way any of the corresponding + // subtrie will be conflicting. } None } @@ -64,17 +67,19 @@ p.entry(pid) .or_insert_with(|| ConflictStoreTrie::Node(BTreeMap::new())) .insert(iter, con); - } // else, We already have a subset of this in the ConflictStore + } + // Else, we already have a subset of this in the `ConflictStore`. } else { - // we are at the end of the set we are adding, there are 3 cases for what to do next: - // 1. self is a empty dummy Node inserted by `or_insert_with` + // We are at the end of the set we are adding, there are three cases for what to do + // next: + // 1. `self` is a empty dummy Node inserted by `or_insert_with` // in witch case we should replace it with `Leaf(con)`. - // 2. self is a Node because we previously inserted a superset of + // 2. `self` is a `Node` because we previously inserted a superset of // the thing we are working on (I don't know if this happens in practice) // but the subset that we are working on will // always match any time the larger set would have // in witch case we can replace it with `Leaf(con)`. - // 3. self is a Leaf that is in the same spot in the structure as + // 3. `self` is a `Leaf` that is in the same spot in the structure as // the thing we are working on. So it is equivalent. // We can replace it with `Leaf(con)`. if cfg!(debug_assertions) { @@ -118,7 +123,7 @@ // look up which entries are still active without // linearly scanning through the full list. // - // Also, as a final note, this map is *not* ever removed from. This remains + // Also, as a final note, this map is **not** ever removed from. This remains // as a global cache which we never delete from. Any entry in this map is // unconditionally true regardless of our resolution history of how we got // here. @@ -164,9 +169,9 @@ self.find_conflicting(cx, dep, None) } - /// Add to the cache a conflict of the form: + /// Adds to the cache a conflict of the form: /// `dep` is known to be unresolvable if - /// all the `PackageId` entries are activated + /// all the `PackageId` entries are activated. pub fn insert(&mut self, dep: &Dependency, con: &BTreeMap) { self.con_from_dep .entry(dep.clone()) diff -Nru cargo-0.33.0/src/cargo/core/resolver/context.rs cargo-0.35.0/src/cargo/core/resolver/context.rs --- cargo-0.33.0/src/cargo/core/resolver/context.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/context.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,15 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::rc::Rc; -use core::interning::InternedString; -use core::{Dependency, FeatureValue, PackageId, SourceId, Summary}; -use im_rc; -use util::CargoResult; -use util::Graph; +// "ensure" seems to require "bail" be in scope (macro hygiene issue?). +#[allow(unused_imports)] +use failure::{bail, ensure}; +use log::debug; + +use crate::core::interning::InternedString; +use crate::core::{Dependency, FeatureValue, PackageId, SourceId, Summary}; +use crate::util::CargoResult; +use crate::util::Graph; use super::errors::ActivateResult; use super::types::{ConflictReason, DepInfo, GraphNode, Method, RcList, RegistryQueryer}; @@ -50,8 +54,8 @@ /// Activate this summary by inserting it into our list of known activations. /// - /// Returns true if this summary with the given method is already activated. - pub fn flag_activated(&mut self, summary: &Summary, method: &Method) -> CargoResult { + /// Returns `true` if this summary with the given method is already activated. + pub fn flag_activated(&mut self, summary: &Summary, method: &Method<'_>) -> CargoResult { let id = summary.package_id(); let prev = self .activations @@ -62,8 +66,8 @@ if let Some(link) = summary.links() { ensure!( self.links.insert(link, id).is_none(), - "Attempting to resolve a with more then one crate with the links={}. \n\ - This will not build as is. Consider rebuilding the .lock file.", + "Attempting to resolve a dependency with more then one crate with the \ + links={}.\nThis will not build as is. Consider rebuilding the .lock file.", &*link ); } @@ -95,10 +99,10 @@ pub fn build_deps( &mut self, - registry: &mut RegistryQueryer, + registry: &mut RegistryQueryer<'_>, parent: Option<&Summary>, candidate: &Summary, - method: &Method, + method: &Method<'_>, ) -> ActivateResult> { // First, figure out our set of dependencies based on the requested set // of features. This also calculates what features we're going to enable @@ -116,7 +120,7 @@ .collect::>>()?; // Attempt to resolve dependencies with fewer candidates before trying - // dependencies with more candidates. This way if the dependency with + // dependencies with more candidates. This way if the dependency with // only one candidate can't be resolved we don't have to do a bunch of // work before we figure that out. deps.sort_by_key(|&(_, ref a, _)| a.len()); @@ -138,8 +142,8 @@ .unwrap_or(false) } - /// checks whether all of `parent` and the keys of `conflicting activations` - /// are still active + /// Checks whether all of `parent` and the keys of `conflicting activations` + /// are still active. pub fn is_conflicting( &self, parent: Option, @@ -151,19 +155,19 @@ .all(|&id| self.is_active(id)) } - /// Return all dependencies and the features we want from them. + /// Returns all dependencies and the features we want from them. fn resolve_features<'b>( &mut self, parent: Option<&Summary>, s: &'b Summary, - method: &'b Method, + method: &'b Method<'_>, ) -> ActivateResult)>> { let dev_deps = match *method { Method::Everything => true, Method::Required { dev_deps, .. } => dev_deps, }; - // First, filter by dev-dependencies + // First, filter by dev-dependencies. let deps = s.dependencies(); let deps = deps.iter().filter(|d| d.is_transitive() || dev_deps); @@ -203,9 +207,11 @@ base.extend(dep.features().iter()); for feature in base.iter() { if feature.contains('/') { - return Err( - format_err!("feature names may not contain slashes: `{}`", feature).into(), - ); + return Err(failure::format_err!( + "feature names may not contain slashes: `{}`", + feature + ) + .into()); } } ret.push((dep.clone(), base)); @@ -224,7 +230,7 @@ if !remaining.is_empty() { let features = remaining.join(", "); return Err(match parent { - None => format_err!( + None => failure::format_err!( "Package `{}` does not have these features: `{}`", s.package_id(), features @@ -279,12 +285,12 @@ } } -/// Takes requested features for a single package from the input Method and +/// Takes requested features for a single package from the input `Method` and /// recurses to find all requested features, dependencies and requested -/// dependency features in a Requirements object, returning it to the resolver. +/// dependency features in a `Requirements` object, returning it to the resolver. fn build_requirements<'a, 'b: 'a>( s: &'a Summary, - method: &'b Method, + method: &'b Method<'_>, ) -> CargoResult> { let mut reqs = Requirements::new(s); @@ -344,7 +350,7 @@ } impl<'r> Requirements<'r> { - fn new(summary: &Summary) -> Requirements { + fn new(summary: &Summary) -> Requirements<'_> { Requirements { summary, deps: HashMap::new(), @@ -389,8 +395,8 @@ .expect("must be a valid feature") { match *fv { - FeatureValue::Feature(ref dep_feat) if **dep_feat == *feat => bail!( - "Cyclic feature dependency: feature `{}` depends on itself", + FeatureValue::Feature(ref dep_feat) if **dep_feat == *feat => failure::bail!( + "cyclic feature dependency: feature `{}` depends on itself", feat ), _ => {} diff -Nru cargo-0.33.0/src/cargo/core/resolver/encode.rs cargo-0.35.0/src/cargo/core/resolver/encode.rs --- cargo-0.33.0/src/cargo/core/resolver/encode.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/encode.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,12 +2,14 @@ use std::fmt; use std::str::FromStr; +use log::debug; use serde::de; use serde::ser; +use serde::{Deserialize, Serialize}; -use core::{Dependency, Package, PackageId, SourceId, Workspace}; -use util::errors::{CargoError, CargoResult, CargoResultExt}; -use util::{internal, Graph}; +use crate::core::{Dependency, Package, PackageId, SourceId, Workspace}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{internal, Graph}; use super::Resolve; @@ -30,7 +32,7 @@ pub type Metadata = BTreeMap; impl EncodableResolve { - pub fn into_resolve(self, ws: &Workspace) -> CargoResult { + pub fn into_resolve(self, ws: &Workspace<'_>) -> CargoResult { let path_deps = build_path_deps(ws); let packages = { @@ -42,7 +44,7 @@ }; // `PackageId`s in the lock file don't include the `source` part - // for workspace members, so we reconstruct proper ids. + // for workspace members, so we reconstruct proper IDs. let live_pkgs = { let mut live_pkgs = HashMap::new(); let mut all_pkgs = HashSet::new(); @@ -54,7 +56,7 @@ }; if !all_pkgs.insert(enc_id.clone()) { - bail!("package `{}` is specified twice in the lockfile", pkg.name); + failure::bail!("package `{}` is specified twice in the lockfile", pkg.name); } let id = match pkg.source.as_ref().or_else(|| path_deps.get(&pkg.name)) { // We failed to find a local package in the workspace. @@ -173,8 +175,8 @@ } } -fn build_path_deps(ws: &Workspace) -> HashMap { - // If a crate is *not* a path source, then we're probably in a situation +fn build_path_deps(ws: &Workspace<'_>) -> HashMap { + // If a crate is **not** a path source, then we're probably in a situation // such as `cargo install` with a lock file from a remote dependency. In // that case we don't need to fixup any path dependencies (as they're not // actually path dependencies any more), so we ignore them. @@ -208,7 +210,7 @@ fn build_pkg( pkg: &Package, - ws: &Workspace, + ws: &Workspace<'_>, ret: &mut HashMap, visited: &mut HashSet, ) { @@ -219,7 +221,7 @@ fn build_dep( dep: &Dependency, - ws: &Workspace, + ws: &Workspace<'_>, ret: &mut HashMap, visited: &mut HashSet, ) { @@ -264,7 +266,7 @@ } impl fmt::Display for EncodablePackageId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{} {}", self.name, self.version)?; if let Some(ref s) = self.source { write!(f, " ({})", s.to_url())?; @@ -274,7 +276,7 @@ } impl FromStr for EncodablePackageId { - type Err = CargoError; + type Err = failure::Error; fn from_str(s: &str) -> CargoResult { let mut s = s.splitn(3, ' '); @@ -287,7 +289,7 @@ if s.starts_with('(') && s.ends_with(')') { Some(SourceId::from_url(&s[1..s.len() - 1])?) } else { - bail!("invalid serialized PackageId") + failure::bail!("invalid serialized PackageId") } } None => None, diff -Nru cargo-0.33.0/src/cargo/core/resolver/errors.rs cargo-0.35.0/src/cargo/core/resolver/errors.rs --- cargo-0.33.0/src/cargo/core/resolver/errors.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/errors.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,11 @@ use std::collections::BTreeMap; use std::fmt; -use core::{Dependency, PackageId, Registry, Summary}; +use crate::core::{Dependency, PackageId, Registry, Summary}; +use crate::util::lev_distance::lev_distance; +use crate::util::Config; use failure::{Error, Fail}; use semver; -use util::lev_distance::lev_distance; -use util::{CargoError, Config}; use super::context::Context; use super::types::{Candidate, ConflictReason}; @@ -32,19 +32,19 @@ } impl Fail for ResolveError { - fn cause(&self) -> Option<&Fail> { + fn cause(&self) -> Option<&dyn Fail> { self.cause.as_fail().cause() } } impl fmt::Debug for ResolveError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.cause.fmt(f) } } impl fmt::Display for ResolveError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.cause.fmt(f) } } @@ -52,7 +52,7 @@ pub type ActivateResult = Result; pub enum ActivateError { - Fatal(CargoError), + Fatal(failure::Error), Conflict(PackageId, ConflictReason), } @@ -70,7 +70,7 @@ pub(super) fn activation_error( cx: &Context, - registry: &mut Registry, + registry: &mut dyn Registry, parent: &Summary, dep: &Dependency, conflicting_activations: &BTreeMap, @@ -161,7 +161,7 @@ msg.push_str(&*dep.package_name()); msg.push_str("` which could resolve this conflict"); - return to_resolve_err(format_err!("{}", msg)); + return to_resolve_err(failure::format_err!("{}", msg)); } // We didn't actually find any candidates, so we need to @@ -253,8 +253,15 @@ names.push("..."); } - msg.push_str("did you mean: "); - msg.push_str(&names.join(", ")); + msg.push_str("perhaps you meant: "); + msg.push_str(&names.iter().enumerate().fold( + String::default(), + |acc, (i, el)| match i { + 0 => acc + el, + i if names.len() - 1 == i && candidates.len() <= 3 => acc + " or " + el, + _ => acc + ", " + el, + }, + )); msg.push_str("\n"); } msg.push_str("required by "); @@ -268,13 +275,13 @@ msg.push_str( "\nAs a reminder, you're using offline mode (-Z offline) \ which can sometimes cause surprising resolution failures, \ - if this error is too confusing you may with to retry \ + if this error is too confusing you may wish to retry \ without the offline flag.", ); } } - to_resolve_err(format_err!("{}", msg)) + to_resolve_err(failure::format_err!("{}", msg)) } /// Returns String representation of dependency chain for a particular `pkgid`. diff -Nru cargo-0.33.0/src/cargo/core/resolver/mod.rs cargo-0.35.0/src/cargo/core/resolver/mod.rs --- cargo-0.33.0/src/cargo/core/resolver/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -//! Resolution of the entire dependency graph for a crate +//! Resolution of the entire dependency graph for a crate. //! //! This module implements the core logic in taking the world of crates and //! constraints and creating a resolved graph with locked versions for all @@ -12,7 +12,7 @@ //! //! 1. Each crate can have any number of dependencies. Each dependency can //! declare a version range that it is compatible with. -//! 2. Crates can be activated with multiple version (e.g. show up in the +//! 2. Crates can be activated with multiple version (e.g., show up in the //! dependency graph twice) so long as each pairwise instance have //! semver-incompatible versions. //! @@ -27,7 +27,7 @@ //! that has the same links attribute as something else //! activated. //! * Always try to activate the highest version crate first. The default -//! dependency in Cargo (e.g. when you write `foo = "0.1.2"`) is +//! dependency in Cargo (e.g., when you write `foo = "0.1.2"`) is //! semver-compatible, so selecting the highest version possible will allow us //! to hopefully satisfy as many dependencies at once. //! @@ -41,7 +41,7 @@ //! //! Note that this is a relatively performance-critical portion of Cargo. The //! data that we're processing is proportional to the size of the dependency -//! graph, which can often be quite large (e.g. take a look at Servo). To make +//! graph, which can often be quite large (e.g., take a look at Servo). To make //! matters worse the DFS algorithm we're implemented is inherently quite //! inefficient. When we add the requirement of backtracking on top it means //! that we're implementing something that probably shouldn't be allocating all @@ -52,14 +52,14 @@ use std::rc::Rc; use std::time::{Duration, Instant}; -use semver; +use log::{debug, trace}; -use core::interning::InternedString; -use core::PackageIdSpec; -use core::{Dependency, PackageId, Registry, Summary}; -use util::config::Config; -use util::errors::CargoResult; -use util::profile; +use crate::core::interning::InternedString; +use crate::core::PackageIdSpec; +use crate::core::{Dependency, PackageId, Registry, Summary}; +use crate::util::config::Config; +use crate::util::errors::CargoResult; +use crate::util::profile; use self::context::{Activations, Context}; use self::types::{Candidate, ConflictReason, DepsFrame, GraphNode}; @@ -97,7 +97,7 @@ /// for the same query every time). Typically this is an instance of a /// `PackageRegistry`. /// -/// * `try_to_use` - this is a list of package ids which were previously found +/// * `try_to_use` - this is a list of package IDs which were previously found /// in the lock file. We heuristically prefer the ids listed in `try_to_use` /// when sorting candidates to activate, but otherwise this isn't used /// anywhere else. @@ -108,9 +108,9 @@ /// * `print_warnings` - whether or not to print backwards-compatibility /// warnings and such pub fn resolve( - summaries: &[(Summary, Method)], + summaries: &[(Summary, Method<'_>)], replacements: &[(PackageIdSpec, Dependency)], - registry: &mut Registry, + registry: &mut dyn Registry, try_to_use: &HashSet, config: Option<&Config>, print_warnings: bool, @@ -167,8 +167,8 @@ /// dependency graph, cx.resolve is returned. fn activate_deps_loop( mut cx: Context, - registry: &mut RegistryQueryer, - summaries: &[(Summary, Method)], + registry: &mut RegistryQueryer<'_>, + summaries: &[(Summary, Method<'_>)], config: Option<&Config>, ) -> CargoResult { let mut backtrack_stack = Vec::new(); @@ -245,13 +245,13 @@ // backtracking to find a place to restart. It is also the list of // things to explain in the error message if we fail to resolve. // - // This is a map of package id to a reason why that packaged caused a + // This is a map of package ID to a reason why that packaged caused a // conflict for us. let mut conflicting_activations = BTreeMap::new(); // When backtracking we don't fully update `conflicting_activations` // especially for the cases that we didn't make a backtrack frame in the - // first place. This `backtracked` var stores whether we are continuing + // first place. This `backtracked` var stores whether we are continuing // from a restored backtrack frame so that we can skip caching // `conflicting_activations` in `past_conflicting_activations` let mut backtracked = false; @@ -580,10 +580,10 @@ /// iterate through next. fn activate( cx: &mut Context, - registry: &mut RegistryQueryer, + registry: &mut RegistryQueryer<'_>, parent: Option<(&Summary, &Dependency)>, candidate: Candidate, - method: &Method, + method: &Method<'_>, ) -> ActivateResult> { if let Some((parent, dep)) = parent { cx.resolve_graph.push(GraphNode::Link( @@ -679,8 +679,8 @@ /// we've reached the end of iteration. /// /// If we've reached the end of the iterator here then `Err` will be - /// returned. The error will contain a map of package id to conflict reason, - /// where each package id caused a candidate to be filtered out from the + /// returned. The error will contain a map of package ID to conflict reason, + /// where each package ID caused a candidate to be filtered out from the /// original list for the reason listed. fn next( &mut self, @@ -845,7 +845,7 @@ ) -> CargoResult<()> { // See if we visited ourselves if !visited.insert(id) { - bail!( + failure::bail!( "cyclic package dependency: package `{}` depends on itself. Cycle:\n{}", id, errors::describe_path(&resolve.path_to_top(&id)) @@ -886,17 +886,17 @@ } } -/// Checks that packages are unique when written to lockfile. +/// Checks that packages are unique when written to lock file. /// -/// When writing package id's to lockfile, we apply lossy encoding. In +/// When writing package ID's to lock file, we apply lossy encoding. In /// particular, we don't store paths of path dependencies. That means that -/// *different* packages may collide in the lockfile, hence this check. +/// *different* packages may collide in the lock file, hence this check. fn check_duplicate_pkgs_in_lockfile(resolve: &Resolve) -> CargoResult<()> { let mut unique_pkg_ids = HashMap::new(); for pkg_id in resolve.iter() { let encodable_pkd_id = encode::encodable_package_id(pkg_id); if let Some(prev_pkg_id) = unique_pkg_ids.insert(encodable_pkd_id, pkg_id) { - bail!( + failure::bail!( "package collision in the lockfile: packages {} and {} are different, \ but only one can be written to lockfile unambiguously", prev_pkg_id, diff -Nru cargo-0.33.0/src/cargo/core/resolver/resolve.rs cargo-0.35.0/src/cargo/core/resolver/resolve.rs --- cargo-0.33.0/src/cargo/core/resolver/resolve.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/resolve.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,13 +6,13 @@ use url::Url; -use core::{Dependency, PackageId, PackageIdSpec, Summary, Target}; -use util::errors::CargoResult; -use util::Graph; +use crate::core::{Dependency, PackageId, PackageIdSpec, Summary, Target}; +use crate::util::errors::CargoResult; +use crate::util::Graph; use super::encode::Metadata; -/// Represents a fully resolved package dependency graph. Each node in the graph +/// Represents a fully-resolved package dependency graph. Each node in the graph /// is a package and edges represent dependencies between packages. /// /// Each instance of `Resolve` also understands the full set of features used @@ -20,7 +20,7 @@ #[derive(PartialEq)] pub struct Resolve { /// A graph, whose vertices are packages and edges are dependency specifications - /// from Cargo.toml. We need a `Vec` here because the same package + /// from `Cargo.toml`. We need a `Vec` here because the same package /// might be present in both `[dependencies]` and `[build-dependencies]`. graph: Graph>, replacements: HashMap, @@ -71,7 +71,7 @@ pub fn merge_from(&mut self, previous: &Resolve) -> CargoResult<()> { // Given a previous instance of resolve, it should be forbidden to ever - // have a checksums which *differ*. If the same package id has differing + // have a checksums which *differ*. If the same package ID has differing // checksums, then something has gone wrong such as: // // * Something got seriously corrupted @@ -94,7 +94,7 @@ // desires stronger checksum guarantees than can be afforded // elsewhere. if cksum.is_none() { - bail!( + failure::bail!( "\ checksum for `{}` was not previously calculated, but a checksum could now \ be calculated @@ -116,7 +116,7 @@ // more realistically we were overridden with a source that does // not have checksums. } else if mine.is_none() { - bail!( + failure::bail!( "\ checksum for `{}` could not be calculated, but a checksum is listed in \ the existing lock file @@ -137,14 +137,14 @@ // must both be Some, in which case the checksum now differs. // That's quite bad! } else { - bail!( + failure::bail!( "\ checksum for `{}` changed between lock files this could be indicative of a few possible errors: * the lock file is corrupt - * a replacement source in use (e.g. a mirror) returned a different checksum + * a replacement source in use (e.g., a mirror) returned a different checksum * the source itself may be corrupt in one way or another unable to verify that `{0}` is the same as when the lockfile was generated @@ -240,17 +240,14 @@ }); let name = names.next().unwrap_or_else(|| crate_name.clone()); for n in names { - if n == name { - continue; - } - bail!( - "multiple dependencies listed for the same crate must \ - all have the same name, but the dependency on `{}` \ - is listed as having different names", - to + failure::ensure!( + n == name, + "the crate `{}` depends on crate `{}` multiple times with different names", + from, + to, ); } - Ok(name.to_string()) + Ok(name) } fn dependencies_listed(&self, from: PackageId, to: PackageId) -> &[Dependency] { @@ -276,7 +273,7 @@ } impl fmt::Debug for Resolve { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(fmt, "graph: {:?}", self.graph)?; writeln!(fmt, "\nfeatures: {{")?; for (pkg, features) in &self.features { diff -Nru cargo-0.33.0/src/cargo/core/resolver/types.rs cargo-0.35.0/src/cargo/core/resolver/types.rs --- cargo-0.33.0/src/cargo/core/resolver/types.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/resolver/types.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,10 +4,12 @@ use std::rc::Rc; use std::time::{Duration, Instant}; -use core::interning::InternedString; -use core::{Dependency, PackageId, PackageIdSpec, Registry, Summary}; -use util::errors::CargoResult; -use util::Config; +use log::debug; + +use crate::core::interning::InternedString; +use crate::core::{Dependency, PackageId, PackageIdSpec, Registry, Summary}; +use crate::util::errors::CargoResult; +use crate::util::Config; use im_rc; @@ -17,6 +19,8 @@ time_to_print: Duration, printed: bool, deps_time: Duration, + #[cfg(debug_assertions)] + slow_cpu_multiplier: u64, } impl ResolverProgress { @@ -27,6 +31,14 @@ time_to_print: Duration::from_millis(500), printed: false, deps_time: Duration::new(0, 0), + // Some CI setups are much slower then the equipment used by Cargo itself. + // Architectures that do not have a modern processor, hardware emulation, ect. + // In the test code we have `slow_cpu_multiplier`, but that is not accessible here. + #[cfg(debug_assertions)] + slow_cpu_multiplier: std::env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER") + .ok() + .and_then(|m| m.parse().ok()) + .unwrap_or(1), } } pub fn shell_status(&mut self, config: Option<&Config>) -> CargoResult<()> { @@ -50,21 +62,27 @@ config.shell().status("Resolving", "dependency graph...")?; } } - // The largest test in our suite takes less then 5000 ticks - // with all the algorithm improvements. - // If any of them are removed then it takes more than I am willing to measure. - // So lets fail the test fast if we have ben running for two long. - debug_assert!( - self.ticks < 50_000, - "got to 50_000 ticks in {:?}", - self.start.elapsed() - ); - // The largest test in our suite takes less then 30 sec - // with all the improvements to how fast a tick can go. - // If any of them are removed then it takes more than I am willing to measure. - // So lets fail the test fast if we have ben running for two long. - if cfg!(debug_assertions) && (self.ticks % 1000 == 0) { - assert!(self.start.elapsed() - self.deps_time < Duration::from_secs(90)); + #[cfg(debug_assertions)] + { + // The largest test in our suite takes less then 5000 ticks + // with all the algorithm improvements. + // If any of them are removed then it takes more than I am willing to measure. + // So lets fail the test fast if we have ben running for two long. + assert!( + self.ticks < 50_000, + "got to 50_000 ticks in {:?}", + self.start.elapsed() + ); + // The largest test in our suite takes less then 30 sec + // with all the improvements to how fast a tick can go. + // If any of them are removed then it takes more than I am willing to measure. + // So lets fail the test fast if we have ben running for two long. + if self.ticks % 1000 == 0 { + assert!( + self.start.elapsed() - self.deps_time + < Duration::from_secs(self.slow_cpu_multiplier * 90) + ); + } } Ok(()) } @@ -74,7 +92,7 @@ } pub struct RegistryQueryer<'a> { - pub registry: &'a mut (Registry + 'a), + pub registry: &'a mut (dyn Registry + 'a), replacements: &'a [(PackageIdSpec, Dependency)], try_to_use: &'a HashSet, cache: HashMap>>, @@ -86,7 +104,7 @@ impl<'a> RegistryQueryer<'a> { pub fn new( - registry: &'a mut Registry, + registry: &'a mut dyn Registry, replacements: &'a [(PackageIdSpec, Dependency)], try_to_use: &'a HashSet, minimal_versions: bool, @@ -142,7 +160,7 @@ let mut summaries = self.registry.query_vec(dep, false)?.into_iter(); let s = summaries.next().ok_or_else(|| { - format_err!( + failure::format_err!( "no matching package for override `{}` found\n\ location searched: {}\n\ version required: {}", @@ -157,7 +175,7 @@ .iter() .map(|s| format!(" * {}", s.package_id())) .collect::>(); - bail!( + failure::bail!( "the replacement specification `{}` matched \ multiple packages:\n * {}\n{}", spec, @@ -182,7 +200,7 @@ // Make sure no duplicates if let Some(&(ref spec, _)) = potential_matches.next() { - bail!( + failure::bail!( "overlapping replacement specifications found:\n\n \ * {}\n * {}\n\nboth specifications match: {}", matched_spec, diff -Nru cargo-0.33.0/src/cargo/core/shell.rs cargo-0.35.0/src/cargo/core/shell.rs --- cargo-0.33.0/src/cargo/core/shell.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/shell.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,9 +5,9 @@ use termcolor::Color::{Cyan, Green, Red, Yellow}; use termcolor::{self, Color, ColorSpec, StandardStream, WriteColor}; -use util::errors::CargoResult; +use crate::util::errors::CargoResult; -/// The requested verbosity of output +/// The requested verbosity of output. #[derive(Debug, Clone, Copy, PartialEq)] pub enum Verbosity { Verbose, @@ -23,10 +23,13 @@ err: ShellOut, /// How verbose messages should be verbosity: Verbosity, + /// Flag that indicates the current line needs to be cleared before + /// printing. Used when a progress bar is currently displayed. + needs_clear: bool, } impl fmt::Debug for Shell { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.err { ShellOut::Write(_) => f .debug_struct("Shell") @@ -44,7 +47,7 @@ /// A `Write`able object, either with or without color support enum ShellOut { /// A plain write object without color support - Write(Box), + Write(Box), /// Color-enabled stdio, with information on whether color should be used Stream { stream: StandardStream, @@ -65,7 +68,7 @@ } impl Shell { - /// Create a new shell (color choice and verbosity), defaulting to 'auto' color and verbose + /// Creates a new shell (color choice and verbosity), defaulting to 'auto' color and verbose /// output. pub fn new() -> Shell { Shell { @@ -75,33 +78,50 @@ tty: atty::is(atty::Stream::Stderr), }, verbosity: Verbosity::Verbose, + needs_clear: false, } } - /// Create a shell from a plain writable object, with no color, and max verbosity. - pub fn from_write(out: Box) -> Shell { + /// Creates a shell from a plain writable object, with no color, and max verbosity. + pub fn from_write(out: Box) -> Shell { Shell { err: ShellOut::Write(out), verbosity: Verbosity::Verbose, + needs_clear: false, } } - /// Print a message, where the status will have `color` color, and can be justified. The + /// Prints a message, where the status will have `color` color, and can be justified. The /// messages follows without color. fn print( &mut self, - status: &fmt::Display, - message: Option<&fmt::Display>, + status: &dyn fmt::Display, + message: Option<&dyn fmt::Display>, color: Color, justified: bool, ) -> CargoResult<()> { match self.verbosity { Verbosity::Quiet => Ok(()), - _ => self.err.print(status, message, color, justified), + _ => { + if self.needs_clear { + self.err_erase_line(); + } + self.err.print(status, message, color, justified) + } } } - /// Returns the width of the terminal in spaces, if any + /// Sets whether the next print should clear the current line. + pub fn set_needs_clear(&mut self, needs_clear: bool) { + self.needs_clear = needs_clear; + } + + /// Returns `true` if the `needs_clear` flag is unset. + pub fn is_cleared(&self) -> bool { + !self.needs_clear + } + + /// Returns the width of the terminal in spaces, if any. pub fn err_width(&self) -> Option { match self.err { ShellOut::Stream { tty: true, .. } => imp::stderr_width(), @@ -109,7 +129,7 @@ } } - /// Returns whether stderr is a tty + /// Returns `true` if stderr is a tty. pub fn is_err_tty(&self) -> bool { match self.err { ShellOut::Stream { tty, .. } => tty, @@ -117,8 +137,11 @@ } } - /// Get a reference to the underlying writer - pub fn err(&mut self) -> &mut Write { + /// Gets a reference to the underlying writer. + pub fn err(&mut self) -> &mut dyn Write { + if self.needs_clear { + self.err_erase_line(); + } self.err.as_write() } @@ -126,6 +149,7 @@ pub fn err_erase_line(&mut self) { if let ShellOut::Stream { tty: true, .. } = self.err { imp::err_erase_line(self); + self.needs_clear = false; } } @@ -159,7 +183,7 @@ self.print(&status, Some(&message), color, true) } - /// Run the callback only if we are in verbose mode + /// Runs the callback only if we are in verbose mode. pub fn verbose(&mut self, mut callback: F) -> CargoResult<()> where F: FnMut(&mut Shell) -> CargoResult<()>, @@ -170,7 +194,7 @@ } } - /// Run the callback if we are not in verbose mode. + /// Runs the callback if we are not in verbose mode. pub fn concise(&mut self, mut callback: F) -> CargoResult<()> where F: FnMut(&mut Shell) -> CargoResult<()>, @@ -181,12 +205,12 @@ } } - /// Print a red 'error' message + /// Prints a red 'error' message. pub fn error(&mut self, message: T) -> CargoResult<()> { self.print(&"error:", Some(&message), Red, false) } - /// Print an amber 'warning' message + /// Prints an amber 'warning' message. pub fn warn(&mut self, message: T) -> CargoResult<()> { match self.verbosity { Verbosity::Quiet => Ok(()), @@ -194,17 +218,17 @@ } } - /// Update the verbosity of the shell + /// Updates the verbosity of the shell. pub fn set_verbosity(&mut self, verbosity: Verbosity) { self.verbosity = verbosity; } - /// Get the verbosity of the shell + /// Gets the verbosity of the shell. pub fn verbosity(&self) -> Verbosity { self.verbosity } - /// Update the color choice (always, never, or auto) from a string. + /// Updates the color choice (always, never, or auto) from a string.. pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> { if let ShellOut::Stream { ref mut stream, @@ -218,7 +242,7 @@ Some("auto") | None => ColorChoice::CargoAuto, - Some(arg) => bail!( + Some(arg) => failure::bail!( "argument for --color must be auto, always, or \ never, but found `{}`", arg @@ -230,10 +254,10 @@ Ok(()) } - /// Get the current color choice + /// Gets the current color choice. /// - /// If we are not using a color stream, this will always return Never, even if the color choice - /// has been set to something else. + /// If we are not using a color stream, this will always return `Never`, even if the color + /// choice has been set to something else. pub fn color_choice(&self) -> ColorChoice { match self.err { ShellOut::Stream { color_choice, .. } => color_choice, @@ -251,6 +275,9 @@ /// Prints a message and translates ANSI escape code into console colors. pub fn print_ansi(&mut self, message: &[u8]) -> CargoResult<()> { + if self.needs_clear { + self.err_erase_line(); + } #[cfg(windows)] { if let ShellOut::Stream { stream, .. } = &mut self.err { @@ -270,12 +297,13 @@ } impl ShellOut { - /// Print out a message with a status. The status comes first and is bold + the given color. - /// The status can be justified, in which case the max width that will right align is 12 chars. + /// Prints out a message with a status. The status comes first, and is bold plus the given + /// color. The status can be justified, in which case the max width that will right align is + /// 12 chars. fn print( &mut self, - status: &fmt::Display, - message: Option<&fmt::Display>, + status: &dyn fmt::Display, + message: Option<&dyn fmt::Display>, color: Color, justified: bool, ) -> CargoResult<()> { @@ -309,8 +337,8 @@ Ok(()) } - /// Get this object as a `io::Write`. - fn as_write(&mut self) -> &mut Write { + /// Gets this object as a `io::Write`. + fn as_write(&mut self) -> &mut dyn Write { match *self { ShellOut::Stream { ref mut stream, .. } => stream, ShellOut::Write(ref mut w) => w, @@ -319,7 +347,7 @@ } impl ColorChoice { - /// Convert our color choice to termcolor's version + /// Converts our color choice to termcolor's version. fn to_termcolor_color_choice(self) -> termcolor::ColorChoice { match self { ColorChoice::Always => termcolor::ColorChoice::Always, @@ -361,7 +389,7 @@ // This is the "EL - Erase in Line" sequence. It clears from the cursor // to the end of line. // https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences - let _ = shell.err().write_all(b"\x1B[K"); + let _ = shell.err.as_write().write_all(b"\x1B[K"); } } @@ -376,15 +404,13 @@ #[cfg(windows)] mod imp { - extern crate winapi; - - use self::winapi::um::fileapi::*; - use self::winapi::um::handleapi::*; - use self::winapi::um::processenv::*; - use self::winapi::um::winbase::*; - use self::winapi::um::wincon::*; - use self::winapi::um::winnt::*; use std::{cmp, mem, ptr}; + use winapi::um::fileapi::*; + use winapi::um::handleapi::*; + use winapi::um::processenv::*; + use winapi::um::winbase::*; + use winapi::um::wincon::*; + use winapi::um::winnt::*; pub(super) use super::default_err_erase_line as err_erase_line; @@ -436,6 +462,6 @@ fn default_err_erase_line(shell: &mut Shell) { if let Some(max_width) = imp::stderr_width() { let blank = " ".repeat(max_width); - drop(write!(shell.err(), "{}\r", blank)); + drop(write!(shell.err.as_write(), "{}\r", blank)); } } diff -Nru cargo-0.33.0/src/cargo/core/source/mod.rs cargo-0.35.0/src/cargo/core/source/mod.rs --- cargo-0.33.0/src/cargo/core/source/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/source/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,20 +1,20 @@ use std::collections::hash_map::HashMap; use std::fmt; -use core::{Dependency, Package, PackageId, Summary}; -use util::CargoResult; +use crate::core::{Dependency, Package, PackageId, Summary}; +use crate::core::package::PackageSet; +use crate::util::{CargoResult, Config}; mod source_id; pub use self::source_id::{GitReference, SourceId}; -/// A Source finds and downloads remote packages based on names and -/// versions. +/// Something that finds and downloads remote packages based on names and versions. pub trait Source { - /// Returns the `SourceId` corresponding to this source + /// Returns the `SourceId` corresponding to this source. fn source_id(&self) -> SourceId; - /// Returns the replaced `SourceId` corresponding to this source + /// Returns the replaced `SourceId` corresponding to this source. fn replaced_source_id(&self) -> SourceId { self.source_id() } @@ -27,14 +27,14 @@ /// the `precise` field in the source id listed. fn requires_precise(&self) -> bool; - /// Attempt to find the packages that match a dependency request. - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()>; + /// Attempts to find the packages that match a dependency request. + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()>; - /// Attempt to find the packages that are close to a dependency request. + /// Attempts to find the packages that are close to a dependency request. /// Each source gets to define what `close` means for it. - /// path/git sources may return all dependencies that are at that uri. - /// where as an Index source may return dependencies that have the same canonicalization. - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()>; + /// Path/Git sources may return all dependencies that are at that URI, + /// whereas an `Index` source may return dependencies that have the same canonicalization. + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()>; fn query_vec(&mut self, dep: &Dependency) -> CargoResult> { let mut ret = Vec::new(); @@ -42,15 +42,23 @@ Ok(ret) } - /// The update method performs any network operations required to - /// get the entire list of all names, versions and dependencies of - /// packages managed by the Source. + /// Performs any network operations required to get the entire list of all names, + /// versions and dependencies of packages managed by the `Source`. fn update(&mut self) -> CargoResult<()>; - /// The download method fetches the full package for each name and - /// version specified. + /// Fetches the full package for each name and version specified. fn download(&mut self, package: PackageId) -> CargoResult; + fn download_now(self: Box, package: PackageId, config: &Config) -> CargoResult + where + Self: std::marker::Sized, + { + let mut sources = SourceMap::new(); + sources.insert(self); + let pkg_set = PackageSet::new(&[package], sources, config)?; + Ok(pkg_set.get_one(package)?.clone()) + } + fn finish_download(&mut self, package: PackageId, contents: Vec) -> CargoResult; /// Generates a unique string which represents the fingerprint of the @@ -79,10 +87,15 @@ /// resolver error messages currently. fn describe(&self) -> String; - /// Returns whether a source is being replaced by another here + /// Returns whether a source is being replaced by another here. fn is_replaced(&self) -> bool { false } + + /// Add a number of crates that should be whitelisted for showing up during + /// queries, even if they are yanked. Currently only applies to registry + /// sources. + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]); } pub enum MaybePackage { @@ -91,42 +104,42 @@ } impl<'a, T: Source + ?Sized + 'a> Source for Box { - /// Forwards to `Source::source_id` + /// Forwards to `Source::source_id`. fn source_id(&self) -> SourceId { (**self).source_id() } - /// Forwards to `Source::replaced_source_id` + /// Forwards to `Source::replaced_source_id`. fn replaced_source_id(&self) -> SourceId { (**self).replaced_source_id() } - /// Forwards to `Source::supports_checksums` + /// Forwards to `Source::supports_checksums`. fn supports_checksums(&self) -> bool { (**self).supports_checksums() } - /// Forwards to `Source::requires_precise` + /// Forwards to `Source::requires_precise`. fn requires_precise(&self) -> bool { (**self).requires_precise() } - /// Forwards to `Source::query` - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + /// Forwards to `Source::query`. + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { (**self).query(dep, f) } - /// Forwards to `Source::query` - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + /// Forwards to `Source::query`. + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { (**self).fuzzy_query(dep, f) } - /// Forwards to `Source::update` + /// Forwards to `Source::update`. fn update(&mut self) -> CargoResult<()> { (**self).update() } - /// Forwards to `Source::download` + /// Forwards to `Source::download`. fn download(&mut self, id: PackageId) -> CargoResult { (**self).download(id) } @@ -135,12 +148,12 @@ (**self).finish_download(id, data) } - /// Forwards to `Source::fingerprint` + /// Forwards to `Source::fingerprint`. fn fingerprint(&self, pkg: &Package) -> CargoResult { (**self).fingerprint(pkg) } - /// Forwards to `Source::verify` + /// Forwards to `Source::verify`. fn verify(&self, pkg: PackageId) -> CargoResult<()> { (**self).verify(pkg) } @@ -152,6 +165,10 @@ fn is_replaced(&self) -> bool { (**self).is_replaced() } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + (**self).add_to_yanked_whitelist(pkgs); + } } impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T { @@ -171,11 +188,11 @@ (**self).requires_precise() } - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { (**self).query(dep, f) } - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { (**self).fuzzy_query(dep, f) } @@ -206,84 +223,87 @@ fn is_replaced(&self) -> bool { (**self).is_replaced() } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + (**self).add_to_yanked_whitelist(pkgs); + } } -/// A `HashMap` of `SourceId` -> `Box` +/// A `HashMap` of `SourceId` -> `Box`. #[derive(Default)] pub struct SourceMap<'src> { - map: HashMap>, + map: HashMap>, } -// impl debug on source requires specialization, if even desirable at all +// `impl Debug` on source requires specialization, if even desirable at all. impl<'src> fmt::Debug for SourceMap<'src> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SourceMap ")?; f.debug_set().entries(self.map.keys()).finish() } } impl<'src> SourceMap<'src> { - /// Create an empty map + /// Creates an empty map. pub fn new() -> SourceMap<'src> { SourceMap { map: HashMap::new(), } } - /// Like `HashMap::contains_key` + /// Like `HashMap::contains_key`. pub fn contains(&self, id: SourceId) -> bool { self.map.contains_key(&id) } - /// Like `HashMap::get` - pub fn get(&self, id: SourceId) -> Option<&(Source + 'src)> { + /// Like `HashMap::get`. + pub fn get(&self, id: SourceId) -> Option<&(dyn Source + 'src)> { let source = self.map.get(&id); source.map(|s| { - let s: &(Source + 'src) = &**s; + let s: &(dyn Source + 'src) = &**s; s }) } - /// Like `HashMap::get_mut` - pub fn get_mut(&mut self, id: SourceId) -> Option<&mut (Source + 'src)> { + /// Like `HashMap::get_mut`. + pub fn get_mut(&mut self, id: SourceId) -> Option<&mut (dyn Source + 'src)> { self.map.get_mut(&id).map(|s| { - let s: &mut (Source + 'src) = &mut **s; + let s: &mut (dyn Source + 'src) = &mut **s; s }) } - /// Like `HashMap::get`, but first calculates the `SourceId` from a - /// `PackageId` - pub fn get_by_package_id(&self, pkg_id: PackageId) -> Option<&(Source + 'src)> { + /// Like `HashMap::get`, but first calculates the `SourceId` from a `PackageId`. + pub fn get_by_package_id(&self, pkg_id: PackageId) -> Option<&(dyn Source + 'src)> { self.get(pkg_id.source_id()) } - /// Like `HashMap::insert`, but derives the SourceId key from the Source - pub fn insert(&mut self, source: Box) { + /// Like `HashMap::insert`, but derives the `SourceId` key from the `Source`. + pub fn insert(&mut self, source: Box) { let id = source.source_id(); self.map.insert(id, source); } - /// Like `HashMap::is_empty` + /// Like `HashMap::is_empty`. pub fn is_empty(&self) -> bool { self.map.is_empty() } - /// Like `HashMap::len` + /// Like `HashMap::len`. pub fn len(&self) -> usize { self.map.len() } - /// Like `HashMap::values` - pub fn sources<'a>(&'a self) -> impl Iterator> { + /// Like `HashMap::values`. + pub fn sources<'a>(&'a self) -> impl Iterator> { self.map.values() } - /// Like `HashMap::iter_mut` + /// Like `HashMap::iter_mut`. pub fn sources_mut<'a>( &'a mut self, - ) -> impl Iterator { + ) -> impl Iterator { self.map.iter_mut().map(|(a, b)| (a, &mut **b)) } } diff -Nru cargo-0.33.0/src/cargo/core/source/source_id.rs cargo-0.35.0/src/cargo/core/source/source_id.rs --- cargo-0.33.0/src/cargo/core/source/source_id.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/source/source_id.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,21 +4,23 @@ use std::hash::{self, Hash}; use std::path::Path; use std::ptr; +use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering::SeqCst; -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT}; use std::sync::Mutex; +use log::trace; use serde::de; use serde::ser; use url::Url; -use ops; -use sources::git; -use sources::DirectorySource; -use sources::{GitSource, PathSource, RegistrySource, CRATES_IO_INDEX}; -use util::{CargoResult, Config, ToUrl}; +use crate::core::PackageId; +use crate::ops; +use crate::sources::git; +use crate::sources::DirectorySource; +use crate::sources::{GitSource, PathSource, RegistrySource, CRATES_IO_INDEX}; +use crate::util::{CargoResult, Config, ToUrl}; -lazy_static! { +lazy_static::lazy_static! { static ref SOURCE_ID_CACHE: Mutex> = Mutex::new(HashSet::new()); } @@ -30,47 +32,49 @@ #[derive(PartialEq, Eq, Clone, Debug, Hash)] struct SourceIdInner { - /// The source URL + /// The source URL. url: Url, - /// `git::canonicalize_url(url)` for the url field + /// The result of `git::canonicalize_url()` on `url` field. canonical_url: Url, - /// The source kind + /// The source kind. kind: Kind, - // e.g. the exact git revision of the specified branch for a Git Source + /// For example, the exact Git revision of the specified branch for a Git Source. precise: Option, /// Name of the registry source for alternative registries + /// WARNING: this is not always set for alt-registries when the name is + /// not known. name: Option, } -/// The possible kinds of code source. Along with SourceIdInner this fully defines the -/// source +/// The possible kinds of code source. Along with `SourceIdInner`, this fully defines the +/// source. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] enum Kind { - /// Kind::Git() represents a git repository + /// A git repository. Git(GitReference), - /// represents a local path + /// A local path.. Path, - /// represents a remote registry + /// A remote registry. Registry, - /// represents a local filesystem-based registry + /// A local filesystem-based registry. LocalRegistry, - /// represents a directory-based registry + /// A directory-based registry. Directory, } -/// Information to find a specific commit in a git repository +/// Information to find a specific commit in a Git repository. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum GitReference { - /// from a tag + /// From a tag. Tag(String), - /// from the HEAD of a branch + /// From the HEAD of a branch. Branch(String), - /// from a specific revision + /// From a specific revision. Rev(String), } impl SourceId { - /// Create a SourceId object from the kind and url. + /// Creates a `SourceId` object from the kind and URL. /// /// The canonical url will be calculated, but the precise field will not fn new(kind: Kind, url: Url) -> CargoResult { @@ -109,7 +113,7 @@ let kind = parts.next().unwrap(); let url = parts .next() - .ok_or_else(|| format_err!("invalid source `{}`", string))?; + .ok_or_else(|| failure::format_err!("invalid source `{}`", string))?; match kind { "git" => { @@ -117,7 +121,7 @@ let mut reference = GitReference::Branch("master".to_string()); for (k, v) in url.query_pairs() { match &k[..] { - // map older 'ref' to branch + // Map older 'ref' to branch. "branch" | "ref" => reference = GitReference::Branch(v.into_owned()), "rev" => reference = GitReference::Rev(v.into_owned()), @@ -138,42 +142,45 @@ let url = url.to_url()?; SourceId::new(Kind::Path, url) } - kind => Err(format_err!("unsupported source protocol: {}", kind)), + kind => Err(failure::format_err!( + "unsupported source protocol: {}", + kind + )), } } - /// A view of the `SourceId` that can be `Display`ed as a URL - pub fn to_url(&self) -> SourceIdToUrl { + /// A view of the `SourceId` that can be `Display`ed as a URL. + pub fn to_url(&self) -> SourceIdToUrl<'_> { SourceIdToUrl { inner: &*self.inner, } } - /// Create a SourceId from a filesystem path. + /// Creates a `SourceId` from a filesystem path. /// - /// Pass absolute path + /// `path`: an absolute path. pub fn for_path(path: &Path) -> CargoResult { let url = path.to_url()?; SourceId::new(Kind::Path, url) } - /// Crate a SourceId from a git reference + /// Creates a `SourceId` from a Git reference. pub fn for_git(url: &Url, reference: GitReference) -> CargoResult { SourceId::new(Kind::Git(reference), url.clone()) } - /// Create a SourceId from a registry url + /// Creates a SourceId from a registry URL. pub fn for_registry(url: &Url) -> CargoResult { SourceId::new(Kind::Registry, url.clone()) } - /// Create a SourceId from a local registry path + /// Creates a SourceId from a local registry path. pub fn for_local_registry(path: &Path) -> CargoResult { let url = path.to_url()?; SourceId::new(Kind::LocalRegistry, url) } - /// Create a SourceId from a directory path + /// Creates a `SourceId` from a directory path. pub fn for_directory(path: &Path) -> CargoResult { let url = path.to_url()?; SourceId::new(Kind::Directory, url) @@ -187,7 +194,7 @@ config.crates_io_source_id(|| { let cfg = ops::registry_configuration(config, None)?; let url = if let Some(ref index) = cfg.index { - static WARNED: AtomicBool = ATOMIC_BOOL_INIT; + static WARNED: AtomicBool = AtomicBool::new(false); if !WARNED.swap(true, SeqCst) { config.shell().warn( "custom registry support via \ @@ -216,7 +223,7 @@ })) } - /// Get this source URL + /// Gets this source URL. pub fn url(&self) -> &Url { &self.inner.url } @@ -229,12 +236,12 @@ } } - /// Is this source from a filesystem path + /// Returns `true` if this source is from a filesystem path. pub fn is_path(self) -> bool { self.inner.kind == Kind::Path } - /// Is this source from a registry (either local or not) + /// Returns `true` if this source is from a registry (either local or not). pub fn is_registry(self) -> bool { match self.inner.kind { Kind::Registry | Kind::LocalRegistry => true, @@ -242,12 +249,7 @@ } } - /// Is this source from an alternative registry - pub fn is_alt_registry(self) -> bool { - self.is_registry() && self.inner.name.is_some() - } - - /// Is this source from a git repository + /// Returns `true` if this source from a Git repository. pub fn is_git(self) -> bool { match self.inner.kind { Kind::Git(_) => true, @@ -256,7 +258,11 @@ } /// Creates an implementation of `Source` corresponding to this ID. - pub fn load<'a>(self, config: &'a Config) -> CargoResult> { + pub fn load<'a>( + self, + config: &'a Config, + yanked_whitelist: &HashSet, + ) -> CargoResult> { trace!("loading SourceId; {}", self); match self.inner.kind { Kind::Git(..) => Ok(Box::new(GitSource::new(self, config)?)), @@ -267,13 +273,22 @@ }; Ok(Box::new(PathSource::new(&path, self, config))) } - Kind::Registry => Ok(Box::new(RegistrySource::remote(self, config))), + Kind::Registry => Ok(Box::new(RegistrySource::remote( + self, + yanked_whitelist, + config, + ))), Kind::LocalRegistry => { let path = match self.inner.url.to_file_path() { Ok(p) => p, Err(()) => panic!("path sources cannot be remote"), }; - Ok(Box::new(RegistrySource::local(self, &path, config))) + Ok(Box::new(RegistrySource::local( + self, + &path, + yanked_whitelist, + config, + ))) } Kind::Directory => { let path = match self.inner.url.to_file_path() { @@ -285,12 +300,12 @@ } } - /// Get the value of the precise field + /// Gets the value of the precise field. pub fn precise(self) -> Option<&'static str> { self.inner.precise.as_ref().map(|s| &s[..]) } - /// Get the git reference if this is a git source, otherwise None. + /// Gets the Git reference if this is a git source, otherwise `None`. pub fn git_reference(self) -> Option<&'static GitReference> { match self.inner.kind { Kind::Git(ref s) => Some(s), @@ -298,7 +313,7 @@ } } - /// Create a new SourceId from this source with the given `precise` + /// Creates a new `SourceId` from this source with the given `precise`. pub fn with_precise(self, v: Option) -> SourceId { SourceId::wrap(SourceIdInner { precise: v, @@ -306,7 +321,7 @@ }) } - /// Whether the remote registry is the standard https://crates.io + /// Returns `true` if the remote registry is the standard . pub fn is_default_registry(self) -> bool { match self.inner.kind { Kind::Registry => {} @@ -315,7 +330,7 @@ self.inner.url.to_string() == CRATES_IO_INDEX } - /// Hash `self` + /// Hashes `self`. /// /// For paths, remove the workspace prefix so the same source will give the /// same hash in different locations. @@ -393,47 +408,26 @@ } impl fmt::Display for SourceId { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match *self.inner { - SourceIdInner { - kind: Kind::Path, - ref url, - .. - } => write!(f, "{}", url_display(url)), - SourceIdInner { - kind: Kind::Git(ref reference), - ref url, - ref precise, - .. - } => { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self.inner.kind { + Kind::Git(ref reference) => { // Don't replace the URL display for git references, // because those are kind of expected to be URLs. - write!(f, "{}", url)?; + write!(f, "{}", self.inner.url)?; if let Some(pretty) = reference.pretty_ref() { write!(f, "?{}", pretty)?; } - if let Some(ref s) = *precise { + if let Some(ref s) = self.inner.precise { let len = cmp::min(s.len(), 8); write!(f, "#{}", &s[..len])?; } Ok(()) } - SourceIdInner { - kind: Kind::Registry, - ref url, - .. - } - | SourceIdInner { - kind: Kind::LocalRegistry, - ref url, - .. - } => write!(f, "registry `{}`", url_display(url)), - SourceIdInner { - kind: Kind::Directory, - ref url, - .. - } => write!(f, "dir {}", url_display(url)), + Kind::Path => write!(f, "{}", url_display(&self.inner.url)), + Kind::Registry => write!(f, "registry `{}`", url_display(&self.inner.url)), + Kind::LocalRegistry => write!(f, "registry `{}`", url_display(&self.inner.url)), + Kind::Directory => write!(f, "dir {}", url_display(&self.inner.url)), } } } @@ -478,7 +472,7 @@ ord => return ord, } match (&self.kind, &other.kind) { - (&Kind::Git(ref ref1), &Kind::Git(ref ref2)) => { + (Kind::Git(ref1), Kind::Git(ref2)) => { (ref1, &self.canonical_url).cmp(&(ref2, &other.canonical_url)) } _ => self.kind.cmp(&other.kind), @@ -492,12 +486,8 @@ impl Hash for SourceId { fn hash(&self, into: &mut S) { self.inner.kind.hash(into); - match *self.inner { - SourceIdInner { - kind: Kind::Git(..), - ref canonical_url, - .. - } => canonical_url.as_str().hash(into), + match self.inner.kind { + Kind::Git(_) => self.inner.canonical_url.as_str().hash(into), _ => self.inner.url.as_str().hash(into), } } @@ -509,7 +499,7 @@ } impl<'a> fmt::Display for SourceIdToUrl<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.inner { SourceIdInner { kind: Kind::Path, @@ -553,7 +543,7 @@ impl GitReference { /// Returns a `Display`able view of this git reference, or None if using /// the head of the "master" branch - pub fn pretty_ref(&self) -> Option { + pub fn pretty_ref(&self) -> Option> { match *self { GitReference::Branch(ref s) if *s == "master" => None, _ => Some(PrettyRef { inner: self }), @@ -567,7 +557,7 @@ } impl<'a> fmt::Display for PrettyRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.inner { GitReference::Branch(ref b) => write!(f, "branch={}", b), GitReference::Tag(ref s) => write!(f, "tag={}", s), @@ -579,7 +569,7 @@ #[cfg(test)] mod tests { use super::{GitReference, Kind, SourceId}; - use util::ToUrl; + use crate::util::ToUrl; #[test] fn github_sources_equal() { diff -Nru cargo-0.33.0/src/cargo/core/summary.rs cargo-0.35.0/src/cargo/core/summary.rs --- cargo-0.33.0/src/cargo/core/summary.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/summary.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,11 +6,11 @@ use serde::{Serialize, Serializer}; -use core::interning::InternedString; -use core::{Dependency, PackageId, SourceId}; +use crate::core::interning::InternedString; +use crate::core::{Dependency, PackageId, SourceId}; use semver::Version; -use util::CargoResult; +use crate::util::CargoResult; /// Subset of a `Manifest`. Contains only the most important information about /// a package. @@ -45,14 +45,14 @@ for dep in dependencies.iter() { let feature = dep.name_in_toml(); if !namespaced_features && features.get(&*feature).is_some() { - bail!( + failure::bail!( "Features and dependencies cannot have the \ same name: `{}`", feature ) } if dep.is_optional() && !dep.is_transitive() { - bail!( + failure::bail!( "Dev-dependencies are not allowed to be optional: `{}`", feature ) @@ -172,7 +172,7 @@ match dep_map.get(feature.borrow()) { Some(ref dep_data) => { if !dep_data.iter().any(|d| d.is_optional()) { - bail!( + failure::bail!( "Feature `{}` includes the dependency of the same name, but this is \ left implicit in the features included by this feature.\n\ Additionally, the dependency must be marked as optional to be \ @@ -241,7 +241,7 @@ (&Feature(feat), dep_exists, false) => { if namespaced && !features.contains_key(&*feat) { if dep_exists { - bail!( + failure::bail!( "Feature `{}` includes `{}` which is not defined as a feature.\n\ A non-optional dependency of the same name is defined; consider \ adding `optional = true` to its definition", @@ -249,7 +249,7 @@ feat ) } else { - bail!( + failure::bail!( "Feature `{}` includes `{}` which is not defined as a feature", feature, feat @@ -264,7 +264,7 @@ // just to provide the correct string for the crate dependency in the error. (&Crate(ref dep), true, false) => { if namespaced { - bail!( + failure::bail!( "Feature `{}` includes `crate:{}` which is not an \ optional dependency.\nConsider adding \ `optional = true` to the dependency", @@ -272,7 +272,7 @@ dep ) } else { - bail!( + failure::bail!( "Feature `{}` depends on `{}` which is not an \ optional dependency.\nConsider adding \ `optional = true` to the dependency", @@ -287,14 +287,14 @@ // namespaced here is just to provide the correct string in the error. (&Crate(ref dep), false, _) => { if namespaced { - bail!( + failure::bail!( "Feature `{}` includes `crate:{}` which is not a known \ dependency", feature, dep ) } else { - bail!( + failure::bail!( "Feature `{}` includes `{}` which is neither a dependency nor \ another feature", feature, @@ -305,7 +305,7 @@ (&Crate(_), true, true) => {} // If the value is a feature for one of the dependencies, bail out if no such // dependency is actually defined in the manifest. - (&CrateFeature(ref dep, _), false, _) => bail!( + (&CrateFeature(ref dep, _), false, _) => failure::bail!( "Feature `{}` requires a feature of `{}` which is not a \ dependency", feature, @@ -319,7 +319,7 @@ if !dependency_found { // If we have not found the dependency of the same-named feature, we should // bail here. - bail!( + failure::bail!( "Feature `{}` includes the optional dependency of the \ same name, but this is left implicit in the features \ included by this feature.\nConsider adding \ diff -Nru cargo-0.33.0/src/cargo/core/workspace.rs cargo-0.35.0/src/cargo/core/workspace.rs --- cargo-0.33.0/src/cargo/core/workspace.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/core/workspace.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,18 +5,19 @@ use std::slice; use glob::glob; +use log::debug; use url::Url; -use core::profiles::Profiles; -use core::registry::PackageRegistry; -use core::{Dependency, PackageIdSpec}; -use core::{EitherManifest, Package, SourceId, VirtualManifest}; -use ops; -use sources::PathSource; -use util::errors::{CargoResult, CargoResultExt, ManifestError}; -use util::paths; -use util::toml::read_manifest; -use util::{Config, Filesystem}; +use crate::core::profiles::Profiles; +use crate::core::registry::PackageRegistry; +use crate::core::{Dependency, PackageIdSpec}; +use crate::core::{EitherManifest, Package, SourceId, VirtualManifest}; +use crate::ops; +use crate::sources::PathSource; +use crate::util::errors::{CargoResult, CargoResultExt, ManifestError}; +use crate::util::paths; +use crate::util::toml::read_manifest; +use crate::util::{Config, Filesystem}; /// The core abstraction in Cargo for working with a workspace of crates. /// @@ -63,11 +64,11 @@ // or only the root package for non-virtual workspaces. default_members: Vec, - // True, if this is a temporary workspace created for the purposes of - // cargo install or cargo package. + // `true` if this is a temporary workspace created for the purposes of the + // `cargo install` or `cargo package` commands. is_ephemeral: bool, - // True if this workspace should enforce optional dependencies even when + // `true` if this workspace should enforce optional dependencies even when // not needed; false if this workspace should only enforce dependencies // needed by the current configuration (such as in cargo install). In some // cases `false` also results in the non-enforcement of dev-dependencies. @@ -206,7 +207,7 @@ /// indicating that something else should be passed. pub fn current(&self) -> CargoResult<&Package> { let pkg = self.current_opt().ok_or_else(|| { - format_err!( + failure::format_err!( "manifest path `{}` is a virtual manifest, but this \ command requires running against an actual package in \ this workspace", @@ -236,13 +237,9 @@ } pub fn profiles(&self) -> &Profiles { - let root = self - .root_manifest - .as_ref() - .unwrap_or(&self.current_manifest); - match *self.packages.get(root) { - MaybePackage::Package(ref p) => p.manifest().profiles(), - MaybePackage::Virtual(ref vm) => vm.profiles(), + match self.root_maybe() { + MaybePackage::Package(p) => p.manifest().profiles(), + MaybePackage::Virtual(vm) => vm.profiles(), } } @@ -259,6 +256,15 @@ .unwrap() } + /// Returns the root Package or VirtualManifest. + fn root_maybe(&self) -> &MaybePackage { + let root = self + .root_manifest + .as_ref() + .unwrap_or(&self.current_manifest); + self.packages.get(root) + } + pub fn target_dir(&self) -> Filesystem { self.target_dir .clone() @@ -269,13 +275,9 @@ /// /// This may be from a virtual crate or an actual crate. pub fn root_replace(&self) -> &[(PackageIdSpec, Dependency)] { - let path = match self.root_manifest { - Some(ref p) => p, - None => &self.current_manifest, - }; - match *self.packages.get(path) { - MaybePackage::Package(ref p) => p.manifest().replace(), - MaybePackage::Virtual(ref vm) => vm.replace(), + match self.root_maybe() { + MaybePackage::Package(p) => p.manifest().replace(), + MaybePackage::Virtual(vm) => vm.replace(), } } @@ -283,13 +285,9 @@ /// /// This may be from a virtual crate or an actual crate. pub fn root_patch(&self) -> &HashMap> { - let path = match self.root_manifest { - Some(ref p) => p, - None => &self.current_manifest, - }; - match *self.packages.get(path) { - MaybePackage::Package(ref p) => p.manifest().patch(), - MaybePackage::Virtual(ref vm) => vm.patch(), + match self.root_maybe() { + MaybePackage::Package(p) => p.manifest().patch(), + MaybePackage::Virtual(vm) => vm.patch(), } } @@ -435,7 +433,7 @@ None } } - _ => bail!( + _ => failure::bail!( "root of a workspace inferred but wasn't a root: {}", root_manifest_path.display() ), @@ -450,7 +448,7 @@ for path in default { let manifest_path = paths::normalize_path(&path.join("Cargo.toml")); if !self.members.contains(&manifest_path) { - bail!( + failure::bail!( "package `{}` is listed in workspace’s default-members \ but is not a member.", path.display() @@ -523,6 +521,18 @@ /// 2. All workspace members agree on this one root as the root. /// 3. The current crate is a member of this workspace. fn validate(&mut self) -> CargoResult<()> { + // Validate config profiles only once per workspace. + let features = match self.root_maybe() { + MaybePackage::Package(p) => p.manifest().features(), + MaybePackage::Virtual(vm) => vm.features(), + }; + let mut warnings = Vec::new(); + self.config.profiles()?.validate(features, &mut warnings)?; + for warning in warnings { + self.config.shell().warn(&warning)?; + } + + // The rest of the checks require a VirtualManifest or multiple members. if self.root_manifest.is_none() { return Ok(()); } @@ -543,7 +553,7 @@ MaybePackage::Virtual(_) => continue, }; if let Some(prev) = names.insert(name, member) { - bail!( + failure::bail!( "two packages named `{}` in this workspace:\n\ - {}\n\ - {}", @@ -556,7 +566,7 @@ } match roots.len() { - 0 => bail!( + 0 => failure::bail!( "`package.workspace` configuration points to a crate \ which is not configured with [workspace]: \n\ configuration at: {}\n\ @@ -566,7 +576,7 @@ ), 1 => {} _ => { - bail!( + failure::bail!( "multiple workspace roots found in the same workspace:\n{}", roots .iter() @@ -585,7 +595,7 @@ match root { Some(root) => { - bail!( + failure::bail!( "package `{}` is a member of the wrong workspace\n\ expected: {}\n\ actual: {}", @@ -595,7 +605,7 @@ ); } None => { - bail!( + failure::bail!( "workspace member `{}` is not hierarchically below \ the workspace root `{}`", member.display(), @@ -647,7 +657,7 @@ } } }; - bail!( + failure::bail!( "current package believes it's in a workspace when it's not:\n\ current: {}\n\ workspace: {}\n\n{}", @@ -694,7 +704,7 @@ pub fn load(&self, manifest_path: &Path) -> CargoResult { match self.packages.maybe_get(manifest_path) { Some(&MaybePackage::Package(ref p)) => return Ok(p.clone()), - Some(&MaybePackage::Virtual(_)) => bail!("cannot load workspace root"), + Some(&MaybePackage::Virtual(_)) => failure::bail!("cannot load workspace root"), None => {} } @@ -748,8 +758,9 @@ let path = path.join("Cargo.toml"); for warning in warnings { if warning.is_critical { - let err = format_err!("{}", warning.message); - let cx = format_err!("failed to parse manifest at `{}`", path.display()); + let err = failure::format_err!("{}", warning.message); + let cx = + failure::format_err!("failed to parse manifest at `{}`", path.display()); return Err(err.context(cx).into()); } else { let msg = if self.root_manifest.is_none() { @@ -825,7 +836,7 @@ } impl WorkspaceRootConfig { - /// Create a new Intermediate Workspace Root configuration. + /// Creates a new Intermediate Workspace Root configuration. pub fn new( root_dir: &Path, members: &Option>, @@ -842,7 +853,7 @@ /// Checks the path against the `excluded` list. /// - /// This method does NOT consider the `members` list. + /// This method does **not** consider the `members` list. fn is_excluded(&self, manifest_path: &Path) -> bool { let excluded = self .exclude @@ -887,9 +898,12 @@ Some(p) => p, None => return Ok(Vec::new()), }; - let res = glob(path).chain_err(|| format_err!("could not parse pattern `{}`", &path))?; + let res = + glob(path).chain_err(|| failure::format_err!("could not parse pattern `{}`", &path))?; let res = res - .map(|p| p.chain_err(|| format_err!("unable to match path to pattern `{}`", &path))) + .map(|p| { + p.chain_err(|| failure::format_err!("unable to match path to pattern `{}`", &path)) + }) .collect::, _>>()?; Ok(res) } diff -Nru cargo-0.33.0/src/cargo/lib.rs cargo-0.35.0/src/cargo/lib.rs --- cargo-0.33.0/src/cargo/lib.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/lib.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,78 +1,31 @@ #![cfg_attr(test, deny(warnings))] -// Clippy isn't enforced by CI, and know that @alexcrichton isn't a fan :) -#![cfg_attr(feature = "cargo-clippy", allow(clippy::boxed_local))] // bug rust-lang-nursery/rust-clippy#1123 -#![cfg_attr(feature = "cargo-clippy", allow(clippy::cyclomatic_complexity))] // large project -#![cfg_attr(feature = "cargo-clippy", allow(clippy::derive_hash_xor_eq))] // there's an intentional incoherence -#![cfg_attr(feature = "cargo-clippy", allow(clippy::explicit_into_iter_loop))] // explicit loops are clearer -#![cfg_attr(feature = "cargo-clippy", allow(clippy::explicit_iter_loop))] // explicit loops are clearer -#![cfg_attr(feature = "cargo-clippy", allow(clippy::identity_op))] // used for vertical alignment -#![cfg_attr(feature = "cargo-clippy", allow(clippy::implicit_hasher))] // large project -#![cfg_attr(feature = "cargo-clippy", allow(clippy::large_enum_variant))] // large project -#![cfg_attr(feature = "cargo-clippy", allow(clippy::redundant_closure_call))] // closures over try catch blocks -#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))] // large project -#![cfg_attr(feature = "cargo-clippy", allow(clippy::type_complexity))] // there's an exceptionally complex type -#![cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))] // perhaps Rc should be special cased in Clippy? - -extern crate atty; -extern crate bytesize; -extern crate clap; -#[cfg(target_os = "macos")] -extern crate core_foundation; -extern crate crates_io as registry; -extern crate crossbeam_utils; -extern crate curl; -extern crate curl_sys; -#[macro_use] -extern crate failure; -extern crate filetime; -extern crate flate2; -extern crate fs2; -#[cfg(windows)] -extern crate fwdansi; -extern crate git2; -extern crate glob; -extern crate hex; -extern crate home; -extern crate ignore; -extern crate jobserver; -#[macro_use] -extern crate lazy_static; -extern crate lazycell; -extern crate libc; -extern crate libgit2_sys; -#[macro_use] -extern crate log; -extern crate num_cpus; -extern crate opener; -extern crate rustfix; -extern crate same_file; -extern crate semver; -#[macro_use] -extern crate serde; -#[macro_use] -extern crate serde_derive; -extern crate serde_ignored; -#[macro_use] -extern crate serde_json; -extern crate im_rc; -extern crate shell_escape; -extern crate tar; -extern crate tempfile; -extern crate termcolor; -extern crate toml; -extern crate unicode_width; -extern crate url; +#![warn(rust_2018_idioms)] +// While we're getting used to 2018: +// Clippy isn't enforced by CI (@alexcrichton isn't a fan). +#![allow(clippy::boxed_local)] // bug rust-lang-nursery/rust-clippy#1123 +#![allow(clippy::cyclomatic_complexity)] // large project +#![allow(clippy::derive_hash_xor_eq)] // there's an intentional incoherence +#![allow(clippy::explicit_into_iter_loop)] // explicit loops are clearer +#![allow(clippy::explicit_iter_loop)] // explicit loops are clearer +#![allow(clippy::identity_op)] // used for vertical alignment +#![allow(clippy::implicit_hasher)] // large project +#![allow(clippy::large_enum_variant)] // large project +#![allow(clippy::redundant_closure_call)] // closures over try catch blocks +#![allow(clippy::too_many_arguments)] // large project +#![allow(clippy::type_complexity)] // there's an exceptionally complex type +#![allow(clippy::wrong_self_convention)] // perhaps `Rc` should be special-cased in Clippy? use std::fmt; use failure::Error; +use log::debug; use serde::ser; -use core::shell::Verbosity::Verbose; -use core::Shell; +use crate::core::shell::Verbosity::Verbose; +use crate::core::Shell; -pub use util::errors::Internal; -pub use util::{CargoError, CargoResult, CliError, CliResult, Config}; +pub use crate::util::errors::Internal; +pub use crate::util::{CargoResult, CliError, CliResult, Config}; pub const CARGO_ENV: &str = "CARGO"; @@ -91,7 +44,7 @@ } pub struct CfgInfo { - // Information about the git repository we may have been built from. + // Information about the Git repository we may have been built from. pub commit_info: Option, // The release channel we were built for. pub release_channel: String, @@ -103,12 +56,12 @@ pub patch: u8, pub pre_release: Option, // Information that's only available when we were built with - // configure/make, rather than cargo itself. + // configure/make, rather than Cargo itself. pub cfg_info: Option, } impl fmt::Display for VersionInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "cargo {}.{}.{}", self.major, self.minor, self.patch)?; if let Some(channel) = self.cfg_info.as_ref().map(|ci| &ci.release_channel) { if channel != "stable" { @@ -145,7 +98,7 @@ exit_code, unknown, } = err; - // exit_code == 0 is non-fatal error, e.g. docopt version info + // `exit_code` of 0 means non-fatal error (e.g., docopt version info). let fatal = exit_code != 0; let hide = unknown && shell.verbosity() != Verbose; @@ -171,7 +124,7 @@ std::process::exit(exit_code) } -pub fn handle_error(err: &CargoError, shell: &mut Shell) { +pub fn handle_error(err: &failure::Error, shell: &mut Shell) { debug!("handle_error; err={:?}", err); let _ignored_result = shell.error(err); @@ -187,14 +140,14 @@ let verbose = shell.verbosity(); if verbose == Verbose { - // The first error has already been printed to the shell - // Print all remaining errors + // The first error has already been printed to the shell. + // Print all remaining errors. for err in cargo_err.iter_causes() { print(&err.to_string(), shell); } } else { - // The first error has already been printed to the shell - // Print remaining errors until one marked as Internal appears + // The first error has already been printed to the shell. + // Print remaining errors until one marked as `Internal` appears. for err in cargo_err.iter_causes() { if err.downcast_ref::().is_some() { return false; diff -Nru cargo-0.33.0/src/cargo/macros.rs cargo-0.35.0/src/cargo/macros.rs --- cargo-0.33.0/src/cargo/macros.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/macros.rs 2019-04-01 21:32:07.000000000 +0000 @@ -11,7 +11,7 @@ ) => ( impl fmt::Debug for $ty { - fn fmt(&$this, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&$this, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Try printing a pretty version where we collapse as many fields as // possible, indicating that they're equivalent to a function call // that's hopefully enough to indicate what each value is without @@ -32,7 +32,7 @@ )* if any_default { - s.field("..", &::macros::DisplayAsDebug(default_name)); + s.field("..", &crate::macros::DisplayAsDebug(default_name)); } s.finish() } @@ -43,7 +43,7 @@ pub struct DisplayAsDebug(pub T); impl fmt::Debug for DisplayAsDebug { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } diff -Nru cargo-0.33.0/src/cargo/ops/cargo_clean.rs cargo-0.35.0/src/cargo/ops/cargo_clean.rs --- cargo-0.33.0/src/cargo/ops/cargo_clean.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_clean.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,13 +2,13 @@ use std::fs; use std::path::Path; -use core::compiler::{BuildConfig, BuildContext, CompileMode, Context, Kind, Unit}; -use core::profiles::UnitFor; -use core::Workspace; -use ops; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::Config; +use crate::core::compiler::{BuildConfig, BuildContext, CompileMode, Context, Kind, Unit}; +use crate::core::profiles::UnitFor; +use crate::core::Workspace; +use crate::ops; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::Config; pub struct CleanOptions<'a> { pub config: &'a Config, @@ -23,7 +23,7 @@ } /// Cleans the package's build artifacts. -pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> { +pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { let mut target_dir = ws.target_dir(); let config = ws.config(); @@ -135,12 +135,13 @@ .shell() .verbose(|shell| shell.status("Removing", path.display()))?; paths::remove_dir_all(path) - .chain_err(|| format_err!("could not remove build directory"))?; + .chain_err(|| failure::format_err!("could not remove build directory"))?; } else if m.is_ok() { config .shell() .verbose(|shell| shell.status("Removing", path.display()))?; - paths::remove_file(path).chain_err(|| format_err!("failed to remove build artifact"))?; + paths::remove_file(path) + .chain_err(|| failure::format_err!("failed to remove build artifact"))?; } Ok(()) } diff -Nru cargo-0.33.0/src/cargo/ops/cargo_compile.rs cargo-0.35.0/src/cargo/ops/cargo_compile.rs --- cargo-0.33.0/src/cargo/ops/cargo_compile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_compile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,40 +1,41 @@ -//! -//! Cargo compile currently does the following steps: +//! Cargo `compile` currently does the following steps. //! //! All configurations are already injected as environment variables via the -//! main cargo command +//! main cargo command. //! -//! 1. Read the manifest +//! 1. Read the manifest. //! 2. Shell out to `cargo-resolve` with a list of dependencies and sources as -//! stdin +//! stdin. //! -//! a. Shell out to `--do update` and `--do list` for each source -//! b. Resolve dependencies and return a list of name/version/source +//! a. Shell out to `--do update` and `--do list` for each source. +//! b. Resolve dependencies and return a list of name/version/source. //! -//! 3. Shell out to `--do download` for each source +//! 3. Shell out to `--do download` for each source. //! 4. Shell out to `--do get` for each source, and build up the list of paths -//! to pass to rustc -L +//! to pass to `rustc -L`. //! 5. Call `cargo-rustc` with the results of the resolver zipped together with -//! the results of the `get` +//! the results of the `get`. //! -//! a. Topologically sort the dependencies +//! a. Topologically sort the dependencies. //! b. Compile each dependency in order, passing in the -L's pointing at each -//! previously compiled dependency -//! +//! previously compiled dependency. -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeSet, HashMap, HashSet}; +use std::iter::FromIterator; use std::path::PathBuf; use std::sync::Arc; -use core::compiler::{BuildConfig, BuildContext, Compilation, Context, DefaultExecutor, Executor}; -use core::compiler::{CompileMode, Kind, Unit}; -use core::profiles::{Profiles, UnitFor}; -use core::resolver::{Method, Resolve}; -use core::{Package, Source, Target}; -use core::{PackageId, PackageIdSpec, TargetKind, Workspace}; -use ops; -use util::config::Config; -use util::{lev_distance, profile, CargoResult}; +use crate::core::compiler::{ + BuildConfig, BuildContext, Compilation, Context, DefaultExecutor, Executor, +}; +use crate::core::compiler::{CompileMode, Kind, Unit}; +use crate::core::profiles::{Profiles, UnitFor}; +use crate::core::resolver::{Method, Resolve}; +use crate::core::{Package, Source, Target}; +use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace}; +use crate::ops; +use crate::util::config::Config; +use crate::util::{lev_distance, profile, CargoResult}; /// Contains information about how a package should be compiled. #[derive(Debug)] @@ -101,29 +102,40 @@ Ok(match (all, exclude.len(), package.len()) { (false, 0, 0) => Packages::Default, (false, 0, _) => Packages::Packages(package), - (false, _, _) => bail!("--exclude can only be used together with --all"), + (false, _, _) => failure::bail!("--exclude can only be used together with --all"), (true, 0, _) => Packages::All, (true, _, _) => Packages::OptOut(exclude), }) } - pub fn to_package_id_specs(&self, ws: &Workspace) -> CargoResult> { - let specs = match *self { + pub fn to_package_id_specs(&self, ws: &Workspace<'_>) -> CargoResult> { + let specs = match self { Packages::All => ws .members() .map(Package::package_id) .map(PackageIdSpec::from_package_id) .collect(), - Packages::OptOut(ref opt_out) => ws - .members() - .map(Package::package_id) - .map(PackageIdSpec::from_package_id) - .filter(|p| opt_out.iter().position(|x| *x == p.name()).is_none()) - .collect(), - Packages::Packages(ref packages) if packages.is_empty() => { + Packages::OptOut(opt_out) => { + let mut opt_out = BTreeSet::from_iter(opt_out.iter().cloned()); + let packages = ws + .members() + .filter(|pkg| !opt_out.remove(pkg.name().as_str())) + .map(Package::package_id) + .map(PackageIdSpec::from_package_id) + .collect(); + if !opt_out.is_empty() { + ws.config().shell().warn(format!( + "excluded package(s) {} not found in workspace `{}`", + opt_out.iter().map(|x| x.as_ref()).collect::>().join(", "), + ws.root().display(), + ))?; + } + packages + }, + Packages::Packages(packages) if packages.is_empty() => { vec![PackageIdSpec::from_package_id(ws.current()?.package_id())] } - Packages::Packages(ref packages) => packages + Packages::Packages(packages) => packages .iter() .map(|p| PackageIdSpec::parse(p)) .collect::>>()?, @@ -135,32 +147,35 @@ }; if specs.is_empty() { if ws.is_virtual() { - bail!( + failure::bail!( "manifest path `{}` contains no package: The manifest is virtual, \ and the workspace has no members.", ws.root().display() ) } - bail!("no packages to compile") + failure::bail!("no packages to compile") } Ok(specs) } - pub fn get_packages<'ws>(&self, ws: &'ws Workspace) -> CargoResult> { + pub fn get_packages<'ws>(&self, ws: &'ws Workspace<'_>) -> CargoResult> { let packages: Vec<_> = match self { Packages::Default => ws.default_members().collect(), Packages::All => ws.members().collect(), - Packages::OptOut(ref opt_out) => ws + Packages::OptOut(opt_out) => ws .members() .filter(|pkg| !opt_out.iter().any(|name| pkg.name().as_str() == name)) .collect(), - Packages::Packages(ref pkgs) => pkgs + Packages::Packages(packages) => packages .iter() .map(|name| { ws.members() .find(|pkg| pkg.name().as_str() == name) .ok_or_else(|| { - format_err!("package `{}` is not a member of the workspace", name) + failure::format_err!( + "package `{}` is not a member of the workspace", + name + ) }) }) .collect::>>()?, @@ -195,7 +210,7 @@ ws: &Workspace<'a>, options: &CompileOptions<'a>, ) -> CargoResult> { - let exec: Arc = Arc::new(DefaultExecutor); + let exec: Arc = Arc::new(DefaultExecutor); compile_with_exec(ws, options, &exec) } @@ -204,7 +219,7 @@ pub fn compile_with_exec<'a>( ws: &Workspace<'a>, options: &CompileOptions<'a>, - exec: &Arc, + exec: &Arc, ) -> CargoResult> { ws.emit_warnings()?; compile_ws(ws, None, options, exec) @@ -212,9 +227,9 @@ pub fn compile_ws<'a>( ws: &Workspace<'a>, - source: Option>, + source: Option>, options: &CompileOptions<'a>, - exec: &Arc, + exec: &Arc, ) -> CargoResult> { let CompileOptions { config, @@ -265,7 +280,7 @@ && !ws.is_member(pkg) && pkg.dependencies().iter().any(|dep| !dep.is_transitive()) { - bail!( + failure::bail!( "package `{}` cannot be tested because it requires dev-dependencies \ and is not a member of the workspace", pkg.name() @@ -302,10 +317,10 @@ let mut extra_compiler_args = HashMap::new(); if let Some(args) = extra_args { if units.len() != 1 { - bail!( + failure::bail!( "extra arguments to `{}` can only be passed to one \ - target, consider filtering\nthe package by passing \ - e.g. `--lib` or `--bin NAME` to specify a single target", + target, consider filtering\nthe package by passing, \ + e.g., `--lib` or `--bin NAME` to specify a single target", extra_args_name ); } @@ -469,7 +484,7 @@ /// A proposed target. /// -/// Proposed targets are later filtered into actual Units based on whether or +/// Proposed targets are later filtered into actual `Unit`s based on whether or /// not the target requires its features to be present. #[derive(Debug)] struct Proposal<'a> { @@ -484,10 +499,9 @@ } /// Generates all the base targets for the packages the user has requested to -/// compile. Dependencies for these targets are computed later in -/// `unit_dependencies`. +/// compile. Dependencies for these targets are computed later in `unit_dependencies`. fn generate_targets<'a>( - ws: &Workspace, + ws: &Workspace<'_>, profiles: &Profiles, packages: &[&'a Package], filter: &CompileFilter, @@ -495,30 +509,30 @@ resolve: &Resolve, build_config: &BuildConfig, ) -> CargoResult>> { - // Helper for creating a Unit struct. + // Helper for creating a `Unit` struct. let new_unit = |pkg: &'a Package, target: &'a Target, target_mode: CompileMode| { let unit_for = if build_config.mode.is_any_test() { - // NOTE: The UnitFor here is subtle. If you have a profile + // NOTE: the `UnitFor` here is subtle. If you have a profile // with `panic` set, the `panic` flag is cleared for - // tests/benchmarks and their dependencies. If this + // tests/benchmarks and their dependencies. If this // was `normal`, then the lib would get compiled three // times (once with panic, once without, and once with - // --test). + // `--test`). // - // This would cause a problem for Doc tests, which would fail + // This would cause a problem for doc tests, which would fail // because `rustdoc` would attempt to link with both libraries // at the same time. Also, it's probably not important (or // even desirable?) for rustdoc to link with a lib with // `panic` set. // // As a consequence, Examples and Binaries get compiled - // without `panic` set. This probably isn't a bad deal. + // without `panic` set. This probably isn't a bad deal. // // Forcing the lib to be compiled three times during `cargo // test` is probably also not desirable. UnitFor::new_test() } else if target.for_host() { - // proc-macro/plugin should not have `panic` set. + // Proc macro / plugin should not have `panic` set. UnitFor::new_compiler() } else { UnitFor::new_normal() @@ -540,18 +554,18 @@ TargetKind::Bench => CompileMode::Bench, _ => CompileMode::Build, }, - // CompileMode::Bench is only used to inform filter_default_targets + // `CompileMode::Bench` is only used to inform `filter_default_targets` // which command is being used (`cargo bench`). Afterwards, tests // and benches are treated identically. Switching the mode allows - // de-duplication of units that are essentially identical. For + // de-duplication of units that are essentially identical. For // example, `cargo build --all-targets --release` creates the units // (lib profile:bench, mode:test) and (lib profile:bench, mode:bench) - // and since these are the same, we want them to be de-duped in + // and since these are the same, we want them to be de-duplicated in // `unit_dependencies`. CompileMode::Bench => CompileMode::Test, _ => target_mode, }; - // Plugins or proc-macro should be built for the host. + // Plugins or proc macros should be built for the host. let kind = if target.for_host() { Kind::Host } else { @@ -574,7 +588,7 @@ }; // Create a list of proposed targets. - let mut proposals: Vec = Vec::new(); + let mut proposals: Vec> = Vec::new(); match *filter { CompileFilter::Default { @@ -614,40 +628,35 @@ } => { if lib { let mut libs = Vec::new(); - for pkg in packages { - for target in pkg.targets().iter().filter(|t| t.is_lib()) { - if build_config.mode == CompileMode::Doctest && !target.doctestable() { - ws.config() - .shell() - .warn(format!( - "doc tests are not supported for crate type(s) `{}` in package `{}`", - target.rustc_crate_types().join(", "), - pkg.name() - ))?; - } else { - libs.push(Proposal { - pkg, - target, - requires_features: false, - mode: build_config.mode, - }); - } + for proposal in filter_targets(packages, Target::is_lib, false, build_config.mode) { + let Proposal { target, pkg, .. } = proposal; + if build_config.mode == CompileMode::Doctest && !target.doctestable() { + ws.config().shell().warn(format!( + "doc tests are not supported for crate type(s) `{}` in package `{}`", + target.rustc_crate_types().join(", "), + pkg.name() + ))?; + } else { + libs.push(proposal) } } if !all_targets && libs.is_empty() { let names = packages.iter().map(|pkg| pkg.name()).collect::>(); if names.len() == 1 { - bail!("no library targets found in package `{}`", names[0]); + failure::bail!("no library targets found in package `{}`", names[0]); } else { - bail!("no library targets found in packages: {}", names.join(", ")); + failure::bail!( + "no library targets found in packages: {}", + names.join(", ") + ); } } proposals.extend(libs); } - // If --tests was specified, add all targets that would be + // If `--tests` was specified, add all targets that would be // generated by `cargo test`. - let test_filter = match *tests { + let test_filter = match tests { FilterRule::All => Target::tested, FilterRule::Just(_) => Target::is_test, }; @@ -656,9 +665,9 @@ CompileMode::Check { .. } => CompileMode::Check { test: true }, _ => build_config.mode, }; - // If --benches was specified, add all targets that would be + // If `--benches` was specified, add all targets that would be // generated by `cargo bench`. - let bench_filter = match *benches { + let bench_filter = match benches { FilterRule::All => Target::benched, FilterRule::Just(_) => Target::is_bench, }; @@ -728,9 +737,9 @@ .iter() .map(|s| format!("`{}`", s)) .collect(); - bail!( + failure::bail!( "target `{}` in package `{}` requires the features: {}\n\ - Consider enabling them by passing e.g. `--features=\"{}\"`", + Consider enabling them by passing, e.g., `--features=\"{}\"`", target.name(), pkg.name(), quoted_required_features.join(", "), @@ -787,10 +796,7 @@ } } -/// Returns a list of targets based on command-line target selection flags. -/// The return value is a list of `(Package, Target, bool, CompileMode)` -/// tuples. The `bool` value indicates whether or not all required features -/// *must* be present. +/// Returns a list of proposed targets based on command-line target selection flags. fn list_rule_targets<'a>( packages: &[&'a Package], rule: &FilterRule, @@ -798,25 +804,14 @@ is_expected_kind: fn(&Target) -> bool, mode: CompileMode, ) -> CargoResult>> { - let mut result = Vec::new(); - match *rule { + let mut proposals = Vec::new(); + match rule { FilterRule::All => { - for pkg in packages { - for target in pkg.targets() { - if is_expected_kind(target) { - result.push(Proposal { - pkg, - target, - requires_features: false, - mode, - }); - } - } - } + proposals.extend(filter_targets(packages, is_expected_kind, false, mode)) } - FilterRule::Just(ref names) => { + FilterRule::Just(names) => { for name in names { - result.extend(find_named_targets( + proposals.extend(find_named_targets( packages, name, target_desc, @@ -826,10 +821,10 @@ } } } - Ok(result) + Ok(proposals) } -/// Find the targets for a specifically named target. +/// Finds the targets for a specifically named target. fn find_named_targets<'a>( packages: &[&'a Package], target_name: &str, @@ -837,20 +832,9 @@ is_expected_kind: fn(&Target) -> bool, mode: CompileMode, ) -> CargoResult>> { - let mut result = Vec::new(); - for pkg in packages { - for target in pkg.targets() { - if target.name() == target_name && is_expected_kind(target) { - result.push(Proposal { - pkg, - target, - requires_features: true, - mode, - }); - } - } - } - if result.is_empty() { + let filter = |t: &Target| t.name() == target_name && is_expected_kind(t); + let proposals = filter_targets(packages, filter, true, mode); + if proposals.is_empty() { let suggestion = packages .iter() .flat_map(|pkg| { @@ -863,14 +847,34 @@ .min_by_key(|t| t.0) .map(|t| t.1); match suggestion { - Some(s) => bail!( + Some(s) => failure::bail!( "no {} target named `{}`\n\nDid you mean `{}`?", target_desc, target_name, s.name() ), - None => bail!("no {} target named `{}`", target_desc, target_name), + None => failure::bail!("no {} target named `{}`", target_desc, target_name), + } + } + Ok(proposals) +} + +fn filter_targets<'a>( + packages: &[&'a Package], + predicate: impl Fn(&Target) -> bool, + requires_features: bool, + mode: CompileMode, +) -> Vec> { + let mut proposals = Vec::new(); + for pkg in packages { + for target in pkg.targets().iter().filter(|t| predicate(t)) { + proposals.push(Proposal { + pkg, + target, + requires_features, + mode, + }); } } - Ok(result) + proposals } diff -Nru cargo-0.33.0/src/cargo/ops/cargo_doc.rs cargo-0.35.0/src/cargo/ops/cargo_doc.rs --- cargo-0.33.0/src/cargo/ops/cargo_doc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_doc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,9 +5,9 @@ use failure::Fail; use opener; -use core::Workspace; -use ops; -use util::CargoResult; +use crate::core::Workspace; +use crate::ops; +use crate::util::CargoResult; /// Strongly typed options for the `cargo doc` command. #[derive(Debug)] @@ -19,7 +19,7 @@ } /// Main method for `cargo doc`. -pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> { +pub fn doc(ws: &Workspace<'_>, options: &DocOptions<'_>) -> CargoResult<()> { let specs = options.compile_opts.spec.to_package_id_specs(ws)?; let resolve = ops::resolve_ws_precisely( ws, @@ -43,7 +43,7 @@ for target in package.targets().iter().filter(|t| t.documented()) { if target.is_lib() { if let Some(prev) = lib_names.insert(target.crate_name(), package) { - bail!( + failure::bail!( "The library `{}` is specified by packages `{}` and \ `{}` but can only be documented once. Consider renaming \ or marking one of the targets as `doc = false`.", @@ -53,7 +53,7 @@ ); } } else if let Some(prev) = bin_names.insert(target.crate_name(), package) { - bail!( + failure::bail!( "The binary `{}` is specified by packages `{}` and \ `{}` but can be documented only once. Consider renaming \ or marking one of the targets as `doc = false`.", @@ -69,7 +69,7 @@ if options.open_result { let name = if pkgs.len() > 1 { - bail!( + failure::bail!( "Passing multiple packages and `open` is not supported.\n\ Please re-run this command with `-p ` where `` \ is one of the following:\n {}", @@ -99,7 +99,7 @@ shell.status("Opening", path.display())?; if let Err(e) = opener::open(&path) { shell.warn(format!("Couldn't open docs: {}", e))?; - for cause in (&e as &Fail).iter_chain() { + for cause in (&e as &dyn Fail).iter_chain() { shell.warn(format!("Caused by:\n {}", cause))?; } } diff -Nru cargo-0.33.0/src/cargo/ops/cargo_fetch.rs cargo-0.35.0/src/cargo/ops/cargo_fetch.rs --- cargo-0.33.0/src/cargo/ops/cargo_fetch.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_fetch.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ -use core::compiler::{BuildConfig, CompileMode, Kind, TargetInfo}; -use core::{PackageSet, Resolve, Workspace}; -use ops; +use crate::core::compiler::{BuildConfig, CompileMode, Kind, TargetInfo}; +use crate::core::{PackageSet, Resolve, Workspace}; +use crate::ops; +use crate::util::CargoResult; +use crate::util::Config; use std::collections::HashSet; -use util::CargoResult; -use util::Config; pub struct FetchOptions<'a> { pub config: &'a Config, diff -Nru cargo-0.33.0/src/cargo/ops/cargo_generate_lockfile.rs cargo-0.35.0/src/cargo/ops/cargo_generate_lockfile.rs --- cargo-0.33.0/src/cargo/ops/cargo_generate_lockfile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_generate_lockfile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,23 +1,25 @@ use std::collections::{BTreeMap, HashSet}; +use log::debug; use termcolor::Color::{self, Cyan, Green, Red}; -use core::registry::PackageRegistry; -use core::resolver::Method; -use core::PackageId; -use core::{Resolve, SourceId, Workspace}; -use ops; -use util::config::Config; -use util::CargoResult; +use crate::core::registry::PackageRegistry; +use crate::core::resolver::Method; +use crate::core::PackageId; +use crate::core::{Resolve, SourceId, Workspace}; +use crate::ops; +use crate::util::config::Config; +use crate::util::CargoResult; pub struct UpdateOptions<'a> { pub config: &'a Config, pub to_update: Vec, pub precise: Option<&'a str>, pub aggressive: bool, + pub dry_run: bool, } -pub fn generate_lockfile(ws: &Workspace) -> CargoResult<()> { +pub fn generate_lockfile(ws: &Workspace<'_>) -> CargoResult<()> { let mut registry = PackageRegistry::new(ws.config())?; let resolve = ops::resolve_with_previous( &mut registry, @@ -33,17 +35,17 @@ Ok(()) } -pub fn update_lockfile(ws: &Workspace, opts: &UpdateOptions) -> CargoResult<()> { +pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoResult<()> { if opts.aggressive && opts.precise.is_some() { - bail!("cannot specify both aggressive and precise simultaneously") + failure::bail!("cannot specify both aggressive and precise simultaneously") } if ws.members().count() == 0 { - bail!("you can't generate a lockfile for an empty workspace.") + failure::bail!("you can't generate a lockfile for an empty workspace.") } if opts.config.cli_unstable().offline { - bail!("you can't update in the offline mode"); + failure::bail!("you can't update in the offline mode"); } let previous_resolve = match ops::load_pkg_lockfile(ws)? { @@ -118,8 +120,13 @@ } } } - - ops::write_pkg_lockfile(ws, &resolve)?; + if opts.dry_run { + opts.config + .shell() + .warn("not updating lockfile due to dry run")?; + } else { + ops::write_pkg_lockfile(ws, &resolve)?; + } return Ok(()); fn fill_with_deps<'a>( @@ -145,15 +152,15 @@ (dep.name().as_str(), dep.source_id()) } - // Removes all package ids in `b` from `a`. Note that this is somewhat - // more complicated because the equality for source ids does not take - // precise versions into account (e.g. git shas), but we want to take + // Removes all package IDs in `b` from `a`. Note that this is somewhat + // more complicated because the equality for source IDs does not take + // precise versions into account (e.g., git shas), but we want to take // that into account here. fn vec_subtract(a: &[PackageId], b: &[PackageId]) -> Vec { a.iter() .filter(|a| { - // If this package id is not found in `b`, then it's definitely - // in the subtracted set + // If this package ID is not found in `b`, then it's definitely + // in the subtracted set. let i = match b.binary_search(a) { Ok(i) => i, Err(..) => return true, @@ -166,7 +173,7 @@ // // Note that we only check this for non-registry sources, // however, as registries contain enough version information in - // the package id to disambiguate + // the package ID to disambiguate. if a.source_id().is_registry() { return false; } @@ -179,7 +186,7 @@ .collect() } - // Map (package name, package source) to (removed versions, added versions). + // Map `(package name, package source)` to `(removed versions, added versions)`. let mut changes = BTreeMap::new(); let empty = (Vec::new(), Vec::new()); for dep in previous_resolve.iter() { diff -Nru cargo-0.33.0/src/cargo/ops/cargo_install.rs cargo-0.35.0/src/cargo/ops/cargo_install.rs --- cargo-0.33.0/src/cargo/ops/cargo_install.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_install.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,42 +1,20 @@ -use std::collections::btree_map::Entry; -use std::collections::{BTreeMap, BTreeSet}; -use std::io::prelude::*; -use std::io::SeekFrom; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::{env, fs}; -use semver::{Version, VersionReq}; use tempfile::Builder as TempFileBuilder; -use toml; -use core::compiler::{DefaultExecutor, Executor}; -use core::package::PackageSet; -use core::source::SourceMap; -use core::{Dependency, Edition, Package, PackageIdSpec, Source, SourceId}; -use core::{PackageId, Workspace}; -use ops::{self, CompileFilter}; -use sources::{GitSource, PathSource, SourceConfigMap}; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::{internal, Config}; -use util::{FileLock, Filesystem}; - -#[derive(Deserialize, Serialize)] -#[serde(untagged)] -enum CrateListing { - V1(CrateListingV1), - Empty(Empty), -} - -#[derive(Deserialize, Serialize)] -#[serde(deny_unknown_fields)] -struct Empty {} - -#[derive(Deserialize, Serialize)] -struct CrateListingV1 { - v1: BTreeMap>, -} +use crate::core::compiler::{DefaultExecutor, Executor}; +use crate::core::{Edition, Package, Source, SourceId}; +use crate::core::{PackageId, Workspace}; +use crate::ops::common_for_install_and_uninstall::*; +use crate::ops::{self, CompileFilter}; +use crate::sources::{GitSource, SourceConfigMap}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::Config; +use crate::util::Filesystem; struct Transaction { bins: Vec, @@ -62,7 +40,7 @@ source_id: SourceId, from_cwd: bool, vers: Option<&str>, - opts: &ops::CompileOptions, + opts: &ops::CompileOptions<'_>, force: bool, ) -> CargoResult<()> { let root = resolve_root(root, opts.config)?; @@ -101,7 +79,7 @@ ) { Ok(()) => succeeded.push(krate), Err(e) => { - ::handle_error(&e, &mut opts.config.shell()); + crate::handle_error(&e, &mut opts.config.shell()); failed.push(krate) } } @@ -144,7 +122,7 @@ } if scheduled_error { - bail!("some crates failed to install"); + failure::bail!("some crates failed to install"); } Ok(()) @@ -152,12 +130,12 @@ fn install_one( root: &Filesystem, - map: &SourceConfigMap, + map: &SourceConfigMap<'_>, krate: Option<&str>, source_id: SourceId, from_cwd: bool, vers: Option<&str>, - opts: &ops::CompileOptions, + opts: &ops::CompileOptions<'_>, force: bool, is_first_install: bool, ) -> CargoResult<()> { @@ -174,26 +152,42 @@ )? } else if source_id.is_path() { let mut src = path_source(source_id, config)?; - src.update().chain_err(|| { - format_err!( - "`{}` is not a crate root; specify a crate to \ - install from crates.io, or use --path or --git to \ - specify an alternate source", + if !src.path().is_dir() { + failure::bail!( + "`{}` is not a directory. \ + --path must point to a directory containing a Cargo.toml file.", src.path().display() ) - })?; + } + if !src.path().join("Cargo.toml").exists() { + if from_cwd { + failure::bail!( + "`{}` is not a crate root; specify a crate to \ + install from crates.io, or use --path or --git to \ + specify an alternate source", + src.path().display() + ); + } else { + failure::bail!( + "`{}` does not contain a Cargo.toml file. \ + --path must point to a directory containing a Cargo.toml file.", + src.path().display() + ) + } + } + src.update()?; select_pkg(src, krate, vers, config, false, &mut |path| { path.read_packages() })? } else { select_pkg( - map.load(source_id)?, + map.load(source_id, &HashSet::new())?, krate, vers, config, is_first_install, &mut |_| { - bail!( + failure::bail!( "must specify a crate to install from \ crates.io, or use --path or --git to \ specify alternate source" @@ -228,19 +222,20 @@ let pkg = ws.current()?; if from_cwd { - match pkg.manifest().edition() { - Edition::Edition2015 => config.shell().warn( + if pkg.manifest().edition() == Edition::Edition2015 { + config.shell().warn( "Using `cargo install` to install the binaries for the \ package in current working directory is deprecated, \ use `cargo install --path .` instead. \ Use `cargo build` if you want to simply build the package.", - )?, - Edition::Edition2018 => bail!( + )? + } else { + failure::bail!( "Using `cargo install` to install the binaries for the \ package in current working directory is no longer supported, \ use `cargo install --path .` instead. \ Use `cargo build` if you want to simply build the package." - ), + ) } }; @@ -256,14 +251,14 @@ check_overwrites(&dst, pkg, &opts.filter, &list, force)?; } - let exec: Arc = Arc::new(DefaultExecutor); + let exec: Arc = Arc::new(DefaultExecutor); let compile = ops::compile_ws(&ws, Some(source), opts, &exec).chain_err(|| { if let Some(td) = td_opt.take() { // preserve the temporary directory, so the user can inspect it td.into_path(); } - format_err!( + failure::format_err!( "failed to compile `{}`, intermediate artifacts can be \ found at `{}`", pkg, @@ -278,12 +273,12 @@ if let Some(s) = name.to_str() { Ok((s, bin.as_ref())) } else { - bail!("Binary `{:?}` name can't be serialized into string", name) + failure::bail!("Binary `{:?}` name can't be serialized into string", name) } }) .collect::>()?; if binaries.is_empty() { - bail!( + failure::bail!( "no binaries are available for install using the selected \ features" ); @@ -297,7 +292,7 @@ fs::create_dir_all(&dst)?; // Copy all binaries to a temporary directory under `dst` first, catching - // some failure modes (e.g. out of space) before touching the existing + // some failure modes (e.g., out of space) before touching the existing // binaries. This directory will get cleaned up via RAII. let staging_dir = TempFileBuilder::new() .prefix("cargo-install") @@ -309,7 +304,7 @@ continue; } fs::copy(src, &dst).chain_err(|| { - format_err!("failed to copy `{}` to `{}`", src.display(), dst.display()) + failure::format_err!("failed to copy `{}` to `{}`", src.display(), dst.display()) })?; } @@ -326,7 +321,7 @@ let dst = dst.join(bin); config.shell().status("Installing", dst.display())?; fs::rename(&src, &dst).chain_err(|| { - format_err!("failed to move `{}` to `{}`", src.display(), dst.display()) + failure::format_err!("failed to move `{}` to `{}`", src.display(), dst.display()) })?; installed.bins.push(dst); } @@ -341,7 +336,11 @@ let dst = dst.join(bin); config.shell().status("Replacing", dst.display())?; fs::rename(&src, &dst).chain_err(|| { - format_err!("failed to move `{}` to `{}`", src.display(), dst.display()) + failure::format_err!( + "failed to move `{}` to `{}`", + src.display(), + dst.display() + ) })?; replaced_names.push(bin); } @@ -353,16 +352,16 @@ // Update records of replaced binaries. for &bin in replaced_names.iter() { if let Some(&Some(ref p)) = duplicates.get(bin) { - if let Some(set) = list.v1.get_mut(p) { + if let Some(set) = list.v1_mut().get_mut(p) { set.remove(bin); } } // Failsafe to force replacing metadata for git packages // https://github.com/rust-lang/cargo/issues/4582 - if let Some(set) = list.v1.remove(&pkg.package_id()) { - list.v1.insert(pkg.package_id(), set); + if let Some(set) = list.v1_mut().remove(&pkg.package_id()) { + list.v1_mut().insert(pkg.package_id(), set); } - list.v1 + list.v1_mut() .entry(pkg.package_id()) .or_insert_with(BTreeSet::new) .insert(bin.to_string()); @@ -370,17 +369,17 @@ // Remove empty metadata lines. let pkgs = list - .v1 + .v1() .iter() .filter_map(|(&p, set)| if set.is_empty() { Some(p) } else { None }) .collect::>(); for p in pkgs.iter() { - list.v1.remove(p); + list.v1_mut().remove(p); } // If installation was successful record newly installed binaries. if result.is_ok() { - list.v1 + list.v1_mut() .entry(pkg.package_id()) .or_insert_with(BTreeSet::new) .extend(to_install.iter().map(|s| s.to_string())); @@ -406,169 +405,6 @@ Ok(()) } -fn path_source<'a>(source_id: SourceId, config: &'a Config) -> CargoResult> { - let path = source_id - .url() - .to_file_path() - .map_err(|()| format_err!("path sources must have a valid path"))?; - Ok(PathSource::new(&path, source_id, config)) -} - -fn select_pkg<'a, T>( - mut source: T, - name: Option<&str>, - vers: Option<&str>, - config: &Config, - needs_update: bool, - list_all: &mut FnMut(&mut T) -> CargoResult>, -) -> CargoResult<(Package, Box)> -where - T: Source + 'a, -{ - if needs_update { - source.update()?; - } - - match name { - Some(name) => { - let vers = match vers { - Some(v) => { - // If the version begins with character <, >, =, ^, ~ parse it as a - // version range, otherwise parse it as a specific version - let first = v - .chars() - .nth(0) - .ok_or_else(|| format_err!("no version provided for the `--vers` flag"))?; - - match first { - '<' | '>' | '=' | '^' | '~' => match v.parse::() { - Ok(v) => Some(v.to_string()), - Err(_) => bail!( - "the `--vers` provided, `{}`, is \ - not a valid semver version requirement\n\n - Please have a look at \ - http://doc.crates.io/specifying-dependencies.html \ - for the correct format", - v - ), - }, - _ => match v.parse::() { - Ok(v) => Some(format!("={}", v)), - Err(_) => { - let mut msg = format!( - "\ - the `--vers` provided, `{}`, is \ - not a valid semver version\n\n\ - historically Cargo treated this \ - as a semver version requirement \ - accidentally\nand will continue \ - to do so, but this behavior \ - will be removed eventually", - v - ); - - // If it is not a valid version but it is a valid version - // requirement, add a note to the warning - if v.parse::().is_ok() { - msg.push_str(&format!( - "\nif you want to specify semver range, \ - add an explicit qualifier, like ^{}", - v - )); - } - config.shell().warn(&msg)?; - Some(v.to_string()) - } - }, - } - } - None => None, - }; - let vers = vers.as_ref().map(|s| &**s); - let vers_spec = if vers.is_none() && source.source_id().is_registry() { - // Avoid pre-release versions from crate.io - // unless explicitly asked for - Some("*") - } else { - vers - }; - let dep = Dependency::parse_no_deprecated(name, vers_spec, source.source_id())?; - let deps = source.query_vec(&dep)?; - let pkgid = match deps.iter().map(|p| p.package_id()).max() { - Some(pkgid) => pkgid, - None => { - let vers_info = vers - .map(|v| format!(" with version `{}`", v)) - .unwrap_or_default(); - bail!( - "could not find `{}` in {}{}", - name, - source.source_id(), - vers_info - ) - } - }; - - let pkg = { - let mut map = SourceMap::new(); - map.insert(Box::new(&mut source)); - PackageSet::new(&[pkgid], map, config)? - .get_one(pkgid)? - .clone() - }; - Ok((pkg, Box::new(source))) - } - None => { - let candidates = list_all(&mut source)?; - let binaries = candidates - .iter() - .filter(|cand| cand.targets().iter().filter(|t| t.is_bin()).count() > 0); - let examples = candidates - .iter() - .filter(|cand| cand.targets().iter().filter(|t| t.is_example()).count() > 0); - let pkg = match one(binaries, |v| multi_err("binaries", v))? { - Some(p) => p, - None => match one(examples, |v| multi_err("examples", v))? { - Some(p) => p, - None => bail!( - "no packages found with binaries or \ - examples" - ), - }, - }; - return Ok((pkg.clone(), Box::new(source))); - - fn multi_err(kind: &str, mut pkgs: Vec<&Package>) -> String { - pkgs.sort_unstable_by_key(|a| a.name()); - format!( - "multiple packages with {} found: {}", - kind, - pkgs.iter() - .map(|p| p.name().as_str()) - .collect::>() - .join(", ") - ) - } - } - } -} - -fn one(mut i: I, f: F) -> CargoResult> -where - I: Iterator, - F: FnOnce(Vec) -> String, -{ - match (i.next(), i.next()) { - (Some(i1), Some(i2)) => { - let mut v = vec![i1, i2]; - v.extend(i); - Err(format_err!("{}", f(v))) - } - (Some(i), None) => Ok(Some(i)), - (None, _) => Ok(None), - } -} - fn check_overwrites( dst: &Path, pkg: &Package, @@ -580,7 +416,7 @@ // get checked during cargo_compile, we only care about the "build // everything" case here if !filter.is_specific() && !pkg.targets().iter().any(|t| t.is_bin()) { - bail!("specified package has no binaries") + failure::bail!("specified package has no binaries") } let duplicates = find_duplicates(dst, pkg, filter, prev); if force || duplicates.is_empty() { @@ -597,7 +433,7 @@ } } msg.push_str("Add --force to overwrite"); - Err(format_err!("{}", msg)) + Err(failure::format_err!("{}", msg)) } fn find_duplicates( @@ -611,7 +447,7 @@ let name = format!("{}{}", name, env::consts::EXE_SUFFIX); if fs::metadata(dst.join(&name)).is_err() { None - } else if let Some((&p, _)) = prev.v1.iter().find(|&(_, v)| v.contains(&name)) { + } else if let Some((&p, _)) = prev.v1().iter().find(|&(_, v)| v.contains(&name)) { Some((name, Some(p))) } else { Some((name, None)) @@ -653,51 +489,11 @@ } } -fn read_crate_list(file: &FileLock) -> CargoResult { - let listing = (|| -> CargoResult<_> { - let mut contents = String::new(); - file.file().read_to_string(&mut contents)?; - let listing = - toml::from_str(&contents).chain_err(|| internal("invalid TOML found for metadata"))?; - match listing { - CrateListing::V1(v1) => Ok(v1), - CrateListing::Empty(_) => Ok(CrateListingV1 { - v1: BTreeMap::new(), - }), - } - })() - .chain_err(|| { - format_err!( - "failed to parse crate metadata at `{}`", - file.path().to_string_lossy() - ) - })?; - Ok(listing) -} - -fn write_crate_list(file: &FileLock, listing: CrateListingV1) -> CargoResult<()> { - (|| -> CargoResult<_> { - let mut file = file.file(); - file.seek(SeekFrom::Start(0))?; - file.set_len(0)?; - let data = toml::to_string(&CrateListing::V1(listing))?; - file.write_all(data.as_bytes())?; - Ok(()) - })() - .chain_err(|| { - format_err!( - "failed to write crate metadata at `{}`", - file.path().to_string_lossy() - ) - })?; - Ok(()) -} - pub fn install_list(dst: Option<&str>, config: &Config) -> CargoResult<()> { let dst = resolve_root(dst, config)?; let dst = metadata(config, &dst)?; let list = read_crate_list(&dst)?; - for (k, v) in list.v1.iter() { + for (k, v) in list.v1().iter() { println!("{}:", k); for bin in v { println!(" {}", bin); @@ -705,163 +501,3 @@ } Ok(()) } - -pub fn uninstall( - root: Option<&str>, - specs: Vec<&str>, - bins: &[String], - config: &Config, -) -> CargoResult<()> { - if specs.len() > 1 && !bins.is_empty() { - bail!("A binary can only be associated with a single installed package, specifying multiple specs with --bin is redundant."); - } - - let root = resolve_root(root, config)?; - let scheduled_error = if specs.len() == 1 { - uninstall_one(&root, specs[0], bins, config)?; - false - } else if specs.is_empty() { - uninstall_cwd(&root, bins, config)?; - false - } else { - let mut succeeded = vec![]; - let mut failed = vec![]; - for spec in specs { - let root = root.clone(); - match uninstall_one(&root, spec, bins, config) { - Ok(()) => succeeded.push(spec), - Err(e) => { - ::handle_error(&e, &mut config.shell()); - failed.push(spec) - } - } - } - - let mut summary = vec![]; - if !succeeded.is_empty() { - summary.push(format!( - "Successfully uninstalled {}!", - succeeded.join(", ") - )); - } - if !failed.is_empty() { - summary.push(format!( - "Failed to uninstall {} (see error(s) above).", - failed.join(", ") - )); - } - - if !succeeded.is_empty() || !failed.is_empty() { - config.shell().status("Summary", summary.join(" "))?; - } - - !failed.is_empty() - }; - - if scheduled_error { - bail!("some packages failed to uninstall"); - } - - Ok(()) -} - -pub fn uninstall_one( - root: &Filesystem, - spec: &str, - bins: &[String], - config: &Config, -) -> CargoResult<()> { - let crate_metadata = metadata(config, root)?; - let metadata = read_crate_list(&crate_metadata)?; - let pkgid = PackageIdSpec::query_str(spec, metadata.v1.keys().cloned())?; - uninstall_pkgid(&crate_metadata, metadata, pkgid, bins, config) -} - -fn uninstall_cwd(root: &Filesystem, bins: &[String], config: &Config) -> CargoResult<()> { - let crate_metadata = metadata(config, root)?; - let metadata = read_crate_list(&crate_metadata)?; - let source_id = SourceId::for_path(config.cwd())?; - let src = path_source(source_id, config)?; - let (pkg, _source) = select_pkg(src, None, None, config, true, &mut |path| { - path.read_packages() - })?; - let pkgid = pkg.package_id(); - uninstall_pkgid(&crate_metadata, metadata, pkgid, bins, config) -} - -fn uninstall_pkgid( - crate_metadata: &FileLock, - mut metadata: CrateListingV1, - pkgid: PackageId, - bins: &[String], - config: &Config, -) -> CargoResult<()> { - let mut to_remove = Vec::new(); - { - let mut installed = match metadata.v1.entry(pkgid) { - Entry::Occupied(e) => e, - Entry::Vacant(..) => bail!("package `{}` is not installed", pkgid), - }; - let dst = crate_metadata.parent().join("bin"); - for bin in installed.get() { - let bin = dst.join(bin); - if fs::metadata(&bin).is_err() { - bail!( - "corrupt metadata, `{}` does not exist when it should", - bin.display() - ) - } - } - - let bins = bins - .iter() - .map(|s| { - if s.ends_with(env::consts::EXE_SUFFIX) { - s.to_string() - } else { - format!("{}{}", s, env::consts::EXE_SUFFIX) - } - }) - .collect::>(); - - for bin in bins.iter() { - if !installed.get().contains(bin) { - bail!("binary `{}` not installed as part of `{}`", bin, pkgid) - } - } - - if bins.is_empty() { - to_remove.extend(installed.get().iter().map(|b| dst.join(b))); - installed.get_mut().clear(); - } else { - for bin in bins.iter() { - to_remove.push(dst.join(bin)); - installed.get_mut().remove(bin); - } - } - if installed.get().is_empty() { - installed.remove(); - } - } - write_crate_list(&crate_metadata, metadata)?; - for bin in to_remove { - config.shell().status("Removing", bin.display())?; - paths::remove_file(bin)?; - } - - Ok(()) -} - -fn metadata(config: &Config, root: &Filesystem) -> CargoResult { - root.open_rw(Path::new(".crates.toml"), config, "crate metadata") -} - -fn resolve_root(flag: Option<&str>, config: &Config) -> CargoResult { - let config_root = config.get_path("install.root")?; - Ok(flag - .map(PathBuf::from) - .or_else(|| env::var_os("CARGO_INSTALL_ROOT").map(PathBuf::from)) - .or_else(move || config_root.map(|v| v.val)) - .map(Filesystem::new) - .unwrap_or_else(|| config.home().clone())) -} diff -Nru cargo-0.33.0/src/cargo/ops/cargo_new.rs cargo-0.35.0/src/cargo/ops/cargo_new.rs --- cargo-0.33.0/src/cargo/ops/cargo_new.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_new.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,15 +2,16 @@ use std::env; use std::fmt; use std::fs; +use std::io::{BufRead, BufReader, ErrorKind}; use std::path::{Path, PathBuf}; use git2::Config as GitConfig; use git2::Repository as GitRepository; -use core::{compiler, Workspace}; -use util::errors::{CargoResult, CargoResultExt}; -use util::{existing_vcs_repo, internal, FossilRepo, GitRepo, HgRepo, PijulRepo}; -use util::{paths, Config}; +use crate::core::{compiler, Workspace}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{existing_vcs_repo, internal, FossilRepo, GitRepo, HgRepo, PijulRepo}; +use crate::util::{paths, validate_package_name, Config}; use toml; @@ -47,7 +48,7 @@ } impl fmt::Display for NewProjectKind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { NewProjectKind::Bin => "binary (application)", NewProjectKind::Lib => "library", @@ -83,7 +84,7 @@ registry: Option, ) -> CargoResult { let kind = match (bin, lib) { - (true, true) => bail!("can't specify both lib and binary outputs"), + (true, true) => failure::bail!("can't specify both lib and binary outputs"), (false, true) => NewProjectKind::Lib, // default to bin (_, false) => NewProjectKind::Bin, @@ -113,14 +114,14 @@ } let file_name = path.file_name().ok_or_else(|| { - format_err!( + failure::format_err!( "cannot auto-detect package name from path {:?} ; use --name to override", path.as_os_str() ) })?; file_name.to_str().ok_or_else(|| { - format_err!( + failure::format_err!( "cannot create package with a non-unicode name: {:?}", file_name ) @@ -145,7 +146,7 @@ "true", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", ]; if blacklist.contains(&name) || (opts.kind.is_bin() && compiler::is_bad_artifact_name(name)) { - bail!( + failure::bail!( "The name `{}` cannot be used as a crate name{}", name, name_help @@ -154,27 +155,14 @@ if let Some(ref c) = name.chars().nth(0) { if c.is_digit(10) { - bail!( + failure::bail!( "Package names starting with a digit cannot be used as a crate name{}", name_help ) } } - for c in name.chars() { - if c.is_alphanumeric() { - continue; - } - if c == '_' || c == '-' { - continue; - } - bail!( - "Invalid character `{}` in crate name: `{}`{}", - c, - name, - name_help - ) - } + validate_package_name(name, "crate name", name_help)?; Ok(()) } @@ -267,7 +255,7 @@ for i in detected_files { if i.bin { if let Some(x) = BTreeMap::get::(&duplicates_checker, i.target_name.as_ref()) { - bail!( + failure::bail!( "\ multiple possible binary sources found: {} @@ -280,7 +268,7 @@ duplicates_checker.insert(i.target_name.as_ref(), i); } else { if let Some(plp) = previous_lib_relpath { - bail!( + failure::bail!( "cannot have a package with \ multiple libraries, \ found both `{}` and `{}`", @@ -314,7 +302,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> { let path = &opts.path; if fs::metadata(path).is_ok() { - bail!( + failure::bail!( "destination `{}` already exists\n\n\ Use `cargo init` to initialize the directory", path.display() @@ -335,7 +323,7 @@ }; mk(config, &mkopts).chain_err(|| { - format_err!( + failure::format_err!( "Failed to create package `{}` at `{}`", name, path.display() @@ -348,7 +336,7 @@ let path = &opts.path; if fs::metadata(&path.join("Cargo.toml")).is_ok() { - bail!("`cargo init` cannot be run on existing Cargo packages") + failure::bail!("`cargo init` cannot be run on existing Cargo packages") } let name = get_name(path, opts)?; @@ -394,7 +382,7 @@ // if none exists, maybe create git, like in `cargo new` if num_detected_vsces > 1 { - bail!( + failure::bail!( "more than one of .hg, .git, .pijul, .fossil configurations \ found and the ignore file can't be filled in as \ a result. specify --vcs to override detection" @@ -413,7 +401,7 @@ }; mk(config, &mkopts).chain_err(|| { - format_err!( + failure::format_err!( "Failed to create package `{}` at `{}`", name, path.display() @@ -422,69 +410,116 @@ Ok(()) } -fn mk(config: &Config, opts: &MkOptions) -> CargoResult<()> { - let path = opts.path; - let name = opts.name; - let cfg = global_config(config)?; - // Please ensure that ignore and hgignore are in sync. - let ignore = [ - "/target\n", - "**/*.rs.bk\n", - if !opts.bin { "Cargo.lock\n" } else { "" }, - ] - .concat(); - // Mercurial glob ignores can't be rooted, so just sticking a 'syntax: glob' at the top of the - // file will exclude too much. Instead, use regexp-based ignores. See 'hg help ignore' for - // more. - let hgignore = [ - "^target/\n", - "glob:*.rs.bk\n", - if !opts.bin { "glob:Cargo.lock\n" } else { "" }, - ] - .concat(); +/// IgnoreList +struct IgnoreList { + /// git like formatted entries + ignore: Vec, + /// mercurial formatted entries + hg_ignore: Vec, +} + +impl IgnoreList { + /// constructor to build a new ignore file + fn new() -> IgnoreList { + IgnoreList { + ignore: Vec::new(), + hg_ignore: Vec::new(), + } + } - let vcs = opts.version_control.unwrap_or_else(|| { - let in_existing_vcs = existing_vcs_repo(path.parent().unwrap_or(path), config.cwd()); - match (cfg.version_control, in_existing_vcs) { - (None, false) => VersionControl::Git, - (Some(opt), false) => opt, - (_, true) => VersionControl::NoVcs, + /// add a new entry to the ignore list. Requires two arguments with the + /// entry in two different formats. One for "git style" entries and one for + /// "mercurial like" entries. + fn push(&mut self, ignore: &str, hg_ignore: &str) { + self.ignore.push(ignore.to_string()); + self.hg_ignore.push(hg_ignore.to_string()); + } + + /// Return the correctly formatted content of the ignore file for the given + /// version control system as `String`. + fn format_new(&self, vcs: VersionControl) -> String { + match vcs { + VersionControl::Hg => self.hg_ignore.join("\n"), + _ => self.ignore.join("\n"), } - }); + } + + /// format_existing is used to format the IgnoreList when the ignore file + /// already exists. It reads the contents of the given `BufRead` and + /// checks if the contents of the ignore list are already existing in the + /// file. + fn format_existing(&self, existing: T, vcs: VersionControl) -> String { + // TODO: is unwrap safe? + let existing_items = existing.lines().collect::, _>>().unwrap(); + + let ignore_items = match vcs { + VersionControl::Hg => &self.hg_ignore, + _ => &self.ignore, + }; + + let mut out = "\n\n#Added by cargo\n\ + #\n\ + #already existing elements are commented out\n" + .to_string(); + + for item in ignore_items { + out.push('\n'); + if existing_items.contains(item) { + out.push('#'); + } + out.push_str(item) + } + + out + } +} + +/// Writes the ignore file to the given directory. If the ignore file for the +/// given vcs system already exists, its content is read and duplicate ignore +/// file entries are filtered out. +fn write_ignore_file( + base_path: &Path, + list: &IgnoreList, + vcs: VersionControl, +) -> CargoResult { + let fp_ignore = match vcs { + VersionControl::Git => base_path.join(".gitignore"), + VersionControl::Hg => base_path.join(".hgignore"), + VersionControl::Pijul => base_path.join(".ignore"), + VersionControl::Fossil => return Ok("".to_string()), + VersionControl::NoVcs => return Ok("".to_string()), + }; + + let ignore: String = match fs::File::open(&fp_ignore) { + Err(why) => match why.kind() { + ErrorKind::NotFound => list.format_new(vcs), + _ => return Err(failure::format_err!("{}", why)), + }, + Ok(file) => list.format_existing(BufReader::new(file), vcs), + }; + + paths::append(&fp_ignore, ignore.as_bytes())?; + Ok(ignore) +} + +/// Initializes the correct VCS system based on the provided config. +fn init_vcs(path: &Path, vcs: VersionControl, config: &Config) -> CargoResult<()> { match vcs { VersionControl::Git => { if !path.join(".git").exists() { GitRepo::init(path, config.cwd())?; } - let ignore = if path.join(".gitignore").exists() { - format!("\n{}", ignore) - } else { - ignore - }; - paths::append(&path.join(".gitignore"), ignore.as_bytes())?; } VersionControl::Hg => { if !path.join(".hg").exists() { HgRepo::init(path, config.cwd())?; } - let hgignore = if path.join(".hgignore").exists() { - format!("\n{}", hgignore) - } else { - hgignore - }; - paths::append(&path.join(".hgignore"), hgignore.as_bytes())?; } VersionControl::Pijul => { if !path.join(".pijul").exists() { PijulRepo::init(path, config.cwd())?; } - let ignore = if path.join(".ignore").exists() { - format!("\n{}", ignore) - } else { - ignore - }; - paths::append(&path.join(".ignore"), ignore.as_bytes())?; } VersionControl::Fossil => { if path.join(".fossil").exists() { @@ -496,8 +531,36 @@ } }; + Ok(()) +} + +fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> { + let path = opts.path; + let name = opts.name; + let cfg = global_config(config)?; + + // Using the push method with two arguments ensures that the entries for + // both `ignore` and `hgignore` are in sync. + let mut ignore = IgnoreList::new(); + ignore.push("/target", "^target/"); + ignore.push("**/*.rs.bk", "glob:*.rs.bk\n"); + if !opts.bin { + ignore.push("Cargo.lock", "glob:Cargo.lock"); + } + + let vcs = opts.version_control.unwrap_or_else(|| { + let in_existing_vcs = existing_vcs_repo(path.parent().unwrap_or(path), config.cwd()); + match (cfg.version_control, in_existing_vcs) { + (None, false) => VersionControl::Git, + (Some(opt), false) => opt, + (_, true) => VersionControl::NoVcs, + } + }); + + init_vcs(path, vcs, config)?; + write_ignore_file(path, &ignore, vcs)?; + let (author_name, email) = discover_author()?; - // Hoo boy, sure glad we've got exhaustiveness checking behind us. let author = match (cfg.name, cfg.email, author_name, email) { (Some(name), Some(email), _, _) | (Some(name), None, _, Some(email)) @@ -508,7 +571,7 @@ let mut cargotoml_path_specifier = String::new(); - // Calculate what [lib] and [[bin]]s do we need to append to Cargo.toml + // Calculate what `[lib]` and `[[bin]]`s we need to append to `Cargo.toml`. for i in &opts.source_files { if i.bin { @@ -536,7 +599,7 @@ } } - // Create Cargo.toml file with necessary [lib] and [[bin]] sections, if needed + // Create `Cargo.toml` file with necessary `[lib]` and `[[bin]]` sections, if needed. paths::write( &path.join("Cargo.toml"), @@ -567,9 +630,7 @@ .as_bytes(), )?; - // Create all specified source files - // (with respective parent directories) - // if they are don't exist + // Create all specified source files (with respective parent directories) if they don't exist. for i in &opts.source_files { let path_of_source_file = path.join(i.relative_path.clone()); @@ -646,7 +707,7 @@ Some(name) => name, None => { let username_var = if cfg!(windows) { "USERNAME" } else { "USER" }; - bail!( + failure::bail!( "could not determine the current user, please set ${}", username_var ) @@ -694,7 +755,7 @@ `cargo-new.vcs`, unknown vcs `{}` \ (found in {})", s, p - ))) + ))); } None => None, }; diff -Nru cargo-0.33.0/src/cargo/ops/cargo_output_metadata.rs cargo-0.35.0/src/cargo/ops/cargo_output_metadata.rs --- cargo-0.33.0/src/cargo/ops/cargo_output_metadata.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_output_metadata.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,13 @@ use std::collections::HashMap; +use std::path::PathBuf; use serde::ser; +use serde::Serialize; -use core::resolver::Resolve; -use core::{Package, PackageId, Workspace}; -use ops::{self, Packages}; -use util::CargoResult; +use crate::core::resolver::Resolve; +use crate::core::{Package, PackageId, Workspace}; +use crate::ops::{self, Packages}; +use crate::util::CargoResult; const VERSION: u32 = 1; @@ -20,9 +22,9 @@ /// Loads the manifest, resolves the dependencies of the package to the concrete /// used versions - considering overrides - and writes all dependencies in a JSON /// format to stdout. -pub fn output_metadata(ws: &Workspace, opt: &OutputMetadataOptions) -> CargoResult { +pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> CargoResult { if opt.version != VERSION { - bail!( + failure::bail!( "metadata version {} not supported, only {} is currently supported", opt.version, VERSION @@ -35,18 +37,18 @@ } } -fn metadata_no_deps(ws: &Workspace, _opt: &OutputMetadataOptions) -> CargoResult { +fn metadata_no_deps(ws: &Workspace<'_>, _opt: &OutputMetadataOptions) -> CargoResult { Ok(ExportInfo { packages: ws.members().cloned().collect(), workspace_members: ws.members().map(|pkg| pkg.package_id()).collect(), resolve: None, - target_directory: ws.target_dir().display().to_string(), + target_directory: ws.target_dir().clone().into_path_unlocked(), version: VERSION, - workspace_root: ws.root().display().to_string(), + workspace_root: ws.root().to_path_buf(), }) } -fn metadata_full(ws: &Workspace, opt: &OutputMetadataOptions) -> CargoResult { +fn metadata_full(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> CargoResult { let specs = Packages::All.to_package_id_specs(ws)?; let (package_set, resolve) = ops::resolve_ws_precisely( ws, @@ -68,9 +70,9 @@ resolve: (packages, resolve), root: ws.current_opt().map(|pkg| pkg.package_id()), }), - target_directory: ws.target_dir().display().to_string(), + target_directory: ws.target_dir().clone().into_path_unlocked(), version: VERSION, - workspace_root: ws.root().display().to_string(), + workspace_root: ws.root().to_path_buf(), }) } @@ -79,13 +81,13 @@ packages: Vec, workspace_members: Vec, resolve: Option, - target_directory: String, + target_directory: PathBuf, version: u32, - workspace_root: String, + workspace_root: PathBuf, } /// Newtype wrapper to provide a custom `Serialize` implementation. -/// The one from lockfile does not fit because it uses a non-standard +/// The one from lock file does not fit because it uses a non-standard /// format for `PackageId`s #[derive(Serialize)] struct MetadataResolve { diff -Nru cargo-0.33.0/src/cargo/ops/cargo_package.rs cargo-0.35.0/src/cargo/ops/cargo_package.rs --- cargo-0.33.0/src/cargo/ops/cargo_package.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_package.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,17 +6,17 @@ use flate2::read::GzDecoder; use flate2::{Compression, GzBuilder}; -use git2; -use serde_json; +use log::debug; +use serde_json::{self, json}; use tar::{Archive, Builder, EntryType, Header}; -use core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor}; -use core::{Package, Source, SourceId, Workspace}; -use ops; -use sources::PathSource; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::{self, internal, Config, FileLock}; +use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor}; +use crate::core::{Package, Source, SourceId, Workspace}; +use crate::ops; +use crate::sources::PathSource; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::{self, internal, Config, FileLock}; pub struct PackageOpts<'cfg> { pub config: &'cfg Config, @@ -26,12 +26,14 @@ pub verify: bool, pub jobs: Option, pub target: Option, - pub registry: Option, + pub features: Vec, + pub all_features: bool, + pub no_default_features: bool, } static VCS_INFO_FILE: &'static str = ".cargo_vcs_info.json"; -pub fn package(ws: &Workspace, opts: &PackageOpts) -> CargoResult> { +pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult> { ops::resolve_ws(ws)?; let pkg = ws.current()?; let config = ws.config(); @@ -67,7 +69,7 @@ let mut list: Vec<_> = src .list_files(pkg)? .iter() - .map(|file| util::without_prefix(file, root).unwrap().to_path_buf()) + .map(|file| file.strip_prefix(root).unwrap().to_path_buf()) .collect(); if include_lockfile(pkg) { list.push("Cargo.lock".into()); @@ -98,7 +100,7 @@ .status("Packaging", pkg.package_id().to_string())?; dst.file().set_len(0)?; tar(ws, &src_files, vcs_info.as_ref(), dst.file(), &filename) - .chain_err(|| format_err!("failed to prepare local package for uploading"))?; + .chain_err(|| failure::format_err!("failed to prepare local package for uploading"))?; if opts.verify { dst.seek(SeekFrom::Start(0))?; run_verify(ws, &dst, opts).chain_err(|| "failed to verify package tarball")? @@ -117,7 +119,7 @@ pkg.manifest().publish_lockfile() && pkg.targets().iter().any(|t| t.is_example() || t.is_bin()) } -// check that the package has some piece of metadata that a human can +// Checks that the package has some piece of metadata that a human can // use to tell what the package is about. fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> { let md = pkg.manifest().metadata(); @@ -141,7 +143,7 @@ if !missing.is_empty() { let mut things = missing[..missing.len() - 1].join(", "); - // things will be empty if and only if length == 1 (i.e. the only case + // `things` will be empty if and only if its length is 1 (i.e., the only case // to have no `or`). if !things.is_empty() { things.push_str(" or "); @@ -150,18 +152,18 @@ config.shell().warn(&format!( "manifest has no {things}.\n\ - See http://doc.crates.io/manifest.html#package-metadata for more info.", + See for more info.", things = things ))? } Ok(()) } -// check that the package dependencies are safe to deploy. +// Checks that the package dependencies are safe to deploy. fn verify_dependencies(pkg: &Package) -> CargoResult<()> { for dep in pkg.dependencies() { if dep.source_id().is_path() && !dep.specified_req() { - bail!( + failure::bail!( "all path dependencies must have a version specified \ when packaging.\ndependency `{}` does not specify \ a version.", @@ -172,8 +174,8 @@ Ok(()) } -// Check if the package source is in a *git* DVCS repository. If *git*, and -// the source is *dirty* (e.g. has uncommited changes) and not `allow_dirty` +// Checks if the package source is in a *git* DVCS repository. If *git*, and +// the source is *dirty* (e.g., has uncommited changes) and not `allow_dirty` // then `bail!` with an informative message. Otherwise return the sha1 hash of // the current *HEAD* commit, or `None` if *dirty*. fn check_repo_state( @@ -210,8 +212,8 @@ })?; } - // No VCS with a checked in Cargo.toml found. so we don't know if the - // directory is dirty or not, so we have to assume that it's clean. + // No VCS with a checked in `Cargo.toml` found, so we don't know if the + // directory is dirty or not, thus we have to assume that it's clean. return Ok(None); fn git( @@ -243,7 +245,7 @@ Ok(Some(rev_obj.id().to_string())) } else { if !allow_dirty { - bail!( + failure::bail!( "{} files in the working directory contain changes that were \ not yet committed into git:\n\n{}\n\n\ to proceed despite this, pass the `--allow-dirty` flag", @@ -256,17 +258,16 @@ } } -// Check for and `bail!` if a source file matches ROOT/VCS_INFO_FILE, since -// this is now a cargo reserved file name, and we don't want to allow -// forgery. +// Checks for and `bail!` if a source file matches `ROOT/VCS_INFO_FILE`, since +// this is now a Cargo reserved file name, and we don't want to allow forgery. fn check_vcs_file_collision(pkg: &Package, src_files: &[PathBuf]) -> CargoResult<()> { let root = pkg.root(); let vcs_info_path = Path::new(VCS_INFO_FILE); let collision = src_files .iter() - .find(|&p| util::without_prefix(&p, root).unwrap() == vcs_info_path); + .find(|&p| p.strip_prefix(root).unwrap() == vcs_info_path); if collision.is_some() { - bail!( + failure::bail!( "Invalid inclusion of reserved file name \ {} in package source", VCS_INFO_FILE @@ -276,28 +277,28 @@ } fn tar( - ws: &Workspace, + ws: &Workspace<'_>, src_files: &[PathBuf], vcs_info: Option<&serde_json::Value>, dst: &File, filename: &str, ) -> CargoResult<()> { - // Prepare the encoder and its header + // Prepare the encoder and its header. let filename = Path::new(filename); let encoder = GzBuilder::new() .filename(util::path2bytes(filename)?) .write(dst, Compression::best()); - // Put all package files into a compressed archive + // Put all package files into a compressed archive. let mut ar = Builder::new(encoder); let pkg = ws.current()?; let config = ws.config(); let root = pkg.root(); for file in src_files.iter() { - let relative = util::without_prefix(file, root).unwrap(); + let relative = file.strip_prefix(root)?; check_filename(relative)?; let relative = relative.to_str().ok_or_else(|| { - format_err!("non-utf8 path in source directory: {}", relative.display()) + failure::format_err!("non-utf8 path in source directory: {}", relative.display()) })?; config .shell() @@ -310,7 +311,7 @@ relative ); - // The tar::Builder type by default will build GNU archives, but + // The `tar::Builder` type by default will build GNU archives, but // unfortunately we force it here to use UStar archives instead. The // UStar format has more limitations on the length of path name that it // can encode, so it's not quite as nice to use. @@ -327,7 +328,7 @@ // // For an instance of this in the wild, use the tar-rs 0.3.3 library to // unpack the selectors 0.4.0 crate on crates.io. Either that or take a - // look at rust-lang/cargo#2326 + // look at rust-lang/cargo#2326. let mut header = Header::new_ustar(); header .set_path(&path) @@ -414,7 +415,7 @@ Ok(()) } -fn run_verify(ws: &Workspace, tar: &FileLock, opts: &PackageOpts) -> CargoResult<()> { +fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> CargoResult<()> { let config = ws.config(); let pkg = ws.current()?; @@ -441,16 +442,16 @@ let pkg_fingerprint = src.last_modified_file(&new_pkg)?; let ws = Workspace::ephemeral(new_pkg, config, None, true)?; - let exec: Arc = Arc::new(DefaultExecutor); + let exec: Arc = Arc::new(DefaultExecutor); ops::compile_ws( &ws, None, &ops::CompileOptions { config, build_config: BuildConfig::new(config, opts.jobs, &opts.target, CompileMode::Build)?, - features: Vec::new(), - no_default_features: false, - all_features: false, + features: opts.features.clone(), + no_default_features: opts.no_default_features, + all_features: opts.all_features, spec: ops::Packages::Packages(Vec::new()), filter: ops::CompileFilter::Default { required_features_filterable: true, @@ -463,11 +464,11 @@ &exec, )?; - // Check that build.rs didn't modify any files in the src directory. + // Check that `build.rs` didn't modify any files in the `src` directory. let ws_fingerprint = src.last_modified_file(ws.current()?)?; if pkg_fingerprint != ws_fingerprint { let (_, path) = ws_fingerprint; - bail!( + failure::bail!( "Source directory was modified by build.rs during cargo publish. \ Build scripts should not modify anything outside of OUT_DIR. \ Modified file: {}\n\n\ @@ -492,7 +493,7 @@ }; let name = match name.to_str() { Some(name) => name, - None => bail!( + None => failure::bail!( "path does not have a unicode filename which may not unpack \ on all platforms: {}", file.display() @@ -500,7 +501,7 @@ }; let bad_chars = ['/', '\\', '<', '>', ':', '"', '|', '?', '*']; if let Some(c) = bad_chars.iter().find(|c| name.contains(**c)) { - bail!( + failure::bail!( "cannot package a filename with a special character `{}`: {}", c, file.display() diff -Nru cargo-0.33.0/src/cargo/ops/cargo_pkgid.rs cargo-0.35.0/src/cargo/ops/cargo_pkgid.rs --- cargo-0.33.0/src/cargo/ops/cargo_pkgid.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_pkgid.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,11 @@ -use core::{PackageIdSpec, Workspace}; -use ops; -use util::CargoResult; +use crate::core::{PackageIdSpec, Workspace}; +use crate::ops; +use crate::util::CargoResult; -pub fn pkgid(ws: &Workspace, spec: Option<&str>) -> CargoResult { +pub fn pkgid(ws: &Workspace<'_>, spec: Option<&str>) -> CargoResult { let resolve = match ops::load_pkg_lockfile(ws)? { Some(resolve) => resolve, - None => bail!("a Cargo.lock must exist for this command"), + None => failure::bail!("a Cargo.lock must exist for this command"), }; let pkgid = match spec { diff -Nru cargo-0.33.0/src/cargo/ops/cargo_read_manifest.rs cargo-0.35.0/src/cargo/ops/cargo_read_manifest.rs --- cargo-0.33.0/src/cargo/ops/cargo_read_manifest.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_read_manifest.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,11 +3,13 @@ use std::io; use std::path::{Path, PathBuf}; -use core::{EitherManifest, Package, PackageId, SourceId}; -use util::errors::{CargoError, CargoResult}; -use util::important_paths::find_project_manifest_exact; -use util::toml::read_manifest; -use util::{self, Config}; +use log::{info, trace}; + +use crate::core::{EitherManifest, Package, PackageId, SourceId}; +use crate::util::errors::CargoResult; +use crate::util::important_paths::find_project_manifest_exact; +use crate::util::toml::read_manifest; +use crate::util::{self, Config}; pub fn read_package( path: &Path, @@ -22,7 +24,7 @@ let (manifest, nested) = read_manifest(path, source_id, config)?; let manifest = match manifest { EitherManifest::Real(manifest) => manifest, - EitherManifest::Virtual(..) => bail!( + EitherManifest::Virtual(..) => failure::bail!( "found a virtual manifest at `{}` instead of a package \ manifest", path.display() @@ -39,7 +41,7 @@ ) -> CargoResult> { let mut all_packages = HashMap::new(); let mut visited = HashSet::::new(); - let mut errors = Vec::::new(); + let mut errors = Vec::::new(); trace!( "looking for root package: {}, source_id={}", @@ -86,7 +88,7 @@ if all_packages.is_empty() { match errors.pop() { Some(err) => Err(err), - None => Err(format_err!( + None => Err(failure::format_err!( "Could not find Cargo.toml in `{}`", path.display() )), @@ -96,7 +98,7 @@ } } -fn walk(path: &Path, callback: &mut FnMut(&Path) -> CargoResult) -> CargoResult<()> { +fn walk(path: &Path, callback: &mut dyn FnMut(&Path) -> CargoResult) -> CargoResult<()> { if !callback(path)? { trace!("not processing {}", path.display()); return Ok(()); @@ -109,7 +111,7 @@ Err(ref e) if e.kind() == io::ErrorKind::PermissionDenied => return Ok(()), Err(e) => { let cx = format!("failed to read directory `{}`", path.display()); - let e = CargoError::from(e); + let e = failure::Error::from(e); return Err(e.context(cx).into()); } }; @@ -132,7 +134,7 @@ source_id: SourceId, config: &Config, visited: &mut HashSet, - errors: &mut Vec, + errors: &mut Vec, ) -> CargoResult<()> { if !visited.insert(path.to_path_buf()) { return Ok(()); diff -Nru cargo-0.33.0/src/cargo/ops/cargo_run.rs cargo-0.35.0/src/cargo/ops/cargo_run.rs --- cargo-0.33.0/src/cargo/ops/cargo_run.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_run.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,44 +1,47 @@ use std::iter; use std::path::Path; -use ops; -use util::{self, CargoResult, ProcessError}; -use core::{TargetKind, Workspace, nightly_features_allowed}; +use crate::core::{nightly_features_allowed, TargetKind, Workspace}; +use crate::ops; +use crate::util::{CargoResult, ProcessError}; pub fn run( - ws: &Workspace, - options: &ops::CompileOptions, + ws: &Workspace<'_>, + options: &ops::CompileOptions<'_>, args: &[String], ) -> CargoResult> { let config = ws.config(); - // We compute the `bins` here *just for diagnosis*. The actual set of + // We compute the `bins` here *just for diagnosis*. The actual set of // packages to be run is determined by the `ops::compile` call below. let packages = options.spec.get_packages(ws)?; let bins: Vec<_> = packages .into_iter() .flat_map(|pkg| { iter::repeat(pkg).zip(pkg.manifest().targets().iter().filter(|target| { - !target.is_lib() && !target.is_custom_build() && if !options.filter.is_specific() { - target.is_bin() - } else { - options.filter.target_run(target) - } + !target.is_lib() + && !target.is_custom_build() + && if !options.filter.is_specific() { + target.is_bin() + } else { + options.filter.target_run(target) + } })) - }).collect(); + }) + .collect(); if bins.is_empty() { if !options.filter.is_specific() { - bail!("a bin target must be available for `cargo run`") + failure::bail!("a bin target must be available for `cargo run`") } else { - // this will be verified in cargo_compile + // This will be verified in `cargo_compile`. } } if bins.len() == 1 { let target = bins[0].1; if let TargetKind::ExampleLib(..) = target.kind() { - bail!( + failure::bail!( "example target `{}` is a library and cannot be executed", target.name() ) @@ -52,7 +55,7 @@ .map(|(_pkg, target)| target.name()) .collect(); if nightly_features_allowed() { - bail!( + failure::bail!( "`cargo run` could not determine which binary to run. \ Use the `--bin` option to specify a binary, \ or (on nightly) the `default-run` manifest key.\n\ @@ -60,7 +63,7 @@ names.join(", ") ) } else { - bail!( + failure::bail!( "`cargo run` requires that a package only have one \ executable; use the `--bin` option to specify which one \ to run\navailable binaries: {}", @@ -68,7 +71,7 @@ ) } } else { - bail!( + failure::bail!( "`cargo run` can run at most one executable, but \ multiple were specified" ) @@ -78,12 +81,10 @@ let compile = ops::compile(ws, options)?; assert_eq!(compile.binaries.len(), 1); let exe = &compile.binaries[0]; - let exe = match util::without_prefix(exe, config.cwd()) { - Some(path) if path.file_name() == Some(path.as_os_str()) => { - Path::new(".").join(path).to_path_buf() - } - Some(path) => path.to_path_buf(), - None => exe.to_path_buf(), + let exe = match exe.strip_prefix(config.cwd()) { + Ok(path) if path.file_name() == Some(path.as_os_str()) => Path::new(".").join(path), + Ok(path) => path.to_path_buf(), + Err(_) => exe.to_path_buf(), }; let pkg = bins[0].0; let mut process = compile.target_process(exe, pkg)?; diff -Nru cargo-0.33.0/src/cargo/ops/cargo_test.rs cargo-0.35.0/src/cargo/ops/cargo_test.rs --- cargo-0.33.0/src/cargo/ops/cargo_test.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_test.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ use std::ffi::OsString; -use core::compiler::{Compilation, Doctest}; -use core::Workspace; -use ops; -use util::errors::CargoResult; -use util::{self, CargoTestError, ProcessError, Test}; +use crate::core::compiler::{Compilation, Doctest}; +use crate::core::Workspace; +use crate::ops; +use crate::util::errors::CargoResult; +use crate::util::{CargoTestError, ProcessError, Test}; pub struct TestOptions<'a> { pub compile_opts: ops::CompileOptions<'a>, @@ -13,8 +13,8 @@ } pub fn run_tests( - ws: &Workspace, - options: &TestOptions, + ws: &Workspace<'_>, + options: &TestOptions<'_>, test_args: &[String], ) -> CargoResult> { let compilation = compile_tests(ws, options)?; @@ -24,7 +24,7 @@ } let (test, mut errors) = run_unit_tests(options, test_args, &compilation)?; - // If we have an error and want to fail fast, return + // If we have an error and want to fail fast, then return. if !errors.is_empty() && !options.no_fail_fast { return Ok(Some(CargoTestError::new(test, errors))); } @@ -40,8 +40,8 @@ } pub fn run_benches( - ws: &Workspace, - options: &TestOptions, + ws: &Workspace<'_>, + options: &TestOptions<'_>, args: &[String], ) -> CargoResult> { let mut args = args.to_vec(); @@ -69,11 +69,11 @@ Ok(compilation) } -/// Run the unit and integration tests of a package. +/// Runs the unit and integration tests of a package. fn run_unit_tests( - options: &TestOptions, + options: &TestOptions<'_>, test_args: &[String], - compilation: &Compilation, + compilation: &Compilation<'_>, ) -> CargoResult<(Test, Vec)> { let config = options.compile_opts.config; let cwd = options.compile_opts.config.cwd(); @@ -81,18 +81,15 @@ let mut errors = Vec::new(); for &(ref pkg, ref kind, ref test, ref exe) in &compilation.tests { - let to_display = match util::without_prefix(exe, cwd) { - Some(path) => path, - None => &**exe, - }; + let exe_display = exe.strip_prefix(cwd).unwrap_or(exe).display(); let mut cmd = compilation.target_process(exe, pkg)?; cmd.args(test_args); config .shell() - .concise(|shell| shell.status("Running", to_display.display().to_string()))?; + .concise(|shell| shell.status("Running", &exe_display))?; config .shell() - .verbose(|shell| shell.status("Running", cmd.to_string()))?; + .verbose(|shell| shell.status("Running", &cmd))?; let result = cmd.exec(); @@ -127,14 +124,14 @@ } fn run_doc_tests( - options: &TestOptions, + options: &TestOptions<'_>, test_args: &[String], - compilation: &Compilation, + compilation: &Compilation<'_>, ) -> CargoResult<(Test, Vec)> { let mut errors = Vec::new(); let config = options.compile_opts.config; - // We don't build/rust doctests if target != host + // We don't build/run doc tests if `target` does not equal `host`. if compilation.host != compilation.target { return Ok((Test::Doc, errors)); } @@ -148,7 +145,7 @@ config.shell().status("Doc-tests", target.name())?; let mut p = compilation.rustdoc_process(package, target)?; p.arg("--test") - .arg(target.src_path().path()) + .arg(target.src_path().path().unwrap()) .arg("--crate-name") .arg(&target.crate_name()); diff -Nru cargo-0.33.0/src/cargo/ops/cargo_uninstall.rs cargo-0.35.0/src/cargo/ops/cargo_uninstall.rs --- cargo-0.33.0/src/cargo/ops/cargo_uninstall.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/cargo_uninstall.rs 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,157 @@ +use std::collections::btree_map::Entry; +use std::{env, fs}; + +use crate::core::PackageId; +use crate::core::{PackageIdSpec, SourceId}; +use crate::ops::common_for_install_and_uninstall::*; +use crate::util::errors::CargoResult; +use crate::util::paths; +use crate::util::Config; +use crate::util::{FileLock, Filesystem}; + +pub fn uninstall( + root: Option<&str>, + specs: Vec<&str>, + bins: &[String], + config: &Config, +) -> CargoResult<()> { + if specs.len() > 1 && !bins.is_empty() { + failure::bail!("A binary can only be associated with a single installed package, specifying multiple specs with --bin is redundant."); + } + + let root = resolve_root(root, config)?; + let scheduled_error = if specs.len() == 1 { + uninstall_one(&root, specs[0], bins, config)?; + false + } else if specs.is_empty() { + uninstall_cwd(&root, bins, config)?; + false + } else { + let mut succeeded = vec![]; + let mut failed = vec![]; + for spec in specs { + let root = root.clone(); + match uninstall_one(&root, spec, bins, config) { + Ok(()) => succeeded.push(spec), + Err(e) => { + crate::handle_error(&e, &mut config.shell()); + failed.push(spec) + } + } + } + + let mut summary = vec![]; + if !succeeded.is_empty() { + summary.push(format!( + "Successfully uninstalled {}!", + succeeded.join(", ") + )); + } + if !failed.is_empty() { + summary.push(format!( + "Failed to uninstall {} (see error(s) above).", + failed.join(", ") + )); + } + + if !succeeded.is_empty() || !failed.is_empty() { + config.shell().status("Summary", summary.join(" "))?; + } + + !failed.is_empty() + }; + + if scheduled_error { + failure::bail!("some packages failed to uninstall"); + } + + Ok(()) +} + +pub fn uninstall_one( + root: &Filesystem, + spec: &str, + bins: &[String], + config: &Config, +) -> CargoResult<()> { + let crate_metadata = metadata(config, root)?; + let metadata = read_crate_list(&crate_metadata)?; + let pkgid = PackageIdSpec::query_str(spec, metadata.v1().keys().cloned())?; + uninstall_pkgid(&crate_metadata, metadata, pkgid, bins, config) +} + +fn uninstall_cwd(root: &Filesystem, bins: &[String], config: &Config) -> CargoResult<()> { + let crate_metadata = metadata(config, root)?; + let metadata = read_crate_list(&crate_metadata)?; + let source_id = SourceId::for_path(config.cwd())?; + let src = path_source(source_id, config)?; + let (pkg, _source) = select_pkg(src, None, None, config, true, &mut |path| { + path.read_packages() + })?; + let pkgid = pkg.package_id(); + uninstall_pkgid(&crate_metadata, metadata, pkgid, bins, config) +} + +fn uninstall_pkgid( + crate_metadata: &FileLock, + mut metadata: CrateListingV1, + pkgid: PackageId, + bins: &[String], + config: &Config, +) -> CargoResult<()> { + let mut to_remove = Vec::new(); + { + let mut installed = match metadata.v1_mut().entry(pkgid) { + Entry::Occupied(e) => e, + Entry::Vacant(..) => failure::bail!("package `{}` is not installed", pkgid), + }; + + let dst = crate_metadata.parent().join("bin"); + for bin in installed.get() { + let bin = dst.join(bin); + if fs::metadata(&bin).is_err() { + failure::bail!( + "corrupt metadata, `{}` does not exist when it should", + bin.display() + ) + } + } + + let bins = bins + .iter() + .map(|s| { + if s.ends_with(env::consts::EXE_SUFFIX) { + s.to_string() + } else { + format!("{}{}", s, env::consts::EXE_SUFFIX) + } + }) + .collect::>(); + + for bin in bins.iter() { + if !installed.get().contains(bin) { + failure::bail!("binary `{}` not installed as part of `{}`", bin, pkgid) + } + } + + if bins.is_empty() { + to_remove.extend(installed.get().iter().map(|b| dst.join(b))); + installed.get_mut().clear(); + } else { + for bin in bins.iter() { + to_remove.push(dst.join(bin)); + installed.get_mut().remove(bin); + } + } + if installed.get().is_empty() { + installed.remove(); + } + } + write_crate_list(&crate_metadata, metadata)?; + for bin in to_remove { + config.shell().status("Removing", bin.display())?; + paths::remove_file(bin)?; + } + + Ok(()) +} diff -Nru cargo-0.33.0/src/cargo/ops/common_for_install_and_uninstall.rs cargo-0.35.0/src/cargo/ops/common_for_install_and_uninstall.rs --- cargo-0.33.0/src/cargo/ops/common_for_install_and_uninstall.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/common_for_install_and_uninstall.rs 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,251 @@ +use std::collections::{BTreeMap, BTreeSet}; +use std::env; +use std::io::prelude::*; +use std::io::SeekFrom; +use std::path::{Path, PathBuf}; + +use semver::VersionReq; +use serde::{Deserialize, Serialize}; + +use crate::core::PackageId; +use crate::core::{Dependency, Package, Source, SourceId}; +use crate::sources::PathSource; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{internal, Config, ToSemver}; +use crate::util::{FileLock, Filesystem}; + +#[derive(Deserialize, Serialize)] +#[serde(untagged)] +pub enum CrateListing { + V1(CrateListingV1), + Empty(Empty), +} + +#[derive(Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Empty {} + +#[derive(Deserialize, Serialize)] +pub struct CrateListingV1 { + v1: BTreeMap>, +} + +impl CrateListingV1 { + pub fn v1(&self) -> &BTreeMap> { + &self.v1 + } + + pub fn v1_mut(&mut self) -> &mut BTreeMap> { + &mut self.v1 + } +} + +pub fn resolve_root(flag: Option<&str>, config: &Config) -> CargoResult { + let config_root = config.get_path("install.root")?; + Ok(flag + .map(PathBuf::from) + .or_else(|| env::var_os("CARGO_INSTALL_ROOT").map(PathBuf::from)) + .or_else(move || config_root.map(|v| v.val)) + .map(Filesystem::new) + .unwrap_or_else(|| config.home().clone())) +} + +pub fn path_source<'a>(source_id: SourceId, config: &'a Config) -> CargoResult> { + let path = source_id + .url() + .to_file_path() + .map_err(|()| failure::format_err!("path sources must have a valid path"))?; + Ok(PathSource::new(&path, source_id, config)) +} + +pub fn select_pkg<'a, T>( + mut source: T, + name: Option<&str>, + vers: Option<&str>, + config: &Config, + needs_update: bool, + list_all: &mut dyn FnMut(&mut T) -> CargoResult>, +) -> CargoResult<(Package, Box)> +where + T: Source + 'a, +{ + if needs_update { + source.update()?; + } + + match name { + Some(name) => { + let vers = match vers { + Some(v) => { + // If the version begins with character <, >, =, ^, ~ parse it as a + // version range, otherwise parse it as a specific version + let first = v.chars().nth(0).ok_or_else(|| { + failure::format_err!("no version provided for the `--vers` flag") + })?; + + match first { + '<' | '>' | '=' | '^' | '~' => match v.parse::() { + Ok(v) => Some(v.to_string()), + Err(_) => failure::bail!( + "the `--vers` provided, `{}`, is \ + not a valid semver version requirement\n\n + Please have a look at \ + http://doc.crates.io/specifying-dependencies.html \ + for the correct format", + v + ), + }, + _ => match v.to_semver() { + Ok(v) => Some(format!("={}", v)), + Err(_) => { + let mut msg = format!( + "\ + the `--vers` provided, `{}`, is \ + not a valid semver version\n\n\ + historically Cargo treated this \ + as a semver version requirement \ + accidentally\nand will continue \ + to do so, but this behavior \ + will be removed eventually", + v + ); + + // If it is not a valid version but it is a valid version + // requirement, add a note to the warning + if v.parse::().is_ok() { + msg.push_str(&format!( + "\nif you want to specify semver range, \ + add an explicit qualifier, like ^{}", + v + )); + } + config.shell().warn(&msg)?; + Some(v.to_string()) + } + }, + } + } + None => None, + }; + let vers = vers.as_ref().map(|s| &**s); + let vers_spec = if vers.is_none() && source.source_id().is_registry() { + // Avoid pre-release versions from crate.io + // unless explicitly asked for + Some("*") + } else { + vers + }; + let dep = Dependency::parse_no_deprecated(name, vers_spec, source.source_id())?; + let deps = source.query_vec(&dep)?; + match deps.iter().map(|p| p.package_id()).max() { + Some(pkgid) => { + let pkg = Box::new(&mut source).download_now(pkgid, config)?; + Ok((pkg, Box::new(source))) + }, + None => { + let vers_info = vers + .map(|v| format!(" with version `{}`", v)) + .unwrap_or_default(); + failure::bail!( + "could not find `{}` in {}{}", + name, + source.source_id(), + vers_info + ) + } + } + } + None => { + let candidates = list_all(&mut source)?; + let binaries = candidates + .iter() + .filter(|cand| cand.targets().iter().filter(|t| t.is_bin()).count() > 0); + let examples = candidates + .iter() + .filter(|cand| cand.targets().iter().filter(|t| t.is_example()).count() > 0); + let pkg = match one(binaries, |v| multi_err("binaries", v))? { + Some(p) => p, + None => match one(examples, |v| multi_err("examples", v))? { + Some(p) => p, + None => failure::bail!( + "no packages found with binaries or \ + examples" + ), + }, + }; + return Ok((pkg.clone(), Box::new(source))); + + fn multi_err(kind: &str, mut pkgs: Vec<&Package>) -> String { + pkgs.sort_unstable_by_key(|a| a.name()); + format!( + "multiple packages with {} found: {}", + kind, + pkgs.iter() + .map(|p| p.name().as_str()) + .collect::>() + .join(", ") + ) + } + } + } +} + +pub fn one(mut i: I, f: F) -> CargoResult> +where + I: Iterator, + F: FnOnce(Vec) -> String, +{ + match (i.next(), i.next()) { + (Some(i1), Some(i2)) => { + let mut v = vec![i1, i2]; + v.extend(i); + Err(failure::format_err!("{}", f(v))) + } + (Some(i), None) => Ok(Some(i)), + (None, _) => Ok(None), + } +} + +pub fn read_crate_list(file: &FileLock) -> CargoResult { + let listing = (|| -> CargoResult<_> { + let mut contents = String::new(); + file.file().read_to_string(&mut contents)?; + let listing = + toml::from_str(&contents).chain_err(|| internal("invalid TOML found for metadata"))?; + match listing { + CrateListing::V1(v1) => Ok(v1), + CrateListing::Empty(_) => Ok(CrateListingV1 { + v1: BTreeMap::new(), + }), + } + })() + .chain_err(|| { + failure::format_err!( + "failed to parse crate metadata at `{}`", + file.path().to_string_lossy() + ) + })?; + Ok(listing) +} + +pub fn write_crate_list(file: &FileLock, listing: CrateListingV1) -> CargoResult<()> { + (|| -> CargoResult<_> { + let mut file = file.file(); + file.seek(SeekFrom::Start(0))?; + file.set_len(0)?; + let data = toml::to_string(&CrateListing::V1(listing))?; + file.write_all(data.as_bytes())?; + Ok(()) + })() + .chain_err(|| { + failure::format_err!( + "failed to write crate metadata at `{}`", + file.path().to_string_lossy() + ) + })?; + Ok(()) +} + +pub fn metadata(config: &Config, root: &Filesystem) -> CargoResult { + root.open_rw(Path::new(".crates.toml"), config, "crate metadata") +} diff -Nru cargo-0.33.0/src/cargo/ops/fix.rs cargo-0.35.0/src/cargo/ops/fix.rs --- cargo-0.33.0/src/cargo/ops/fix.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/fix.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,3 +1,44 @@ +//! High-level overview of how `fix` works: +//! +//! The main goal is to run `cargo check` to get rustc to emit JSON +//! diagnostics with suggested fixes that can be applied to the files on the +//! filesystem, and validate that those changes didn't break anything. +//! +//! Cargo begins by launching a `LockServer` thread in the background to +//! listen for network connections to coordinate locking when multiple targets +//! are built simultaneously. It ensures each package has only one fix running +//! at once. +//! +//! The `RustfixDiagnosticServer` is launched in a background thread (in +//! `JobQueue`) to listen for network connections to coordinate displaying +//! messages to the user on the console (so that multiple processes don't try +//! to print at the same time). +//! +//! Cargo begins a normal `cargo check` operation with itself set as a proxy +//! for rustc by setting `cargo_as_rustc_wrapper` in the build config. When +//! cargo launches rustc to check a crate, it is actually launching itself. +//! The `FIX_ENV` environment variable is set so that cargo knows it is in +//! fix-proxy-mode. It also sets the `RUSTC` environment variable to the +//! actual rustc so Cargo knows what to execute. +//! +//! Each proxied cargo-as-rustc detects it is in fix-proxy-mode (via `FIX_ENV` +//! environment variable in `main`) and does the following: +//! +//! - Acquire a lock from the `LockServer` from the master cargo process. +//! - Launches the real rustc (`rustfix_and_fix`), looking at the JSON output +//! for suggested fixes. +//! - Uses the `rustfix` crate to apply the suggestions to the files on the +//! file system. +//! - If rustfix fails to apply any suggestions (for example, they are +//! overlapping), but at least some suggestions succeeded, it will try the +//! previous two steps up to 4 times as long as some suggestions succeed. +//! - Assuming there's at least one suggestion applied, and the suggestions +//! applied cleanly, rustc is run again to verify the suggestions didn't +//! break anything. The change will be backed out if it fails (unless +//! `--broken-code` is used). +//! - If there are any warnings or errors, rustc will be run one last time to +//! show them to the user. + use std::collections::{BTreeSet, HashMap, HashSet}; use std::env; use std::ffi::OsString; @@ -7,23 +48,21 @@ use std::str; use failure::{Error, ResultExt}; -use git2; +use log::{debug, trace, warn}; use rustfix::diagnostics::Diagnostic; use rustfix::{self, CodeFix}; -use serde_json; -use core::Workspace; -use ops::{self, CompileOptions}; -use util::diagnostic_server::{Message, RustfixDiagnosticServer}; -use util::errors::CargoResult; -use util::paths; -use util::{existing_vcs_repo, LockServer, LockServerClient}; +use crate::core::Workspace; +use crate::ops::{self, CompileOptions}; +use crate::util::diagnostic_server::{Message, RustfixDiagnosticServer}; +use crate::util::errors::CargoResult; +use crate::util::paths; +use crate::util::{existing_vcs_repo, LockServer, LockServerClient}; const FIX_ENV: &str = "__CARGO_FIX_PLZ"; const BROKEN_CODE_ENV: &str = "__CARGO_FIX_BROKEN_CODE"; const PREPARE_FOR_ENV: &str = "__CARGO_FIX_PREPARE_FOR"; const EDITION_ENV: &str = "__CARGO_FIX_EDITION"; - const IDIOMS_ENV: &str = "__CARGO_FIX_IDIOMS"; pub struct FixOptions<'a> { @@ -37,11 +76,10 @@ pub broken_code: bool, } -pub fn fix(ws: &Workspace, opts: &mut FixOptions) -> CargoResult<()> { +pub fn fix(ws: &Workspace<'_>, opts: &mut FixOptions<'_>) -> CargoResult<()> { check_version_control(opts)?; - // Spin up our lock server which our subprocesses will use to synchronize - // fixes. + // Spin up our lock server, which our subprocesses will use to synchronize fixes. let lock_server = LockServer::new()?; opts.compile_opts .build_config @@ -88,13 +126,13 @@ Ok(()) } -fn check_version_control(opts: &FixOptions) -> CargoResult<()> { +fn check_version_control(opts: &FixOptions<'_>) -> CargoResult<()> { if opts.allow_no_vcs { return Ok(()); } let config = opts.compile_opts.config; if !existing_vcs_repo(config.cwd(), config.cwd()) { - bail!( + failure::bail!( "no VCS found for this package and `cargo fix` can potentially \ perform destructive changes; if you'd like to suppress this \ error pass `--allow-no-vcs`" @@ -149,7 +187,7 @@ files_list.push_str(" (staged)\n"); } - bail!( + failure::bail!( "the working directory of this package has uncommitted changes, and \ `cargo fix` can potentially perform destructive changes; if you'd \ like to suppress this error pass `--allow-dirty`, `--allow-staged`, \ @@ -191,7 +229,7 @@ // *stop* compiling then we want to back them out and continue to print // warnings to the user. // - // If we didn't actually make any changes then we can immediately exec the + // If we didn't actually make any changes then we can immediately execute the // new rustc, and otherwise we capture the output to hide it in the scenario // that we have to back it all out. if !fixes.files.is_empty() { @@ -217,7 +255,7 @@ return Ok(true); } - // Otherwise if our rustc just failed then that means that we broke the + // Otherwise, if our rustc just failed, then that means that we broke the // user's code with our changes. Back out everything and fall through // below to recompile again. if !output.status.success() { @@ -255,15 +293,16 @@ ) -> Result { args.verify_not_preparing_for_enabled_edition()?; - // First up we want to make sure that each crate is only checked by one + // First up, we want to make sure that each crate is only checked by one // process at a time. If two invocations concurrently check a crate then // it's likely to corrupt it. // - // Currently we do this by assigning the name on our lock to the first - // argument that looks like a Rust file. - let _lock = LockServerClient::lock(&lock_addr.parse()?, filename)?; + // We currently do this by assigning the name on our lock to the manifest + // directory. + let dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is missing?"); + let _lock = LockServerClient::lock(&lock_addr.parse()?, dir)?; - // Next up this is a bit suspicious, but we *iteratively* execute rustc and + // Next up, this is a bit suspicious, but we *iteratively* execute rustc and // collect suggestions to feed to rustfix. Once we hit our limit of times to // execute rustc or we appear to be reaching a fixed point we stop running // rustc. @@ -274,7 +313,7 @@ // // where there are two fixes to happen here: `crate::foo::()`. // The spans for these two suggestions are overlapping and its difficult in - // the compiler to *not* have overlapping spans here. As a result, a naive + // the compiler to **not** have overlapping spans here. As a result, a naive // implementation would feed the two compiler suggestions for the above fix // into `rustfix`, but one would be rejected because it overlaps with the // other. @@ -285,7 +324,7 @@ // failed to apply, assuming that they can be fixed the next time we run // rustc. // - // Naturally we want a few protections in place here though to avoid looping + // Naturally, we want a few protections in place here though to avoid looping // forever or otherwise losing data. To that end we have a few termination // conditions: // @@ -306,7 +345,8 @@ last_fix_counts.clear(); for (path, file) in fixes.files.iter_mut() { last_fix_counts.insert(path.clone(), file.fixes_applied); - file.errors_applying_fixes.clear(); // we'll generate new errors below + // We'll generate new errors below. + file.errors_applying_fixes.clear(); } rustfix_and_fix(&mut fixes, rustc, filename, args)?; let mut progress_yet_to_be_made = false; @@ -341,7 +381,7 @@ Ok(fixes) } -/// Execute `rustc` to apply one round of suggestions to the crate in question. +/// Executes `rustc` to apply one round of suggestions to the crate in question. /// /// This will fill in the `fixes` map with original code, suggestions applied, /// and any errors encountered while fixing files. @@ -351,9 +391,8 @@ filename: &Path, args: &FixArgs, ) -> Result<(), Error> { - // If not empty, filter by these lints - // - // TODO: Implement a way to specify this + // If not empty, filter by these lints. + // TODO: implement a way to specify this. let only = HashSet::new(); let mut cmd = Command::new(rustc); @@ -381,17 +420,17 @@ .map(|_| rustfix::Filter::Everything) .unwrap_or(rustfix::Filter::MachineApplicableOnly); - // Sift through the output of the compiler to look for JSON messages + // Sift through the output of the compiler to look for JSON messages. // indicating fixes that we can apply. - let stderr = str::from_utf8(&output.stderr).context("failed to parse rustc stderr as utf-8")?; + let stderr = str::from_utf8(&output.stderr).context("failed to parse rustc stderr as UTF-8")?; let suggestions = stderr .lines() .filter(|x| !x.is_empty()) .inspect(|y| trace!("line: {}", y)) - // Parse each line of stderr ignoring errors as they may not all be json + // Parse each line of stderr, ignoring errors, as they may not all be JSON. .filter_map(|line| serde_json::from_str::(line).ok()) - // From each diagnostic try to extract suggestions from rustc + // From each diagnostic, try to extract suggestions from rustc. .filter_map(|diag| rustfix::collect_suggestions(&diag, &only, fix_mode)); // Collect suggestions by file so we can apply them one at a time later. @@ -400,21 +439,23 @@ for suggestion in suggestions { trace!("suggestion"); // Make sure we've got a file associated with this suggestion and all - // snippets point to the same location. Right now it's not clear what - // we would do with multiple locations. - let (file_name, range) = match suggestion.snippets.get(0) { - Some(s) => (s.file_name.clone(), s.line_range), - None => { - trace!("rejecting as it has no snippets {:?}", suggestion); - continue; - } - }; - if !suggestion - .snippets + // snippets point to the same file. Right now it's not clear what + // we would do with multiple files. + let file_names = suggestion + .solutions .iter() - .all(|s| s.file_name == file_name && s.line_range == range) - { - trace!("rejecting as it spans multiple files {:?}", suggestion); + .flat_map(|s| s.replacements.iter()) + .map(|r| &r.snippet.file_name); + + let file_name = if let Some(file_name) = file_names.clone().next() { + file_name.clone() + } else { + trace!("rejecting as it has no solutions {:?}", suggestion); + continue; + }; + + if !file_names.clone().all(|f| f == &file_name) { + trace!("rejecting as it changes multiple files: {:?}", suggestion); continue; } @@ -495,7 +536,9 @@ .filter(|x| !x.is_empty()) .filter_map(|line| serde_json::from_str::(line).ok()); let mut files = BTreeSet::new(); + let mut errors = Vec::new(); for diagnostic in diagnostics { + errors.push(diagnostic.rendered.unwrap_or(diagnostic.message)); for span in diagnostic.spans.into_iter() { files.insert(span.file_name); } @@ -515,7 +558,12 @@ } let files = files.into_iter().collect(); - Message::FixFailed { files, krate }.post()?; + Message::FixFailed { + files, + krate, + errors, + } + .post()?; Ok(()) } @@ -588,7 +636,7 @@ } } - /// Verify that we're not both preparing for an enabled edition and enabling + /// Verifies that we're not both preparing for an enabled edition and enabling /// the edition. /// /// This indicates that `cargo fix --prepare-for` is being executed out of diff -Nru cargo-0.33.0/src/cargo/ops/lockfile.rs cargo-0.35.0/src/cargo/ops/lockfile.rs --- cargo-0.33.0/src/cargo/ops/lockfile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/lockfile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,13 +2,13 @@ use toml; -use core::resolver::WorkspaceResolve; -use core::{resolver, Resolve, Workspace}; -use util::errors::{CargoResult, CargoResultExt}; -use util::toml as cargo_toml; -use util::Filesystem; +use crate::core::resolver::WorkspaceResolve; +use crate::core::{resolver, Resolve, Workspace}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::toml as cargo_toml; +use crate::util::Filesystem; -pub fn load_pkg_lockfile(ws: &Workspace) -> CargoResult> { +pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult> { if !ws.root().join("Cargo.lock").exists() { return Ok(None); } @@ -29,8 +29,8 @@ Ok(resolve) } -pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()> { - // Load the original lockfile if it exists. +pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &Resolve) -> CargoResult<()> { + // Load the original lock file if it exists. let ws_root = Filesystem::new(ws.root().to_path_buf()); let orig = ws_root.open_ro("Cargo.lock", ws.config(), "Cargo.lock file"); let orig = orig.and_then(|mut f| { @@ -43,13 +43,32 @@ let mut out = String::new(); - // Preserve the top comments in the lockfile - // This is in preparation for marking it as generated - // https://github.com/rust-lang/cargo/issues/6180 + // At the start of the file we notify the reader that the file is generated. + // Specifically Phabricator ignores files containing "@generated", so we use that. + let marker_line = "# This file is automatically @generated by Cargo."; + let extra_line = "# It is not intended for manual editing."; + out.push_str(marker_line); + out.push('\n'); + out.push_str(extra_line); + out.push('\n'); + // and preserve any other top comments if let Ok(orig) = &orig { - for line in orig.lines().take_while(|line| line.starts_with('#')) { - out.push_str(line); - out.push_str("\n"); + let mut comments = orig.lines().take_while(|line| line.starts_with('#')); + if let Some(first) = comments.next() { + if first != marker_line { + out.push_str(first); + out.push('\n'); + } + if let Some(second) = comments.next() { + if second != extra_line { + out.push_str(second); + out.push('\n'); + } + for line in comments { + out.push_str(line); + out.push('\n'); + } + } } } @@ -75,7 +94,7 @@ out.push_str(&meta.to_string()); } - // If the lockfile contents haven't changed so don't rewrite it. This is + // If the lock file contents haven't changed so don't rewrite it. This is // helpful on read-only filesystems. if let Ok(orig) = orig { if are_equal_lockfiles(orig, &out, ws) { @@ -85,7 +104,7 @@ if !ws.config().lock_update_allowed() { if ws.config().cli_unstable().offline { - bail!("can't update in the offline mode"); + failure::bail!("can't update in the offline mode"); } let flag = if ws.config().network_allowed() { @@ -93,7 +112,7 @@ } else { "--frozen" }; - bail!( + failure::bail!( "the lock file {} needs to be updated but {} was passed to \ prevent this", ws.root().to_path_buf().join("Cargo.lock").display(), @@ -113,14 +132,14 @@ Ok(()) } -fn are_equal_lockfiles(mut orig: String, current: &str, ws: &Workspace) -> bool { +fn are_equal_lockfiles(mut orig: String, current: &str, ws: &Workspace<'_>) -> bool { if has_crlf_line_endings(&orig) { orig = orig.replace("\r\n", "\n"); } - // If we want to try and avoid updating the lockfile, parse both and + // If we want to try and avoid updating the lock file, parse both and // compare them; since this is somewhat expensive, don't do it in the - // common case where we can update lockfiles. + // common case where we can update lock files. if !ws.config().lock_update_allowed() { let res: CargoResult = (|| { let old: resolver::EncodableResolve = toml::from_str(&orig)?; diff -Nru cargo-0.33.0/src/cargo/ops/mod.rs cargo-0.35.0/src/cargo/ops/mod.rs --- cargo-0.33.0/src/cargo/ops/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,28 +1,31 @@ pub use self::cargo_clean::{clean, CleanOptions}; pub use self::cargo_compile::{compile, compile_with_exec, compile_ws, CompileOptions}; pub use self::cargo_compile::{CompileFilter, FilterRule, Packages}; -pub use self::cargo_read_manifest::{read_package, read_packages}; -pub use self::cargo_run::run; -pub use self::cargo_install::{install, install_list, uninstall}; -pub use self::cargo_new::{init, new, NewOptions, VersionControl}; pub use self::cargo_doc::{doc, DocOptions}; +pub use self::cargo_fetch::{fetch, FetchOptions}; pub use self::cargo_generate_lockfile::generate_lockfile; pub use self::cargo_generate_lockfile::update_lockfile; pub use self::cargo_generate_lockfile::UpdateOptions; -pub use self::lockfile::{load_pkg_lockfile, write_pkg_lockfile}; -pub use self::cargo_test::{run_benches, run_tests, TestOptions}; +pub use self::cargo_install::{install, install_list}; +pub use self::cargo_new::{init, new, NewOptions, VersionControl}; +pub use self::cargo_output_metadata::{output_metadata, ExportInfo, OutputMetadataOptions}; pub use self::cargo_package::{package, PackageOpts}; -pub use self::registry::{publish, registry_configuration, RegistryConfig}; +pub use self::cargo_pkgid::pkgid; +pub use self::cargo_read_manifest::{read_package, read_packages}; +pub use self::cargo_run::run; +pub use self::cargo_test::{run_benches, run_tests, TestOptions}; +pub use self::cargo_uninstall::uninstall; +pub use self::fix::{fix, fix_maybe_exec_rustc, FixOptions}; +pub use self::lockfile::{load_pkg_lockfile, write_pkg_lockfile}; +pub use self::registry::HttpTimeout; +pub use self::registry::{configure_http_handle, http_handle_and_timeout}; pub use self::registry::{http_handle, needs_custom_http_transport, registry_login, search}; pub use self::registry::{modify_owners, yank, OwnersOptions, PublishOpts}; -pub use self::registry::{configure_http_handle, http_handle_and_timeout}; -pub use self::registry::HttpTimeout; -pub use self::cargo_fetch::{fetch, FetchOptions}; -pub use self::cargo_pkgid::pkgid; -pub use self::resolve::{add_overrides, get_resolved_packages, resolve_with_previous, resolve_ws, - resolve_ws_precisely, resolve_ws_with_method}; -pub use self::cargo_output_metadata::{output_metadata, ExportInfo, OutputMetadataOptions}; -pub use self::fix::{fix, FixOptions, fix_maybe_exec_rustc}; +pub use self::registry::{publish, registry_configuration, RegistryConfig}; +pub use self::resolve::{ + add_overrides, get_resolved_packages, resolve_with_previous, resolve_ws, resolve_ws_precisely, + resolve_ws_with_method, +}; mod cargo_clean; mod cargo_compile; @@ -37,7 +40,9 @@ mod cargo_read_manifest; mod cargo_run; mod cargo_test; +mod cargo_uninstall; +mod common_for_install_and_uninstall; +mod fix; mod lockfile; mod registry; mod resolve; -mod fix; diff -Nru cargo-0.33.0/src/cargo/ops/registry.rs cargo-0.35.0/src/cargo/ops/registry.rs --- cargo-0.33.0/src/cargo/ops/registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,29 +1,28 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::fs::{self, File}; +use std::io::{self, BufRead}; use std::iter::repeat; use std::str; use std::time::Duration; use std::{cmp, env}; +use crates_io::{NewCrate, NewCrateDependency, Registry}; use curl::easy::{Easy, InfoType, SslOpt}; -use git2; -use log::Level; -use registry::{NewCrate, NewCrateDependency, Registry}; - +use log::{log, Level}; use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET}; -use core::dependency::Kind; -use core::manifest::ManifestMetadata; -use core::source::Source; -use core::{Package, SourceId, Workspace}; -use ops; -use sources::{RegistrySource, SourceConfigMap}; -use util::config::{self, Config}; -use util::errors::{CargoResult, CargoResultExt}; -use util::important_paths::find_root_manifest_for_wd; -use util::paths; -use util::ToUrl; -use version; +use crate::core::dependency::Kind; +use crate::core::manifest::ManifestMetadata; +use crate::core::source::Source; +use crate::core::{Package, SourceId, Workspace}; +use crate::ops; +use crate::sources::{RegistrySource, SourceConfigMap}; +use crate::util::config::{self, Config}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::important_paths::find_root_manifest_for_wd; +use crate::util::ToUrl; +use crate::util::{paths, validate_package_name}; +use crate::version; pub struct RegistryConfig { pub index: Option, @@ -40,9 +39,12 @@ pub target: Option, pub dry_run: bool, pub registry: Option, + pub features: Vec, + pub all_features: bool, + pub no_default_features: bool, } -pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> { +pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> { let pkg = ws.current()?; if let Some(ref allowed_registries) = *pkg.publish() { @@ -50,7 +52,7 @@ Some(ref registry) => allowed_registries.contains(registry), None => false, } { - bail!( + failure::bail!( "some crates cannot be published.\n\ `{}` is marked as unpublishable", pkg.name() @@ -58,17 +60,14 @@ } } - if !pkg.manifest().patch().is_empty() { - bail!("published crates cannot contain [patch] sections"); - } - let (mut registry, reg_id) = registry( opts.config, opts.token.clone(), opts.index.clone(), opts.registry.clone(), + true, )?; - verify_dependencies(pkg, reg_id)?; + verify_dependencies(pkg, ®istry, reg_id)?; // Prepare a tarball, with a non-surpressable warning if metadata // is missing since this is being put online. @@ -82,7 +81,9 @@ allow_dirty: opts.allow_dirty, target: opts.target.clone(), jobs: opts.jobs, - registry: opts.registry.clone(), + features: opts.features.clone(), + all_features: opts.all_features, + no_default_features: opts.no_default_features, }, )? .unwrap(); @@ -103,11 +104,15 @@ Ok(()) } -fn verify_dependencies(pkg: &Package, registry_src: SourceId) -> CargoResult<()> { +fn verify_dependencies( + pkg: &Package, + registry: &Registry, + registry_src: SourceId, +) -> CargoResult<()> { for dep in pkg.dependencies().iter() { if dep.source_id().is_path() { if !dep.specified_req() { - bail!( + failure::bail!( "all path dependencies must have a version specified \ when publishing.\ndependency `{}` does not specify \ a version", @@ -116,10 +121,17 @@ } } else if dep.source_id() != registry_src { if dep.source_id().is_registry() { - // Block requests to send to a registry if it is not an alternative - // registry - if !registry_src.is_alt_registry() { - bail!("crates cannot be published to crates.io with dependencies sourced from other\n\ + // Block requests to send to crates.io with alt-registry deps. + // This extra hostname check is mostly to assist with testing, + // but also prevents someone using `--index` to specify + // something that points to crates.io. + let is_crates_io = registry + .host() + .to_url() + .map(|u| u.host_str() == Some("crates.io")) + .unwrap_or(false); + if registry_src.is_default_registry() || is_crates_io { + failure::bail!("crates cannot be published to crates.io with dependencies sourced from other\n\ registries either publish `{}` on crates.io or pull it into this repository\n\ and specify it with a path and version\n\ (crate `{}` is pulled from {})", @@ -128,10 +140,10 @@ dep.source_id()); } } else { - bail!( - "crates cannot be published to crates.io with dependencies sourced from \ - a repository\neither publish `{}` as its own crate on crates.io and \ - specify a crates.io version as a dependency or pull it into this \ + failure::bail!( + "crates cannot be published with dependencies sourced from \ + a repository\neither publish `{}` as its own crate and \ + specify a version as a dependency or pull it into this \ repository and specify it with a path and version\n(crate `{}` has \ repository path `{}`)", dep.package_name(), @@ -160,8 +172,10 @@ // registry in the dependency. let dep_registry_id = match dep.registry_id() { Some(id) => id, - None => bail!("dependency missing registry ID"), + None => SourceId::crates_io(config)?, }; + // In the index and Web API, None means "from the same registry" + // whereas in Cargo.toml, it means "from crates.io". let dep_registry = if dep_registry_id != registry_id { Some(dep_registry_id.url().to_string()) } else { @@ -207,7 +221,7 @@ }; if let Some(ref file) = *license_file { if fs::metadata(&pkg.root().join(file)).is_err() { - bail!("the license file `{}` does not exist", file) + failure::bail!("the license file `{}` does not exist", file) } } @@ -296,12 +310,15 @@ registry: Option, ) -> CargoResult { let (index, token) = match registry { - Some(registry) => ( - Some(config.get_registry_index(®istry)?.to_string()), - config - .get_string(&format!("registries.{}.token", registry))? - .map(|p| p.val), - ), + Some(registry) => { + validate_package_name(®istry, "registry name", "")?; + ( + Some(config.get_registry_index(®istry)?.to_string()), + config + .get_string(&format!("registries.{}.token", registry))? + .map(|p| p.val), + ) + } None => { // Checking out for default index and token ( @@ -319,6 +336,7 @@ token: Option, index: Option, registry: Option, + force_update: bool, ) -> CargoResult<(Registry, SourceId)> { // Parse all configuration options let RegistryConfig { @@ -328,16 +346,24 @@ let token = token.or(token_config); let sid = get_source_id(config, index_config.or(index), registry)?; let api_host = { - let mut src = RegistrySource::remote(sid, config); - src.update() - .chain_err(|| format!("failed to update {}", sid))?; - (src.config()?).unwrap().api.unwrap() + let mut src = RegistrySource::remote(sid, &HashSet::new(), config); + // Only update the index if the config is not available or `force` is set. + let cfg = src.config(); + let cfg = if force_update || cfg.is_err() { + src.update() + .chain_err(|| format!("failed to update {}", sid))?; + cfg.or_else(|_| src.config())? + } else { + cfg.unwrap() + }; + cfg.and_then(|cfg| cfg.api) + .ok_or_else(|| failure::format_err!("{} does not support API commands", sid))? }; let handle = http_handle(config)?; Ok((Registry::new_handle(api_host, token, handle), sid)) } -/// Create a new HTTP handle with appropriate global configuration for cargo. +/// Creates a new HTTP handle with appropriate global configuration for cargo. pub fn http_handle(config: &Config) -> CargoResult { let (mut handle, timeout) = http_handle_and_timeout(config)?; timeout.configure(&mut handle)?; @@ -346,13 +372,13 @@ pub fn http_handle_and_timeout(config: &Config) -> CargoResult<(Easy, HttpTimeout)> { if config.frozen() { - bail!( + failure::bail!( "attempting to make an HTTP request, but --frozen was \ specified" ) } if !config.network_allowed() { - bail!("can't make HTTP request in the offline mode") + failure::bail!("can't make HTTP request in the offline mode") } // The timeout option for libcurl by default times out the entire transfer, @@ -466,7 +492,7 @@ } } -/// Find an explicit HTTP proxy if one is available. +/// Finds an explicit HTTP proxy if one is available. /// /// Favor cargo's `http.proxy`, then git's `http.proxy`. Proxies specified /// via environment variables are picked up by libcurl. @@ -502,18 +528,51 @@ } } -pub fn registry_login(config: &Config, token: String, registry: Option) -> CargoResult<()> { +pub fn registry_login( + config: &Config, + token: Option, + reg: Option, +) -> CargoResult<()> { + let (registry, _) = registry(config, token.clone(), None, reg.clone(), false)?; + + let token = match token { + Some(token) => token, + None => { + println!( + "please visit {}/me and paste the API Token below", + registry.host() + ); + let mut line = String::new(); + let input = io::stdin(); + input + .lock() + .read_line(&mut line) + .chain_err(|| "failed to read stdin") + .map_err(failure::Error::from)?; + line.trim().to_string() + } + }; + let RegistryConfig { token: old_token, .. - } = registry_configuration(config, registry.clone())?; + } = registry_configuration(config, reg.clone())?; if let Some(old_token) = old_token { if old_token == token { + config.shell().status("Login", "already logged in")?; return Ok(()); } } - config::save_credentials(config, token, registry) + config::save_credentials(config, token, reg.clone())?; + config.shell().status( + "Login", + format!( + "token for `{}` saved", + reg.as_ref().map_or("crates.io", String::as_str) + ), + )?; + Ok(()) } pub struct OwnersOptions { @@ -541,13 +600,14 @@ opts.token.clone(), opts.index.clone(), opts.registry.clone(), + true, )?; if let Some(ref v) = opts.to_add { let v = v.iter().map(|s| &s[..]).collect::>(); - let msg = registry - .add_owners(&name, &v) - .map_err(|e| format_err!("failed to invite owners to crate {}: {}", name, e))?; + let msg = registry.add_owners(&name, &v).map_err(|e| { + failure::format_err!("failed to invite owners to crate {}: {}", name, e) + })?; config.shell().status("Owner", msg)?; } @@ -598,10 +658,10 @@ }; let version = match version { Some(v) => v, - None => bail!("a version must be specified to yank"), + None => failure::bail!("a version must be specified to yank"), }; - let (mut registry, _) = registry(config, token, index, reg)?; + let (mut registry, _) = registry(config, token, index, reg, true)?; if undo { config @@ -632,7 +692,7 @@ (_, Some(i)) => SourceId::for_registry(&i.to_url()?), _ => { let map = SourceConfigMap::new(config)?; - let src = map.load(SourceId::crates_io(config)?)?; + let src = map.load(SourceId::crates_io(config)?, &HashSet::new())?; Ok(src.replaced_source_id()) } } @@ -657,22 +717,7 @@ prefix } - let sid = get_source_id(config, index, reg)?; - - let mut regsrc = RegistrySource::remote(sid, config); - let cfg = match regsrc.config() { - Ok(c) => c, - Err(_) => { - regsrc - .update() - .chain_err(|| format!("failed to update {}", &sid))?; - regsrc.config()? - } - }; - - let api_host = cfg.unwrap().api.unwrap(); - let handle = http_handle(config)?; - let mut registry = Registry::new_handle(api_host, None, handle); + let (mut registry, source_id) = registry(config, None, index, reg, false)?; let (crates, total_crates) = registry .search(query, limit) .chain_err(|| "failed to retrieve search results from the registry")?; @@ -713,11 +758,15 @@ total_crates - limit ); } else if total_crates > limit && limit >= search_max_limit { - println!( - "... and {} crates more (go to http://crates.io/search?q={} to see more)", - total_crates - limit, - percent_encode(query.as_bytes(), QUERY_ENCODE_SET) - ); + let extra = if source_id.is_default_registry() { + format!( + " (go to http://crates.io/search?q={} to see more)", + percent_encode(query.as_bytes(), QUERY_ENCODE_SET) + ) + } else { + String::new() + }; + println!("... and {} crates more{}", total_crates - limit, extra); } Ok(()) diff -Nru cargo-0.33.0/src/cargo/ops/resolve.rs cargo-0.35.0/src/cargo/ops/resolve.rs --- cargo-0.33.0/src/cargo/ops/resolve.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/ops/resolve.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,18 +1,26 @@ use std::collections::HashSet; -use core::registry::PackageRegistry; -use core::resolver::{self, Method, Resolve}; -use core::{PackageId, PackageIdSpec, PackageSet, Source, SourceId, Workspace}; -use ops; -use sources::PathSource; -use util::errors::{CargoResult, CargoResultExt}; -use util::profile; +use log::{debug, trace}; -/// Resolve all dependencies for the workspace using the previous -/// lockfile as a guide if present. +use crate::core::registry::PackageRegistry; +use crate::core::resolver::{self, Method, Resolve}; +use crate::core::{PackageId, PackageIdSpec, PackageSet, Source, SourceId, Workspace}; +use crate::ops; +use crate::sources::PathSource; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::profile; + +const UNUSED_PATCH_WARNING: &str = "\ +Check that the patched package version and available features are compatible +with the dependency requirements. If the patch has a different version from +what is locked in the Cargo.lock file, run `cargo update` to use the new +version. This may also occur with an optional dependency that is not enabled."; + +/// Resolves all dependencies for the workspace using the previous +/// lock file as a guide if present. /// /// This function will also write the result of resolution as a new -/// lockfile. +/// lock file. pub fn resolve_ws<'a>(ws: &Workspace<'a>) -> CargoResult<(PackageSet<'a>, Resolve)> { let mut registry = PackageRegistry::new(ws.config())?; let resolve = resolve_with_registry(ws, &mut registry, true)?; @@ -24,7 +32,7 @@ /// taking into account `paths` overrides and activated features. pub fn resolve_ws_precisely<'a>( ws: &Workspace<'a>, - source: Option>, + source: Option>, features: &[String], all_features: bool, no_default_features: bool, @@ -46,8 +54,8 @@ pub fn resolve_ws_with_method<'a>( ws: &Workspace<'a>, - source: Option>, - method: Method, + source: Option>, + method: Method<'_>, specs: &[PackageIdSpec], ) -> CargoResult<(PackageSet<'a>, Resolve)> { let mut registry = PackageRegistry::new(ws.config())?; @@ -65,7 +73,7 @@ // Second, resolve with precisely what we're doing. Filter out // transitive dependencies if necessary, specify features, handle // overrides, etc. - let _p = profile::start("resolving w/ overrides..."); + let _p = profile::start("resolving with overrides..."); add_overrides(&mut registry, ws)?; @@ -124,19 +132,19 @@ Ok(resolve) } -/// Resolve all dependencies for a package using an optional previous instance +/// Resolves all dependencies for a package using an optional previous instance. /// of resolve to guide the resolution process. /// /// This also takes an optional hash set, `to_avoid`, which is a list of package -/// ids that should be avoided when consulting the previous instance of resolve +/// IDs that should be avoided when consulting the previous instance of resolve /// (often used in pairings with updates). /// -/// The previous resolve normally comes from a lockfile. This function does not -/// read or write lockfiles from the filesystem. +/// The previous resolve normally comes from a lock file. This function does not +/// read or write lock files from the filesystem. pub fn resolve_with_previous<'cfg>( registry: &mut PackageRegistry<'cfg>, ws: &Workspace<'cfg>, - method: Method, + method: Method<'_>, previous: Option<&Resolve>, to_avoid: Option<&HashSet>, specs: &[PackageIdSpec], @@ -144,12 +152,12 @@ warn: bool, ) -> CargoResult { // Here we place an artificial limitation that all non-registry sources - // cannot be locked at more than one revision. This means that if a git + // cannot be locked at more than one revision. This means that if a Git // repository provides more than one package, they must all be updated in // step when any of them are updated. // - // TODO: This seems like a hokey reason to single out the registry as being - // different + // TODO: this seems like a hokey reason to single out the registry as being + // different. let mut to_avoid_sources: HashSet = HashSet::new(); if let Some(to_avoid) = to_avoid { to_avoid_sources.extend( @@ -230,7 +238,7 @@ .. } => { if specs.len() > 1 && !features.is_empty() { - bail!("cannot specify features for more than one package"); + failure::bail!("cannot specify features for more than one package"); } members.extend( ws.members() @@ -241,7 +249,7 @@ // into the resolution graph. if members.is_empty() { if !(features.is_empty() && !all_features && uses_default_features) { - bail!("cannot specify features for packages outside of workspace"); + failure::bail!("cannot specify features for packages outside of workspace"); } members.extend(ws.members()); } @@ -332,6 +340,24 @@ warn, )?; resolved.register_used_patches(registry.patches()); + if register_patches { + // It would be good if this warning was more targeted and helpful + // (such as showing close candidates that failed to match). However, + // that's not terribly easy to do, so just show a general help + // message. + let warnings: Vec = resolved + .unused_patches() + .iter() + .map(|pkgid| format!("Patch `{}` was not used in the crate graph.", pkgid)) + .collect(); + if !warnings.is_empty() { + ws.config().shell().warn(format!( + "{}\n{}", + warnings.join("\n"), + UNUSED_PATCH_WARNING + ))?; + } + } if let Some(previous) = previous { resolved.merge_from(previous)?; } @@ -391,16 +417,16 @@ /// want to make sure that we properly re-resolve (conservatively) instead of /// providing an opaque error. /// -/// The logic here is somewhat subtle but there should be more comments below to -/// help out, and otherwise feel free to ask on IRC if there's questions! +/// The logic here is somewhat subtle, but there should be more comments below to +/// clarify things. /// /// Note that this function, at the time of this writing, is basically the -/// entire fix for #4127 +/// entire fix for issue #4127. fn register_previous_locks( - ws: &Workspace, - registry: &mut PackageRegistry, + ws: &Workspace<'_>, + registry: &mut PackageRegistry<'_>, resolve: &Resolve, - keep: &Fn(&PackageId) -> bool, + keep: &dyn Fn(&PackageId) -> bool, ) { let path_pkg = |id: SourceId| { if !id.is_path() { @@ -415,16 +441,16 @@ }; // Ok so we've been passed in a `keep` function which basically says "if I - // return true then this package wasn't listed for an update on the command - // line". AKA if we run `cargo update -p foo` then `keep(bar)` will return - // `true`, whereas `keep(foo)` will return `true` (roughly). + // return `true` then this package wasn't listed for an update on the command + // line". That is, if we run `cargo update -p foo` then `keep(bar)` will return + // `true`, whereas `keep(foo)` will return `false` (roughly speaking). // // This isn't actually quite what we want, however. Instead we want to // further refine this `keep` function with *all transitive dependencies* of - // the packages we're not keeping. For example consider a case like this: + // the packages we're not keeping. For example, consider a case like this: // - // * There's a crate `log` - // * There's a crate `serde` which depends on `log` + // * There's a crate `log`. + // * There's a crate `serde` which depends on `log`. // // Let's say we then run `cargo update -p serde`. This may *also* want to // update the `log` dependency as our newer version of `serde` may have a @@ -437,14 +463,15 @@ // newer version of `serde` requires a new version of `log` it'll get pulled // in (as we didn't accidentally lock it to an old version). // - // Additionally here we process all path dependencies listed in the previous + // Additionally, here we process all path dependencies listed in the previous // resolve. They can not only have their dependencies change but also // the versions of the package change as well. If this ends up happening - // then we want to make sure we don't lock a package id node that doesn't + // then we want to make sure we don't lock a package ID node that doesn't // actually exist. Note that we don't do transitive visits of all the // package's dependencies here as that'll be covered below to poison those // if they changed. let mut avoid_locking = HashSet::new(); + registry.add_to_yanked_whitelist(resolve.iter().filter(keep)); for node in resolve.iter() { if !keep(&node) { add_deps(resolve, node, &mut avoid_locking); @@ -455,7 +482,7 @@ } } - // Ok but the above loop isn't the entire story! Updates to the dependency + // Ok, but the above loop isn't the entire story! Updates to the dependency // graph can come from two locations, the `cargo update` command or // manifests themselves. For example a manifest on the filesystem may // have been updated to have an updated version requirement on `serde`. In @@ -495,16 +522,15 @@ for dep in member.dependencies() { // If this dependency didn't match anything special then we may want // to poison the source as it may have been added. If this path - // dependencies is *not* a workspace member, however, and it's an + // dependencies is **not** a workspace member, however, and it's an // optional/non-transitive dependency then it won't be necessarily // be in our lock file. If this shows up then we avoid poisoning // this source as otherwise we'd repeatedly update the registry. // // TODO: this breaks adding an optional dependency in a - // non-workspace member and then simultaneously editing the - // dependency on that crate to enable the feature. For now - // this bug is better than the always updating registry - // though... + // non-workspace member and then simultaneously editing the + // dependency on that crate to enable the feature. For now, + // this bug is better than the always-updating registry though. if !ws .members() .any(|pkg| pkg.package_id() == member.package_id()) @@ -513,20 +539,20 @@ continue; } - // If this is a path dependency then try to push it onto our - // worklist + // If this is a path dependency, then try to push it onto our + // worklist. if let Some(pkg) = path_pkg(dep.source_id()) { path_deps.push(pkg); continue; } // If we match *anything* in the dependency graph then we consider - // ourselves A-OK and assume that we'll resolve to that. + // ourselves all ok, and assume that we'll resolve to that. if resolve.iter().any(|id| dep.matches_ignoring_source(id)) { continue; } - // Ok if nothing matches, then we poison the source of this + // Ok if nothing matches, then we poison the source of these // dependencies and the previous lock file. debug!( "poisoning {} because {} looks like it changed {}", @@ -544,7 +570,7 @@ } // Alright now that we've got our new, fresh, shiny, and refined `keep` - // function let's put it to action. Take a look at the previous lockfile, + // function let's put it to action. Take a look at the previous lock file, // filter everything by this callback, and then shove everything else into // the registry as a locked dependency. let keep = |id: &PackageId| keep(id) && !avoid_locking.contains(id); @@ -554,7 +580,7 @@ registry.register_lock(node, deps); } - /// recursively add `node` and all its transitive dependencies to `set` + /// Recursively add `node` and all its transitive dependencies to `set`. fn add_deps(resolve: &Resolve, node: PackageId, set: &mut HashSet) { if !set.insert(node) { return; diff -Nru cargo-0.33.0/src/cargo/sources/config.rs cargo-0.35.0/src/cargo/sources/config.rs --- cargo-0.33.0/src/cargo/sources/config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,16 +4,17 @@ //! structure usable by Cargo itself. Currently this is primarily used to map //! sources to one another via the `replace-with` key in `.cargo/config`. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; +use log::debug; use url::Url; -use core::{GitReference, Source, SourceId}; -use sources::{ReplacedSource, CRATES_IO_REGISTRY}; -use util::config::ConfigValue; -use util::errors::{CargoResult, CargoResultExt}; -use util::{Config, ToUrl}; +use crate::core::{GitReference, PackageId, Source, SourceId}; +use crate::sources::{ReplacedSource, CRATES_IO_REGISTRY}; +use crate::util::config::ConfigValue; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{Config, ToUrl}; #[derive(Clone)] pub struct SourceConfigMap<'cfg> { @@ -72,11 +73,15 @@ self.config } - pub fn load(&self, id: SourceId) -> CargoResult> { + pub fn load( + &self, + id: SourceId, + yanked_whitelist: &HashSet, + ) -> CargoResult> { debug!("loading: {}", id); let mut name = match self.id2name.get(&id) { Some(name) => name, - None => return Ok(id.load(self.config)?), + None => return Ok(id.load(self.config, yanked_whitelist)?), }; let mut path = Path::new("/"); let orig_name = name; @@ -84,7 +89,7 @@ loop { let cfg = match self.cfgs.get(name) { Some(cfg) => cfg, - None => bail!( + None => failure::bail!( "could not find a configured source with the \ name `{}` when attempting to lookup `{}` \ (configuration in `{}`)", @@ -98,7 +103,7 @@ name = s; path = p; } - None if id == cfg.id => return Ok(id.load(self.config)?), + None if id == cfg.id => return Ok(id.load(self.config, yanked_whitelist)?), None => { new_id = cfg.id.with_precise(id.precise().map(|s| s.to_string())); break; @@ -106,7 +111,7 @@ } debug!("following pointer to {}", name); if name == orig_name { - bail!( + failure::bail!( "detected a cycle of `replace-with` sources, the source \ `{}` is eventually replaced with itself \ (configuration in `{}`)", @@ -115,10 +120,17 @@ ) } } - let new_src = new_id.load(self.config)?; - let old_src = id.load(self.config)?; + + let new_src = new_id.load( + self.config, + &yanked_whitelist + .iter() + .map(|p| p.map_source(id, new_id)) + .collect(), + )?; + let old_src = id.load(self.config, yanked_whitelist)?; if !new_src.supports_checksums() && old_src.supports_checksums() { - bail!( + failure::bail!( "\ cannot replace `{orig}` with `{name}`, the source `{orig}` supports \ checksums, but `{name}` does not @@ -131,7 +143,7 @@ } if old_src.requires_precise() && id.precise().is_none() { - bail!( + failure::bail!( "\ the source {orig} requires a lock file to be present first before it can be used against vendored source code @@ -176,7 +188,7 @@ } if let Some(val) = table.get("git") { let url = url(val, &format!("source.{}.git", name))?; - let try = |s: &str| { + let r#try = |s: &str| { let val = match table.get(s) { Some(s) => s, None => return Ok(None), @@ -184,11 +196,11 @@ let key = format!("source.{}.{}", name, s); val.string(&key).map(Some) }; - let reference = match try("branch")? { + let reference = match r#try("branch")? { Some(b) => GitReference::Branch(b.0.to_string()), - None => match try("tag")? { + None => match r#try("tag")? { Some(b) => GitReference::Tag(b.0.to_string()), - None => match try("rev")? { + None => match r#try("rev")? { Some(b) => GitReference::Rev(b.0.to_string()), None => GitReference::Branch("master".to_string()), }, @@ -202,14 +214,14 @@ let mut srcs = srcs.into_iter(); let src = srcs.next().ok_or_else(|| { - format_err!( + failure::format_err!( "no source URL specified for `source.{}`, need \ either `registry` or `local-registry` defined", name ) })?; if srcs.next().is_some() { - bail!("more than one source URL specified for `source.{}`", name) + failure::bail!("more than one source URL specified for `source.{}`", name) } let mut replace_with = None; diff -Nru cargo-0.33.0/src/cargo/sources/directory.rs cargo-0.35.0/src/cargo/sources/directory.rs --- cargo-0.33.0/src/cargo/sources/directory.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/directory.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,16 +4,14 @@ use std::io::Read; use std::path::{Path, PathBuf}; -use hex; +use serde::Deserialize; -use serde_json; - -use core::source::MaybePackage; -use core::{Dependency, Package, PackageId, Source, SourceId, Summary}; -use sources::PathSource; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::{Config, Sha256}; +use crate::core::source::MaybePackage; +use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::sources::PathSource; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::{Config, Sha256}; pub struct DirectorySource<'cfg> { source_id: SourceId, @@ -40,13 +38,13 @@ } impl<'cfg> Debug for DirectorySource<'cfg> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "DirectorySource {{ root: {:?} }}", self.root) } } impl<'cfg> Source for DirectorySource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let packages = self.packages.values().map(|p| &p.0); let matches = packages.filter(|pkg| dep.matches(pkg.summary())); for summary in matches.map(|pkg| pkg.summary().clone()) { @@ -55,7 +53,7 @@ Ok(()) } - fn fuzzy_query(&mut self, _dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn fuzzy_query(&mut self, _dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let packages = self.packages.values().map(|p| &p.0); for summary in packages.map(|pkg| pkg.summary().clone()) { f(summary); @@ -157,7 +155,7 @@ .map(|p| &p.0) .cloned() .map(MaybePackage::Ready) - .ok_or_else(|| format_err!("failed to find package with id: {}", id)) + .ok_or_else(|| failure::format_err!("failed to find package with id: {}", id)) } fn finish_download(&mut self, _id: PackageId, _data: Vec) -> CargoResult { @@ -171,7 +169,7 @@ fn verify(&self, id: PackageId) -> CargoResult<()> { let (pkg, cksum) = match self.packages.get(&id) { Some(&(ref pkg, ref cksum)) => (pkg, cksum), - None => bail!("failed to find entry for `{}` in directory source", id), + None => failure::bail!("failed to find entry for `{}` in directory source", id), }; let mut buf = [0; 16 * 1024]; @@ -192,7 +190,7 @@ let actual = hex::encode(h.finish()); if &*actual != cksum { - bail!( + failure::bail!( "\ the listed checksum of `{}` has changed:\n\ expected: {}\n\ @@ -216,4 +214,6 @@ fn describe(&self) -> String { format!("directory source `{}`", self.root.display()) } + + fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {} } diff -Nru cargo-0.33.0/src/cargo/sources/git/mod.rs cargo-0.35.0/src/cargo/sources/git/mod.rs --- cargo-0.33.0/src/cargo/sources/git/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/git/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -pub use self::utils::{fetch, GitCheckout, GitDatabase, GitRemote, GitRevision}; pub use self::source::{canonicalize_url, GitSource}; -mod utils; +pub use self::utils::{fetch, GitCheckout, GitDatabase, GitRemote, GitRevision}; mod source; +mod utils; diff -Nru cargo-0.33.0/src/cargo/sources/git/source.rs cargo-0.35.0/src/cargo/sources/git/source.rs --- cargo-0.33.0/src/cargo/sources/git/source.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/git/source.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,15 +1,16 @@ use std::fmt::{self, Debug, Formatter}; +use log::trace; use url::Url; -use core::source::{MaybePackage, Source, SourceId}; -use core::GitReference; -use core::{Dependency, Package, PackageId, Summary}; -use sources::git::utils::{GitRemote, GitRevision}; -use sources::PathSource; -use util::errors::CargoResult; -use util::hex::short_hash; -use util::Config; +use crate::core::source::{MaybePackage, Source, SourceId}; +use crate::core::GitReference; +use crate::core::{Dependency, Package, PackageId, Summary}; +use crate::sources::git::utils::{GitRemote, GitRevision}; +use crate::sources::PathSource; +use crate::util::errors::CargoResult; +use crate::util::hex::short_hash; +use crate::util::Config; pub struct GitSource<'cfg> { remote: GitRemote, @@ -70,36 +71,36 @@ Ok(format!("{}-{}", ident, short_hash(&url))) } -// Some hacks and heuristics for making equivalent URLs hash the same +// Some hacks and heuristics for making equivalent URLs hash the same. pub fn canonicalize_url(url: &Url) -> CargoResult { let mut url = url.clone(); - // cannot-be-a-base-urls are not supported - // eg. github.com:rust-lang-nursery/rustfmt.git + // cannot-be-a-base-urls (e.g., `github.com:rust-lang-nursery/rustfmt.git`) + // are not supported. if url.cannot_be_a_base() { - bail!( + failure::bail!( "invalid url `{}`: cannot-be-a-base-URLs are not supported", url ) } - // Strip a trailing slash + // Strip a trailing slash. if url.path().ends_with('/') { url.path_segments_mut().unwrap().pop_if_empty(); } - // HACKHACK: For GitHub URL's specifically just lowercase - // everything. GitHub treats both the same, but they hash + // HACK: for GitHub URLs specifically, just lower-case + // everything. GitHub treats both the same, but they hash // differently, and we're gonna be hashing them. This wants a more // general solution, and also we're almost certainly not using the - // same case conversion rules that GitHub does. (#84) + // same case conversion rules that GitHub does. (See issue #84.) if url.host_str() == Some("github.com") { url.set_scheme("https").unwrap(); let path = url.path().to_lowercase(); url.set_path(&path); } - // Repos generally can be accessed with or w/o '.git' + // Repos can generally be accessed with or without `.git` extension. let needs_chopping = url.path().ends_with(".git"); if needs_chopping { let last = { @@ -113,7 +114,7 @@ } impl<'cfg> Debug for GitSource<'cfg> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "git repo at {}", self.remote.url())?; match self.reference.pretty_ref() { @@ -124,19 +125,19 @@ } impl<'cfg> Source for GitSource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let src = self .path_source .as_mut() - .expect("BUG: update() must be called before query()"); + .expect("BUG: `update()` must be called before `query()`"); src.query(dep, f) } - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let src = self .path_source .as_mut() - .expect("BUG: update() must be called before query()"); + .expect("BUG: `update()` must be called before `query()`"); src.fuzzy_query(dep, f) } @@ -161,7 +162,7 @@ let db_path = lock.parent().join("db").join(&self.ident); if self.config.cli_unstable().offline && !db_path.exists() { - bail!( + failure::bail!( "can't checkout from '{}': you are in the offline mode (-Z offline)", self.remote.url() ); @@ -188,9 +189,8 @@ (self.remote.db_at(&db_path)?, actual_rev.unwrap()) }; - // Don’t use the full hash, - // to contribute less to reaching the path length limit on Windows: - // https://github.com/servo/servo/pull/14397 + // Don’t use the full hash, in order to contribute less to reaching the path length limit + // on Windows. See . let short_id = db.to_short_id(&actual_rev).unwrap(); let checkout_path = lock @@ -216,13 +216,13 @@ fn download(&mut self, id: PackageId) -> CargoResult { trace!( - "getting packages for package id `{}` from `{:?}`", + "getting packages for package ID `{}` from `{:?}`", id, self.remote ); self.path_source .as_mut() - .expect("BUG: update() must be called before get()") + .expect("BUG: `update()` must be called before `get()`") .download(id) } @@ -235,15 +235,17 @@ } fn describe(&self) -> String { - format!("git repository {}", self.source_id) + format!("Git repository {}", self.source_id) } + + fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {} } #[cfg(test)] mod test { use super::ident; + use crate::util::ToUrl; use url::Url; - use util::ToUrl; #[test] pub fn test_url_to_path_ident_with_path() { diff -Nru cargo-0.33.0/src/cargo/sources/git/utils.rs cargo-0.35.0/src/cargo/sources/git/utils.rs --- cargo-0.33.0/src/cargo/sources/git/utils.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/git/utils.rs 2019-04-01 21:32:07.000000000 +0000 @@ -7,14 +7,16 @@ use curl::easy::{Easy, List}; use git2::{self, ObjectType}; +use log::{debug, info}; use serde::ser; +use serde::Serialize; use url::Url; -use core::GitReference; -use util::errors::{CargoError, CargoResult, CargoResultExt}; -use util::paths; -use util::process_builder::process; -use util::{internal, network, Config, Progress, ToUrl}; +use crate::core::GitReference; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::process_builder::process; +use crate::util::{internal, network, Config, Progress, ToUrl}; #[derive(PartialEq, Clone, Debug)] pub struct GitRevision(git2::Oid); @@ -34,7 +36,7 @@ } impl fmt::Display for GitRevision { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } @@ -67,7 +69,7 @@ /// `GitCheckout` is a local checkout of a particular revision. Calling /// `clone_into` with a reference will resolve the reference into a revision, -/// and return a `CargoError` if no revision for that reference was found. +/// and return a `failure::Error` if no revision for that reference was found. #[derive(Serialize)] pub struct GitCheckout<'a> { database: &'a GitDatabase, @@ -109,7 +111,8 @@ let (repo, rev) = match repo_and_rev { Some(pair) => pair, None => { - let repo = self.clone_into(into, cargo_config) + let repo = self + .clone_into(into, cargo_config) .chain_err(|| format!("failed to clone into: {}", into.display()))?; let rev = reference.resolve(&repo)?; (repo, rev) @@ -163,7 +166,7 @@ rev: GitRevision, dest: &Path, cargo_config: &Config, - ) -> CargoResult { + ) -> CargoResult> { let mut checkout = None; if let Ok(repo) = git2::Repository::open(dest) { let mut co = GitCheckout::new(dest, self, rev.clone(), repo); @@ -211,13 +214,14 @@ let obj = obj.peel(ObjectType::Commit)?; Ok(obj.id()) })() - .chain_err(|| format!("failed to find tag `{}`", s))?, + .chain_err(|| format!("failed to find tag `{}`", s))?, GitReference::Branch(ref s) => { - let b = repo.find_branch(s, git2::BranchType::Local) + let b = repo + .find_branch(s, git2::BranchType::Local) .chain_err(|| format!("failed to find branch `{}`", s))?; b.get() .target() - .ok_or_else(|| format_err!("branch `{}` did not have a target", s))? + .ok_or_else(|| failure::format_err!("branch `{}` did not have a target", s))? } GitReference::Rev(ref s) => { let obj = repo.revparse_single(s)?; @@ -253,7 +257,8 @@ config: &Config, ) -> CargoResult> { let dirname = into.parent().unwrap(); - fs::create_dir_all(&dirname).chain_err(|| format!("Couldn't mkdir {}", dirname.display()))?; + fs::create_dir_all(&dirname) + .chain_err(|| format!("Couldn't mkdir {}", dirname.display()))?; if into.exists() { paths::remove_dir_all(into)?; } @@ -316,7 +321,7 @@ } fn reset(&self, config: &Config) -> CargoResult<()> { - // If we're interrupted while performing this reset (e.g. we die because + // If we're interrupted while performing this reset (e.g., we die because // of a signal) Cargo needs to be sure to try to check out this repo // again on the next go-round. // @@ -352,7 +357,7 @@ fn update_submodule( parent: &git2::Repository, - child: &mut git2::Submodule, + child: &mut git2::Submodule<'_>, cargo_config: &Config, ) -> CargoResult<()> { child.init(false)?; @@ -424,7 +429,7 @@ /// /// * If a username/password is allowed, then we fallback to git2-rs's /// implementation of the credential helper. This is what is configured -/// with `credential.helper` in git, and is the interface for the OSX +/// with `credential.helper` in git, and is the interface for the macOS /// keychain, for example. /// /// * After the above two have failed, we just kinda grapple attempting to @@ -436,7 +441,7 @@ /// attempted and we don't try the same ones again. fn with_authentication(url: &str, cfg: &git2::Config, mut f: F) -> CargoResult where - F: FnMut(&mut git2::Credentials) -> CargoResult, + F: FnMut(&mut git2::Credentials<'_>) -> CargoResult, { let mut cred_helper = git2::CredentialHelper::new(url); cred_helper.config(cfg); @@ -479,7 +484,7 @@ // ssh-agent currently. // // If we get called with this then the only way that should be possible - // is if a username is specified in the URL itself (e.g. `username` is + // is if a username is specified in the URL itself (e.g., `username` is // Some), hence the unwrap() here. We try custom usernames down below. if allowed.contains(git2::CredentialType::SSH_KEY) && !tried_sshkey { // If ssh-agent authentication fails, libgit2 will keep @@ -498,7 +503,12 @@ // but we currently don't! Right now the only way we support fetching a // plaintext password is through the `credential.helper` support, so // fetch that here. - if allowed.contains(git2::CredentialType::USER_PASS_PLAINTEXT) { + // + // If ssh-agent authentication fails, libgit2 will keep calling this + // callback asking for other authentication methods to try. Check + // cred_helper_bad to make sure we only try the git credentail helper + // once, to avoid looping forever. + if allowed.contains(git2::CredentialType::USER_PASS_PLAINTEXT) && cred_helper_bad.is_none() { let r = git2::Cred::credential_helper(cfg, url, username); cred_helper_bad = Some(r.is_err()); return r; @@ -566,7 +576,7 @@ // for another mode of authentication. // // Essentially, if `attempts == 2` then in theory the only error was - // that this username failed to authenticate (e.g. no other network + // that this username failed to authenticate (e.g., no other network // errors happened). Otherwise something else is funny so we bail // out. if attempts != 2 { @@ -582,7 +592,7 @@ // In the case of an authentication failure (where we tried something) then // we try to give a more helpful error message about precisely what we // tried. - let res = res.map_err(CargoError::from).chain_err(|| { + let res = res.map_err(failure::Error::from).chain_err(|| { let mut msg = "failed to authenticate when downloading \ repository" .to_string(); @@ -617,7 +627,7 @@ Ok(res) } -fn reset(repo: &git2::Repository, obj: &git2::Object, config: &Config) -> CargoResult<()> { +fn reset(repo: &git2::Repository, obj: &git2::Object<'_>, config: &Config) -> CargoResult<()> { let mut pb = Progress::new("Checkout", config); let mut opts = git2::build::CheckoutBuilder::new(); opts.progress(|_, cur, max| { @@ -631,7 +641,7 @@ git_config: &git2::Config, url: &Url, config: &Config, - cb: &mut FnMut(git2::FetchOptions) -> CargoResult<()>, + cb: &mut dyn FnMut(git2::FetchOptions<'_>) -> CargoResult<()>, ) -> CargoResult<()> { let mut progress = Progress::new("Fetch", config); network::with_retry(config, || { @@ -663,13 +673,13 @@ config: &Config, ) -> CargoResult<()> { if config.frozen() { - bail!( + failure::bail!( "attempting to update a git repository, but --frozen \ was specified" ) } if !config.network_allowed() { - bail!("can't update a git repository in the offline mode") + failure::bail!("can't update a git repository in the offline mode") } // If we're fetching from GitHub, attempt GitHub's special fast path for @@ -720,7 +730,8 @@ let mut repo_reinitialized = false; loop { debug!("initiating fetch of {} from {}", refspec, url); - let res = repo.remote_anonymous(url.as_str())? + let res = repo + .remote_anonymous(url.as_str())? .fetch(&[refspec], Some(&mut opts), None); let err = match res { Ok(()) => break, @@ -759,7 +770,9 @@ .arg(url.to_string()) .arg(refspec) .cwd(repo.path()); - config.shell().verbose(|s| s.status("Running", &cmd.to_string()))?; + config + .shell() + .verbose(|s| s.status("Running", &cmd.to_string()))?; cmd.exec()?; Ok(()) } @@ -875,18 +888,20 @@ /// just return a `bool`. Any real errors will be reported through the normal /// update path above. fn github_up_to_date(handle: &mut Easy, url: &Url, oid: &git2::Oid) -> bool { - macro_rules! try { - ($e:expr) => (match $e { - Some(e) => e, - None => return false, - }) + macro_rules! r#try { + ($e:expr) => { + match $e { + Some(e) => e, + None => return false, + } + }; } // This expects GitHub urls in the form `github.com/user/repo` and nothing // else - let mut pieces = try!(url.path_segments()); - let username = try!(pieces.next()); - let repo = try!(pieces.next()); + let mut pieces = r#try!(url.path_segments()); + let username = r#try!(pieces.next()); + let repo = r#try!(pieces.next()); if pieces.next().is_some() { return false; } @@ -895,14 +910,14 @@ "https://api.github.com/repos/{}/{}/commits/master", username, repo ); - try!(handle.get(true).ok()); - try!(handle.url(&url).ok()); - try!(handle.useragent("cargo").ok()); + r#try!(handle.get(true).ok()); + r#try!(handle.url(&url).ok()); + r#try!(handle.useragent("cargo").ok()); let mut headers = List::new(); - try!(headers.append("Accept: application/vnd.github.3.sha").ok()); - try!(headers.append(&format!("If-None-Match: \"{}\"", oid)).ok()); - try!(handle.http_headers(headers).ok()); - try!(handle.perform().ok()); + r#try!(headers.append("Accept: application/vnd.github.3.sha").ok()); + r#try!(headers.append(&format!("If-None-Match: \"{}\"", oid)).ok()); + r#try!(handle.http_headers(headers).ok()); + r#try!(handle.perform().ok()); - try!(handle.response_code().ok()) == 304 + r#try!(handle.response_code().ok()) == 304 } diff -Nru cargo-0.33.0/src/cargo/sources/path.rs cargo-0.35.0/src/cargo/sources/path.rs --- cargo-0.33.0/src/cargo/sources/path.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/path.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,17 +3,17 @@ use std::path::{Path, PathBuf}; use filetime::FileTime; -use git2; use glob::Pattern; use ignore::gitignore::GitignoreBuilder; use ignore::Match; +use log::{trace, warn}; -use core::source::MaybePackage; -use core::{Dependency, Package, PackageId, Source, SourceId, Summary}; -use ops; -use util::paths; -use util::Config; -use util::{self, internal, CargoResult}; +use crate::core::source::MaybePackage; +use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::ops; +use crate::util::paths; +use crate::util::Config; +use crate::util::{internal, CargoResult}; pub struct PathSource<'cfg> { source_id: SourceId, @@ -25,7 +25,7 @@ } impl<'cfg> PathSource<'cfg> { - /// Invoked with an absolute path to a directory that contains a Cargo.toml. + /// Invoked with an absolute path to a directory that contains a `Cargo.toml`. /// /// This source will only return the package at precisely the `path` /// specified, and it will be an error if there's not a package at `path`. @@ -103,19 +103,19 @@ /// stages are: /// /// 1) Only warn users about the future change iff their matching rules are - /// affected. (CURRENT STAGE) + /// affected. (CURRENT STAGE) /// /// 2) Switch to the new strategy and update documents. Still keep warning /// affected users. /// /// 3) Drop the old strategy and no more warnings. /// - /// See for more info. + /// See rust-lang/cargo#4268 for more info. pub fn list_files(&self, pkg: &Package) -> CargoResult> { let root = pkg.root(); let no_include_option = pkg.manifest().include().is_empty(); - // glob-like matching rules + // Glob-like matching rules. let glob_parse = |p: &String| { let pattern: &str = if p.starts_with('/') { @@ -124,7 +124,7 @@ p }; Pattern::new(pattern) - .map_err(|e| format_err!("could not parse glob pattern `{}`: {}", p, e)) + .map_err(|e| failure::format_err!("could not parse glob pattern `{}`: {}", p, e)) }; let glob_exclude = pkg @@ -148,7 +148,7 @@ .any(|pattern| pattern.matches_path(relative_path)) } - // include and exclude options are mutually exclusive. + // "Include" and "exclude" options are mutually exclusive. if no_include_option { !glob_match(&glob_exclude, relative_path) } else { @@ -156,7 +156,7 @@ } }; - // ignore-like matching rules + // Ignore-like matching rules. let mut exclude_builder = GitignoreBuilder::new(root); for rule in pkg.manifest().exclude() { @@ -171,14 +171,14 @@ let ignore_include = include_builder.build()?; let ignore_should_package = |relative_path: &Path| -> CargoResult { - // include and exclude options are mutually exclusive. + // "Include" and "exclude" options are mutually exclusive. if no_include_option { match ignore_exclude .matched_path_or_any_parents(relative_path, /* is_dir */ false) { Match::None => Ok(true), Match::Ignore(_) => Ok(false), - Match::Whitelist(pattern) => Err(format_err!( + Match::Whitelist(pattern) => Err(failure::format_err!( "exclude rules cannot start with `!`: {}", pattern.original() )), @@ -189,7 +189,7 @@ { Match::None => Ok(false), Match::Ignore(_) => Ok(true), - Match::Whitelist(pattern) => Err(format_err!( + Match::Whitelist(pattern) => Err(failure::format_err!( "include rules cannot start with `!`: {}", pattern.original() )), @@ -197,10 +197,10 @@ } }; - // matching to paths + // Matching to paths. let mut filter = |path: &Path| -> CargoResult { - let relative_path = util::without_prefix(path, root).unwrap(); + let relative_path = path.strip_prefix(root)?; let glob_should_package = glob_should_package(relative_path); let ignore_should_package = ignore_should_package(relative_path)?; @@ -210,14 +210,16 @@ self.config.shell().warn(format!( "Pattern matching for Cargo's include/exclude fields is changing and \ file `{}` WILL be excluded in a future Cargo version.\n\ - See https://github.com/rust-lang/cargo/issues/4268 for more info", + See for more \ + information.", relative_path.display() ))?; } else { self.config.shell().warn(format!( "Pattern matching for Cargo's include/exclude fields is changing and \ file `{}` WILL NOT be included in a future Cargo version.\n\ - See https://github.com/rust-lang/cargo/issues/4268 for more info", + See for more \ + information.", relative_path.display() ))?; } @@ -225,24 +227,26 @@ self.config.shell().warn(format!( "Pattern matching for Cargo's include/exclude fields is changing and \ file `{}` WILL NOT be excluded in a future Cargo version.\n\ - See https://github.com/rust-lang/cargo/issues/4268 for more info", + See for more \ + information.", relative_path.display() ))?; } else { self.config.shell().warn(format!( "Pattern matching for Cargo's include/exclude fields is changing and \ file `{}` WILL be included in a future Cargo version.\n\ - See https://github.com/rust-lang/cargo/issues/4268 for more info", + See for more \ + information.", relative_path.display() ))?; } } - // Update to ignore_should_package for Stage 2 + // Update to `ignore_should_package` for Stage 2. Ok(glob_should_package) }; - // attempt git-prepopulate only if no `include` (rust-lang/cargo#4135) + // Attempt Git-prepopulate only if no `include` (see rust-lang/cargo#4135). if no_include_option { if let Some(result) = self.discover_git_and_list_files(pkg, root, &mut filter) { return result; @@ -251,40 +255,40 @@ self.list_files_walk(pkg, &mut filter) } - // Returns Some(_) if found sibling Cargo.toml and .git folder; - // otherwise caller should fall back on full file list. + // Returns `Some(_)` if found sibling `Cargo.toml` and `.git` directory; + // otherwise, caller should fall back on full file list. fn discover_git_and_list_files( &self, pkg: &Package, root: &Path, - filter: &mut FnMut(&Path) -> CargoResult, + filter: &mut dyn FnMut(&Path) -> CargoResult, ) -> Option>> { - // If this package is in a git repository, then we really do want to - // query the git repository as it takes into account items such as - // .gitignore. We're not quite sure where the git repository is, + // If this package is in a Git repository, then we really do want to + // query the Git repository as it takes into account items such as + // `.gitignore`. We're not quite sure where the Git repository is, // however, so we do a bit of a probe. // // We walk this package's path upwards and look for a sibling - // Cargo.toml and .git folder. If we find one then we assume that we're - // part of that repository. + // `Cargo.toml` and `.git` directory. If we find one then we assume that + // we're part of that repository. let mut cur = root; loop { if cur.join("Cargo.toml").is_file() { - // If we find a git repository next to this Cargo.toml, we still + // If we find a Git repository next to this `Cargo.toml`, we still // check to see if we are indeed part of the index. If not, then - // this is likely an unrelated git repo, so keep going. + // this is likely an unrelated Git repo, so keep going. if let Ok(repo) = git2::Repository::open(cur) { let index = match repo.index() { Ok(index) => index, Err(err) => return Some(Err(err.into())), }; - let path = util::without_prefix(root, cur).unwrap().join("Cargo.toml"); + let path = root.strip_prefix(cur).unwrap().join("Cargo.toml"); if index.get_path(&path, 0).is_some() { return Some(self.list_files_git(pkg, &repo, filter)); } } } - // don't cross submodule boundaries + // Don't cross submodule boundaries. if cur.join(".git").is_dir() { break; } @@ -300,7 +304,7 @@ &self, pkg: &Package, repo: &git2::Repository, - filter: &mut FnMut(&Path) -> CargoResult, + filter: &mut dyn FnMut(&Path) -> CargoResult, ) -> CargoResult> { warn!("list_files_git {}", pkg.package_id()); let index = repo.index()?; @@ -311,9 +315,9 @@ let mut ret = Vec::::new(); - // We use information from the git repository to guide us in traversing + // We use information from the Git repository to guide us in traversing // its tree. The primary purpose of this is to take advantage of the - // .gitignore and auto-ignore files that don't matter. + // `.gitignore` and auto-ignore files that don't matter. // // Here we're also careful to look at both tracked and untracked files as // the untracked files are often part of a build and may become relevant @@ -325,7 +329,7 @@ }); let mut opts = git2::StatusOptions::new(); opts.include_untracked(true); - if let Some(suffix) = util::without_prefix(pkg_path, root) { + if let Ok(suffix) = pkg_path.strip_prefix(root) { opts.pathspec(suffix); } let statuses = repo.statuses(Some(&mut opts))?; @@ -347,14 +351,14 @@ } match file_path.file_name().and_then(|s| s.to_str()) { - // Filter out Cargo.lock and target always, we don't want to + // Filter out `Cargo.lock` and `target` always; we don't want to // package a lock file no one will ever read and we also avoid - // build artifacts + // build artifacts. Some("Cargo.lock") | Some("target") => continue, // Keep track of all sub-packages found and also strip out all // matches we've found so far. Note, though, that if we find - // our own `Cargo.toml` we keep going. + // our own `Cargo.toml`, we keep going. Some("Cargo.toml") => { let path = file_path.parent().unwrap(); if path != pkg_path { @@ -376,10 +380,10 @@ if is_dir.unwrap_or_else(|| file_path.is_dir()) { warn!(" found submodule {}", file_path.display()); - let rel = util::without_prefix(&file_path, root).unwrap(); - let rel = rel - .to_str() - .ok_or_else(|| format_err!("invalid utf-8 filename: {}", rel.display()))?; + let rel = file_path.strip_prefix(root)?; + let rel = rel.to_str().ok_or_else(|| { + failure::format_err!("invalid utf-8 filename: {}", rel.display()) + })?; // Git submodules are currently only named through `/` path // separators, explicitly not `\` which windows uses. Who knew? let rel = rel.replace(r"\", "/"); @@ -422,7 +426,7 @@ fn list_files_walk( &self, pkg: &Package, - filter: &mut FnMut(&Path) -> CargoResult, + filter: &mut dyn FnMut(&Path) -> CargoResult, ) -> CargoResult> { let mut ret = Vec::new(); PathSource::walk(pkg.root(), &mut ret, true, filter)?; @@ -433,7 +437,7 @@ path: &Path, ret: &mut Vec, is_root: bool, - filter: &mut FnMut(&Path) -> CargoResult, + filter: &mut dyn FnMut(&Path) -> CargoResult, ) -> CargoResult<()> { if !fs::metadata(&path).map(|m| m.is_dir()).unwrap_or(false) { if (*filter)(path)? { @@ -441,7 +445,7 @@ } return Ok(()); } - // Don't recurse into any sub-packages that we have + // Don't recurse into any sub-packages that we have. if !is_root && fs::metadata(&path.join("Cargo.toml")).is_ok() { return Ok(()); } @@ -449,19 +453,18 @@ // For package integration tests, we need to sort the paths in a deterministic order to // be able to match stdout warnings in the same order. // - // TODO: Drop collect and sort after transition period and dropping warning tests. - // See - // and + // TODO: drop `collect` and sort after transition period and dropping warning tests. + // See rust-lang/cargo#4268 and rust-lang/cargo#4270. let mut entries: Vec = fs::read_dir(path)?.map(|e| e.unwrap().path()).collect(); entries.sort_unstable_by(|a, b| a.as_os_str().cmp(b.as_os_str())); for path in entries { let name = path.file_name().and_then(|s| s.to_str()); - // Skip dotfile directories + // Skip dotfile directories. if name.map(|s| s.starts_with('.')) == Some(true) { continue; } if is_root { - // Skip cargo artifacts + // Skip Cargo artifacts. match name { Some("target") | Some("Cargo.lock") => continue, _ => {} @@ -480,11 +483,11 @@ let mut max = FileTime::zero(); let mut max_path = PathBuf::new(); for file in self.list_files(pkg)? { - // An fs::stat error here is either because path is a + // An `fs::stat` error here is either because path is a // broken symlink, a permissions error, or a race - // condition where this path was rm'ed - either way, - // we can ignore the error and treat the path's mtime - // as 0. + // condition where this path was `rm`-ed -- either way, + // we can ignore the error and treat the path's `mtime` + // as `0`. let mtime = paths::mtime(&file).unwrap_or_else(|_| FileTime::zero()); if mtime > max { max = mtime; @@ -501,13 +504,13 @@ } impl<'cfg> Debug for PathSource<'cfg> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "the paths source") } } impl<'cfg> Source for PathSource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { for s in self.packages.iter().map(|p| p.summary()) { if dep.matches(s) { f(s.clone()) @@ -516,7 +519,7 @@ Ok(()) } - fn fuzzy_query(&mut self, _dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn fuzzy_query(&mut self, _dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { for s in self.packages.iter().map(|p| p.summary()) { f(s.clone()) } @@ -569,4 +572,6 @@ Err(_) => self.source_id.to_string(), } } + + fn add_to_yanked_whitelist(&mut self, _pkgs: &[PackageId]) {} } diff -Nru cargo-0.33.0/src/cargo/sources/registry/index.rs cargo-0.35.0/src/cargo/sources/registry/index.rs --- cargo-0.33.0/src/cargo/sources/registry/index.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/registry/index.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,22 +1,21 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::path::Path; use std::str; +use log::{info, trace}; use semver::Version; -use serde_json; -use core::dependency::Dependency; -use core::{PackageId, SourceId, Summary}; -use sources::registry::RegistryData; -use sources::registry::{RegistryPackage, INDEX_LOCK}; -use util::{internal, CargoResult, Config, Filesystem}; - -/// Crates.io treats hyphen and underscores as interchangeable -/// but, the index and old cargo do not. So the index must store uncanonicalized version -/// of the name so old cargos can find it. -/// This loop tries all possible combinations of switching -/// hyphen and underscores to find the uncanonicalized one. -/// As all stored inputs have the correct spelling, we start with the spelling as provided. +use crate::core::dependency::Dependency; +use crate::core::{PackageId, SourceId, Summary}; +use crate::sources::registry::RegistryData; +use crate::sources::registry::{RegistryPackage, INDEX_LOCK}; +use crate::util::{internal, CargoResult, Config, Filesystem, ToSemver}; + +/// Crates.io treats hyphen and underscores as interchangeable, but the index and old Cargo do not. +/// Therefore, the index must store uncanonicalized version of the name so old Cargo's can find it. +/// This loop tries all possible combinations of switching hyphen and underscores to find the +/// uncanonicalized one. As all stored inputs have the correct spelling, we start with the spelling +/// as-provided. struct UncanonicalizedIter<'s> { input: &'s str, num_hyphen_underscore: u32, @@ -101,7 +100,8 @@ source_id: SourceId, path: Filesystem, cache: HashMap<&'static str, Vec<(Summary, bool)>>, - hashes: HashMap<&'static str, HashMap>, // (name, vers) => cksum + // `(name, vers)` -> `checksum` + hashes: HashMap<&'static str, HashMap>, config: &'cfg Config, locked: bool, } @@ -123,8 +123,8 @@ } } - /// Return the hash listed for a specified PackageId. - pub fn hash(&mut self, pkg: PackageId, load: &mut RegistryData) -> CargoResult { + /// Returns the hash listed for a specified `PackageId`. + pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> CargoResult { let name = pkg.name().as_str(); let version = pkg.version(); if let Some(s) = self.hashes.get(name).and_then(|v| v.get(version)) { @@ -139,14 +139,13 @@ .map(|s| s.clone()) } - /// Parse the on-disk metadata for the package provided + /// Parses the on-disk metadata for the package provided. /// - /// Returns a list of pairs of (summary, yanked) for the package name - /// specified. + /// Returns a list of pairs of `(summary, yanked)` for the package name specified. pub fn summaries( &mut self, name: &'static str, - load: &mut RegistryData, + load: &mut dyn RegistryData, ) -> CargoResult<&Vec<(Summary, bool)>> { if self.cache.contains_key(name) { return Ok(&self.cache[name]); @@ -159,7 +158,7 @@ fn load_summaries( &mut self, name: &str, - load: &mut RegistryData, + load: &mut dyn RegistryData, ) -> CargoResult> { // Prepare the `RegistryData` which will lazily initialize internal data // structures. Note that this is also importantly needed to initialize @@ -184,7 +183,7 @@ .flat_map(|c| c.to_lowercase()) .collect::(); - // see module comment for why this is structured the way it is + // See module comment for why this is structured the way it is. let raw_path = match fs_name.len() { 1 => format!("1/{}", fs_name), 2 => format!("2/{}", fs_name), @@ -197,7 +196,7 @@ let err = load.load(&root, Path::new(&path), &mut |contents| { hit_closure = true; let contents = str::from_utf8(contents) - .map_err(|_| format_err!("registry index file was not valid utf-8"))?; + .map_err(|_| failure::format_err!("registry index file was not valid utf-8"))?; ret.reserve(contents.lines().count()); let lines = contents.lines().map(|s| s.trim()).filter(|l| !l.is_empty()); @@ -240,8 +239,7 @@ Ok(ret) } - /// Parse a line from the registry's index file into a Summary for a - /// package. + /// Parses a line from the registry's index file into a `Summary` for a package. /// /// The returned boolean is whether or not the summary has been yanked. fn parse_registry_package(&mut self, line: &str) -> CargoResult<(Summary, bool)> { @@ -272,15 +270,22 @@ pub fn query_inner( &mut self, dep: &Dependency, - load: &mut RegistryData, - f: &mut FnMut(Summary), + load: &mut dyn RegistryData, + yanked_whitelist: &HashSet, + f: &mut dyn FnMut(Summary), ) -> CargoResult<()> { let source_id = self.source_id; let name = dep.package_name().as_str(); let summaries = self.summaries(name, load)?; let summaries = summaries .iter() - .filter(|&&(_, yanked)| dep.source_id().precise().is_some() || !yanked) + .filter(|&(summary, yanked)| { + !yanked || { + log::debug!("{:?}", yanked_whitelist); + log::debug!("{:?}", summary.package_id()); + yanked_whitelist.contains(&summary.package_id()) + } + }) .map(|s| s.0.clone()); // Handle `cargo update --precise` here. If specified, our own source @@ -293,7 +298,7 @@ let mut vers = p[name.len() + 1..].splitn(2, "->"); if dep .version_req() - .matches(&Version::parse(vers.next().unwrap()).unwrap()) + .matches(&vers.next().unwrap().to_semver().unwrap()) { vers.next().unwrap() == s.version().to_string() } else { diff -Nru cargo-0.33.0/src/cargo/sources/registry/local.rs cargo-0.35.0/src/cargo/sources/registry/local.rs --- cargo-0.33.0/src/cargo/sources/registry/local.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/registry/local.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,12 +2,12 @@ use std::io::SeekFrom; use std::path::Path; -use core::PackageId; +use crate::core::PackageId; +use crate::sources::registry::{MaybeLock, RegistryConfig, RegistryData}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::{Config, FileLock, Filesystem, Sha256}; use hex; -use sources::registry::{MaybeLock, RegistryConfig, RegistryData}; -use util::errors::{CargoResult, CargoResultExt}; -use util::paths; -use util::{Config, FileLock, Filesystem, Sha256}; pub struct LocalRegistry<'cfg> { index_path: Filesystem, @@ -40,7 +40,7 @@ &self, root: &Path, path: &Path, - data: &mut FnMut(&[u8]) -> CargoResult<()>, + data: &mut dyn FnMut(&[u8]) -> CargoResult<()>, ) -> CargoResult<()> { data(&paths::read_bytes(&root.join(path))?) } @@ -57,11 +57,11 @@ // these directories exist. let root = self.root.clone().into_path_unlocked(); if !root.is_dir() { - bail!("local registry path is not a directory: {}", root.display()) + failure::bail!("local registry path is not a directory: {}", root.display()) } let index_path = self.index_path.clone().into_path_unlocked(); if !index_path.is_dir() { - bail!( + failure::bail!( "local registry index path is not a directory: {}", index_path.display() ) @@ -96,7 +96,7 @@ state.update(&buf[..n]); } if hex::encode(state.finish()) != checksum { - bail!("failed to verify the checksum of `{}`", pkg) + failure::bail!("failed to verify the checksum of `{}`", pkg) } crate_file.seek(SeekFrom::Start(0))?; diff -Nru cargo-0.33.0/src/cargo/sources/registry/mod.rs cargo-0.35.0/src/cargo/sources/registry/mod.rs --- cargo-0.33.0/src/cargo/sources/registry/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/registry/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -160,25 +160,27 @@ use std::borrow::Cow; use std::collections::BTreeMap; -use std::fs::File; +use std::collections::HashSet; +use std::io::Write; use std::path::{Path, PathBuf}; use flate2::read::GzDecoder; +use log::debug; use semver::Version; -#[cfg(test)] -use serde_json; +use serde::Deserialize; use tar::Archive; -use core::dependency::{Dependency, Kind}; -use core::source::MaybePackage; -use core::{Package, PackageId, Source, SourceId, Summary}; -use sources::PathSource; -use util::errors::CargoResultExt; -use util::hex; -use util::to_url::ToUrl; -use util::{internal, CargoResult, Config, FileLock, Filesystem}; +use crate::core::dependency::{Dependency, Kind}; +use crate::core::source::MaybePackage; +use crate::core::{Package, PackageId, Source, SourceId, Summary}; +use crate::sources::PathSource; +use crate::util::errors::CargoResultExt; +use crate::util::hex; +use crate::util::to_url::ToUrl; +use crate::util::{internal, CargoResult, Config, FileLock, Filesystem}; const INDEX_LOCK: &str = ".cargo-index-lock"; +const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok"; pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index"; pub const CRATES_IO_REGISTRY: &str = "crates-io"; const CRATE_TEMPLATE: &str = "{crate}"; @@ -189,8 +191,9 @@ src_path: Filesystem, config: &'cfg Config, updated: bool, - ops: Box, + ops: Box, index: index::RegistryIndex<'cfg>, + yanked_whitelist: HashSet, index_locked: bool, } @@ -211,6 +214,7 @@ /// API endpoint for the registry. This is what's actually hit to perform /// operations like yanks, owner modifications, publish new crates, etc. + /// If this is None, the registry does not support API commands. pub api: Option, } @@ -227,17 +231,17 @@ #[test] fn escaped_cher_in_json() { - let _: RegistryPackage = serde_json::from_str( + let _: RegistryPackage<'_> = serde_json::from_str( r#"{"name":"a","vers":"0.0.1","deps":[],"cksum":"bae3","features":{}}"#, ) .unwrap(); - let _: RegistryPackage = serde_json::from_str( + let _: RegistryPackage<'_> = serde_json::from_str( r#"{"name":"a","vers":"0.0.1","deps":[],"cksum":"bae3","features":{"test":["k","q"]},"links":"a-sys"}"# ).unwrap(); // Now we add escaped cher all the places they can go // these are not valid, but it should error later than json parsing - let _: RegistryPackage = serde_json::from_str( + let _: RegistryPackage<'_> = serde_json::from_str( r#"{ "name":"This name has a escaped cher in it \n\t\" ", "vers":"0.0.1", @@ -298,7 +302,7 @@ package, } = self; - let id = if let Some(registry) = registry { + let id = if let Some(registry) = ®istry { SourceId::for_registry(®istry.to_url()?)? } else { default @@ -327,6 +331,12 @@ // out here. features.retain(|s| !s.is_empty()); + // In index, "registry" is null if it is from the same index. + // In Cargo.toml, "registry" is None if it is from the default + if !id.is_default_registry() { + dep.set_registry_id(id); + } + dep.set_optional(optional) .set_default_features(default_features) .set_features(features) @@ -344,7 +354,7 @@ &self, _root: &Path, path: &Path, - data: &mut FnMut(&[u8]) -> CargoResult<()>, + data: &mut dyn FnMut(&[u8]) -> CargoResult<()>, ) -> CargoResult<()>; fn config(&mut self) -> CargoResult>; fn update_index(&mut self) -> CargoResult<()>; @@ -377,23 +387,47 @@ } impl<'cfg> RegistrySource<'cfg> { - pub fn remote(source_id: SourceId, config: &'cfg Config) -> RegistrySource<'cfg> { + pub fn remote( + source_id: SourceId, + yanked_whitelist: &HashSet, + config: &'cfg Config, + ) -> RegistrySource<'cfg> { let name = short_name(source_id); let ops = remote::RemoteRegistry::new(source_id, config, &name); - RegistrySource::new(source_id, config, &name, Box::new(ops), true) + RegistrySource::new( + source_id, + config, + &name, + Box::new(ops), + yanked_whitelist, + true, + ) } - pub fn local(source_id: SourceId, path: &Path, config: &'cfg Config) -> RegistrySource<'cfg> { + pub fn local( + source_id: SourceId, + path: &Path, + yanked_whitelist: &HashSet, + config: &'cfg Config, + ) -> RegistrySource<'cfg> { let name = short_name(source_id); let ops = local::LocalRegistry::new(path, config, &name); - RegistrySource::new(source_id, config, &name, Box::new(ops), false) + RegistrySource::new( + source_id, + config, + &name, + Box::new(ops), + yanked_whitelist, + false, + ) } fn new( source_id: SourceId, config: &'cfg Config, name: &str, - ops: Box, + ops: Box, + yanked_whitelist: &HashSet, index_locked: bool, ) -> RegistrySource<'cfg> { RegistrySource { @@ -402,6 +436,7 @@ source_id, updated: false, index: index::RegistryIndex::new(source_id, ops.index_path(), config, index_locked), + yanked_whitelist: yanked_whitelist.clone(), index_locked, ops, } @@ -419,23 +454,38 @@ /// /// No action is taken if the source looks like it's already unpacked. fn unpack_package(&self, pkg: PackageId, tarball: &FileLock) -> CargoResult { - let dst = self - .src_path - .join(&format!("{}-{}", pkg.name(), pkg.version())); - dst.create_dir()?; - // Note that we've already got the `tarball` locked above, and that - // implies a lock on the unpacked destination as well, so this access - // via `into_path_unlocked` should be ok. - let dst = dst.into_path_unlocked(); - let ok = dst.join(".cargo-ok"); - if ok.exists() { - return Ok(dst); + // The `.cargo-ok` file is used to track if the source is already + // unpacked and to lock the directory for unpacking. + let mut ok = { + let package_dir = format!("{}-{}", pkg.name(), pkg.version()); + let dst = self.src_path.join(&package_dir); + dst.create_dir()?; + + // Attempt to open a read-only copy first to avoid an exclusive write + // lock and also work with read-only filesystems. If the file has + // any data, assume the source is already unpacked. + if let Ok(ok) = dst.open_ro(PACKAGE_SOURCE_LOCK, self.config, &package_dir) { + let meta = ok.file().metadata()?; + if meta.len() > 0 { + let unpack_dir = ok.parent().to_path_buf(); + return Ok(unpack_dir); + } + } + + dst.open_rw(PACKAGE_SOURCE_LOCK, self.config, &package_dir)? + }; + let unpack_dir = ok.parent().to_path_buf(); + + // If the file has any data, assume the source is already unpacked. + let meta = ok.file().metadata()?; + if meta.len() > 0 { + return Ok(unpack_dir); } let gz = GzDecoder::new(tarball.file()); let mut tar = Archive::new(gz); - let prefix = dst.file_name().unwrap(); - let parent = dst.parent().unwrap(); + let prefix = unpack_dir.file_name().unwrap(); + let parent = unpack_dir.parent().unwrap(); for entry in tar.entries()? { let mut entry = entry.chain_err(|| "failed to iterate over archive")?; let entry_path = entry @@ -450,7 +500,7 @@ // crates.io should also block uploads with these sorts of tarballs, // but be extra sure by adding a check here as well. if !entry_path.starts_with(prefix) { - bail!( + failure::bail!( "invalid tarball downloaded, contains \ a file at {:?} which isn't under {:?}", entry_path, @@ -463,8 +513,11 @@ .unpack_in(parent) .chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; } - File::create(&ok)?; - Ok(dst.clone()) + + // Write to the lock file to indicate that unpacking was successful. + write!(ok, "ok")?; + + Ok(unpack_dir) } fn do_update(&mut self) -> CargoResult<()> { @@ -485,40 +538,26 @@ MaybePackage::Ready(pkg) => pkg, MaybePackage::Download { .. } => unreachable!(), }; - - // Unfortunately the index and the actual Cargo.toml in the index can - // differ due to historical Cargo bugs. To paper over these we trash the - // *summary* loaded from the Cargo.toml we just downloaded with the one - // we loaded from the index. - let summaries = self - .index - .summaries(package.name().as_str(), &mut *self.ops)?; - let summary = summaries - .iter() - .map(|s| &s.0) - .find(|s| s.package_id() == package) - .expect("summary not found"); - let mut manifest = pkg.manifest().clone(); - manifest.set_summary(summary.clone()); - Ok(Package::new(manifest, pkg.manifest_path())) + Ok(pkg) } } impl<'cfg> Source for RegistrySource<'cfg> { - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { - // If this is a precise dependency, then it came from a lockfile and in + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { + // If this is a precise dependency, then it came from a lock file and in // theory the registry is known to contain this version. If, however, we // come back with no summaries, then our registry may need to be // updated, so we fall back to performing a lazy update. if dep.source_id().precise().is_some() && !self.updated { debug!("attempting query without update"); let mut called = false; - self.index.query_inner(dep, &mut *self.ops, &mut |s| { - if dep.matches(&s) { - called = true; - f(s); - } - })?; + self.index + .query_inner(dep, &mut *self.ops, &self.yanked_whitelist, &mut |s| { + if dep.matches(&s) { + called = true; + f(s); + } + })?; if called { return Ok(()); } else { @@ -527,15 +566,17 @@ } } - self.index.query_inner(dep, &mut *self.ops, &mut |s| { - if dep.matches(&s) { - f(s); - } - }) + self.index + .query_inner(dep, &mut *self.ops, &self.yanked_whitelist, &mut |s| { + if dep.matches(&s) { + f(s); + } + }) } - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { - self.index.query_inner(dep, &mut *self.ops, f) + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { + self.index + .query_inner(dep, &mut *self.ops, &self.yanked_whitelist, f) } fn supports_checksums(&self) -> bool { @@ -589,4 +630,8 @@ fn describe(&self) -> String { self.source_id.display_registry() } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + self.yanked_whitelist.extend(pkgs); + } } diff -Nru cargo-0.33.0/src/cargo/sources/registry/remote.rs cargo-0.35.0/src/cargo/sources/registry/remote.rs --- cargo-0.33.0/src/cargo/sources/registry/remote.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/registry/remote.rs 2019-04-01 21:32:07.000000000 +0000 @@ -6,20 +6,18 @@ use std::path::Path; use std::str; -use git2; -use hex; use lazycell::LazyCell; -use serde_json; +use log::{debug, trace}; -use core::{PackageId, SourceId}; -use sources::git; -use sources::registry::MaybeLock; -use sources::registry::{ +use crate::core::{PackageId, SourceId}; +use crate::sources::git; +use crate::sources::registry::MaybeLock; +use crate::sources::registry::{ RegistryConfig, RegistryData, CRATE_TEMPLATE, INDEX_LOCK, VERSION_TEMPLATE, }; -use util::errors::{CargoResult, CargoResultExt}; -use util::{Config, Sha256}; -use util::{FileLock, Filesystem}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::{Config, Sha256}; +use crate::util::{FileLock, Filesystem}; pub struct RemoteRegistry<'cfg> { index_path: Filesystem, @@ -98,7 +96,7 @@ Ok(self.head.get().unwrap()) } - fn tree(&self) -> CargoResult> { + fn tree(&self) -> CargoResult>> { { let tree = self.tree.borrow(); if tree.is_some() { @@ -121,7 +119,7 @@ // (`RemoteRegistry`) so we then just need to ensure that the tree is // destroyed first in the destructor, hence the destructor on // `RemoteRegistry` below. - let tree = unsafe { mem::transmute::>(tree) }; + let tree = unsafe { mem::transmute::, git2::Tree<'static>>(tree) }; *self.tree.borrow_mut() = Some(tree); Ok(Ref::map(self.tree.borrow(), |s| s.as_ref().unwrap())) } @@ -145,7 +143,7 @@ &self, _root: &Path, path: &Path, - data: &mut FnMut(&[u8]) -> CargoResult<()>, + data: &mut dyn FnMut(&[u8]) -> CargoResult<()>, ) -> CargoResult<()> { // Note that the index calls this method and the filesystem is locked // in the index, so we don't need to worry about an `update_index` @@ -156,7 +154,7 @@ let object = entry.to_object(repo)?; let blob = match object.as_blob() { Some(blob) => blob, - None => bail!("path `{}` is not a blob in the git repo", path.display()), + None => failure::bail!("path `{}` is not a blob in the git repo", path.display()), }; data(blob.content()) } @@ -230,7 +228,7 @@ } let config = self.config()?.unwrap(); - let mut url = config.dl.clone(); + let mut url = config.dl; if !url.contains(CRATE_TEMPLATE) && !url.contains(VERSION_TEMPLATE) { write!(url, "/{}/{}/download", CRATE_TEMPLATE, VERSION_TEMPLATE).unwrap(); } @@ -254,7 +252,7 @@ let mut state = Sha256::new(); state.update(data); if hex::encode(state.finish()) != checksum { - bail!("failed to verify the checksum of `{}`", pkg) + failure::bail!("failed to verify the checksum of `{}`", pkg) } let filename = self.filename(pkg); diff -Nru cargo-0.33.0/src/cargo/sources/replaced.rs cargo-0.35.0/src/cargo/sources/replaced.rs --- cargo-0.33.0/src/cargo/sources/replaced.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/sources/replaced.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,18 +1,18 @@ -use core::source::MaybePackage; -use core::{Dependency, Package, PackageId, Source, SourceId, Summary}; -use util::errors::{CargoResult, CargoResultExt}; +use crate::core::source::MaybePackage; +use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary}; +use crate::util::errors::{CargoResult, CargoResultExt}; pub struct ReplacedSource<'cfg> { to_replace: SourceId, replace_with: SourceId, - inner: Box, + inner: Box, } impl<'cfg> ReplacedSource<'cfg> { pub fn new( to_replace: SourceId, replace_with: SourceId, - src: Box, + src: Box, ) -> ReplacedSource<'cfg> { ReplacedSource { to_replace, @@ -39,7 +39,7 @@ self.inner.requires_precise() } - fn query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let (replace_with, to_replace) = (self.replace_with, self.to_replace); let dep = dep.clone().map_source(to_replace, replace_with); @@ -51,7 +51,7 @@ Ok(()) } - fn fuzzy_query(&mut self, dep: &Dependency, f: &mut FnMut(Summary)) -> CargoResult<()> { + fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> { let (replace_with, to_replace) = (self.replace_with, self.to_replace); let dep = dep.clone().map_source(to_replace, replace_with); @@ -113,4 +113,10 @@ fn is_replaced(&self) -> bool { true } + + fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) { + let pkgs = pkgs.iter().map(|id| id.with_source_id(self.replace_with)) + .collect::>(); + self.inner.add_to_yanked_whitelist(&pkgs); + } } diff -Nru cargo-0.33.0/src/cargo/util/cfg.rs cargo-0.35.0/src/cargo/util/cfg.rs --- cargo-0.33.0/src/cargo/util/cfg.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/cfg.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,8 @@ -use std::str::{self, FromStr}; -use std::iter; use std::fmt; +use std::iter; +use std::str::{self, FromStr}; -use util::{CargoError, CargoResult}; +use crate::util::CargoResult; #[derive(Eq, PartialEq, Hash, Ord, PartialOrd, Clone, Debug)] pub enum Cfg { @@ -38,20 +38,20 @@ } impl FromStr for Cfg { - type Err = CargoError; + type Err = failure::Error; fn from_str(s: &str) -> CargoResult { let mut p = Parser::new(s); let e = p.cfg()?; if p.t.next().is_some() { - bail!("malformed cfg value or key/value pair: `{}`", s) + failure::bail!("malformed cfg value or key/value pair: `{}`", s) } Ok(e) } } impl fmt::Display for Cfg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Cfg::Name(ref s) => s.fmt(f), Cfg::KeyPair(ref k, ref v) => write!(f, "{} = \"{}\"", k, v), @@ -63,9 +63,12 @@ /// Utility function to check if the key, "cfg(..)" matches the `target_cfg` pub fn matches_key(key: &str, target_cfg: &[Cfg]) -> bool { if key.starts_with("cfg(") && key.ends_with(')') { - let cfg = &key[4..key.len() - 1 ]; + let cfg = &key[4..key.len() - 1]; - CfgExpr::from_str(cfg).ok().map(|ce| ce.matches(target_cfg)).unwrap_or(false) + CfgExpr::from_str(cfg) + .ok() + .map(|ce| ce.matches(target_cfg)) + .unwrap_or(false) } else { false } @@ -82,13 +85,13 @@ } impl FromStr for CfgExpr { - type Err = CargoError; + type Err = failure::Error; fn from_str(s: &str) -> CargoResult { let mut p = Parser::new(s); let e = p.expr()?; if p.t.next().is_some() { - bail!( + failure::bail!( "can only have one cfg-expression, consider using all() or \ any() explicitly" ) @@ -98,7 +101,7 @@ } impl fmt::Display for CfgExpr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { CfgExpr::Not(ref e) => write!(f, "not({})", e), CfgExpr::All(ref e) => write!(f, "all({})", CommaSep(e)), @@ -108,10 +111,10 @@ } } -struct CommaSep<'a, T: 'a>(&'a [T]); +struct CommaSep<'a, T>(&'a [T]); impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for (i, v) in self.0.iter().enumerate() { if i > 0 { write!(f, ", ")?; @@ -128,7 +131,8 @@ t: Tokenizer { s: s.char_indices().peekable(), orig: s, - }.peekable(), + } + .peekable(), } } @@ -138,9 +142,9 @@ self.t.next(); let mut e = Vec::new(); self.eat(&Token::LeftParen)?; - while !self.try(&Token::RightParen) { + while !self.r#try(&Token::RightParen) { e.push(self.expr()?); - if !self.try(&Token::Comma) { + if !self.r#try(&Token::Comma) { self.eat(&Token::RightParen)?; break; } @@ -160,7 +164,7 @@ } Some(&Ok(..)) => self.cfg().map(CfgExpr::Value), Some(&Err(..)) => Err(self.t.next().unwrap().err().unwrap()), - None => bail!( + None => failure::bail!( "expected start of a cfg expression, \ found nothing" ), @@ -170,12 +174,12 @@ fn cfg(&mut self) -> CargoResult { match self.t.next() { Some(Ok(Token::Ident(name))) => { - let e = if self.try(&Token::Equals) { + let e = if self.r#try(&Token::Equals) { let val = match self.t.next() { Some(Ok(Token::String(s))) => s, - Some(Ok(t)) => bail!("expected a string, found {}", t.classify()), + Some(Ok(t)) => failure::bail!("expected a string, found {}", t.classify()), Some(Err(e)) => return Err(e), - None => bail!("expected a string, found nothing"), + None => failure::bail!("expected a string, found nothing"), }; Cfg::KeyPair(name.to_string(), val.to_string()) } else { @@ -183,13 +187,13 @@ }; Ok(e) } - Some(Ok(t)) => bail!("expected identifier, found {}", t.classify()), + Some(Ok(t)) => failure::bail!("expected identifier, found {}", t.classify()), Some(Err(e)) => Err(e), - None => bail!("expected identifier, found nothing"), + None => failure::bail!("expected identifier, found nothing"), } } - fn try(&mut self, token: &Token<'a>) -> bool { + fn r#try(&mut self, token: &Token<'a>) -> bool { match self.t.peek() { Some(&Ok(ref t)) if token == t => {} _ => return false, @@ -201,9 +205,9 @@ fn eat(&mut self, token: &Token<'a>) -> CargoResult<()> { match self.t.next() { Some(Ok(ref t)) if token == t => Ok(()), - Some(Ok(t)) => bail!("expected {}, found {}", token.classify(), t.classify()), + Some(Ok(t)) => failure::bail!("expected {}, found {}", token.classify(), t.classify()), Some(Err(e)) => Err(e), - None => bail!("expected {}, but cfg expr ended", token.classify()), + None => failure::bail!("expected {}, but cfg expr ended", token.classify()), } } } @@ -225,7 +229,7 @@ return Some(Ok(Token::String(&self.orig[start + 1..end]))); } } - return Some(Err(format_err!("unterminated string in cfg"))); + return Some(Err(failure::format_err!("unterminated string in cfg"))); } Some((start, ch)) if is_ident_start(ch) => { while let Some(&(end, ch)) = self.s.peek() { @@ -238,13 +242,13 @@ return Some(Ok(Token::Ident(&self.orig[start..]))); } Some((_, ch)) => { - return Some(Err(format_err!( + return Some(Err(failure::format_err!( "unexpected character in \ cfg `{}`, expected parens, \ a comma, an identifier, or \ a string", ch - ))) + ))); } None => return None, } diff -Nru cargo-0.33.0/src/cargo/util/command_prelude.rs cargo-0.35.0/src/cargo/util/command_prelude.rs --- cargo-0.33.0/src/cargo/util/command_prelude.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/command_prelude.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,18 +1,22 @@ -use std::path::PathBuf; use std::fs; +use std::path::PathBuf; +use crate::core::compiler::{BuildConfig, MessageFormat}; +use crate::core::Workspace; +use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl}; +use crate::sources::CRATES_IO_REGISTRY; +use crate::util::important_paths::find_root_manifest_for_wd; +use crate::util::{paths, validate_package_name}; +use crate::util::{ + print_available_benches, print_available_binaries, print_available_examples, + print_available_tests, +}; +use crate::CargoResult; use clap::{self, SubCommand}; -use CargoResult; -use core::Workspace; -use core::compiler::{BuildConfig, MessageFormat}; -use ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl}; -use sources::CRATES_IO_REGISTRY; -use util::paths; -use util::important_paths::find_root_manifest_for_wd; +pub use crate::core::compiler::CompileMode; +pub use crate::{CliError, CliResult, Config}; pub use clap::{AppSettings, Arg, ArgMatches}; -pub use {CliError, CliResult, Config}; -pub use core::compiler::CompileMode; pub type App = clap::App<'static, 'static>; @@ -60,18 +64,18 @@ all: &'static str, ) -> Self { self.arg_targets_lib_bin(lib, bin, bins) - ._arg(multi_opt("example", "NAME", example)) + ._arg(optional_multi_opt("example", "NAME", example)) ._arg(opt("examples", examples)) - ._arg(multi_opt("test", "NAME", test)) + ._arg(optional_multi_opt("test", "NAME", test)) ._arg(opt("tests", tests)) - ._arg(multi_opt("bench", "NAME", bench)) + ._arg(optional_multi_opt("bench", "NAME", bench)) ._arg(opt("benches", benches)) ._arg(opt("all-targets", all)) } fn arg_targets_lib_bin(self, lib: &'static str, bin: &'static str, bins: &'static str) -> Self { self._arg(opt("lib", lib)) - ._arg(multi_opt("bin", "NAME", bin)) + ._arg(optional_multi_opt("bin", "NAME", bin)) ._arg(opt("bins", bins)) } @@ -82,25 +86,26 @@ example: &'static str, examples: &'static str, ) -> Self { - self._arg(multi_opt("bin", "NAME", bin)) + self._arg(optional_multi_opt("bin", "NAME", bin)) ._arg(opt("bins", bins)) - ._arg(multi_opt("example", "NAME", example)) + ._arg(optional_multi_opt("example", "NAME", example)) ._arg(opt("examples", examples)) } fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self { - self._arg(multi_opt("bin", "NAME", bin)) - ._arg(multi_opt("example", "NAME", example)) + self._arg(optional_multi_opt("bin", "NAME", bin)) + ._arg(optional_multi_opt("example", "NAME", example)) } fn arg_features(self) -> Self { self._arg( opt("features", "Space-separated list of features to activate").value_name("FEATURES"), - )._arg(opt("all-features", "Activate all available features")) - ._arg(opt( - "no-default-features", - "Do not activate the `default` feature", - )) + ) + ._arg(opt("all-features", "Activate all available features")) + ._arg(opt( + "no-default-features", + "Do not activate the `default` feature", + )) } fn arg_release(self, release: &'static str) -> Self { @@ -116,7 +121,9 @@ } fn arg_target_dir(self) -> Self { - self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY")) + self._arg( + opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"), + ) } fn arg_manifest_path(self) -> Self { @@ -146,32 +153,38 @@ control system (git, hg, pijul, or fossil) or do not \ initialize any version control at all (none), overriding \ a global configuration.", - ).value_name("VCS") - .possible_values(&["git", "hg", "pijul", "fossil", "none"]), - ) - ._arg(opt("bin", "Use a binary (application) template [default]")) - ._arg(opt("lib", "Use a library template")) - ._arg( - opt("edition", "Edition to set for the crate generated") - .possible_values(&["2015", "2018"]) - .value_name("YEAR") ) - ._arg( - opt( - "name", - "Set the resulting package name, defaults to the directory name", - ).value_name("NAME"), + .value_name("VCS") + .possible_values(&["git", "hg", "pijul", "fossil", "none"]), + ) + ._arg(opt("bin", "Use a binary (application) template [default]")) + ._arg(opt("lib", "Use a library template")) + ._arg( + opt("edition", "Edition to set for the crate generated") + .possible_values(&["2015", "2018"]) + .value_name("YEAR"), + ) + ._arg( + opt( + "name", + "Set the resulting package name, defaults to the directory name", ) + .value_name("NAME"), + ) } fn arg_index(self) -> Self { - self._arg(opt("index", "Registry index to upload the package to").value_name("INDEX")) + self._arg(opt("index", "Registry index URL to upload the package to").value_name("INDEX")) ._arg( opt("host", "DEPRECATED, renamed to '--index'") .value_name("HOST") .hidden(true), ) } + + fn arg_dry_run(self, dry_run: &'static str) -> Self { + self._arg(opt("dry-run", dry_run)) + } } impl AppExt for App { @@ -184,6 +197,18 @@ Arg::with_name(name).long(name).help(help) } +pub fn optional_multi_opt( + name: &'static str, + value_name: &'static str, + help: &'static str, +) -> Arg<'static, 'static> { + opt(name, help) + .value_name(value_name) + .multiple(true) + .min_values(0) + .number_of_values(1) +} + pub fn multi_opt( name: &'static str, value_name: &'static str, @@ -191,7 +216,7 @@ ) -> Arg<'static, 'static> { // Note that all `.multiple(true)` arguments in Cargo should specify // `.number_of_values(1)` as well, so that `--foo val1 val2` is - // **not** parsed as `foo` with values ["val1", "val2"]. + // *not* parsed as `foo` with values ["val1", "val2"]. // `number_of_values` should become the default in clap 3. opt(name, help) .value_name(value_name) @@ -229,10 +254,10 @@ // but in this particular case we need it to fix #3586. let path = paths::normalize_path(&path); if !path.ends_with("Cargo.toml") { - bail!("the manifest-path must be a path to a Cargo.toml file") + failure::bail!("the manifest-path must be a path to a Cargo.toml file") } if fs::metadata(&path).is_err() { - bail!( + failure::bail!( "manifest path `{}` does not exist", self._value_of("manifest-path").unwrap() ) @@ -263,6 +288,7 @@ &self, config: &'a Config, mode: CompileMode, + workspace: Option<&Workspace<'a>>, ) -> CargoResult> { let spec = Packages::from_flags( self._is_present("all"), @@ -290,7 +316,7 @@ build_config.release = self._is_present("release"); build_config.build_plan = self._is_present("build-plan"); if build_config.build_plan && !config.cli_unstable().unstable_options { - Err(format_err!( + Err(failure::format_err!( "`--build-plan` flag is unstable, pass `-Z unstable-options` to enable it" ))?; }; @@ -319,6 +345,11 @@ local_rustdoc_args: None, export_dir: None, }; + + if let Some(ws) = workspace { + self.check_optional_opts(ws, &opts)?; + } + Ok(opts) } @@ -326,8 +357,9 @@ &self, config: &'a Config, mode: CompileMode, + workspace: Option<&Workspace<'a>>, ) -> CargoResult> { - let mut compile_opts = self.compile_options(config, mode)?; + let mut compile_opts = self.compile_options(config, mode, workspace)?; compile_opts.spec = Packages::Packages(self._values_of("package")); Ok(compile_opts) } @@ -355,37 +387,27 @@ fn registry(&self, config: &Config) -> CargoResult> { match self._value_of("registry") { Some(registry) => { - if !config.cli_unstable().unstable_options { - return Err(format_err!( - "registry option is an unstable feature and \ - requires -Zunstable-options to use." - )); - } + validate_package_name(registry, "registry name", "")?; if registry == CRATES_IO_REGISTRY { - // If "crates.io" is specified then we just need to return None + // If "crates.io" is specified, then we just need to return `None`, // as that will cause cargo to use crates.io. This is required - // for the case where a default alterative registry is used + // for the case where a default alternative registry is used // but the user wants to switch back to crates.io for a single // command. Ok(None) + } else { + Ok(Some(registry.to_string())) } - else { - Ok(Some(registry.to_string())) - } - } - None => { - config.default_registry() } + None => config.default_registry(), } } fn index(&self, config: &Config) -> CargoResult> { - // TODO: Deprecated - // remove once it has been decided --host can be removed - // We may instead want to repurpose the host flag, as - // mentioned in this issue - // https://github.com/rust-lang/cargo/issues/4208 + // TODO: deprecated. Remove once it has been decided `--host` can be removed + // We may instead want to repurpose the host flag, as mentioned in issue + // rust-lang/cargo#4208. let msg = "The flag '--host' is no longer valid. Previous versions of Cargo accepted this flag, but it is being @@ -406,6 +428,34 @@ Ok(index) } + fn check_optional_opts( + &self, + workspace: &Workspace<'_>, + compile_opts: &CompileOptions<'_>, + ) -> CargoResult<()> { + if self.is_present_with_zero_values("example") { + print_available_examples(&workspace, &compile_opts)?; + } + + if self.is_present_with_zero_values("bin") { + print_available_binaries(&workspace, &compile_opts)?; + } + + if self.is_present_with_zero_values("bench") { + print_available_benches(&workspace, &compile_opts)?; + } + + if self.is_present_with_zero_values("test") { + print_available_tests(&workspace, &compile_opts)?; + } + + Ok(()) + } + + fn is_present_with_zero_values(&self, name: &str) -> bool { + self._is_present(name) && self._value_of(name).is_none() + } + fn _value_of(&self, name: &str) -> Option<&str>; fn _values_of(&self, name: &str) -> Vec; @@ -430,7 +480,7 @@ } } -pub fn values(args: &ArgMatches, name: &str) -> Vec { +pub fn values(args: &ArgMatches<'_>, name: &str) -> Vec { args.values_of(name) .unwrap_or_default() .map(|s| s.to_string()) @@ -439,7 +489,7 @@ #[derive(PartialEq, PartialOrd, Eq, Ord)] pub enum CommandInfo { - BuiltIn { name: String, about: Option, }, + BuiltIn { name: String, about: Option }, External { name: String, path: PathBuf }, } diff -Nru cargo-0.33.0/src/cargo/util/config.rs cargo-0.35.0/src/cargo/util/config.rs --- cargo-0.33.0/src/cargo/util/config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,3 @@ -use std; use std::cell::{RefCell, RefMut}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::HashMap; @@ -16,24 +15,21 @@ use std::vec; use curl::easy::Easy; -use failure; -use jobserver; use lazycell::LazyCell; +use serde::Deserialize; use serde::{de, de::IntoDeserializer}; -use toml; - -use core::profiles::ConfigProfiles; -use core::shell::Verbosity; -use core::{CliUnstable, Shell, SourceId, Workspace}; -use ops; use url::Url; -use util::errors::{internal, CargoResult, CargoResultExt}; -use util::paths; -use util::toml as cargo_toml; -use util::Filesystem; -use util::Rustc; -use util::ToUrl; +use crate::core::profiles::ConfigProfiles; +use crate::core::shell::Verbosity; +use crate::core::{CliUnstable, Shell, SourceId, Workspace}; +use crate::ops; +use crate::util::errors::{internal, CargoResult, CargoResultExt}; +use crate::util::toml as cargo_toml; +use crate::util::Filesystem; +use crate::util::Rustc; +use crate::util::ToUrl; +use crate::util::{paths, validate_package_name}; use self::ConfigValue as CV; /// Configuration information for cargo. This is not specific to a build, it is information @@ -141,7 +137,7 @@ let cwd = env::current_dir().chain_err(|| "couldn't get the current directory of the process")?; let homedir = homedir(&cwd).ok_or_else(|| { - format_err!( + failure::format_err!( "Cargo couldn't find your home directory. \ This probably means that $HOME was not set." ) @@ -149,32 +145,32 @@ Ok(Config::new(shell, cwd, homedir)) } - /// The user's cargo home directory (OS-dependent) + /// Gets the user's Cargo home directory (OS-dependent). pub fn home(&self) -> &Filesystem { &self.home_path } - /// The cargo git directory (`/git`) + /// Gets the Cargo Git directory (`/git`). pub fn git_path(&self) -> Filesystem { self.home_path.join("git") } - /// The cargo registry index directory (`/registry/index`) + /// Gets the Cargo registry index directory (`/registry/index`). pub fn registry_index_path(&self) -> Filesystem { self.home_path.join("registry").join("index") } - /// The cargo registry cache directory (`/registry/path`) + /// Gets the Cargo registry cache directory (`/registry/path`). pub fn registry_cache_path(&self) -> Filesystem { self.home_path.join("registry").join("cache") } - /// The cargo registry source directory (`/registry/src`) + /// Gets the Cargo registry source directory (`/registry/src`). pub fn registry_source_path(&self) -> Filesystem { self.home_path.join("registry").join("src") } - /// The default cargo registry (`alternative-registry`) + /// Gets the default Cargo registry. pub fn default_registry(&self) -> CargoResult> { Ok(match self.get_string("registry.default")? { Some(registry) => Some(registry.val), @@ -182,20 +178,20 @@ }) } - /// Get a reference to the shell, for e.g. writing error messages - pub fn shell(&self) -> RefMut { + /// Gets a reference to the shell, e.g., for writing error messages. + pub fn shell(&self) -> RefMut<'_, Shell> { self.shell.borrow_mut() } - /// Get the path to the `rustdoc` executable + /// Gets the path to the `rustdoc` executable. pub fn rustdoc(&self) -> CargoResult<&Path> { self.rustdoc .try_borrow_with(|| self.get_tool("rustdoc")) .map(AsRef::as_ref) } - /// Get the path to the `rustc` executable - pub fn rustc(&self, ws: Option<&Workspace>) -> CargoResult { + /// Gets the path to the `rustc` executable. + pub fn rustc(&self, ws: Option<&Workspace<'_>>) -> CargoResult { let cache_location = ws.map(|ws| { ws.target_dir() .join(".rustc_info.json") @@ -218,32 +214,32 @@ ) } - /// Get the path to the `cargo` executable + /// Gets the path to the `cargo` executable. pub fn cargo_exe(&self) -> CargoResult<&Path> { self.cargo_exe .try_borrow_with(|| { fn from_current_exe() -> CargoResult { - // Try fetching the path to `cargo` using env::current_exe(). + // Try fetching the path to `cargo` using `env::current_exe()`. // The method varies per operating system and might fail; in particular, - // it depends on /proc being mounted on Linux, and some environments + // it depends on `/proc` being mounted on Linux, and some environments // (like containers or chroots) may not have that available. let exe = env::current_exe()?.canonicalize()?; Ok(exe) } fn from_argv() -> CargoResult { - // Grab argv[0] and attempt to resolve it to an absolute path. - // If argv[0] has one component, it must have come from a PATH lookup, - // so probe PATH in that case. + // Grab `argv[0]` and attempt to resolve it to an absolute path. + // If `argv[0]` has one component, it must have come from a `PATH` lookup, + // so probe `PATH` in that case. // Otherwise, it has multiple components and is either: - // - a relative path (e.g. `./cargo`, `target/debug/cargo`), or - // - an absolute path (e.g. `/usr/local/bin/cargo`). - // In either case, Path::canonicalize will return the full absolute path - // to the target if it exists + // - a relative path (e.g., `./cargo`, `target/debug/cargo`), or + // - an absolute path (e.g., `/usr/local/bin/cargo`). + // In either case, `Path::canonicalize` will return the full absolute path + // to the target if it exists. let argv0 = env::args_os() .map(PathBuf::from) .next() - .ok_or_else(|| format_err!("no argv[0]"))?; + .ok_or_else(|| failure::format_err!("no argv[0]"))?; paths::resolve_executable(&argv0) } @@ -278,14 +274,14 @@ self.values.try_borrow_with(|| self.load_values()) } - // Note: This is used by RLS, not Cargo. + // Note: this is used by RLS, not Cargo. pub fn set_values(&self, values: HashMap) -> CargoResult<()> { if self.values.borrow().is_some() { - bail!("config values already found") + failure::bail!("config values already found") } match self.values.fill(values) { Ok(()) => Ok(()), - Err(_) => bail!("could not fill values"), + Err(_) => failure::bail!("could not fill values"), } } @@ -334,7 +330,7 @@ | CV::Boolean(_, ref path) => { let idx = key.split('.').take(i).fold(0, |n, s| n + s.len()) + i - 1; let key_so_far = &key[..idx]; - bail!( + failure::bail!( "expected table for configuration key `{}`, \ but found {} in {}", key_so_far, @@ -440,7 +436,7 @@ if is_path { definition.root(self).join(value) } else { - // A pathless name + // A pathless name. PathBuf::from(value) } } @@ -471,7 +467,7 @@ Ok(None) } - // NOTE: This does *not* support environment variables. Use `get` instead + // NOTE: this does **not** support environment variables. Use `get` instead // if you want that. pub fn get_list(&self, key: &str) -> CargoResult>> { match self.get_cv(key)? { @@ -517,8 +513,8 @@ } } - // Recommend use `get` if you want a specific type, such as an unsigned value. - // Example: config.get::>("some.key")? + // Recommended to use `get` if you want a specific type, such as an unsigned value. + // Example: `config.get::>("some.key")?`. pub fn get_i64(&self, key: &str) -> CargoResult> { self.get_integer(&ConfigKey::from_str(key)) .map_err(|e| e.into()) @@ -541,7 +537,7 @@ fn expected(&self, ty: &str, key: &str, val: &CV) -> CargoResult { val.expected(ty, key) - .map_err(|e| format_err!("invalid configuration for key `{}`\n{}", key, e)) + .map_err(|e| failure::format_err!("invalid configuration for key `{}`\n{}", key, e)) } pub fn configure( @@ -566,14 +562,14 @@ let verbosity = match (verbose, cfg_verbose, quiet) { (Some(true), _, None) | (None, Some(true), None) => Verbosity::Verbose, - // command line takes precedence over configuration, so ignore the - // configuration. + // Command line takes precedence over configuration, so ignore the + // configuration.. (None, _, Some(true)) => Verbosity::Quiet, // Can't pass both at the same time on the command line regardless // of configuration. (Some(true), _, Some(true)) => { - bail!("cannot set both --verbose and --quiet"); + failure::bail!("cannot set both --verbose and --quiet"); } // Can't actually get `Some(false)` as a value from the command @@ -621,7 +617,7 @@ !self.frozen && !self.locked } - /// Loads configuration from the filesystem + /// Loads configuration from the filesystem. pub fn load_values(&self) -> CargoResult> { self.load_values_from(&self.cwd) } @@ -659,21 +655,23 @@ /// Gets the index for a registry. pub fn get_registry_index(&self, registry: &str) -> CargoResult { + validate_package_name(registry, "registry name", "")?; Ok( match self.get_string(&format!("registries.{}.index", registry))? { Some(index) => { let url = index.val.to_url()?; if url.password().is_some() { - bail!("Registry URLs may not contain passwords"); + failure::bail!("Registry URLs may not contain passwords"); } url } - None => bail!("No index found for registry: `{}`", registry), + None => failure::bail!("No index found for registry: `{}`", registry), }, ) } - /// Loads credentials config from the credentials file into the ConfigValue object, if present. + /// Loads credentials config from the credentials file into the `ConfigValue` object, if + /// present. fn load_credentials(&self, cfg: &mut ConfigValue) -> CargoResult<()> { let home_path = self.home_path.clone().into_path_unlocked(); let credentials = home_path.join("credentials"); @@ -704,7 +702,7 @@ ) })?; - // backwards compatibility for old .cargo/credentials layout + // Backwards compatibility for old `.cargo/credentials` layout. { let value = match value { CV::Table(ref mut value, _) => value, @@ -721,14 +719,14 @@ } } - // we want value to override cfg, so swap these + // We want value to override `cfg`, so swap these. mem::swap(cfg, &mut value); cfg.merge(value)?; Ok(()) } - /// Look for a path for `tool` in an environment variable or config path, but return `None` + /// Looks for a path for `tool` in an environment variable or config path, and returns `None` /// if it's not present. fn maybe_get_tool(&self, tool: &str) -> CargoResult> { let var = tool @@ -756,7 +754,7 @@ Ok(None) } - /// Look for a path for `tool` in an environment variable or config path, defaulting to `tool` + /// Looks for a path for `tool` in an environment variable or config path, defaulting to `tool` /// as a path. fn get_tool(&self, tool: &str) -> CargoResult { self.maybe_get_tool(tool) @@ -791,9 +789,10 @@ self.creation_time } - // Retrieve a config variable. + // Retrieves a config variable. + // + // This supports most serde `Deserialize` types. Examples: // - // This supports most serde `Deserialize` types. Examples: // let v: Option = config.get("some.nested.key")?; // let v: Option = config.get("some.key")?; // let v: Option> = config.get("foo")?; @@ -878,7 +877,7 @@ } impl fmt::Display for ConfigKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.to_config().fmt(f) } } @@ -900,7 +899,7 @@ fn expected(key: &str, expected: &str, found: &ConfigValue) -> ConfigError { ConfigError { - error: format_err!( + error: failure::format_err!( "`{}` expected {}, but found a {}", key, expected, @@ -912,32 +911,28 @@ fn missing(key: &str) -> ConfigError { ConfigError { - error: format_err!("missing config key `{}`", key), + error: failure::format_err!("missing config key `{}`", key), definition: None, } } fn with_key_context(self, key: &str, definition: Definition) -> ConfigError { ConfigError { - error: format_err!("could not load config key `{}`: {}", key, self), + error: failure::format_err!("could not load config key `{}`: {}", key, self), definition: Some(definition), } } } impl std::error::Error for ConfigError { - // This can be removed once 1.27 is stable. - fn description(&self) -> &str { - "An error has occurred." - } } -// Future Note: Currently we cannot override Fail::cause (due to +// Future note: currently, we cannot override `Fail::cause` (due to // specialization) so we have no way to return the underlying causes. In the // future, once this limitation is lifted, this should instead implement // `cause` and avoid doing the cause formatting here. impl fmt::Display for ConfigError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let message = self .error .iter_chain() @@ -1063,7 +1058,7 @@ if self.config.has_key(&self.key) { visitor.visit_some(self) } else { - // Treat missing values as None. + // Treat missing values as `None`. visitor.visit_none() } } @@ -1140,7 +1135,7 @@ } // These aren't really supported, yet. - forward_to_deserialize_any! { + serde::forward_to_deserialize_any! { f32 f64 char str bytes byte_buf unit unit_struct enum identifier ignored_any @@ -1161,21 +1156,21 @@ ) -> Result, ConfigError> { let mut set = HashSet::new(); if let Some(mut v) = config.get_table(&key.to_config())? { - // v: Value> + // `v: Value>` for (key, _value) in v.val.drain() { set.insert(ConfigKeyPart::CasePart(key)); } } if config.cli_unstable().advanced_env { - // CARGO_PROFILE_DEV_OVERRIDES_ + // `CARGO_PROFILE_DEV_OVERRIDES_` let env_pattern = format!("{}_", key.to_env()); for env_key in config.env.keys() { if env_key.starts_with(&env_pattern) { - // CARGO_PROFILE_DEV_OVERRIDES_bar_OPT_LEVEL = 3 + // `CARGO_PROFILE_DEV_OVERRIDES_bar_OPT_LEVEL = 3` let rest = &env_key[env_pattern.len()..]; - // rest = bar_OPT_LEVEL + // `rest = bar_OPT_LEVEL` let part = rest.splitn(2, '_').next().unwrap(); - // part = "bar" + // `part = "bar"` set.insert(ConfigKeyPart::CasePart(part.to_string())); } } @@ -1269,7 +1264,7 @@ if !(v.starts_with('[') && v.ends_with(']')) { return Err(ConfigError::new( format!("should have TOML list syntax, found `{}`", v), - def.clone(), + def, )); } let temp_key = key.last().to_env(); @@ -1285,7 +1280,7 @@ .as_array() .expect("env var was not array"); for value in values { - // TODO: support other types + // TODO: support other types. let s = value.as_str().ok_or_else(|| { ConfigError::new( format!("expected string, found {}", value.type_str()), @@ -1310,7 +1305,7 @@ T: de::DeserializeSeed<'de>, { match self.list_iter.next() { - // TODO: Add def to err? + // TODO: add `def` to error? Some((value, _def)) => seed.deserialize(value.into_deserializer()).map(Some), None => Ok(None), } @@ -1318,7 +1313,7 @@ } /// Use with the `get` API to fetch a string that will be converted to a -/// `PathBuf`. Relative paths are converted to absolute paths based on the +/// `PathBuf`. Relative paths are converted to absolute paths based on the /// location of the config file. #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct ConfigRelativePath(PathBuf); @@ -1352,7 +1347,7 @@ } impl fmt::Debug for ConfigValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { CV::Integer(i, ref path) => write!(f, "{} (from {})", i, path.display()), CV::Boolean(b, ref path) => write!(f, "{} (from {})", b, path.display()), @@ -1382,7 +1377,7 @@ val.into_iter() .map(|toml| match toml { toml::Value::String(val) => Ok((val, path.to_path_buf())), - v => bail!("expected string but found {} in list", v.type_str()), + v => failure::bail!("expected string but found {} in list", v.type_str()), }) .collect::>()?, path.to_path_buf(), @@ -1397,7 +1392,7 @@ .collect::>()?, path.to_path_buf(), )), - v => bail!( + v => failure::bail!( "found TOML configuration value of unknown type `{}`", v.type_str() ), @@ -1458,7 +1453,7 @@ "expected {}, but found {}", expected.desc(), found.desc() - ))) + ))); } _ => {} } @@ -1522,7 +1517,7 @@ } fn expected(&self, wanted: &str, key: &str) -> CargoResult { - bail!( + failure::bail!( "expected a {}, but found a {} for `{}` in {}", wanted, self.desc(), @@ -1542,7 +1537,7 @@ } impl fmt::Display for Definition { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Definition::Path(ref p) => p.display().fmt(f), Definition::Environment(ref key) => write!(f, "environment variable `{}`", key), @@ -1615,7 +1610,7 @@ let mut toml = cargo_toml::parse(&contents, file.path(), cfg)?; - // move the old token location to the new one + // Move the old token location to the new one. if let Some(token) = toml.as_table_mut().unwrap().remove("token") { let mut map = HashMap::new(); map.insert("token".to_string(), token); diff -Nru cargo-0.33.0/src/cargo/util/dependency_queue.rs cargo-0.35.0/src/cargo/util/dependency_queue.rs --- cargo-0.33.0/src/cargo/util/dependency_queue.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/dependency_queue.rs 2019-04-01 21:32:07.000000000 +0000 @@ -93,7 +93,8 @@ let mut my_dependencies = HashSet::new(); for dep in dependencies { my_dependencies.insert(dep.clone()); - let rev = self.reverse_dep_map + let rev = self + .reverse_dep_map .entry(dep.clone()) .or_insert_with(HashSet::new); rev.insert(key.clone()); @@ -122,13 +123,13 @@ results.insert(key.clone(), IN_PROGRESS); - let depth = 1 - + map.get(&key) - .into_iter() - .flat_map(|it| it) - .map(|dep| depth(dep, map, results)) - .max() - .unwrap_or(0); + let depth = 1 + map + .get(&key) + .into_iter() + .flat_map(|it| it) + .map(|dep| depth(dep, map, results)) + .max() + .unwrap_or(0); *results.get_mut(key).unwrap() = depth; @@ -151,7 +152,8 @@ // TODO: it'd be best here to throw in a heuristic of crate size as // well. For example how long did this crate historically take to // compile? How large is its source code? etc. - let next = self.dep_map + let next = self + .dep_map .iter() .filter(|&(_, &(ref deps, _))| deps.is_empty()) .map(|(key, _)| key.clone()) @@ -170,7 +172,7 @@ Some((fresh, key, data)) } - /// Returns whether there are remaining packages to be built. + /// Returns `true` if there are remaining packages to be built. pub fn is_empty(&self) -> bool { self.dep_map.is_empty() && self.pending.is_empty() } diff -Nru cargo-0.33.0/src/cargo/util/diagnostic_server.rs cargo-0.35.0/src/cargo/util/diagnostic_server.rs --- cargo-0.33.0/src/cargo/util/diagnostic_server.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/diagnostic_server.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,15 +5,16 @@ use std::env; use std::io::{BufReader, Read, Write}; use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream}; -use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; use std::thread::{self, JoinHandle}; use failure::{Error, ResultExt}; -use serde_json; +use log::warn; +use serde::{Deserialize, Serialize}; -use util::{Config, ProcessBuilder}; -use util::errors::CargoResult; +use crate::util::errors::CargoResult; +use crate::util::{Config, ProcessBuilder}; const DIAGNOSICS_SERVER_VAR: &str = "__CARGO_FIX_DIAGNOSTICS_SERVER"; const PLEASE_REPORT_THIS_BUG: &str = @@ -22,8 +23,10 @@ and we would appreciate a bug report! You're likely to see \n\ a number of compiler warnings after this message which cargo\n\ attempted to fix but failed. If you could open an issue at\n\ - https://github.com/rust-lang/cargo/issues\n\ - quoting the full output of this command we'd be very appreciative!\n\n\ + https://github.com/rust-lang/rust/issues\n\ + quoting the full output of this command we'd be very appreciative!\n\ + Note that you may be able to make some more progress in the near-term\n\ + fixing code with the `--broken-code` flag\n\n\ "; #[derive(Deserialize, Serialize)] @@ -35,6 +38,7 @@ FixFailed { files: Vec, krate: Option, + errors: Vec, }, ReplaceFailed { file: String, @@ -53,8 +57,8 @@ impl Message { pub fn post(&self) -> Result<(), Error> { - let addr = env::var(DIAGNOSICS_SERVER_VAR) - .context("diagnostics collector misconfigured")?; + let addr = + env::var(DIAGNOSICS_SERVER_VAR).context("diagnostics collector misconfigured")?; let mut client = TcpStream::connect(&addr).context("failed to connect to parent diagnostics target")?; @@ -108,7 +112,11 @@ write!(self.config.shell().err(), "{}", PLEASE_REPORT_THIS_BUG)?; Ok(()) } - Message::FixFailed { files, krate } => { + Message::FixFailed { + files, + krate, + errors, + } => { if let Some(ref krate) = *krate { self.config.shell().warn(&format!( "failed to automatically apply fixes suggested by rustc \ @@ -116,9 +124,9 @@ krate, ))?; } else { - self.config.shell().warn( - "failed to automatically apply fixes suggested by rustc" - )?; + self.config + .shell() + .warn("failed to automatically apply fixes suggested by rustc")?; } if !files.is_empty() { writeln!( @@ -132,12 +140,28 @@ writeln!(self.config.shell().err())?; } write!(self.config.shell().err(), "{}", PLEASE_REPORT_THIS_BUG)?; + if !errors.is_empty() { + writeln!( + self.config.shell().err(), + "The following errors were reported:" + )?; + for error in errors { + write!(self.config.shell().err(), "{}", error)?; + if !error.ends_with('\n') { + writeln!(self.config.shell().err())?; + } + } + } + writeln!( + self.config.shell().err(), + "Original diagnostics will follow.\n" + )?; Ok(()) } Message::EditionAlreadyEnabled { file, edition } => { // Like above, only warn once per file if !self.edition_already_enabled.insert(file.clone()) { - return Ok(()) + return Ok(()); } let msg = format!( @@ -158,10 +182,14 @@ self.config.shell().error(&msg)?; Ok(()) } - Message::IdiomEditionMismatch { file, idioms, edition } => { + Message::IdiomEditionMismatch { + file, + idioms, + edition, + } => { // Same as above if !self.idiom_mismatch.insert(file.clone()) { - return Ok(()) + return Ok(()); } self.config.shell().error(&format!( "\ @@ -230,16 +258,25 @@ }) } - fn run(self, on_message: &Fn(Message), done: &AtomicBool) { + fn run(self, on_message: &dyn Fn(Message), done: &AtomicBool) { while let Ok((client, _)) = self.listener.accept() { - let client = BufReader::new(client); - match serde_json::from_reader(client) { - Ok(message) => on_message(message), - Err(e) => warn!("invalid diagnostics message: {}", e), - } if done.load(Ordering::SeqCst) { - break + break; + } + let mut client = BufReader::new(client); + let mut s = String::new(); + if let Err(e) = client.read_to_string(&mut s) { + warn!("diagnostic server failed to read: {}", e); + } else { + match serde_json::from_str(&s) { + Ok(message) => on_message(message), + Err(e) => warn!("invalid diagnostics message: {}", e), + } } + // The client should be kept alive until after `on_message` is + // called to ensure that the client doesn't exit too soon (and + // Message::Finish getting posted before Message::FixDiagnostic). + drop(client); } } } diff -Nru cargo-0.33.0/src/cargo/util/errors.rs cargo-0.35.0/src/cargo/util/errors.rs --- cargo-0.33.0/src/cargo/util/errors.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/errors.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,16 +1,17 @@ #![allow(unknown_lints)] use std::fmt; +use std::path::PathBuf; use std::process::{ExitStatus, Output}; use std::str; -use std::path::PathBuf; -use core::{TargetKind, Workspace}; -use failure::{Context, Error, Fail}; use clap; +use failure::{Context, Error, Fail}; +use log::trace; + +use crate::core::{TargetKind, Workspace}; -pub use failure::Error as CargoError; -pub type CargoResult = Result; +pub type CargoResult = failure::Fallible; // Alex's body isn't quite ready to give up "Result" pub trait CargoResultExt { fn chain_err(self, f: F) -> Result> @@ -56,19 +57,19 @@ } impl Fail for Internal { - fn cause(&self) -> Option<&Fail> { + fn cause(&self) -> Option<&dyn Fail> { self.inner.as_fail().cause() } } impl fmt::Debug for Internal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.inner.fmt(f) } } impl fmt::Display for Internal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.inner.fmt(f) } } @@ -96,25 +97,25 @@ /// Returns an iterator over the `ManifestError` chain of causes. /// /// So if this error was not caused by another `ManifestError` this will be empty. - pub fn manifest_causes(&self) -> ManifestCauses { + pub fn manifest_causes(&self) -> ManifestCauses<'_> { ManifestCauses { current: self } } } impl Fail for ManifestError { - fn cause(&self) -> Option<&Fail> { + fn cause(&self) -> Option<&dyn Fail> { self.cause.as_fail().cause() } } impl fmt::Debug for ManifestError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.cause.fmt(f) } } impl fmt::Display for ManifestError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.cause.fmt(f) } } @@ -187,7 +188,7 @@ } } - pub fn hint(&self, ws: &Workspace) -> String { + pub fn hint(&self, ws: &Workspace<'_>) -> String { match self.test { Test::UnitTest { ref kind, @@ -230,13 +231,13 @@ #[derive(Debug)] pub struct CliError { - pub error: Option, + pub error: Option, pub unknown: bool, pub exit_code: i32, } impl CliError { - pub fn new(error: CargoError, code: i32) -> CliError { + pub fn new(error: failure::Error, code: i32) -> CliError { let unknown = error.downcast_ref::().is_some(); CliError { error: Some(error), @@ -254,8 +255,8 @@ } } -impl From for CliError { - fn from(err: CargoError) -> CliError { +impl From for CliError { + fn from(err: failure::Error) -> CliError { CliError::new(err, 101) } } @@ -307,7 +308,6 @@ #[cfg(unix)] fn status_to_string(status: ExitStatus) -> String { use std::os::unix::process::*; - use libc; if let Some(signal) = status.signal() { let name = match signal as libc::c_int { @@ -336,14 +336,54 @@ #[cfg(windows)] fn status_to_string(status: ExitStatus) -> String { - status.to_string() + use winapi::shared::minwindef::DWORD; + use winapi::um::winnt::*; + + let mut base = status.to_string(); + let extra = match status.code().unwrap() as DWORD { + STATUS_ACCESS_VIOLATION => "STATUS_ACCESS_VIOLATION", + STATUS_IN_PAGE_ERROR => "STATUS_IN_PAGE_ERROR", + STATUS_INVALID_HANDLE => "STATUS_INVALID_HANDLE", + STATUS_INVALID_PARAMETER => "STATUS_INVALID_PARAMETER", + STATUS_NO_MEMORY => "STATUS_NO_MEMORY", + STATUS_ILLEGAL_INSTRUCTION => "STATUS_ILLEGAL_INSTRUCTION", + STATUS_NONCONTINUABLE_EXCEPTION => "STATUS_NONCONTINUABLE_EXCEPTION", + STATUS_INVALID_DISPOSITION => "STATUS_INVALID_DISPOSITION", + STATUS_ARRAY_BOUNDS_EXCEEDED => "STATUS_ARRAY_BOUNDS_EXCEEDED", + STATUS_FLOAT_DENORMAL_OPERAND => "STATUS_FLOAT_DENORMAL_OPERAND", + STATUS_FLOAT_DIVIDE_BY_ZERO => "STATUS_FLOAT_DIVIDE_BY_ZERO", + STATUS_FLOAT_INEXACT_RESULT => "STATUS_FLOAT_INEXACT_RESULT", + STATUS_FLOAT_INVALID_OPERATION => "STATUS_FLOAT_INVALID_OPERATION", + STATUS_FLOAT_OVERFLOW => "STATUS_FLOAT_OVERFLOW", + STATUS_FLOAT_STACK_CHECK => "STATUS_FLOAT_STACK_CHECK", + STATUS_FLOAT_UNDERFLOW => "STATUS_FLOAT_UNDERFLOW", + STATUS_INTEGER_DIVIDE_BY_ZERO => "STATUS_INTEGER_DIVIDE_BY_ZERO", + STATUS_INTEGER_OVERFLOW => "STATUS_INTEGER_OVERFLOW", + STATUS_PRIVILEGED_INSTRUCTION => "STATUS_PRIVILEGED_INSTRUCTION", + STATUS_STACK_OVERFLOW => "STATUS_STACK_OVERFLOW", + STATUS_DLL_NOT_FOUND => "STATUS_DLL_NOT_FOUND", + STATUS_ORDINAL_NOT_FOUND => "STATUS_ORDINAL_NOT_FOUND", + STATUS_ENTRYPOINT_NOT_FOUND => "STATUS_ENTRYPOINT_NOT_FOUND", + STATUS_CONTROL_C_EXIT => "STATUS_CONTROL_C_EXIT", + STATUS_DLL_INIT_FAILED => "STATUS_DLL_INIT_FAILED", + STATUS_FLOAT_MULTIPLE_FAULTS => "STATUS_FLOAT_MULTIPLE_FAULTS", + STATUS_FLOAT_MULTIPLE_TRAPS => "STATUS_FLOAT_MULTIPLE_TRAPS", + STATUS_REG_NAT_CONSUMPTION => "STATUS_REG_NAT_CONSUMPTION", + STATUS_HEAP_CORRUPTION => "STATUS_HEAP_CORRUPTION", + STATUS_STACK_BUFFER_OVERRUN => "STATUS_STACK_BUFFER_OVERRUN", + STATUS_ASSERTION_FAILURE => "STATUS_ASSERTION_FAILURE", + _ => return base, + }; + base.push_str(", "); + base.push_str(extra); + base } } -pub fn internal(error: S) -> CargoError { +pub fn internal(error: S) -> failure::Error { _internal(&error) } -fn _internal(error: &fmt::Display) -> CargoError { - Internal::new(format_err!("{}", error)).into() +fn _internal(error: &dyn fmt::Display) -> failure::Error { + Internal::new(failure::format_err!("{}", error)).into() } diff -Nru cargo-0.33.0/src/cargo/util/flock.rs cargo-0.35.0/src/cargo/util/flock.rs --- cargo-0.33.0/src/cargo/util/flock.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/flock.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,16 +1,16 @@ use std::fs::{self, File, OpenOptions}; -use std::io::{Read, Seek, SeekFrom, Write}; use std::io; +use std::io::{Read, Seek, SeekFrom, Write}; use std::path::{Display, Path, PathBuf}; -use termcolor::Color::Cyan; use fs2::{lock_contended_error, FileExt}; #[allow(unused_imports)] use libc; +use termcolor::Color::Cyan; -use util::Config; -use util::paths; -use util::errors::{CargoError, CargoResult, CargoResultExt}; +use crate::util::errors::{CargoResult, CargoResultExt}; +use crate::util::paths; +use crate::util::Config; pub struct FileLock { f: Option, @@ -146,7 +146,7 @@ /// Returns an adaptor that can be used to print the path of this /// filesystem. - pub fn display(&self) -> Display { + pub fn display(&self) -> Display<'_> { self.root.display() } @@ -208,7 +208,8 @@ // If we want an exclusive lock then if we fail because of NotFound it's // likely because an intermediate directory didn't exist, so try to // create the directory and then continue. - let f = opts.open(&path) + let f = opts + .open(&path) .or_else(|e| { if e.kind() == io::ErrorKind::NotFound && state == State::Exclusive { fs::create_dir_all(path.parent().unwrap())?; @@ -270,13 +271,13 @@ config: &Config, msg: &str, path: &Path, - try: &Fn() -> io::Result<()>, - block: &Fn() -> io::Result<()>, + r#try: &dyn Fn() -> io::Result<()>, + block: &dyn Fn() -> io::Result<()>, ) -> CargoResult<()> { // File locking on Unix is currently implemented via `flock`, which is known // to be broken on NFS. We could in theory just ignore errors that happen on // NFS, but apparently the failure mode [1] for `flock` on NFS is **blocking - // forever**, even if the nonblocking flag is passed! + // forever**, even if the "non-blocking" flag is passed! // // As a result, we just skip all file locks entirely on NFS mounts. That // should avoid calling any `flock` functions at all, and it wouldn't work @@ -287,28 +288,22 @@ return Ok(()); } - match try() { + match r#try() { Ok(()) => return Ok(()), // In addition to ignoring NFS which is commonly not working we also // just ignore locking on filesystems that look like they don't // implement file locking. We detect that here via the return value of - // locking (e.g. inspecting errno). + // locking (e.g., inspecting errno). #[cfg(unix)] - Err(ref e) if e.raw_os_error() == Some(libc::ENOTSUP) => - { - return Ok(()) - } + Err(ref e) if e.raw_os_error() == Some(libc::ENOTSUP) => return Ok(()), #[cfg(target_os = "linux")] - Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => - { - return Ok(()) - } + Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => return Ok(()), Err(e) => { if e.raw_os_error() != lock_contended_error().raw_os_error() { - let e = CargoError::from(e); + let e = failure::Error::from(e); let cx = format!("failed to lock file: {}", path.display()); return Err(e.context(cx).into()); } diff -Nru cargo-0.33.0/src/cargo/util/graph.rs cargo-0.35.0/src/cargo/util/graph.rs --- cargo-0.33.0/src/cargo/util/graph.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/graph.rs 2019-04-01 21:32:07.000000000 +0000 @@ -101,7 +101,7 @@ } impl fmt::Debug for Graph { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(fmt, "Graph {{")?; for (n, e) in &self.nodes { diff -Nru cargo-0.33.0/src/cargo/util/important_paths.rs cargo-0.35.0/src/cargo/util/important_paths.rs --- cargo-0.33.0/src/cargo/util/important_paths.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/important_paths.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ +use crate::util::errors::CargoResult; +use crate::util::paths; use std::fs; use std::path::{Path, PathBuf}; -use util::errors::CargoResult; -use util::paths; -/// Find the root Cargo.toml +/// Finds the root `Cargo.toml`. pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult { let file = "Cargo.toml"; for current in paths::ancestors(cwd) { @@ -13,20 +13,20 @@ } } - bail!( + failure::bail!( "could not find `{}` in `{}` or any parent directory", file, cwd.display() ) } -/// Return the path to the `file` in `pwd`, if it exists. +/// Returns the path to the `file` in `pwd`, if it exists. pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult { let manifest = pwd.join(file); if manifest.exists() { Ok(manifest) } else { - bail!("Could not find `{}` in `{}`", file, pwd.display()) + failure::bail!("Could not find `{}` in `{}`", file, pwd.display()) } } diff -Nru cargo-0.33.0/src/cargo/util/job.rs cargo-0.35.0/src/cargo/util/job.rs --- cargo-0.33.0/src/cargo/util/job.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/job.rs 2019-04-01 21:32:07.000000000 +0000 @@ -23,8 +23,8 @@ #[cfg(unix)] mod imp { - use std::env; use libc; + use std::env; pub type Setup = (); @@ -42,18 +42,18 @@ #[cfg(windows)] mod imp { - extern crate winapi; - use std::io; use std::mem; use std::ptr; - use self::winapi::shared::minwindef::*; - use self::winapi::um::handleapi::*; - use self::winapi::um::jobapi2::*; - use self::winapi::um::processthreadsapi::*; - use self::winapi::um::winnt::*; - use self::winapi::um::winnt::HANDLE; + use log::info; + + use winapi::shared::minwindef::*; + use winapi::um::handleapi::*; + use winapi::um::jobapi2::*; + use winapi::um::processthreadsapi::*; + use winapi::um::winnt::HANDLE; + use winapi::um::winnt::*; pub struct Setup { job: Handle, @@ -115,7 +115,7 @@ fn drop(&mut self) { // On normal exits (not ctrl-c), we don't want to kill any child // processes. The destructor here configures our job object to - // *not* kill everything on close, then closes the job object. + // **not** kill everything on close, then closes the job object. unsafe { let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION; info = mem::zeroed(); diff -Nru cargo-0.33.0/src/cargo/util/lockserver.rs cargo-0.35.0/src/cargo/util/lockserver.rs --- cargo-0.33.0/src/cargo/util/lockserver.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/lockserver.rs 2019-04-01 21:32:07.000000000 +0000 @@ -14,7 +14,6 @@ use std::collections::HashMap; use std::io::{BufRead, BufReader, Read, Write}; use std::net::{SocketAddr, TcpListener, TcpStream}; -use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::thread::{self, JoinHandle}; @@ -156,11 +155,11 @@ } impl LockServerClient { - pub fn lock(addr: &SocketAddr, name: &Path) -> Result { - let mut client = - TcpStream::connect(&addr).with_context(|_| "failed to connect to parent lock server")?; + pub fn lock(addr: &SocketAddr, name: impl AsRef<[u8]>) -> Result { + let mut client = TcpStream::connect(&addr) + .with_context(|_| "failed to connect to parent lock server")?; client - .write_all(name.display().to_string().as_bytes()) + .write_all(name.as_ref()) .and_then(|_| client.write_all(b"\n")) .with_context(|_| "failed to write to lock server")?; let mut buf = [0]; @@ -170,4 +169,3 @@ Ok(LockServerClient { _socket: client }) } } - diff -Nru cargo-0.33.0/src/cargo/util/machine_message.rs cargo-0.35.0/src/cargo/util/machine_message.rs --- cargo-0.33.0/src/cargo/util/machine_message.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/machine_message.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,10 @@ +use std::path::PathBuf; + use serde::ser; -use serde_json::{self, value::RawValue}; +use serde::Serialize; +use serde_json::{self, json, value::RawValue}; -use core::{PackageId, Target}; +use crate::core::{PackageId, Target}; pub trait Message: ser::Serialize { fn reason(&self) -> &str; @@ -33,7 +36,8 @@ pub target: &'a Target, pub profile: ArtifactProfile, pub features: Vec, - pub filenames: Vec, + pub filenames: Vec, + pub executable: Option, pub fresh: bool, } diff -Nru cargo-0.33.0/src/cargo/util/mod.rs cargo-0.35.0/src/cargo/util/mod.rs --- cargo-0.33.0/src/cargo/util/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,52 +3,57 @@ pub use self::cfg::{Cfg, CfgExpr}; pub use self::config::{homedir, Config, ConfigValue}; pub use self::dependency_queue::{DependencyQueue, Dirty, Fresh, Freshness}; -pub use self::errors::{CargoError, CargoResult, CargoResultExt, CliResult, Test}; -pub use self::errors::{CargoTestError, CliError, ProcessError}; +pub use self::diagnostic_server::RustfixDiagnosticServer; pub use self::errors::{internal, process_error}; +pub use self::errors::{CargoResult, CargoResultExt, CliResult, Test}; +pub use self::errors::{CargoTestError, CliError, ProcessError}; pub use self::flock::{FileLock, Filesystem}; pub use self::graph::Graph; -pub use self::hex::{short_hash, to_hex, hash_u64}; +pub use self::hex::{hash_u64, short_hash, to_hex}; pub use self::lev_distance::lev_distance; -pub use self::paths::{dylib_path, join_paths, bytes2path, path2bytes}; -pub use self::paths::{dylib_path_envvar, normalize_path, without_prefix}; +pub use self::lockserver::{LockServer, LockServerClient, LockServerStarted}; +pub use self::paths::{bytes2path, dylib_path, join_paths, path2bytes}; +pub use self::paths::{dylib_path_envvar, normalize_path}; pub use self::process_builder::{process, ProcessBuilder}; +pub use self::progress::{Progress, ProgressStyle}; +pub use self::read2::read2; pub use self::rustc::Rustc; pub use self::sha256::Sha256; pub use self::to_semver::ToSemver; pub use self::to_url::ToUrl; -pub use self::vcs::{FossilRepo, GitRepo, HgRepo, PijulRepo, existing_vcs_repo}; -pub use self::read2::read2; -pub use self::progress::{Progress, ProgressStyle}; -pub use self::lockserver::{LockServer, LockServerStarted, LockServerClient}; -pub use self::diagnostic_server::RustfixDiagnosticServer; +pub use self::vcs::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo}; +pub use self::workspace::{ + print_available_benches, print_available_binaries, print_available_examples, + print_available_tests, +}; +mod cfg; +pub mod command_prelude; pub mod config; +mod dependency_queue; +pub mod diagnostic_server; pub mod errors; +mod flock; pub mod graph; pub mod hex; pub mod important_paths; pub mod job; pub mod lev_distance; +mod lockserver; pub mod machine_message; pub mod network; pub mod paths; pub mod process_builder; pub mod profile; +mod progress; +mod read2; +mod rustc; +mod sha256; pub mod to_semver; pub mod to_url; pub mod toml; -pub mod command_prelude; -mod cfg; -mod dependency_queue; -mod rustc; -mod sha256; mod vcs; -mod flock; -mod read2; -mod progress; -mod lockserver; -pub mod diagnostic_server; +mod workspace; pub fn elapsed(duration: Duration) -> String { let secs = duration.as_secs(); @@ -59,3 +64,19 @@ format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000) } } + +/// Check the base requirements for a package name. +/// +/// This can be used for other things than package names, to enforce some +/// level of sanity. Note that package names have other restrictions +/// elsewhere. `cargo new` has a few restrictions, such as checking for +/// reserved names. crates.io has even more restrictions. +pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult<()> { + if let Some(ch) = name + .chars() + .find(|ch| !ch.is_alphanumeric() && *ch != '_' && *ch != '-') + { + failure::bail!("Invalid character `{}` in {}: `{}`{}", ch, what, name, help); + } + Ok(()) +} diff -Nru cargo-0.33.0/src/cargo/util/network.rs cargo-0.35.0/src/cargo/util/network.rs --- cargo-0.33.0/src/cargo/util/network.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/network.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,8 +3,8 @@ use failure::Error; -use util::Config; -use util::errors::{CargoResult, HttpNot200}; +use crate::util::errors::{CargoResult, HttpNot200}; +use crate::util::Config; pub struct Retry<'a> { config: &'a Config, @@ -19,9 +19,7 @@ }) } - pub fn try(&mut self, f: impl FnOnce() -> CargoResult) - -> CargoResult> - { + pub fn r#try(&mut self, f: impl FnOnce() -> CargoResult) -> CargoResult> { match f() { Err(ref e) if maybe_spurious(e) && self.remaining > 0 => { let msg = format!( @@ -84,8 +82,8 @@ { let mut retry = Retry::new(config)?; loop { - if let Some(ret) = retry.try(&mut callback)? { - return Ok(ret) + if let Some(ret) = retry.r#try(&mut callback)? { + return Ok(ret); } } } @@ -95,11 +93,13 @@ let error1 = HttpNot200 { code: 501, url: "Uri".to_string(), - }.into(); + } + .into(); let error2 = HttpNot200 { code: 502, url: "Uri".to_string(), - }.into(); + } + .into(); let mut results: Vec> = vec![Ok(()), Err(error1), Err(error2)]; let config = Config::default().unwrap(); let result = with_retry(&config, || results.pop().unwrap()); @@ -108,20 +108,18 @@ #[test] fn with_retry_finds_nested_spurious_errors() { - use util::CargoError; - //Error HTTP codes (5xx) are considered maybe_spurious and will prompt retry //String error messages are not considered spurious - let error1 = CargoError::from(HttpNot200 { + let error1 = failure::Error::from(HttpNot200 { code: 501, url: "Uri".to_string(), }); - let error1 = CargoError::from(error1.context("A non-spurious wrapping err")); - let error2 = CargoError::from(HttpNot200 { + let error1 = failure::Error::from(error1.context("A non-spurious wrapping err")); + let error2 = failure::Error::from(HttpNot200 { code: 502, url: "Uri".to_string(), }); - let error2 = CargoError::from(error2.context("A second chained error")); + let error2 = failure::Error::from(error2.context("A second chained error")); let mut results: Vec> = vec![Ok(()), Err(error1), Err(error2)]; let config = Config::default().unwrap(); let result = with_retry(&config, || results.pop().unwrap()); diff -Nru cargo-0.33.0/src/cargo/util/paths.rs cargo-0.35.0/src/cargo/util/paths.rs --- cargo-0.33.0/src/cargo/util/paths.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/paths.rs 2019-04-01 21:32:07.000000000 +0000 @@ -8,7 +8,7 @@ use filetime::FileTime; -use util::errors::{CargoError, CargoResult, CargoResultExt, Internal}; +use crate::util::errors::{CargoResult, CargoResultExt, Internal}; pub fn join_paths>(paths: &[T], env: &str) -> CargoResult { let err = match env::join_paths(paths.iter()) { @@ -16,9 +16,12 @@ Err(e) => e, }; let paths = paths.iter().map(Path::new).collect::>(); - let err = CargoError::from(err); - let explain = Internal::new(format_err!("failed to join path array: {:?}", paths)); - let err = CargoError::from(err.context(explain)); + let err = failure::Error::from(err); + let explain = Internal::new(failure::format_err!( + "failed to join path array: {:?}", + paths + )); + let err = failure::Error::from(err.context(explain)); let more_explain = format!( "failed to join search paths together\n\ Does ${} have an unterminated quote character?", @@ -31,7 +34,22 @@ if cfg!(windows) { "PATH" } else if cfg!(target_os = "macos") { - "DYLD_LIBRARY_PATH" + // When loading and linking a dynamic library or bundle, dlopen + // searches in LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, PWD, and + // DYLD_FALLBACK_LIBRARY_PATH. + // In the Mach-O format, a dynamic library has an "install path." + // Clients linking against the library record this path, and the + // dynamic linker, dyld, uses it to locate the library. + // dyld searches DYLD_LIBRARY_PATH *before* the install path. + // dyld searches DYLD_FALLBACK_LIBRARY_PATH only if it cannot + // find the library in the install path. + // Setting DYLD_LIBRARY_PATH can easily have unintended + // consequences. + // + // Also, DYLD_LIBRARY_PATH appears to have significant performance + // penalty starting in 10.13. Cargo's testsuite ran more than twice as + // slow with it on CI. + "DYLD_FALLBACK_LIBRARY_PATH" } else { "LD_LIBRARY_PATH" } @@ -71,23 +89,9 @@ ret } -pub fn without_prefix<'a>(long_path: &'a Path, prefix: &'a Path) -> Option<&'a Path> { - let mut a = long_path.components(); - let mut b = prefix.components(); - loop { - match b.next() { - Some(y) => match a.next() { - Some(x) if x == y => continue, - _ => return None, - }, - None => return Some(a.as_path()), - } - } -} - pub fn resolve_executable(exec: &Path) -> CargoResult { if exec.components().count() == 1 { - let paths = env::var_os("PATH").ok_or_else(|| format_err!("no PATH"))?; + let paths = env::var_os("PATH").ok_or_else(|| failure::format_err!("no PATH"))?; let candidates = env::split_paths(&paths).flat_map(|path| { let candidate = path.join(&exec); let with_exe = if env::consts::EXE_EXTENSION == "" { @@ -105,7 +109,7 @@ } } - bail!("no executable for `{}` found in PATH", exec.display()) + failure::bail!("no executable for `{}` found in PATH", exec.display()) } else { Ok(exec.canonicalize()?) } @@ -114,7 +118,7 @@ pub fn read(path: &Path) -> CargoResult { match String::from_utf8(read_bytes(path)?) { Ok(s) => Ok(s), - Err(_) => bail!("path at `{}` was not valid utf-8", path.display()), + Err(_) => failure::bail!("path at `{}` was not valid utf-8", path.display()), } } @@ -127,7 +131,8 @@ } f.read_to_end(&mut ret)?; Ok(ret) - })().chain_err(|| format!("failed to read `{}`", path.display()))?; + })() + .chain_err(|| format!("failed to read `{}`", path.display()))?; Ok(res) } @@ -136,7 +141,8 @@ let mut f = File::create(path)?; f.write_all(contents)?; Ok(()) - })().chain_err(|| format!("failed to write `{}`", path.display()))?; + })() + .chain_err(|| format!("failed to write `{}`", path.display()))?; Ok(()) } @@ -156,7 +162,8 @@ f.write_all(contents)?; } Ok(()) - })().chain_err(|| format!("failed to write `{}`", path.as_ref().display()))?; + })() + .chain_err(|| format!("failed to write `{}`", path.as_ref().display()))?; Ok(()) } @@ -170,7 +177,8 @@ f.write_all(contents)?; Ok(()) - })().chain_err(|| format!("failed to write `{}`", path.display()))?; + })() + .chain_err(|| format!("failed to write `{}`", path.display()))?; Ok(()) } @@ -179,6 +187,18 @@ Ok(FileTime::from_last_modification_time(&meta)) } +/// get `FileTime::from_system_time(SystemTime::now());` using the exact clock that this file system is using. +pub fn get_current_filesystem_time(path: &Path) -> CargoResult { + // note that if `FileTime::from_system_time(SystemTime::now());` is determined to be sufficient, + // then this can be removed. + let timestamp = path.with_file_name("invoked.timestamp"); + write( + ×tamp, + b"This file has an mtime of when this was started.", + )?; + Ok(mtime(×tamp)?) +} + #[cfg(unix)] pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> { use std::os::unix::prelude::*; @@ -188,13 +208,15 @@ pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> { match path.as_os_str().to_str() { Some(s) => Ok(s.as_bytes()), - None => Err(format_err!("invalid non-unicode path: {}", path.display())), + None => Err(failure::format_err!( + "invalid non-unicode path: {}", + path.display() + )), } } #[cfg(unix)] pub fn bytes2path(bytes: &[u8]) -> CargoResult { - use std::ffi::OsStr; use std::os::unix::prelude::*; Ok(PathBuf::from(OsStr::from_bytes(bytes))) } @@ -203,11 +225,11 @@ use std::str; match str::from_utf8(bytes) { Ok(s) => Ok(PathBuf::from(s)), - Err(..) => Err(format_err!("invalid non-unicode path")), + Err(..) => Err(failure::format_err!("invalid non-unicode path")), } } -pub fn ancestors(path: &Path) -> PathAncestors { +pub fn ancestors(path: &Path) -> PathAncestors<'_> { PathAncestors::new(path) } @@ -217,7 +239,7 @@ } impl<'a> PathAncestors<'a> { - fn new(path: &Path) -> PathAncestors { + fn new(path: &Path) -> PathAncestors<'_> { PathAncestors { current: Some(path), //HACK: avoid reading `~/.cargo/config` when testing Cargo itself. diff -Nru cargo-0.33.0/src/cargo/util/process_builder.rs cargo-0.35.0/src/cargo/util/process_builder.rs --- cargo-0.33.0/src/cargo/util/process_builder.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/process_builder.rs 2019-04-01 21:32:07.000000000 +0000 @@ -9,7 +9,7 @@ use jobserver::Client; use shell_escape::escape; -use util::{process_error, CargoResult, CargoResultExt, read2}; +use crate::util::{process_error, read2, CargoResult, CargoResultExt}; /// A builder object for an external process, similar to `std::process::Command`. #[derive(Clone, Debug)] @@ -20,18 +20,35 @@ args: Vec, /// Any environment variables that should be set for the program. env: HashMap>, - /// Which directory to run the program from. + /// The directory to run the program from. cwd: Option, /// The `make` jobserver. See the [jobserver crate][jobserver_docs] for /// more information. /// /// [jobserver_docs]: https://docs.rs/jobserver/0.1.6/jobserver/ jobserver: Option, + /// `true` to include environment variable in display. + display_env_vars: bool, } impl fmt::Display for ProcessBuilder { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "`{}", self.program.to_string_lossy())?; + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "`")?; + + if self.display_env_vars { + for (key, val) in self.env.iter() { + if let Some(val) = val { + let val = escape(val.to_string_lossy()); + if cfg!(windows) { + write!(f, "set {}={}&& ", key, val)?; + } else { + write!(f, "{}={} ", key, val)?; + } + } + } + } + + write!(f, "{}", self.program.to_string_lossy())?; for arg in &self.args { write!(f, " {}", escape(arg.to_string_lossy()))?; @@ -42,69 +59,69 @@ } impl ProcessBuilder { - /// (chainable) Set the executable for the process. + /// (chainable) Sets the executable for the process. pub fn program>(&mut self, program: T) -> &mut ProcessBuilder { self.program = program.as_ref().to_os_string(); self } - /// (chainable) Add an arg to the args list. + /// (chainable) Adds `arg` to the args list. pub fn arg>(&mut self, arg: T) -> &mut ProcessBuilder { self.args.push(arg.as_ref().to_os_string()); self } - /// (chainable) Add many args to the args list. - pub fn args>(&mut self, arguments: &[T]) -> &mut ProcessBuilder { + /// (chainable) Adds multiple `args` to the args list. + pub fn args>(&mut self, args: &[T]) -> &mut ProcessBuilder { self.args - .extend(arguments.iter().map(|t| t.as_ref().to_os_string())); + .extend(args.iter().map(|t| t.as_ref().to_os_string())); self } - /// (chainable) Replace args with new args list - pub fn args_replace>(&mut self, arguments: &[T]) -> &mut ProcessBuilder { - self.args = arguments + /// (chainable) Replaces the args list with the given `args`. + pub fn args_replace>(&mut self, args: &[T]) -> &mut ProcessBuilder { + self.args = args .iter() .map(|t| t.as_ref().to_os_string()) .collect(); self } - /// (chainable) Set the current working directory of the process + /// (chainable) Sets the current working directory of the process. pub fn cwd>(&mut self, path: T) -> &mut ProcessBuilder { self.cwd = Some(path.as_ref().to_os_string()); self } - /// (chainable) Set an environment variable for the process. + /// (chainable) Sets an environment variable for the process. pub fn env>(&mut self, key: &str, val: T) -> &mut ProcessBuilder { self.env .insert(key.to_string(), Some(val.as_ref().to_os_string())); self } - /// (chainable) Unset an environment variable for the process. + /// (chainable) Unsets an environment variable for the process. pub fn env_remove(&mut self, key: &str) -> &mut ProcessBuilder { self.env.insert(key.to_string(), None); self } - /// Get the executable name. + /// Gets the executable name. pub fn get_program(&self) -> &OsString { &self.program } - /// Get the program arguments + /// Gets the program arguments. pub fn get_args(&self) -> &[OsString] { &self.args } - /// Get the current working directory for the process + /// Gets the current working directory for the process. pub fn get_cwd(&self) -> Option<&Path> { self.cwd.as_ref().map(Path::new) } - /// Get an environment variable as the process will see it (will inherit from environment + /// Gets an environment variable as the process will see it (will inherit from environment /// unless explicitally unset). pub fn get_env(&self, var: &str) -> Option { self.env @@ -114,13 +131,13 @@ .and_then(|s| s) } - /// Get all environment variables explicitly set or unset for the process (not inherited + /// Gets all environment variables explicitly set or unset for the process (not inherited /// vars). pub fn get_envs(&self) -> &HashMap> { &self.env } - /// Set the `make` jobserver. See the [jobserver crate][jobserver_docs] for + /// Sets the `make` jobserver. See the [jobserver crate][jobserver_docs] for /// more information. /// /// [jobserver_docs]: https://docs.rs/jobserver/0.1.6/jobserver/ @@ -129,15 +146,17 @@ self } - /// Run the process, waiting for completion, and mapping non-success exit codes to an error. + /// Enables environment variable display. + pub fn display_env_vars(&mut self) -> &mut Self { + self.display_env_vars = true; + self + } + + /// Runs the process, waiting for completion, and mapping non-success exit codes to an error. pub fn exec(&self) -> CargoResult<()> { let mut command = self.build_command(); let exit = command.status().chain_err(|| { - process_error( - &format!("could not execute process {}", self), - None, - None, - ) + process_error(&format!("could not execute process {}", self), None, None) })?; if exit.success() { @@ -147,22 +166,23 @@ &format!("process didn't exit successfully: {}", self), Some(exit), None, - ).into()) + ) + .into()) } } /// Replaces the current process with the target process. /// - /// On Unix, this executes the process using the unix syscall `execvp`, which will block + /// On Unix, this executes the process using the Unix syscall `execvp`, which will block /// this process, and will only return if there is an error. /// /// On Windows this isn't technically possible. Instead we emulate it to the best of our - /// ability. One aspect we fix here is that we specify a handler for the ctrl-c handler. - /// In doing so (and by effectively ignoring it) we should emulate proxying ctrl-c + /// ability. One aspect we fix here is that we specify a handler for the Ctrl-C handler. + /// In doing so (and by effectively ignoring it) we should emulate proxying Ctrl-C /// handling to the application at hand, which will either terminate or handle it itself. - /// According to microsoft's documentation at: - /// https://docs.microsoft.com/en-us/windows/console/ctrl-c-and-ctrl-break-signals - /// the ctrl-c signal is sent to all processes attached to a terminal, which should + /// According to Microsoft's documentation at + /// . + /// the Ctrl-C signal is sent to all processes attached to a terminal, which should /// include our child process. If the child terminates then we'll reap them in Cargo /// pretty quickly, and if the child handles the signal then we won't terminate /// (and we shouldn't!) until the process itself later exits. @@ -170,16 +190,12 @@ imp::exec_replace(self) } - /// Execute the process, returning the stdio output, or an error if non-zero exit status. + /// Executes the process, returning the stdio output, or an error if non-zero exit status. pub fn exec_with_output(&self) -> CargoResult { let mut command = self.build_command(); let output = command.output().chain_err(|| { - process_error( - &format!("could not execute process {}", self), - None, - None, - ) + process_error(&format!("could not execute process {}", self), None, None) })?; if output.status.success() { @@ -189,11 +205,12 @@ &format!("process didn't exit successfully: {}", self), Some(output.status), Some(&output), - ).into()) + ) + .into()) } } - /// Execute a command, passing each line of stdout and stderr to the supplied callbacks, which + /// Executes a command, passing each line of stdout and stderr to the supplied callbacks, which /// can mutate the string data. /// /// If any invocations of these function return an error, it will be propagated. @@ -201,8 +218,8 @@ /// Optionally, output can be passed to errors using `print_output` pub fn exec_with_streaming( &self, - on_stdout_line: &mut FnMut(&str) -> CargoResult<()>, - on_stderr_line: &mut FnMut(&str) -> CargoResult<()>, + on_stdout_line: &mut dyn FnMut(&str) -> CargoResult<()>, + on_stderr_line: &mut dyn FnMut(&str) -> CargoResult<()>, capture_output: bool, ) -> CargoResult { let mut stdout = Vec::new(); @@ -227,7 +244,8 @@ None => return, } }; - { // scope for new_lines + { + // scope for new_lines let new_lines = if capture_output { let dst = if is_out { &mut stdout } else { &mut stderr }; let start = dst.len(); @@ -257,13 +275,7 @@ })?; child.wait() })() - .chain_err(|| { - process_error( - &format!("could not execute process {}", self), - None, - None, - ) - })?; + .chain_err(|| process_error(&format!("could not execute process {}", self), None, None))?; let output = Output { stdout, stderr, @@ -292,7 +304,7 @@ Ok(output) } - /// Converts ProcessBuilder into a `std::process::Command`, and handles the jobserver if + /// Converts `ProcessBuilder` into a `std::process::Command`, and handles the jobserver, if /// present. pub fn build_command(&self) -> Command { let mut command = Command::new(&self.program); @@ -327,19 +339,20 @@ cwd: None, env: HashMap::new(), jobserver: None, + display_env_vars: false, } } #[cfg(unix)] mod imp { - use CargoResult; + use crate::util::{process_error, ProcessBuilder}; + use crate::CargoResult; use std::os::unix::process::CommandExt; - use util::{process_error, ProcessBuilder}; pub fn exec_replace(process_builder: &ProcessBuilder) -> CargoResult<()> { let mut command = process_builder.build_command(); let error = command.exec(); - Err(::util::CargoError::from(error) + Err(failure::Error::from(error) .context(process_error( &format!("could not execute process {}", process_builder), None, @@ -351,29 +364,24 @@ #[cfg(windows)] mod imp { - extern crate winapi; - - use CargoResult; - use util::{process_error, ProcessBuilder}; - use self::winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE}; - use self::winapi::um::consoleapi::SetConsoleCtrlHandler; + use crate::util::{process_error, ProcessBuilder}; + use crate::CargoResult; + use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE}; + use winapi::um::consoleapi::SetConsoleCtrlHandler; unsafe extern "system" fn ctrlc_handler(_: DWORD) -> BOOL { - // Do nothing. Let the child process handle it. + // Do nothing; let the child process handle it. TRUE } pub fn exec_replace(process_builder: &ProcessBuilder) -> CargoResult<()> { unsafe { if SetConsoleCtrlHandler(Some(ctrlc_handler), TRUE) == FALSE { - return Err(process_error( - "Could not set Ctrl-C handler.", - None, - None).into()); + return Err(process_error("Could not set Ctrl-C handler.", None, None).into()); } } - // Just exec the process as normal. + // Just execute the process as normal. process_builder.exec() } } diff -Nru cargo-0.33.0/src/cargo/util/profile.rs cargo-0.35.0/src/cargo/util/profile.rs --- cargo-0.33.0/src/cargo/util/profile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/profile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ +use std::cell::RefCell; use std::env; use std::fmt; +use std::io::{stdout, StdoutLock, Write}; +use std::iter::repeat; use std::mem; use std::time; -use std::iter::repeat; -use std::cell::RefCell; -use std::io::{stdout, StdoutLock, Write}; thread_local!(static PROFILE_STACK: RefCell> = RefCell::new(Vec::new())); thread_local!(static MESSAGES: RefCell> = RefCell::new(Vec::new())); @@ -46,8 +46,7 @@ (start, stack.len()) }); let duration = start.elapsed(); - let duration_ms = - duration.as_secs() * 1000 + u64::from(duration.subsec_millis()); + let duration_ms = duration.as_secs() * 1000 + u64::from(duration.subsec_millis()); let msg = ( stack_len, @@ -57,7 +56,7 @@ MESSAGES.with(|msgs| msgs.borrow_mut().push(msg)); if stack_len == 0 { - fn print(lvl: usize, msgs: &[Message], enabled: usize, stdout: &mut StdoutLock) { + fn print(lvl: usize, msgs: &[Message], enabled: usize, stdout: &mut StdoutLock<'_>) { if lvl > enabled { return; } @@ -72,7 +71,8 @@ repeat(" ").take(lvl + 1).collect::(), time, msg - ).expect("printing profiling info to stdout"); + ) + .expect("printing profiling info to stdout"); print(lvl + 1, &msgs[last..i], enabled, stdout); last = i; diff -Nru cargo-0.33.0/src/cargo/util/progress.rs cargo-0.35.0/src/cargo/util/progress.rs --- cargo-0.33.0/src/cargo/util/progress.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/progress.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,8 +2,8 @@ use std::env; use std::time::{Duration, Instant}; -use core::shell::Verbosity; -use util::{CargoResult, Config}; +use crate::core::shell::Verbosity; +use crate::util::{CargoResult, Config}; use unicode_width::UnicodeWidthChar; @@ -27,6 +27,7 @@ name: String, done: bool, throttle: Throttle, + last_line: Option, } struct Format { @@ -59,6 +60,7 @@ name: name.to_string(), done: false, throttle: Throttle::new(), + last_line: None, }), } } @@ -94,7 +96,7 @@ // draw to the console every so often. Currently there's a 100ms // delay between updates. if !s.throttle.allowed() { - return Ok(()) + return Ok(()); } s.tick(cur, max, "") @@ -140,12 +142,12 @@ if self.first { let delay = Duration::from_millis(500); if self.last_update.elapsed() < delay { - return false + return false; } } else { let interval = Duration::from_millis(100); if self.last_update.elapsed() < interval { - return false + return false; } } self.update(); @@ -183,22 +185,34 @@ // make sure we have enough room for the header if self.format.max_width < 15 { - return Ok(()) + return Ok(()); } - self.config.shell().status_header(&self.name)?; + let mut line = prefix.to_string(); self.format.render(&mut line, msg); - while line.len() < self.format.max_width - 15 { line.push(' '); } - write!(self.config.shell().err(), "{}\r", line)?; + // Only update if the line has changed. + if self.config.shell().is_cleared() || self.last_line.as_ref() != Some(&line) { + let mut shell = self.config.shell(); + shell.set_needs_clear(false); + shell.status_header(&self.name)?; + write!(shell.err(), "{}\r", line)?; + self.last_line = Some(line); + shell.set_needs_clear(true); + } + Ok(()) } fn clear(&mut self) { - self.config.shell().err_erase_line(); + // No need to clear if the progress is not currently being displayed. + if self.last_line.is_some() && !self.config.shell().is_cleared() { + self.config.shell().err_erase_line(); + self.last_line = None; + } } fn try_update_max_width(&mut self) { @@ -255,7 +269,7 @@ let mut avail_msg_len = self.max_width - string.len() - 15; let mut ellipsis_pos = 0; if avail_msg_len <= 3 { - return + return; } for c in msg.chars() { let display_width = c.width().unwrap_or(0); @@ -401,8 +415,5 @@ max_print: 24, max_width: 24, }; - assert_eq!( - format.progress_status(1, 1, ""), - None - ); + assert_eq!(format.progress_status(1, 1, ""), None); } diff -Nru cargo-0.33.0/src/cargo/util/read2.rs cargo-0.35.0/src/cargo/util/read2.rs --- cargo-0.33.0/src/cargo/util/read2.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/read2.rs 2019-04-01 21:32:07.000000000 +0000 @@ -12,7 +12,7 @@ pub fn read2( mut out_pipe: ChildStdout, mut err_pipe: ChildStderr, - data: &mut FnMut(bool, &mut Vec, bool), + data: &mut dyn FnMut(bool, &mut Vec, bool), ) -> io::Result<()> { unsafe { libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK); @@ -77,18 +77,15 @@ #[cfg(windows)] mod imp { - extern crate miow; - extern crate winapi; - use std::io; use std::os::windows::prelude::*; use std::process::{ChildStderr, ChildStdout}; use std::slice; - use self::miow::iocp::{CompletionPort, CompletionStatus}; - use self::miow::pipe::NamedPipe; - use self::miow::Overlapped; - use self::winapi::shared::winerror::ERROR_BROKEN_PIPE; + use miow::iocp::{CompletionPort, CompletionStatus}; + use miow::pipe::NamedPipe; + use miow::Overlapped; + use winapi::shared::winerror::ERROR_BROKEN_PIPE; struct Pipe<'a> { dst: &'a mut Vec, @@ -100,7 +97,7 @@ pub fn read2( out_pipe: ChildStdout, err_pipe: ChildStderr, - data: &mut FnMut(bool, &mut Vec, bool), + data: &mut dyn FnMut(bool, &mut Vec, bool), ) -> io::Result<()> { let mut out = Vec::new(); let mut err = Vec::new(); diff -Nru cargo-0.33.0/src/cargo/util/rustc.rs cargo-0.35.0/src/cargo/util/rustc.rs --- cargo-0.33.0/src/cargo/util/rustc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/rustc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,16 +1,17 @@ #![allow(deprecated)] // for SipHasher -use std::path::{Path, PathBuf}; -use std::hash::{Hash, Hasher, SipHasher}; use std::collections::hash_map::{Entry, HashMap}; -use std::sync::Mutex; -use std::process::Stdio; use std::env; +use std::hash::{Hash, Hasher, SipHasher}; +use std::path::{Path, PathBuf}; +use std::process::Stdio; +use std::sync::Mutex; -use serde_json; +use log::{debug, info, warn}; +use serde::{Deserialize, Serialize}; -use util::{self, internal, profile, CargoResult, ProcessBuilder}; -use util::paths; +use crate::util::paths; +use crate::util::{self, internal, profile, CargoResult, ProcessBuilder}; /// Information on the `rustc` executable #[derive(Debug)] @@ -28,7 +29,7 @@ } impl Rustc { - /// Run the compiler at `path` to learn various pieces of information about + /// Runs the compiler at `path` to learn various pieces of information about /// it, with an optional wrapper. /// /// If successful this function returns a description of the compiler along @@ -65,7 +66,7 @@ }) } - /// Get a process builder set up to use the found rustc version, with a wrapper if Some + /// Gets a process builder set up to use the found rustc version, with a wrapper if `Some`. pub fn process(&self) -> ProcessBuilder { match self.wrapper { Some(ref wrapper) if !wrapper.as_os_str().is_empty() => { @@ -73,7 +74,7 @@ cmd.arg(&self.path); cmd } - _ => self.process_no_wrapper() + _ => self.process_no_wrapper(), } } @@ -260,7 +261,7 @@ .with_extension(env::consts::EXE_EXTENSION); paths::mtime(&real_rustc)?.hash(&mut hasher); } - (true, _, _) => bail!("probably rustup rustc, but without rustup's env vars"), + (true, _, _) => failure::bail!("probably rustup rustc, but without rustup's env vars"), _ => (), } diff -Nru cargo-0.33.0/src/cargo/util/sha256.rs cargo-0.35.0/src/cargo/util/sha256.rs --- cargo-0.33.0/src/cargo/util/sha256.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/sha256.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -extern crate crypto_hash; use self::crypto_hash::{Algorithm, Hasher}; +use crypto_hash; use std::io::Write; pub struct Sha256(Hasher); diff -Nru cargo-0.33.0/src/cargo/util/toml/mod.rs cargo-0.35.0/src/cargo/util/toml/mod.rs --- cargo-0.33.0/src/cargo/util/toml/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/toml/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -5,23 +5,23 @@ use std::rc::Rc; use std::str; +use log::{debug, trace}; use semver::{self, VersionReq}; -use serde::de::{self, Deserialize}; +use serde::de; use serde::ser; -use serde_ignored; -use toml; +use serde::{Deserialize, Serialize}; use url::Url; -use core::dependency::{Kind, Platform}; -use core::manifest::{LibKind, ManifestMetadata, TargetSourcePath, Warnings}; -use core::profiles::Profiles; -use core::{Dependency, Manifest, PackageId, Summary, Target}; -use core::{Edition, EitherManifest, Feature, Features, VirtualManifest}; -use core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig}; -use sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY}; -use util::errors::{CargoError, CargoResult, CargoResultExt, ManifestError}; -use util::paths; -use util::{self, Config, ToUrl}; +use crate::core::dependency::{Kind, Platform}; +use crate::core::manifest::{LibKind, ManifestMetadata, TargetSourcePath, Warnings}; +use crate::core::profiles::Profiles; +use crate::core::{Dependency, Manifest, PackageId, Summary, Target}; +use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest}; +use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig}; +use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY}; +use crate::util::errors::{CargoResult, CargoResultExt, ManifestError}; +use crate::util::paths; +use crate::util::{self, validate_package_name, Config, ToUrl}; mod targets; use self::targets::targets; @@ -53,7 +53,7 @@ let toml = { let pretty_filename = - util::without_prefix(manifest_file, config.cwd()).unwrap_or(manifest_file); + manifest_file.strip_prefix(config.cwd()).unwrap_or(manifest_file); parse(contents, pretty_filename, config)? }; @@ -78,7 +78,7 @@ TomlManifest::to_real_manifest(&manifest, source_id, package_root, config)?; add_unused(manifest.warnings_mut()); if !manifest.targets().iter().any(|t| !t.is_custom_build()) { - bail!( + failure::bail!( "no targets specified in the manifest\n \ either src/lib.rs, src/main.rs, a [lib] section, or \ [[bin]] section must be present" @@ -92,7 +92,7 @@ Ok((EitherManifest::Virtual(m), paths)) }; - fn stringify(dst: &mut String, path: &serde_ignored::Path) { + fn stringify(dst: &mut String, path: &serde_ignored::Path<'_>) { use serde_ignored::Path; match *path { @@ -132,7 +132,7 @@ TOML file found which contains invalid syntax and will soon not parse at `{}`. -The TOML spec requires newlines after table definitions (e.g. `[a] b = 1` is +The TOML spec requires newlines after table definitions (e.g., `[a] b = 1` is invalid), but this file has a table header which does not have a newline after it. A newline needs to be added and this warning will soon become a hard error in the future.", @@ -142,7 +142,7 @@ return Ok(ret); } - let first_error = CargoError::from(first_error); + let first_error = failure::Error::from(first_error); Err(first_error.context("could not parse input as TOML").into()) } @@ -152,7 +152,7 @@ type TomlTestTarget = TomlTarget; type TomlBenchTarget = TomlTarget; -#[derive(Debug, Serialize)] +#[derive(Clone, Debug, Serialize)] #[serde(untagged)] pub enum TomlDependency { Simple(String), @@ -169,7 +169,7 @@ impl<'de> de::Visitor<'de> for TomlDependencyVisitor { type Value = TomlDependency; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str( "a version string like \"0.9.8\" or a \ detailed dependency like { version = \"0.9.8\" }", @@ -201,6 +201,12 @@ pub struct DetailedTomlDependency { version: Option, registry: Option, + /// The URL of the `registry` field. + /// This is an internal implementation detail. When Cargo creates a + /// package, it replaces `registry` with `registry-index` so that the + /// manifest contains the correct URL. All users won't have the same + /// registry names configured, so Cargo can't rely on just the name for + /// crates published by other users. registry_index: Option, path: Option, git: Option, @@ -285,7 +291,7 @@ impl<'de> de::Visitor<'de> for Visitor { type Value = TomlOptLevel; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("an optimization level") } @@ -345,7 +351,7 @@ impl<'de> de::Visitor<'de> for Visitor { type Value = U32OrBool; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a boolean or an integer") } @@ -447,7 +453,7 @@ "dev" | "release" => {} _ => { if self.overrides.is_some() || self.build_override.is_some() { - bail!( + failure::bail!( "Profile overrides may only be specified for \ `dev` or `release` profile, not `{}`.", name @@ -472,16 +478,16 @@ fn validate_override(&self) -> CargoResult<()> { if self.overrides.is_some() || self.build_override.is_some() { - bail!("Profile overrides cannot be nested."); + failure::bail!("Profile overrides cannot be nested."); } if self.panic.is_some() { - bail!("`panic` may not be specified in a profile override.") + failure::bail!("`panic` may not be specified in a profile override.") } if self.lto.is_some() { - bail!("`lto` may not be specified in a profile override.") + failure::bail!("`lto` may not be specified in a profile override.") } if self.rpath.is_some() { - bail!("`rpath` may not be specified in a profile override.") + failure::bail!("`rpath` may not be specified in a profile override.") } Ok(()) } @@ -500,7 +506,7 @@ impl<'de> de::Visitor<'de> for Visitor { type Value = StringOrVec; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("string or list of strings") } @@ -541,7 +547,7 @@ impl<'de> de::Visitor<'de> for Visitor { type Value = StringOrBool; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a boolean or a string") } @@ -581,7 +587,7 @@ impl<'de> de::Visitor<'de> for Visitor { type Value = VecStringOrBool; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("a boolean or vector of strings") } @@ -608,7 +614,7 @@ /// Represents the `package`/`project` sections of a `Cargo.toml`. /// /// Note that the order of the fields matters, since this is the order they -/// are serialized to a TOML file. For example, you cannot have values after +/// are serialized to a TOML file. For example, you cannot have values after /// the field `metadata`, since it is a table and values cannot appear after /// tables. #[derive(Deserialize, Serialize, Clone, Debug)] @@ -637,7 +643,7 @@ #[serde(rename = "default-run")] default_run: Option, - // package metadata + // Package metadata. description: Option, homepage: Option, documentation: Option, @@ -796,32 +802,20 @@ let mut warnings = vec![]; let mut errors = vec![]; - // Parse features first so they will be available when parsing other parts of the toml + // Parse features first so they will be available when parsing other parts of the TOML. let empty = Vec::new(); let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); let features = Features::new(&cargo_features, &mut warnings)?; let project = me.project.as_ref().or_else(|| me.package.as_ref()); - let project = project.ok_or_else(|| format_err!("no `package` section found"))?; + let project = project.ok_or_else(|| failure::format_err!("no `package` section found"))?; let package_name = project.name.trim(); if package_name.is_empty() { - bail!("package name cannot be an empty string") + failure::bail!("package name cannot be an empty string") } - for c in package_name.chars() { - if c.is_alphanumeric() { - continue; - } - if c == '_' || c == '-' { - continue; - } - bail!( - "Invalid character `{}` in package name: `{}`", - c, - package_name - ) - } + validate_package_name(package_name, "package name", "")?; let pkgid = project.to_package_id(source_id)?; @@ -840,9 +834,9 @@ features.require(Feature::metabuild())?; } - // If we have no lib at all, use the inferred lib if available - // If we have a lib with a path, we're done - // If we have a lib with no path, use the inferred lib or_else package name + // If we have no lib at all, use the inferred lib, if available. + // If we have a lib with a path, we're done. + // If we have a lib with no path, use the inferred lib or else the package name. let targets = targets( &features, me, @@ -885,7 +879,7 @@ }; fn process_dependencies( - cx: &mut Context, + cx: &mut Context<'_, '_>, new_deps: Option<&BTreeMap>, kind: Option, ) -> CargoResult<()> { @@ -901,7 +895,7 @@ Ok(()) } - // Collect the deps + // Collect the dependencies. process_dependencies(&mut cx, me.dependencies.as_ref(), None)?; let dev_deps = me .dev_dependencies @@ -939,7 +933,7 @@ let name = dep.name_in_toml(); let prev = names_sources.insert(name.to_string(), dep.source_id()); if prev.is_some() && prev != Some(dep.source_id()) { - bail!( + failure::bail!( "Dependency '{}' has different source paths depending on the build \ target. Each dependency must have a single canonical source path \ irrespective of build target.", @@ -994,21 +988,14 @@ (None, root) => WorkspaceConfig::Member { root: root.cloned(), }, - (Some(..), Some(..)) => bail!( + (Some(..), Some(..)) => failure::bail!( "cannot configure both `package.workspace` and \ `[workspace]`, only one can be specified" ), }; let profiles = Profiles::new(me.profile.as_ref(), config, &features, &mut warnings)?; let publish = match project.publish { - Some(VecStringOrBool::VecString(ref vecstring)) => { - features - .require(Feature::alternative_registries()) - .chain_err(|| { - "the `publish` manifest key is unstable for anything other than a value of true or false" - })?; - Some(vecstring.clone()) - } + Some(VecStringOrBool::VecString(ref vecstring)) => Some(vecstring.clone()), Some(VecStringOrBool::Bool(false)) => Some(vec![]), None | Some(VecStringOrBool::Bool(true)) => None, }; @@ -1021,6 +1008,14 @@ None => false, }; + if summary.features().contains_key("default-features") { + warnings.push( + "`default-features = [\"..\"]` was found in [features]. \ + Did you mean to use `default = [\"..\"]`?" + .to_string(), + ) + } + let custom_metadata = project.metadata.clone(); let mut manifest = Manifest::new( summary, @@ -1069,43 +1064,43 @@ config: &Config, ) -> CargoResult<(VirtualManifest, Vec)> { if me.project.is_some() { - bail!("virtual manifests do not define [project]"); + failure::bail!("virtual manifests do not define [project]"); } if me.package.is_some() { - bail!("virtual manifests do not define [package]"); + failure::bail!("virtual manifests do not define [package]"); } if me.lib.is_some() { - bail!("virtual manifests do not specify [lib]"); + failure::bail!("virtual manifests do not specify [lib]"); } if me.bin.is_some() { - bail!("virtual manifests do not specify [[bin]]"); + failure::bail!("virtual manifests do not specify [[bin]]"); } if me.example.is_some() { - bail!("virtual manifests do not specify [[example]]"); + failure::bail!("virtual manifests do not specify [[example]]"); } if me.test.is_some() { - bail!("virtual manifests do not specify [[test]]"); + failure::bail!("virtual manifests do not specify [[test]]"); } if me.bench.is_some() { - bail!("virtual manifests do not specify [[bench]]"); + failure::bail!("virtual manifests do not specify [[bench]]"); } if me.dependencies.is_some() { - bail!("virtual manifests do not specify [dependencies]"); + failure::bail!("virtual manifests do not specify [dependencies]"); } if me.dev_dependencies.is_some() || me.dev_dependencies2.is_some() { - bail!("virtual manifests do not specify [dev-dependencies]"); + failure::bail!("virtual manifests do not specify [dev-dependencies]"); } if me.build_dependencies.is_some() || me.build_dependencies2.is_some() { - bail!("virtual manifests do not specify [build-dependencies]"); + failure::bail!("virtual manifests do not specify [build-dependencies]"); } if me.features.is_some() { - bail!("virtual manifests do not specify [features]"); + failure::bail!("virtual manifests do not specify [features]"); } if me.target.is_some() { - bail!("virtual manifests do not specify [target]"); + failure::bail!("virtual manifests do not specify [target]"); } if me.badges.is_some() { - bail!("virtual manifests do not specify [badges]"); + failure::bail!("virtual manifests do not specify [badges]"); } let mut nested_paths = Vec::new(); @@ -1138,18 +1133,18 @@ &config.exclude, )), None => { - bail!("virtual manifests must be configured with [workspace]"); + failure::bail!("virtual manifests must be configured with [workspace]"); } }; Ok(( - VirtualManifest::new(replace, patch, workspace_config, profiles), + VirtualManifest::new(replace, patch, workspace_config, profiles, features), nested_paths, )) } - fn replace(&self, cx: &mut Context) -> CargoResult> { + fn replace(&self, cx: &mut Context<'_, '_>) -> CargoResult> { if self.patch.is_some() && self.replace.is_some() { - bail!("cannot specify both [replace] and [patch]"); + failure::bail!("cannot specify both [replace] and [patch]"); } let mut replace = Vec::new(); for (spec, replacement) in self.replace.iter().flat_map(|x| x) { @@ -1169,7 +1164,7 @@ TomlDependency::Simple(..) => true, }; if version_specified { - bail!( + failure::bail!( "replacements cannot specify a version \ requirement, but found one for `{}`", spec @@ -1179,7 +1174,7 @@ let mut dep = replacement.to_dependency(spec.name(), cx, None)?; { let version = spec.version().ok_or_else(|| { - format_err!( + failure::format_err!( "replacements must specify a version \ to replace, but `{}` does not", spec @@ -1192,12 +1187,18 @@ Ok(replace) } - fn patch(&self, cx: &mut Context) -> CargoResult>> { + fn patch(&self, cx: &mut Context<'_, '_>) -> CargoResult>> { let mut patch = HashMap::new(); for (url, deps) in self.patch.iter().flat_map(|x| x) { let url = match &url[..] { CRATES_IO_REGISTRY => CRATES_IO_INDEX.parse().unwrap(), - _ => url.to_url()?, + _ => cx + .config + .get_registry_index(url) + .or_else(|_| url.to_url()) + .chain_err(|| { + format!("[patch] entry `{}` should be a URL or registry name", url) + })?, }; patch.insert( url, @@ -1216,13 +1217,14 @@ ) -> Option { let build_rs = package_root.join("build.rs"); match *build { - Some(StringOrBool::Bool(false)) => None, // explicitly no build script + // Explicitly no build script. + Some(StringOrBool::Bool(false)) => None, Some(StringOrBool::Bool(true)) => Some(build_rs), Some(StringOrBool::String(ref s)) => Some(PathBuf::from(s)), None => { match fs::metadata(&build_rs) { - // If there is a build.rs file next to the Cargo.toml, assume it is - // a build script + // If there is a `build.rs` file next to the `Cargo.toml`, assume it is + // a build script. Ok(ref e) if e.is_file() => Some(build_rs), Ok(_) | Err(_) => None, } @@ -1235,7 +1237,7 @@ } } -/// Will check a list of build targets, and make sure the target names are unique within a vector. +/// Checks a list of build targets, and ensures the target names are unique within a vector. /// If not, the name of the offending build target is returned. fn unique_build_targets(targets: &[Target], package_root: &Path) -> Result<(), String> { let mut seen = HashSet::new(); @@ -1254,7 +1256,7 @@ fn to_dependency( &self, name: &str, - cx: &mut Context, + cx: &mut Context<'_, '_>, kind: Option, ) -> CargoResult { match *self { @@ -1272,7 +1274,7 @@ fn to_dependency( &self, name_in_toml: &str, - cx: &mut Context, + cx: &mut Context<'_, '_>, kind: Option, ) -> CargoResult { if self.version.is_none() && self.path.is_none() && self.git.is_none() { @@ -1305,26 +1307,18 @@ } } - let registry_id = match self.registry { - Some(ref registry) => { - cx.features.require(Feature::alternative_registries())?; - SourceId::alt_registry(cx.config, registry)? - } - None => SourceId::crates_io(cx.config)?, - }; - let new_source_id = match ( self.git.as_ref(), self.path.as_ref(), self.registry.as_ref(), self.registry_index.as_ref(), ) { - (Some(_), _, Some(_), _) | (Some(_), _, _, Some(_)) => bail!( + (Some(_), _, Some(_), _) | (Some(_), _, _, Some(_)) => failure::bail!( "dependency ({}) specification is ambiguous. \ Only one of `git` or `registry` is allowed.", name_in_toml ), - (_, _, Some(_), Some(_)) => bail!( + (_, _, Some(_), Some(_)) => failure::bail!( "dependency ({}) specification is ambiguous. \ Only one of `registry` or `registry-index` is allowed.", name_in_toml @@ -1367,11 +1361,11 @@ } (None, Some(path), _, _) => { cx.nested_paths.push(PathBuf::from(path)); - // If the source id for the package we're parsing is a path + // If the source ID for the package we're parsing is a path // source, then we normalize the path here to get rid of // components like `..`. // - // The purpose of this is to get a canonical id for the package + // The purpose of this is to get a canonical ID for the package // that we're depending on to ensure that builds of this package // always end up hashing to the same value no matter where it's // built from. @@ -1408,8 +1402,17 @@ .unwrap_or(true), ) .set_optional(self.optional.unwrap_or(false)) - .set_platform(cx.platform.clone()) - .set_registry_id(registry_id); + .set_platform(cx.platform.clone()); + if let Some(registry) = &self.registry { + let registry_id = SourceId::alt_registry(cx.config, registry)?; + dep.set_registry_id(registry_id); + } + if let Some(registry_index) = &self.registry_index { + let url = registry_index.to_url()?; + let registry_id = SourceId::for_registry(&url)?; + dep.set_registry_id(registry_id); + } + if let Some(kind) = kind { dep.set_kind(kind); } @@ -1514,7 +1517,7 @@ } impl fmt::Debug for PathValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } diff -Nru cargo-0.33.0/src/cargo/util/toml/targets.rs cargo-0.35.0/src/cargo/util/toml/targets.rs --- cargo-0.33.0/src/cargo/util/toml/targets.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/toml/targets.rs 2019-04-01 21:32:07.000000000 +0000 @@ -18,8 +18,8 @@ LibKind, PathValue, StringOrBool, StringOrVec, TomlBenchTarget, TomlBinTarget, TomlExampleTarget, TomlLibTarget, TomlManifest, TomlTarget, TomlTestTarget, }; -use core::{compiler, Edition, Feature, Features, Target}; -use util::errors::{CargoResult, CargoResultExt}; +use crate::core::{compiler, Edition, Feature, Features, Target}; +use crate::util::errors::{CargoResult, CargoResultExt}; pub fn targets( features: &Features, @@ -54,7 +54,7 @@ .package .as_ref() .or_else(|| manifest.project.as_ref()) - .ok_or_else(|| format_err!("manifest has no `package` (or `project`)"))?; + .ok_or_else(|| failure::format_err!("manifest has no `package` (or `project`)"))?; targets.extend(clean_bins( features, @@ -101,7 +101,7 @@ // processing the custom build script if let Some(custom_build) = manifest.maybe_custom_build(custom_build, package_root) { if metabuild.is_some() { - bail!("cannot specify both `metabuild` and `build`"); + failure::bail!("cannot specify both `metabuild` and `build`"); } let name = format!( "build-script-{}", @@ -121,7 +121,7 @@ let bdeps = manifest.build_dependencies.as_ref(); for name in &metabuild.0 { if !bdeps.map_or(false, |bd| bd.contains_key(name)) { - bail!( + failure::bail!( "metabuild package `{}` must be specified in `build-dependencies`", name ); @@ -151,7 +151,7 @@ if let Some(ref name) = lib.name { // XXX: other code paths dodge this validation if name.contains('-') { - bail!("library target names cannot contain hyphens: {}", name) + failure::bail!("library target names cannot contain hyphens: {}", name) } } Some(TomlTarget { @@ -178,7 +178,7 @@ (None, Some(path)) => path, (None, None) => { let legacy_path = package_root.join("src").join(format!("{}.rs", lib.name())); - if edition < Edition::Edition2018 && legacy_path.exists() { + if edition == Edition::Edition2015 && legacy_path.exists() { warnings.push(format!( "path `{}` was erroneously implicitly accepted for library `{}`,\n\ please rename the file to `src/lib.rs` or set lib.path in Cargo.toml", @@ -187,7 +187,7 @@ )); legacy_path } else { - bail!( + failure::bail!( "can't find library `{}`, \ rename file to `src/lib.rs` or specify lib.path", lib.name() @@ -198,7 +198,7 @@ // Per the Macros 1.1 RFC: // - // > Initially if a crate is compiled with the proc-macro crate type + // > Initially if a crate is compiled with the `proc-macro` crate type // > (and possibly others) it will forbid exporting any items in the // > crate other than those functions tagged #[proc_macro_derive] and // > those functions must also be placed at the crate root. @@ -219,11 +219,13 @@ lib.name() )); if kinds.len() > 1 { - bail!("cannot mix `proc-macro` crate type with others"); + failure::bail!("cannot mix `proc-macro` crate type with others"); } vec![LibKind::ProcMacro] } - (_, Some(true), Some(true)) => bail!("lib.plugin and lib.proc-macro cannot both be true"), + (_, Some(true), Some(true)) => { + failure::bail!("`lib.plugin` and `lib.proc-macro` cannot both be `true`") + } (Some(kinds), _, _) => kinds.iter().map(|s| s.into()).collect(), (None, Some(true), _) => vec![LibKind::Dylib], (None, _, Some(true)) => vec![LibKind::ProcMacro], @@ -285,7 +287,7 @@ } if compiler::is_bad_artifact_name(&name) { - bail!("the binary target name `{}` is forbidden", name) + failure::bail!("the binary target name `{}` is forbidden", name) } } @@ -308,7 +310,7 @@ }); let path = match path { Ok(path) => path, - Err(e) => bail!("{}", e), + Err(e) => failure::bail!("{}", e), }; let mut target = @@ -510,7 +512,7 @@ autodiscover: Option, warnings: &mut Vec, errors: &mut Vec, - legacy_path: &mut FnMut(&TomlTarget) -> Option, + legacy_path: &mut dyn FnMut(&TomlTarget) -> Option, autodiscover_flag_name: &str, ) -> CargoResult> { let toml_targets = toml_targets_and_inferred( @@ -659,9 +661,8 @@ let autodiscover = match autodiscover { Some(autodiscover) => autodiscover, - None => match edition { - Edition::Edition2018 => true, - Edition::Edition2015 => { + None => { + if edition == Edition::Edition2015 { if !rem_targets.is_empty() { let mut rem_targets_str = String::new(); for t in rem_targets.iter() { @@ -692,8 +693,10 @@ )); }; false + } else { + true } - }, + } }; if autodiscover { @@ -724,10 +727,10 @@ match target.name { Some(ref name) => { if name.trim().is_empty() { - bail!("{} target names cannot be empty", target_kind_human) + failure::bail!("{} target names cannot be empty", target_kind_human) } } - None => bail!( + None => failure::bail!( "{} target {}.name is required", target_kind_human, target_kind @@ -742,7 +745,7 @@ let mut seen = HashSet::new(); for name in targets.iter().map(|e| e.name()) { if !seen.insert(name.clone()) { - bail!( + failure::bail!( "found duplicate {target_kind} name {name}, \ but all {target_kind} targets must have a unique name", target_kind = target_kind, @@ -761,6 +764,7 @@ .set_doctest(toml.doctest.unwrap_or_else(|| t2.doctested())) .set_benched(toml.bench.unwrap_or_else(|| t2.benched())) .set_harness(toml.harness.unwrap_or_else(|| t2.harness())) + .set_proc_macro(toml.proc_macro.unwrap_or_else(|| t2.proc_macro())) .set_for_host(match (toml.plugin, toml.proc_macro()) { (None, None) => t2.for_host(), (Some(true), _) | (_, Some(true)) => true, @@ -785,7 +789,7 @@ target_kind: &str, package_root: &Path, edition: Edition, - legacy_path: &mut FnMut(&TomlTarget) -> Option, + legacy_path: &mut dyn FnMut(&TomlTarget) -> Option, ) -> Result { if let Some(ref path) = target.path { // Should we verify that this path exists here? @@ -803,7 +807,7 @@ match (first, second) { (Some(path), None) => Ok(path), (None, None) | (Some(_), Some(_)) => { - if edition < Edition::Edition2018 { + if edition == Edition::Edition2015 { if let Some(path) = legacy_path(target) { return Ok(path); } diff -Nru cargo-0.33.0/src/cargo/util/to_semver.rs cargo-0.35.0/src/cargo/util/to_semver.rs --- cargo-0.33.0/src/cargo/util/to_semver.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/to_semver.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ +use crate::util::errors::CargoResult; use semver::Version; -use util::errors::CargoResult; pub trait ToSemver { fn to_semver(self) -> CargoResult; @@ -15,7 +15,7 @@ fn to_semver(self) -> CargoResult { match Version::parse(self) { Ok(v) => Ok(v), - Err(..) => Err(format_err!("cannot parse '{}' as a semver", self)), + Err(..) => Err(failure::format_err!("cannot parse '{}' as a semver", self)), } } } diff -Nru cargo-0.33.0/src/cargo/util/to_url.rs cargo-0.35.0/src/cargo/util/to_url.rs --- cargo-0.33.0/src/cargo/util/to_url.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/to_url.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,7 +2,7 @@ use url::Url; -use util::CargoResult; +use crate::util::CargoResult; /// A type that can be converted to a Url pub trait ToUrl { @@ -12,12 +12,13 @@ impl<'a> ToUrl for &'a str { fn to_url(self) -> CargoResult { - Url::parse(self).map_err(|s| format_err!("invalid url `{}`: {}", self, s)) + Url::parse(self).map_err(|s| failure::format_err!("invalid url `{}`: {}", self, s)) } } impl<'a> ToUrl for &'a Path { fn to_url(self) -> CargoResult { - Url::from_file_path(self).map_err(|()| format_err!("invalid path url `{}`", self.display())) + Url::from_file_path(self) + .map_err(|()| failure::format_err!("invalid path url `{}`", self.display())) } } diff -Nru cargo-0.33.0/src/cargo/util/vcs.rs cargo-0.35.0/src/cargo/util/vcs.rs --- cargo-0.33.0/src/cargo/util/vcs.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/vcs.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ -use std::path::Path; use std::fs::create_dir; +use std::path::Path; use git2; -use util::{process, CargoResult}; +use crate::util::{process, CargoResult}; // Check if we are in an existing repo. We define that to be true if either: // @@ -13,8 +13,12 @@ pub fn existing_vcs_repo(path: &Path, cwd: &Path) -> bool { fn in_git_repo(path: &Path, cwd: &Path) -> bool { if let Ok(repo) = GitRepo::discover(path, cwd) { - repo.is_path_ignored(path).map(|ignored| !ignored).unwrap_or(true) - } else { false } + repo.is_path_ignored(path) + .map(|ignored| !ignored) + .unwrap_or(true) + } else { + false + } } in_git_repo(path, cwd) || HgRepo::discover(path, cwd).is_ok() @@ -69,7 +73,11 @@ db_path.push(db_fname); // then create the fossil DB in that location - process("fossil").cwd(cwd).arg("init").arg(&db_path).exec()?; + process("fossil") + .cwd(cwd) + .arg("init") + .arg(&db_path) + .exec()?; // open it in that new directory process("fossil") diff -Nru cargo-0.33.0/src/cargo/util/workspace.rs cargo-0.35.0/src/cargo/util/workspace.rs --- cargo-0.33.0/src/cargo/util/workspace.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/cargo/util/workspace.rs 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,75 @@ +use crate::core::{Target, Workspace}; +use crate::ops::CompileOptions; +use crate::util::CargoResult; + +use std::fmt::Write; + +fn get_available_targets<'a>( + filter_fn: fn(&Target) -> bool, + ws: &'a Workspace<'_>, + options: &'a CompileOptions<'_>, +) -> CargoResult> { + let packages = options.spec.get_packages(ws)?; + + let mut targets: Vec<_> = packages + .into_iter() + .flat_map(|pkg| { + pkg.manifest() + .targets() + .iter() + .filter(|target| filter_fn(target)) + }) + .collect(); + + targets.sort(); + + Ok(targets) +} + +fn print_available( + filter_fn: fn(&Target) -> bool, + ws: &Workspace<'_>, + options: &CompileOptions<'_>, + option_name: &str, + plural_name: &str, +) -> CargoResult<()> { + let targets = get_available_targets(filter_fn, ws, options)?; + + let mut output = String::new(); + writeln!(output, "\"{}\" takes one argument.", option_name)?; + + if targets.is_empty() { + writeln!(output, "No {} available.", plural_name)?; + } else { + writeln!(output, "Available {}:", plural_name)?; + for target in targets { + writeln!(output, " {}", target.name())?; + } + } + Err(failure::err_msg(output))? +} + +pub fn print_available_examples( + ws: &Workspace<'_>, + options: &CompileOptions<'_>, +) -> CargoResult<()> { + print_available(Target::is_example, ws, options, "--example", "examples") +} + +pub fn print_available_binaries( + ws: &Workspace<'_>, + options: &CompileOptions<'_>, +) -> CargoResult<()> { + print_available(Target::is_bin, ws, options, "--bin", "binaries") +} + +pub fn print_available_benches( + ws: &Workspace<'_>, + options: &CompileOptions<'_>, +) -> CargoResult<()> { + print_available(Target::is_bench, ws, options, "--bench", "benches") +} + +pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions<'_>) -> CargoResult<()> { + print_available(Target::is_test, ws, options, "--test", "tests") +} diff -Nru cargo-0.33.0/src/crates-io/Cargo.toml cargo-0.35.0/src/crates-io/Cargo.toml --- cargo-0.33.0/src/crates-io/Cargo.toml 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/crates-io/Cargo.toml 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,7 @@ [package] name = "crates-io" -version = "0.21.0" +version = "0.23.0" +edition = "2018" authors = ["Alex Crichton "] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/cargo" @@ -15,7 +16,8 @@ [dependencies] curl = "0.4" failure = "0.1.1" -serde = "1.0" +http = "0.1" +serde = { version = "1.0", features = ['derive'] } serde_derive = "1.0" serde_json = "1.0" url = "1.0" diff -Nru cargo-0.33.0/src/crates-io/lib.rs cargo-0.35.0/src/crates-io/lib.rs --- cargo-0.33.0/src/crates-io/lib.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/crates-io/lib.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,13 +1,5 @@ #![allow(unknown_lints)] -#![cfg_attr(feature = "cargo-clippy", allow(identity_op))] // used for vertical alignment - -extern crate curl; -#[macro_use] -extern crate failure; -#[macro_use] -extern crate serde_derive; -extern crate serde_json; -extern crate url; +#![allow(clippy::identity_op)] // used for vertical alignment use std::collections::BTreeMap; use std::fs::File; @@ -15,13 +7,21 @@ use std::io::Cursor; use curl::easy::{Easy, List}; +use failure::bail; +use http::status::StatusCode; +use serde::{Deserialize, Serialize}; +use serde_json; use url::percent_encoding::{percent_encode, QUERY_ENCODE_SET}; pub type Result = std::result::Result; pub struct Registry { + /// The base URL for issuing API requests. host: String, + /// Optional authorization token. + /// If None, commands requiring authorization will fail. token: Option, + /// Curl handle for issuing requests. handle: Easy, } @@ -56,7 +56,8 @@ pub license_file: Option, pub repository: Option, pub badges: BTreeMap>, - #[serde(default)] pub links: Option, + #[serde(default)] + pub links: Option, } #[derive(Serialize)] @@ -136,6 +137,10 @@ } } + pub fn host(&self) -> &str { + &self.host + } + pub fn add_owners(&mut self, krate: &str, owners: &[&str]) -> Result { let body = serde_json::to_string(&OwnersReq { users: owners })?; let body = self.put(&format!("/crates/{}/owners", krate), body.as_bytes())?; @@ -302,7 +307,7 @@ } } -fn handle(handle: &mut Easy, read: &mut FnMut(&mut [u8]) -> usize) -> Result { +fn handle(handle: &mut Easy, read: &mut dyn FnMut(&mut [u8]) -> usize) -> Result { let mut headers = Vec::new(); let mut body = Vec::new(); { @@ -319,30 +324,31 @@ handle.perform()?; } - match handle.response_code()? { - 0 => {} // file upload url sometimes - 200 => {} - 403 => bail!("received 403 unauthorized response code"), - 404 => bail!("received 404 not found response code"), - code => bail!( + let body = match String::from_utf8(body) { + Ok(body) => body, + Err(..) => bail!("response body was not valid utf-8"), + }; + let errors = serde_json::from_str::(&body).ok().map(|s| { + s.errors.into_iter().map(|s| s.detail).collect::>() + }); + + match (handle.response_code()?, errors) { + (0, None) | (200, None) => {}, + (code, Some(errors)) => { + let code = StatusCode::from_u16(code as _)?; + bail!("api errors (status {}): {}", code, errors.join(", ")) + } + (code, None) => bail!( "failed to get a 200 OK response, got {}\n\ headers:\n\ \t{}\n\ body:\n\ {}", - code, - headers.join("\n\t"), - String::from_utf8_lossy(&body) + code, + headers.join("\n\t"), + body, ), } - let body = match String::from_utf8(body) { - Ok(body) => body, - Err(..) => bail!("response body was not valid utf-8"), - }; - if let Ok(errors) = serde_json::from_str::(&body) { - let errors = errors.errors.into_iter().map(|s| s.detail); - bail!("api errors: {}", errors.collect::>().join(", ")); - } Ok(body) } diff -Nru cargo-0.33.0/src/doc/asciidoc-extension.rb cargo-0.35.0/src/doc/asciidoc-extension.rb --- cargo-0.33.0/src/doc/asciidoc-extension.rb 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/asciidoc-extension.rb 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,109 @@ +require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' + +include Asciidoctor + +# An inline macro that generates links to related man pages. +# +# Usage +# +# man:gittutorial[7] +# +class ManInlineMacro < Extensions::InlineMacroProcessor + use_dsl + + named :man + name_positional_attributes 'volnum' + + def process parent, target, attrs + manname = target + suffix = if (volnum = attrs['volnum']) + "(#{volnum})" + else + nil + end + text = %(#{manname}#{suffix}) + if parent.document.basebackend? 'html' + parent.document.register :links, target + if manname == 'rustc' + html_target = 'https://doc.rust-lang.org/rustc/index.html' + elsif manname == 'rustdoc' + html_target = 'https://doc.rust-lang.org/rustdoc/index.html' + elsif manname == 'cargo' + html_target = 'commands/index.html' + else + html_target = %(commands/#{manname}.html) + end + %(#{(create_anchor parent, text, type: :link, target: html_target).render}) + elsif parent.document.backend == 'manpage' + %(\x1b\\fB#{manname}\x1b\\fP#{suffix}) + else + text + end + end +end + +# Creates a link to something in the cargo documentation. +# +# For HTML this creates a relative link (using mdbook's 0.1's base-style +# links). For the man page it gives a direct link to doc.rust-lang.org. +# +# Usage +# +# linkcargo:reference/manifest.html[the manifest] +# +class LinkCargoInlineMacro < Extensions::InlineMacroProcessor + use_dsl + + named :linkcargo + name_positional_attributes 'text' + + def process parent, target, attrs + text = attrs['text'] + if parent.document.basebackend? 'html' + parent.document.register :links, target + %(#{(create_anchor parent, text, type: :link, target: target).render}) + elsif parent.document.backend == 'manpage' + target = %(https://doc.rust-lang.org/cargo/#{target}) + %(#{(create_anchor parent, text, type: :link, target: target).render}) + else + %(#{text} <#{target}>) + end + end +end + +# Backticks in the manpage renderer use the CR font (courier), but in most +# cases in a terminal this doesn't look any different. Instead, use bold which +# should follow man page conventions better. +class MonoPostprocessor < Extensions::Postprocessor + def process document, output + if document.basebackend? 'manpage' + output = output.gsub(/\\f\(CR/, '\\fB') + end + output + end +end + +# General utility for converting text. Example: +# +# convert:lowercase[{somevar}] +class ConvertInlineMacro < Extensions::InlineMacroProcessor + use_dsl + + named :convert + name_positional_attributes 'text' + + def process parent, target, attrs + text = attrs['text'] + case target + when 'lowercase' + text.downcase + end + end +end + +Extensions.register :uri_schemes do + inline_macro ManInlineMacro + inline_macro LinkCargoInlineMacro + inline_macro ConvertInlineMacro + postprocessor MonoPostprocessor +end diff -Nru cargo-0.33.0/src/doc/Makefile cargo-0.35.0/src/doc/Makefile --- cargo-0.33.0/src/doc/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/Makefile 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,28 @@ +# This Makefile is used to build the Cargo man pages. +# +# The source for the man pages are located in src/doc/man in Asciidoctor +# format. See https://asciidoctor.org/ for more information. +# +# Just run `make` and it will generate the man pages in src/etc/man and the +# HTML pages in src/doc/man/generated. +# +# There are some Asciidoctor extensions, see the file `asciidoc-extensions.rb` +# for the documentation. + +MAN_SOURCE = $(sort $(wildcard man/cargo*.adoc)) +COMMANDS = $(notdir $(MAN_SOURCE)) +HTML = $(patsubst %.adoc,man/generated/%.html,$(COMMANDS)) +MAN_LOCATION = ../etc/man +MAN = $(patsubst %.adoc,$(MAN_LOCATION)/%.1,$(COMMANDS)) +ASCIIDOCOPTS = -r ./asciidoc-extension.rb +OTHER_DEPS = asciidoc-extension.rb $(filter-out $(MAN_SOURCE),$(sort $(wildcard man/*.adoc))) + +all: commands-html man +commands-html: $(HTML) +man: $(MAN) + +$(HTML): man/generated/%.html : man/%.adoc asciidoc-extension.rb $(OTHER_DEPS) + asciidoctor $(ASCIIDOCOPTS) -s $< -o $@ + +$(MAN): $(MAN_LOCATION)/%.1 : man/%.adoc $(OTHER_DEPS) + asciidoctor $(ASCIIDOCOPTS) -b manpage $< -o $@ diff -Nru cargo-0.33.0/src/doc/man/cargo.adoc cargo-0.35.0/src/doc/man/cargo.adoc --- cargo-0.33.0/src/doc/man/cargo.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,217 @@ += cargo(1) +:doctype: manpage + +== NAME + +cargo - The Rust package manager + +== SYNOPSIS + +[%hardbreaks] +`cargo [_OPTIONS_] _COMMAND_ [_ARGS_]` +`cargo [_OPTIONS_] --version` +`cargo [_OPTIONS_] --list` +`cargo [_OPTIONS_] --help` +`cargo [_OPTIONS_] --explain _CODE_` + +== DESCRIPTION + +This program is a package manager and build tool for the Rust language, +available at . + +== COMMANDS + +=== Build Commands + +man:cargo-bench[1]:: + Execute benchmarks of a package. + +man:cargo-build[1]:: + Compile a package. + +man:cargo-check[1]:: + Check a local package and all of its dependencies for errors. + +man:cargo-clean[1]:: + Remove artifacts that Cargo has generated in the past. + +man:cargo-doc[1]:: + Build a package's documentation. + +man:cargo-fetch[1]:: + Fetch dependencies of a package from the network. + +man:cargo-fix[1]:: + Automatically fix lint warnings reported by rustc. + +man:cargo-run[1]:: + Run a binary or example of the local package. + +man:cargo-rustc[1]:: + Compile a package, and pass extra options to the compiler. + +man:cargo-rustdoc[1]:: + Build a package's documentation, using specified custom flags. + +man:cargo-test[1]:: + Execute unit and integration tests of a package. + +=== Manifest Commands + +man:cargo-generate-lockfile[1]:: + Generate `Cargo.lock` for a project. + +man:cargo-locate-project[1]:: + Print a JSON representation of a `Cargo.toml` file's location. + +man:cargo-metadata[1]:: + Output the resolved dependencies of a package, the concrete used versions + including overrides, in machine-readable format. + +man:cargo-pkgid[1]:: + Print a fully qualified package specification. + +man:cargo-update[1]:: + Update dependencies as recorded in the local lock file. + +man:cargo-verify-project[1]:: + Check correctness of crate manifest. + +=== Package Commands + +man:cargo-init[1]:: + Create a new Cargo package in an existing directory. + +man:cargo-install[1]:: + Build and install a Rust binary. + +man:cargo-new[1]:: + Create a new Cargo package. + +man:cargo-search[1]:: + Search packages in crates.io. + +man:cargo-uninstall[1]:: + Remove a Rust binary. + +=== Publishing Commands + +man:cargo-login[1]:: + Save an API token from the registry locally. + +man:cargo-owner[1]:: + Manage the owners of a crate on the registry. + +man:cargo-package[1]:: + Assemble the local package into a distributable tarball. + +man:cargo-publish[1]:: + Upload a package to the registry. + +man:cargo-yank[1]:: + Remove a pushed crate from the index. + +=== General Commands + +man:cargo-help[1]:: + Display help information about Cargo. + +man:cargo-version[1]:: + Show version information. + +== OPTIONS + +=== Special Options + +*-V*:: +*--version*:: + Print version info and exit. If used with `--verbose`, prints extra + information. + +*--list*:: + List all installed Cargo subcommands. If used with `--verbose`, prints + extra information. + +*--explain _CODE_*:: + Run `rustc --explain CODE` which will print out a detailed explanation of + an error message (for example, `E0004`). + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== FILES + +`~/.cargo/`:: + Default location for Cargo's "home" directory where it stores various + files. The location can be changed with the `CARGO_HOME` environment + variable. + +`$CARGO_HOME/bin/`:: + Binaries installed by man:cargo-install[1] will be located here. If using + rustup, executables distributed with Rust are also located here. + +`$CARGO_HOME/config`:: + The global configuration file. See linkcargo:reference/config.html[the reference] + for more information about configuration files. + +`.cargo/config`:: + Cargo automatically searches for a file named `.cargo/config` in the + current directory, and all parent directories. These configuration files + will be merged with the global configuration file. + +`$CARGO_HOME/credentials`:: + Private authentication information for logging in to a registry. + +`$CARGO_HOME/registry/`:: + This directory contains cached downloads of the registry index and any + downloaded dependencies. + +`$CARGO_HOME/git/`:: + This directory contains cached downloads of git dependencies. + +== EXAMPLES + +. Build a local package and all of its dependencies: + + cargo build + +. Build a package with optimizations: + + cargo build --release + +. Run tests for a cross-compiled target: + + cargo test --target i686-unknown-linux-gnu + +. Create a new package that builds an executable: + + cargo new foobar + +. Create a package in the current directory: + + mkdir foo && cd foo + cargo init . + +. Learn about a command's options and usage: + + cargo help clean + +== BUGS + +See https://github.com/rust-lang/cargo/issues for issues. + +== SEE ALSO +man:rustc[1], man:rustdoc[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-bench.adoc cargo-0.35.0/src/doc/man/cargo-bench.adoc --- cargo-0.33.0/src/doc/man/cargo-bench.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-bench.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,142 @@ += cargo-bench(1) +:idprefix: cargo_bench_ +:doctype: manpage +:actionverb: Benchmark +:nouns: benchmarks + +== NAME + +cargo-bench - Execute benchmarks of a package + +== SYNOPSIS + +`cargo bench [_OPTIONS_] [BENCHNAME] [-- _BENCH-OPTIONS_]` + +== DESCRIPTION + +Compile and execute benchmarks. + +The benchmark filtering argument `BENCHNAME` and all the arguments following +the two dashes (`--`) are passed to the benchmark binaries and thus to +_libtest_ (rustc's built in unit-test and micro-benchmarking framework). If +you're passing arguments to both Cargo and the binary, the ones after `--` go +to the binary, the ones before go to Cargo. For details about libtest's +arguments see the output of `cargo bench -- --help`. As an example, this will +run only the benchmark named `foo` (and skip other similarly named benchmarks +like `foobar`): + + cargo bench -- foo --exact + +Benchmarks are built with the `--test` option to `rustc` which creates an +executable with a `main` function that automatically runs all functions +annotated with the `#[bench]` attribute. Cargo passes the `--bench` flag to +the test harness to tell it to run only benchmarks. + +The libtest harness may be disabled by setting `harness = false` in the target +manifest settings, in which case your code will need to provide its own `main` +function to handle running benchmarks. + +== OPTIONS + +=== Benchmark Options + +include::options-test.adoc[] + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo bench` will build the +following targets of the selected packages: + +- lib — used to link with binaries and benchmarks +- bins (only if benchmark targets are built and required features are + available) +- lib as a benchmark +- bins as benchmarks +- benchmark targets + +The default behavior can be changed by setting the `bench` flag for the target +in the manifest settings. Setting examples to `bench = true` will build and +run the example as a benchmark. Setting targets to `bench = false` will stop +them from being benchmarked by default. Target selection options that take a +target by name ignore the `bench` flag and will always benchmark the given +target. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +By default the Rust test harness hides output from benchmark execution to keep +results readable. Benchmark output can be recovered (e.g., for debugging) by +passing `--nocapture` to the benchmark binaries: + + cargo bench -- --nocapture + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +The `--jobs` argument affects the building of the benchmark executable but +does not affect how many threads are used when running the benchmarks. The +Rust test harness runs benchmarks serially in a single thread. + +include::options-jobs.adoc[] + +== PROFILES + +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +linkcargo:reference/manifest.html#the-profile-sections[the reference] +for more details. + +Benchmarks are always built with the `bench` profile. Binary and lib targets +are built separately as benchmarks with the `bench` profile. Library targets +are built with the `release` profiles when linked to binaries and benchmarks. +Dependencies use the `release` profile. + +If you need a debug build of a benchmark, try building it with +man:cargo-build[1] which will use the `test` profile which is by default +unoptimized and includes debug information. You can then run the debug-enabled +benchmark manually. + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Build and execute all the benchmarks of the current package: + + cargo bench + +. Run only a specific benchmark within a specific benchmark target: + + cargo bench --bench bench_name -- modname::some_benchmark + +== SEE ALSO +man:cargo[1], man:cargo-test[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-build.adoc cargo-0.35.0/src/doc/man/cargo-build.adoc --- cargo-0.33.0/src/doc/man/cargo-build.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-build.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,94 @@ += cargo-build(1) +:idprefix: cargo_build_ +:doctype: manpage +:actionverb: Build + +== NAME + +cargo-build - Compile the current package + +== SYNOPSIS + +`cargo build [_OPTIONS_]` + +== DESCRIPTION + +Compile local packages and all of their dependencies. + +== OPTIONS + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo build` will build all +binary and library targets of the selected packages. Binaries are skipped if +they have `required-features` that are missing. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +*--out-dir* _DIRECTORY_:: + Copy final artifacts to this directory. ++ +This option is unstable and available only on the nightly channel and requires +the `-Z unstable-options` flag to enable. + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +*--build-plan*:: + Outputs a series of JSON messages to stdout that indicate the commands to + run the build. ++ +This option is unstable and available only on the nightly channel and requires +the `-Z unstable-options` flag to enable. + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Build the local package and all of its dependencies: + + cargo build + +. Build with optimizations: + + cargo build --release + +== SEE ALSO +man:cargo[1], man:cargo-rustc[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-check.adoc cargo-0.35.0/src/doc/man/cargo-check.adoc --- cargo-0.33.0/src/doc/man/cargo-check.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-check.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,87 @@ += cargo-check(1) +:idprefix: cargo_check_ +:doctype: manpage +:actionverb: Check + +== NAME + +cargo-check - Check the current package + +== SYNOPSIS + +`cargo check [_OPTIONS_]` + +== DESCRIPTION + +Check a local package and all of its dependencies for errors. This will +essentially compile the packages without performing the final step of code +generation, which is faster than running `cargo build`. The compiler will save +metadata files to disk so that future runs will reuse them if the source has +not been modified. + +== OPTIONS + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo check` will check all +binary and library targets of the selected packages. Binaries are skipped if +they have `required-features` that are missing. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +include::options-profile.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Check the local package for errors: + + cargo check + +. Check all targets, including unit tests: + + cargo check --all-targets --profile=test + +== SEE ALSO +man:cargo[1], man:cargo-build[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-clean.adoc cargo-0.35.0/src/doc/man/cargo-clean.adoc --- cargo-0.33.0/src/doc/man/cargo-clean.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-clean.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,76 @@ += cargo-clean(1) +:idprefix: cargo_clean_ +:doctype: manpage +:actionverb: Clean + +== NAME + +cargo-clean - Remove generated artifacts + +== SYNOPSIS + +`cargo clean [_OPTIONS_]` + +== DESCRIPTION + +Remove artifacts from the target directory that Cargo has generated in the +past. + +With no options, `cargo clean` will delete the entire target directory. + +== OPTIONS + +=== Package Selection + +When no packages are selected, all packages and all dependencies in the +workspace are cleaned. + +*-p* _SPEC_...:: +*--package* _SPEC_...:: + Clean only the specified packages. This flag may be specified + multiple times. See man:cargo-pkgid[1] for the SPEC format. + +=== Clean Options + +*--doc*:: + This option will cause `cargo clean` to remove only the `doc` directory in + the target directory. + +*--release*:: + Clean all artifacts that were built with the `release` or `bench` + profiles. + +include::options-target-dir.adoc[] + +include::options-target-triple.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Remove the entire target directory: + + cargo clean + +. Remove only the release artifacts: + + cargo clean --release + +== SEE ALSO +man:cargo[1], man:cargo-build[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-doc.adoc cargo-0.35.0/src/doc/man/cargo-doc.adoc --- cargo-0.33.0/src/doc/man/cargo-doc.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-doc.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,95 @@ += cargo-doc(1) +:idprefix: cargo_doc_ +:doctype: manpage +:actionverb: Document + +== NAME + +cargo-doc - Build a package's documentation + +== SYNOPSIS + +`cargo doc [_OPTIONS_]` + +== DESCRIPTION + +Build the documentation for the local package and all dependencies. The output +is placed in `target/doc` in rustdoc's usual format. + +== OPTIONS + +=== Documentation Options + +*--open*:: + Open the docs in a browser after building them. + +*--no-deps*:: + Do not build documentation for dependencies. + +*--document-private-items*:: + Include non-public items in the documentation. + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo doc` will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +`required-features` that are missing. + +The default behavior can be changed by setting `doc = false` for the target in +the manifest settings. Using target selection options will ignore the `doc` +flag and will always document the given target. + +include::options-targets-lib-bin.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Build the local package documentation and its dependencies and output to +`target/doc`. + + cargo doc + +== SEE ALSO +man:cargo[1], man:cargo-rustdoc[1], man:rustdoc[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-fetch.adoc cargo-0.35.0/src/doc/man/cargo-fetch.adoc --- cargo-0.33.0/src/doc/man/cargo-fetch.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-fetch.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,57 @@ += cargo-fetch(1) +:idprefix: cargo_fetch_ +:doctype: manpage +:actionverb: Fetch + +== NAME + +cargo-fetch - Fetch dependencies of a package from the network + +== SYNOPSIS + +`cargo fetch [_OPTIONS_]` + +== DESCRIPTION + +If a `Cargo.lock` file is available, this command will ensure that all of the +git dependencies and/or registry dependencies are downloaded and locally +available. Subsequent Cargo commands never touch the network after a `cargo +fetch` unless the lock file changes. + +If the lock file is not available, then this command will generate the lock +file before fetching the dependencies. + +If `--target` is not specified, then all target dependencies are fetched. + +== OPTIONS + +=== Fetch options + +include::options-target-triple.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Fetch all dependencies: + + cargo fetch + +== SEE ALSO +man:cargo[1], man:cargo-update[1], man:cargo-generate-lockfile[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-fix.adoc cargo-0.35.0/src/doc/man/cargo-fix.adoc --- cargo-0.33.0/src/doc/man/cargo-fix.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-fix.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,138 @@ += cargo-fix(1) +:idprefix: cargo_fix_ +:doctype: manpage +:actionverb: Fix + +== NAME + +cargo-fix - Automatically fix lint warnings reported by rustc + +== SYNOPSIS + +`cargo fix [_OPTIONS_]` + +== DESCRIPTION + +This Cargo subcommand will automatically take rustc's suggestions from +diagnostics like warnings and apply them to your source code. This is intended +to help automate tasks that rustc itself already knows how to tell you to fix! +The `cargo fix` subcommand is also being developed for the Rust 2018 edition +to provide code the ability to easily opt-in to the new edition without having +to worry about any breakage. + +Executing `cargo fix` will under the hood execute man:cargo-check[1]. Any warnings +applicable to your crate will be automatically fixed (if possible) and all +remaining warnings will be displayed when the check process is finished. For +example if you'd like to prepare for the 2018 edition, you can do so by +executing: + + cargo fix --edition + +which behaves the same as `cargo check --all-targets`. Similarly if you'd like +to fix code for different platforms you can do: + + cargo fix --edition --target x86_64-pc-windows-gnu + +or if your crate has optional features: + + cargo fix --edition --no-default-features --features foo + +If you encounter any problems with `cargo fix` or otherwise have any questions +or feature requests please don't hesitate to file an issue at +https://github.com/rust-lang/cargo + +== OPTIONS + +=== Fix options + +*--broken-code*:: + Fix code even if it already has compiler errors. This is useful if `cargo + fix` fails to apply the changes. It will apply the changes and leave the + broken code in the working directory for you to inspect and manually fix. + +*--edition*:: + Apply changes that will update the code to the latest edition. This will + not update the edition in the `Cargo.toml` manifest, which must be updated + manually. + +*--edition-idioms*:: + Apply suggestions that will update code to the preferred style for the + current edition. + +*--allow-no-vcs*:: + Fix code even if a VCS was not detected. + +*--allow-dirty*:: + Fix code even if the working directory has changes. + +*--allow-staged*:: + Fix code even if the working directory has staged changes. + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo fix` will fix all targets +(`--all-targets` implied). Binaries are skipped if they have +`required-features` that are missing. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +include::options-profile.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Apply compiler suggestions to the local package: + + cargo fix + +. Convert a 2015 edition to 2018: + + cargo fix --edition + +. Apply suggested idioms for the current edition: + + cargo fix --edition-idioms + +== SEE ALSO +man:cargo[1], man:cargo-check[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-generate-lockfile.adoc cargo-0.35.0/src/doc/man/cargo-generate-lockfile.adoc --- cargo-0.33.0/src/doc/man/cargo-generate-lockfile.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-generate-lockfile.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,49 @@ += cargo-generate-lockfile(1) +:idprefix: cargo_generate-lockfile_ +:doctype: manpage + +== NAME + +cargo-generate-lockfile - Generate the lockfile for a package + +== SYNOPSIS + +`cargo generate-lockfile [_OPTIONS_]` + +== DESCRIPTION + +This command will create the `Cargo.lock` lockfile for the current package or +workspace. If the lockfile already exists, it will be rebuilt if there are any +manifest changes or dependency updates. + +See also man:cargo-update[1] which is also capable of creating a `Cargo.lock` +lockfile and has more options for controlling update behavior. + +== OPTIONS + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Create or update the lockfile for the current package or workspace: + + cargo generate-lockfile + +== SEE ALSO +man:cargo[1], man:cargo-update[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-help.adoc cargo-0.35.0/src/doc/man/cargo-help.adoc --- cargo-0.33.0/src/doc/man/cargo-help.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-help.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,28 @@ += cargo-help(1) +:idprefix: cargo_help_ +:doctype: manpage + +== NAME + +cargo-help - Get help for a Cargo command + +== SYNOPSIS + +`cargo help [_SUBCOMMAND_]` + +== DESCRIPTION + +Prints a help message for the given command. + +== EXAMPLES + +. Get help for a command: + + cargo help build + +. Help is also available with the `--help` flag: + + cargo build --help + +== SEE ALSO +man:cargo[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-init.adoc cargo-0.35.0/src/doc/man/cargo-init.adoc --- cargo-0.33.0/src/doc/man/cargo-init.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-init.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,55 @@ += cargo-init(1) +:idprefix: cargo_init_ +:doctype: manpage + +== NAME + +cargo-init - Create a new Cargo package in an existing directory + +== SYNOPSIS + +`cargo init [_OPTIONS_] [_PATH_]` + +== DESCRIPTION + +This command will create a new Cargo manifest in the current directory. Give a +path as an argument to create in the given directory. + +If there are typically-named Rust source files already in the directory, those +will be used. If not, then a sample `src/main.rs` file will be created, or +`src/lib.rs` if `--lib` is passed. + +If the directory is not already in a VCS repository, then a new repository +is created (see `--vcs` below). + +include::description-new-authors.adoc[] + +See man:cargo-new[1] for a similar command which will create a new package in +a new directory. + +== OPTIONS + +=== Init Options + +include::options-new.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Create a binary Cargo package in the current directory: + + cargo init + +== SEE ALSO +man:cargo[1], man:cargo-new[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-install.adoc cargo-0.35.0/src/doc/man/cargo-install.adoc --- cargo-0.33.0/src/doc/man/cargo-install.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-install.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,130 @@ += cargo-install(1) +:idprefix: cargo_install_ +:doctype: manpage +:actionverb: Install + +== NAME + +cargo-install - Build and install a Rust binary + +== SYNOPSIS + +[%hardbreaks] +`cargo install [_OPTIONS_] _CRATE_...` +`cargo install [_OPTIONS_] --path _PATH_` +`cargo install [_OPTIONS_] --git _URL_ [_CRATE_...]` +`cargo install [_OPTIONS_] --list` + +== DESCRIPTION + +This command manages Cargo's local set of installed binary crates. Only packages +which have `\[[bin]]` targets can be installed, and all binaries are installed into +the installation root's `bin` folder. + +include::description-install-root.adoc[] + +There are multiple sources from which a crate can be installed. The default +location is crates.io but the `--git` and `--path` flags can change this +source. If the source contains more than one package (such as crates.io or a +git repository with multiple crates) the _CRATE_ argument is required to +indicate which crate should be installed. + +Crates from crates.io can optionally specify the version they wish to install +via the `--version` flags, and similarly packages from git repositories can +optionally specify the branch, tag, or revision that should be installed. If a +crate has multiple binaries, the `--bin` argument can selectively install only +one of them, and if you'd rather install examples the `--example` argument can +be used as well. + +If the source is crates.io or `--git` then by default the crate will be built +in a temporary target directory. To avoid this, the target directory can be +specified by setting the `CARGO_TARGET_DIR` environment variable to a relative +path. In particular, this can be useful for caching build artifacts on +continuous integration systems. + +== OPTIONS + +=== Install Options + +*--vers* _VERSION_:: +*--version* _VERSION_:: + Specify a version to install from crates.io. + +*--git* _URL_:: + Git URL to install the specified crate from. + +*--branch* _BRANCH_:: + Branch to use when installing from git. + +*--tag* _TAG_:: + Tag to use when installing from git. + +*--rev* _SHA_:: + Specific commit to use when installing from git. + +*--path* _PATH_:: + Filesystem path to local crate to install. + +*--list*:: + List all installed packages and their versions. + +*-f*:: +*--force*:: + Force overwriting existing crates or binaries. This can be used to + reinstall or upgrade a crate. + + +*--bin* _NAME_...:: + Install only the specified binary. + +*--bins*:: + Install all binaries. + +*--example* _NAME_...:: + Install only the specified example. + +*--examples*:: + Install all examples. + +*--root* _DIR_:: + Directory to install packages into. + +include::options-registry.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +*--debug*:: + Build with the `dev` profile instead the `release` profile. + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Install a package from crates.io: + + cargo install ripgrep + +. Reinstall or upgrade a package: + + cargo install ripgrep --force + +== SEE ALSO +man:cargo[1], man:cargo-uninstall[1], man:cargo-search[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-locate-project.adoc cargo-0.35.0/src/doc/man/cargo-locate-project.adoc --- cargo-0.33.0/src/doc/man/cargo-locate-project.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-locate-project.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,46 @@ += cargo-locate-project(1) +:idprefix: cargo_locate-project_ +:doctype: manpage + +== NAME + +cargo-locate-project - Print a JSON representation of a Cargo.toml file's location + +== SYNOPSIS + +`cargo locate-project [_OPTIONS_]` + +== DESCRIPTION + +This command will print a JSON object to stdout with the full path to the +`Cargo.toml` manifest. + +See also man:cargo-metadata[1] which is capable of returning the path to a +workspace root. + +== OPTIONS + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Display the path to the manifest based on the current directory: + + cargo locate-project + +== SEE ALSO +man:cargo[1], man:cargo-metadata[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-login.adoc cargo-0.35.0/src/doc/man/cargo-login.adoc --- cargo-0.33.0/src/doc/man/cargo-login.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-login.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,51 @@ += cargo-login(1) +:idprefix: cargo_login_ +:doctype: manpage + +== NAME + +cargo-login - Save an API token from the registry locally + +== SYNOPSIS + +`cargo login [_OPTIONS_] [_TOKEN_]` + +== DESCRIPTION + +This command will save the API token to disk so that commands that require +authentication, such as man:cargo-publish[1], will be automatically +authenticated. The token is saved in `$CARGO_HOME/credentials`. `CARGO_HOME` +defaults to `.cargo` in your home directory. + +If the _TOKEN_ argument is not specified, it will be read from stdin. + +The API token for crates.io may be retrieved from https://crates.io/me. + +Take care to keep the token secret, it should not be shared with anyone else. + +== OPTIONS + +=== Login Options + +include::options-registry.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Save the API token to disk: + + cargo login + +== SEE ALSO +man:cargo[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-metadata.adoc cargo-0.35.0/src/doc/man/cargo-metadata.adoc --- cargo-0.33.0/src/doc/man/cargo-metadata.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-metadata.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,286 @@ += cargo-metadata(1) +:idprefix: cargo_metadata_ +:doctype: manpage +:source-highlighter: highlightjs + +== NAME + +cargo-metadata - Machine-readable metadata about the current package + +== SYNOPSIS + +`cargo metadata [_OPTIONS_]` + +== DESCRIPTION + +Output the resolved dependencies of a package, the concrete used versions +including overrides, in JSON to stdout. + +It is recommended to include the `--format-version` flag to future-proof +your code to ensure the output is in the format you are expecting. + +See the link:https://crates.io/crates/cargo_metadata[cargo_metadata crate] +for a Rust API for reading the metadata. + +== OUTPUT FORMAT + +The output has the following format: + +[source,javascript] +---- +{ + /* Array of all packages in the workspace. + It also includes all feature-enabled dependencies unless --no-deps is used. + */ + "packages": [ + { + /* The name of the package. */ + "name": "my-package", + /* The version of the package. */ + "version": "0.1.0", + /* The Package ID, a unique identifier for referring to the package. */ + "id": "my-package 0.1.0 (path+file:///path/to/my-package)", + /* The license value from the manifest, or null. */ + "license": "MIT/Apache-2.0", + /* The license-file value from the manifest, or null. */ + "license_file": "LICENSE", + /* The description value from the manifest, or null. */ + "description": "Package description.", + /* The source ID of the package. This represents where + a package is retrieved from. + This is null for path dependencies and workspace members. + For other dependencies, it is a string with the format: + - "registry+URL" for registry-based dependencies. + Example: "registry+https://github.com/rust-lang/crates.io-index" + - "git+URL" for git-based dependencies. + Example: "git+https://github.com/rust-lang/cargo?rev=5e85ba14aaa20f8133863373404cb0af69eeef2c#5e85ba14aaa20f8133863373404cb0af69eeef2c" + */ + "source": null, + /* Array of dependencies declared in the package's manifest. */ + "dependencies": [ + { + /* The name of the dependency. */ + "name": "bitflags", + /* The source ID of the dependency. May be null, see + description for the package source. + */ + "source": "registry+https://github.com/rust-lang/crates.io-index", + /* The version requirement for the dependency. + Dependencies without a version requirement have a value of "*". + */ + "req": "^1.0", + /* The dependency kind. + "dev", "build", or null for a normal dependency. + */ + "kind": null, + /* If the dependency is renamed, this is the new name for + the dependency as a string. null if it is not renamed. + */ + "rename": null, + /* Boolean of whether or not this is an optional dependency. */ + "optional": false, + /* Boolean of whether or not default features are enabled. */ + "uses_default_features": true, + /* Array of features enabled. */ + "features": [], + /* The target platform for the dependency. + null if not a target dependency. + */ + "target": "cfg(windows)", + /* A string of the URL of the registry this dependency is from. + If not specified or null, the dependency is from the default + registry (crates.io). + */ + "registry": null + } + ], + /* Array of Cargo targets. */ + "targets": [ + { + /* Array of target kinds. + - lib targets list the `crate-type` values from the + manifest such as "lib", "rlib", "dylib", + "proc-macro", etc. (default ["lib"]) + - binary is ["bin"] + - example is ["example"] + - integration test is ["test"] + - benchmark is ["bench"] + - build script is ["custom-build"] + */ + "kind": [ + "bin" + ], + /* Array of crate types. + - lib and example libraries list the `crate-type` values + from the manifest such as "lib", "rlib", "dylib", + "proc-macro", etc. (default ["lib"]) + - all other target kinds are ["bin"] + */ + "crate_types": [ + "bin" + ], + /* The name of the target. */ + "name": "my-package", + /* Absolute path to the root source file of the target. */ + "src_path": "/path/to/my-package/src/main.rs", + /* The Rust edition of the target. + Defaults to the package edition. + */ + "edition": "2018", + /* Array of required features. + This property is not included if no required features are set. + */ + "required-features": ["feat1"] + } + ], + /* Set of features defined for the package. + Each feature maps to an array of features or dependencies it + enables. + */ + "features": { + "default": [ + "feat1" + ], + "feat1": [], + "feat2": [] + }, + /* Absolute path to this package's manifest. */ + "manifest_path": "/path/to/my-package/Cargo.toml", + /* Package metadata. + This is null if no metadata is specified. + */ + "metadata": { + "docs": { + "rs": { + "all-features": true + } + } + }, + /* Array of authors from the manifest. + Empty array if no authors specified. + */ + "authors": [ + "Jane Doe " + ], + /* Array of categories from the manifest. */ + "categories": [ + "command-line-utilities" + ], + /* Array of keywords from the manifest. */ + "keywords": [ + "cli" + ], + /* The readme value from the manifest or null if not specified. */ + "readme": "README.md", + /* The repository value from the manifest or null if not specified. */ + "repository": "https://github.com/rust-lang/cargo", + /* The default edition of the package. + Note that individual targets may have different editions. + */ + "edition": "2018", + /* Optional string that is the name of a native library the package + is linking to. + */ + "links": null, + } + ], + /* Array of members of the workspace. + Each entry is the Package ID for the package. + */ + "workspace_members": [ + "my-package 0.1.0 (path+file:///path/to/my-package)", + ], + /* The resolved dependency graph, with the concrete versions and features + selected. The set depends on the enabled features. + This is null if --no-deps is specified. + */ + "resolve": { + /* Array of nodes within the dependency graph. + Each node is a package. + */ + "nodes": [ + { + /* The Package ID of this node. */ + "id": "my-package 0.1.0 (path+file:///path/to/my-package)", + /* The dependencies of this package, an array of Package IDs. */ + "dependencies": [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" + ], + /* The dependencies of this package. This is an alternative to + "dependencies" which contains additional information. In + particular, this handles renamed dependencies. + */ + "deps": [ + { + /* The name of the dependency. + If this is a renamed dependency, this is the new + name. + */ + "name": "bitflags", + /* The Package ID of the dependency. */ + "pkg": "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" + } + ], + /* Array of features enabled on this package. */ + "features": [ + "default" + ] + } + ], + /* The root package of the workspace. + This is null if this is a virtual workspace. Otherwise it is + the Package ID of the root package. + */ + "root": "my-package 0.1.0 (path+file:///path/to/my-package)" + }, + /* The absolute path to the build directory where Cargo places its output. */ + "target_directory": "/path/to/my-package/target", + /* The version of the schema for this metadata structure. + This will be changed if incompatible changes are ever made. + */ + "version": 1, + /* The absolute path to the root of the workspace. */ + "workspace_root": "/path/to/my-package" +} +---- + +== OPTIONS + +=== Output Options + +*--no-deps*:: + Output information only about the workspace members and don't fetch + dependencies. + +*--format-version* _VERSION_:: + Specify the version of the output format to use. Currently `1` is the only + possible value. + +include::options-features.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Output JSON about the current package: + + cargo metadata --format-version=1 + +== SEE ALSO +man:cargo[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-new.adoc cargo-0.35.0/src/doc/man/cargo-new.adoc --- cargo-0.33.0/src/doc/man/cargo-new.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-new.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,50 @@ += cargo-new(1) +:idprefix: cargo_new_ +:doctype: manpage + +== NAME + +cargo-new - Create a new Cargo package + +== SYNOPSIS + +`cargo new [_OPTIONS_] _PATH_` + +== DESCRIPTION + +This command will create a new Cargo package in the given directory. This +includes a simple template with a `Cargo.toml` manifest, sample source file, +and a VCS ignore file. If the directory is not already in a VCS repository, +then a new repository is created (see `--vcs` below). + +include::description-new-authors.adoc[] + +See man:cargo-init[1] for a similar command which will create a new manifest +in an existing directory. + +== OPTIONS + +=== New Options + +include::options-new.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Create a binary Cargo package in the given directory: + + cargo new foo + +== SEE ALSO +man:cargo[1], man:cargo-init[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-owner.adoc cargo-0.35.0/src/doc/man/cargo-owner.adoc --- cargo-0.33.0/src/doc/man/cargo-owner.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-owner.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,80 @@ += cargo-owner(1) +:idprefix: cargo_owner_ +:doctype: manpage + +== NAME + +cargo-owner - Manage the owners of a crate on the registry + +== SYNOPSIS + +[%hardbreaks] +`cargo owner [_OPTIONS_] --add _LOGIN_ [_CRATE_]` +`cargo owner [_OPTIONS_] --remove _LOGIN_ [_CRATE_]` +`cargo owner [_OPTIONS_] --list [_CRATE_]` + +== DESCRIPTION + +This command will modify the owners for a crate on the registry. Owners of a +crate can upload new versions and yank old versions. Non-team owners can also +modify the set of owners, so take care! + +This command requires you to be authenticated with either the `--token` option +or using man:cargo-login[1]. + +If the crate name is not specified, it will use the package name from the +current directory. + +See linkcargo:reference/publishing.html#cargo-owner[the reference] for more +information about owners and publishing. + +== OPTIONS + +=== Owner Options + +*-a*:: +*--add* _LOGIN_...:: + Invite the given user or team as an owner. + +*-r*:: +*--remove* _LOGIN_...:: + Remove the given user or team as an owner. + +*-l*:: +*--list*:: + List owners of a crate. + +include::options-token.adoc[] + +include::options-index.adoc[] + +include::options-registry.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. List owners of a package: + + cargo owner --list foo + +. Invite an owner to a package: + + cargo owner --add username foo + +. Remove an owner from a package: + + cargo owner --remove username foo + +== SEE ALSO +man:cargo[1], man:cargo-login[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-package.adoc cargo-0.35.0/src/doc/man/cargo-package.adoc --- cargo-0.33.0/src/doc/man/cargo-package.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-package.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,95 @@ += cargo-package(1) +:idprefix: cargo_package_ +:doctype: manpage +:actionverb: Package + +== NAME + +cargo-package - Assemble the local package into a distributable tarball + +== SYNOPSIS + +`cargo package [_OPTIONS_]` + +== DESCRIPTION + +This command will create a distributable, compressed `.crate` file with the +source code of the package in the current directory. The resulting file will +be stored in the `target/package` directory. This performs the following +steps: + +. Load and check the current workspace, performing some basic checks. + - Path dependencies are not allowed unless they have a version key. Cargo + will ignore the path key for dependencies in published packages. +. Create the compressed `.crate` file. + - The original `Cargo.toml` file is rewritten and normalized. + - `[patch]`, `[replace]`, and `[workspace]` sections are removed from the + manifest. + - A `.cargo_vcs_info.json` file is included that contains information + about the current VCS checkout hash if available (not included with + `--allow-dirty`). +. Extract the `.crate` file and build it to verify it can build. +. Check that build scripts did not modify any source files. + +The list of files included can be controlled with the `include` and `exclude` +fields in the manifest. + +See linkcargo:reference/publishing.html[the reference] for more details about +packaging and publishing. + +== OPTIONS + +=== Package Options + +*-l*:: +*--list*:: + Print files included in a package without making one. + +*--no-verify*:: + Don't verify the contents by building them. + +*--no-metadata*:: + Ignore warnings about a lack of human-usable metadata (such as the + description or the license). + +*--allow-dirty*:: + Allow working directories with uncommitted VCS changes to be packaged. + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-target-dir.adoc[] + +include::options-features.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Create a compressed `.crate` file of the current package: + + cargo package + +== SEE ALSO +man:cargo[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-pkgid.adoc cargo-0.35.0/src/doc/man/cargo-pkgid.adoc --- cargo-0.33.0/src/doc/man/cargo-pkgid.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-pkgid.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,94 @@ += cargo-pkgid(1) +:idprefix: cargo_pkgid_ +:doctype: manpage + +== NAME + +cargo-pkgid - Print a fully qualified package specification + +== SYNOPSIS + +`cargo pkgid [_OPTIONS_] [_SPEC_]` + +== DESCRIPTION + +Given a _SPEC_ argument, print out the fully qualified package ID specifier +for a package or dependency in the current workspace. This command will +generate an error if _SPEC_ is ambiguous as to which package it refers to in +the dependency graph. If no _SPEC_ is given, then the specifier for the local +package is printed. + +This command requires that a lockfile is available and dependencies have been +fetched. + +A package specifier consists of a name, version, and source URL. You are +allowed to use partial specifiers to succinctly match a specific package as +long as it matches only one package. The format of a _SPEC_ can be one of the +following: + +[%autowidth] +.SPEC Query Format +|=== +|SPEC Structure |Example SPEC + +|__NAME__ +|`bitflags` + +|__NAME__``:``__VERSION__ +|`bitflags:1.0.4` + +|__URL__ +|`https://github.com/rust-lang/cargo` + +|__URL__``#``__VERSION__ +|`https://github.com/rust-lang/cargo#0.33.0` + +|__URL__``#``__NAME__ +|`https://github.com/rust-lang/crates.io-index#bitflags` + +|__URL__``#``__NAME__``:``__VERSION__ +|`https://github.com/rust-lang/cargo#crates-io:0.21.0` +|=== + +== OPTIONS + +=== Package Selection + +*-p* _SPEC_:: +*--package* _SPEC_:: + Get the package ID for the given package instead of the current package. + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Retrieve package specification for `foo` package: + + cargo pkgid foo + +. Retrieve package specification for version 1.0.0 of `foo`: + + cargo pkgid foo:1.0.0 + +. Retrieve package specification for `foo` from crates.io: + + cargo pkgid https://github.com/rust-lang/crates.io-index#foo + +== SEE ALSO +man:cargo[1], man:cargo-generate-lockfile[1], man:cargo-metadata[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-publish.adoc cargo-0.35.0/src/doc/man/cargo-publish.adoc --- cargo-0.33.0/src/doc/man/cargo-publish.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-publish.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,90 @@ += cargo-publish(1) +:idprefix: cargo_publish_ +:doctype: manpage +:actionverb: Publish + +== NAME + +cargo-publish - Upload a package to the registry + +== SYNOPSIS + +`cargo package [_OPTIONS_]` + +== DESCRIPTION + +This command will create a distributable, compressed `.crate` file with the +source code of the package in the current directory and upload it to a +registry. The default registry is https://crates.io. This performs the +following steps: + +. Performs a few checks, including: + - Checks the `package.publish` key in the manifest for restrictions on which + registries you are allowed to publish to. +. Create a `.crate` file by following the steps in man:cargo-package[1]. +. Upload the crate to the registry. Note that the server will perform + additional checks on the crate. + +This command requires you to be authenticated with either the `--token` option +or using man:cargo-login[1]. + +See linkcargo:reference/publishing.html[the reference] for more details about +packaging and publishing. + +== OPTIONS + +=== Publish Options + +*--dry-run*:: + Perform all checks without uploading. + +include::options-token.adoc[] + +*--no-verify*:: + Don't verify the contents by building them. + +*--allow-dirty*:: + Allow working directories with uncommitted VCS changes to be packaged. + +include::options-index.adoc[] + +include::options-registry.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-target-dir.adoc[] + +include::options-features.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Publish the current package: + + cargo publish + +== SEE ALSO +man:cargo[1], man:cargo-package[1], man:cargo-login[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-run.adoc cargo-0.35.0/src/doc/man/cargo-run.adoc --- cargo-0.33.0/src/doc/man/cargo-run.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-run.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,89 @@ += cargo-run(1) +:idprefix: cargo_run_ +:doctype: manpage +:actionverb: Run + +== NAME + +cargo-run - Run the current package + +== SYNOPSIS + +`cargo run [_OPTIONS_] [-- _ARGS_]` + +== DESCRIPTION + +Run a binary or example of the local package. + +All the arguments following the two dashes (`--`) are passed to the binary to +run. If you're passing arguments to both Cargo and the binary, the ones after +`--` go to the binary, the ones before go to Cargo. + +== OPTIONS + +=== Package Selection + +include::options-package.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo run` will run the binary +target. If there are multiple binary targets, you must pass a target flag to +choose one. + +*--bin* _NAME_:: + Run the specified binary. + +*--example* _NAME_:: + Run the specified example. + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Build the local package and run its main target (assuming only one binary): + + cargo run + +. Run an example with extra arguments: + + cargo run --example exname -- --exoption exarg1 exarg2 + +== SEE ALSO +man:cargo[1], man:cargo-build[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-rustc.adoc cargo-0.35.0/src/doc/man/cargo-rustc.adoc --- cargo-0.33.0/src/doc/man/cargo-rustc.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-rustc.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,94 @@ += cargo-rustc(1) +:idprefix: cargo_rustc_ +:doctype: manpage +:actionverb: Build + +== NAME + +cargo-rustc - Compile the current package, and pass extra options to the compiler + +== SYNOPSIS + +`cargo rustc [_OPTIONS_] [-- _ARGS_]` + +== DESCRIPTION + +The specified target for the current package (or package specified by `-p` if +provided) will be compiled along with all of its dependencies. The specified +_ARGS_ will all be passed to the final compiler invocation, not any of the +dependencies. Note that the compiler will still unconditionally receive +arguments such as `-L`, `--extern`, and `--crate-type`, and the specified +_ARGS_ will simply be added to the compiler invocation. + +See https://doc.rust-lang.org/rustc/index.html for documentation on rustc +flags. + +include::description-one-target.adoc[] +To pass flags to all compiler processes spawned by Cargo, use the `RUSTFLAGS` +environment variable or the `build.rustflags` +linkcargo:reference/config.html[config value]. + +== OPTIONS + +=== Package Selection + +include::options-package.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo rustc` will build all +binary and library targets of the selected package. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Check if your package (not including dependencies) uses unsafe code: + + cargo rustc --lib -- -D unsafe-code + +. Try an experimental flag on the nightly compiler, such as this which prints + the size of every type: + + cargo rustc --lib -- -Z print-type-sizes + +== SEE ALSO +man:cargo[1], man:cargo-build[1], man:rustc[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-rustdoc.adoc cargo-0.35.0/src/doc/man/cargo-rustdoc.adoc --- cargo-0.33.0/src/doc/man/cargo-rustdoc.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-rustdoc.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,96 @@ += cargo-rustdoc(1) +:idprefix: cargo_rustdoc_ +:doctype: manpage +:actionverb: Document + +== NAME + +cargo-rustdoc - Build a package's documentation, using specified custom flags + +== SYNOPSIS + +`cargo rustdoc [_OPTIONS_] [-- _ARGS_]` + +== DESCRIPTION + +The specified target for the current package (or package specified by `-p` if +provided) will be documented with the specified _ARGS_ being passed to the +final rustdoc invocation. Dependencies will not be documented as part of this +command. Note that rustdoc will still unconditionally receive arguments such +as `-L`, `--extern`, and `--crate-type`, and the specified _ARGS_ will simply +be added to the rustdoc invocation. + +See https://doc.rust-lang.org/rustdoc/index.html for documentation on rustdoc +flags. + +include::description-one-target.adoc[] +To pass flags to all rustdoc processes spawned by Cargo, use the +`RUSTDOCFLAGS` environment variable or the `build.rustdocflags` configuration +option. + +== OPTIONS + +=== Documentation Options + +*--open*:: + Open the docs in a browser after building them. + +=== Package Selection + +include::options-package.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo rustdoc` will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +`required-features` that are missing. + +include::options-targets.adoc[] + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Build documentation with custom CSS included from a given file: + + cargo rustdoc --lib -- --extend-css extra.css + +== SEE ALSO +man:cargo[1], man:cargo-doc[1], man:rustdoc[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-search.adoc cargo-0.35.0/src/doc/man/cargo-search.adoc --- cargo-0.33.0/src/doc/man/cargo-search.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-search.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,49 @@ += cargo-search(1) +:idprefix: cargo_search_ +:doctype: manpage + +== NAME + +cargo-search - Search packages in crates.io + +== SYNOPSIS + +`cargo search [_OPTIONS_] [_QUERY_...]` + +== DESCRIPTION + +This performs a textual search for crates on https://crates.io. The matching +crates will be displayed along with their description in TOML format suitable +for copying into a `Cargo.toml` manifest. + +== OPTIONS + +=== Search Options + +*--limit* _LIMIT_:: + Limit the number of results (default: 10, max: 100). + +include::options-index.adoc[] + +include::options-registry.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Search for a package from crates.io: + + cargo search serde + +== SEE ALSO +man:cargo[1], man:cargo-install[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-test.adoc cargo-0.35.0/src/doc/man/cargo-test.adoc --- cargo-0.33.0/src/doc/man/cargo-test.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-test.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,152 @@ += cargo-test(1) +:idprefix: cargo_test_ +:doctype: manpage +:actionverb: Test +:nouns: tests + +== NAME + +cargo-test - Execute unit and integration tests of a package + +== SYNOPSIS + +`cargo test [_OPTIONS_] [TESTNAME] [-- _TEST-OPTIONS_]` + +== DESCRIPTION + +Compile and execute unit and integration tests. + +The test filtering argument `TESTNAME` and all the arguments following the two +dashes (`--`) are passed to the test binaries and thus to _libtest_ (rustc's +built in unit-test and micro-benchmarking framework). If you're passing +arguments to both Cargo and the binary, the ones after `--` go to the binary, +the ones before go to Cargo. For details about libtest's arguments see the +output of `cargo test -- --help`. As an example, this will run all tests with +`foo` in their name on 3 threads in parallel: + + cargo test foo -- --test-threads 3 + +Tests are built with the `--test` option to `rustc` which creates an +executable with a `main` function that automatically runs all functions +annotated with the `\#[test]` attribute in multiple threads. `#[bench]` +annotated functions will also be run with one iteration to verify that they +are functional. + +The libtest harness may be disabled by setting `harness = false` in the target +manifest settings, in which case your code will need to provide its own `main` +function to handle running tests. + +Documentation tests are also run by default, which is handled by `rustdoc`. It +extracts code samples from documentation comments and executes them. See the +link:https://doc.rust-lang.org/rustdoc/[rustdoc book] for more information on +writing doc tests. + +== OPTIONS + +=== Test Options + +include::options-test.adoc[] + +=== Package Selection + +include::options-packages.adoc[] + +=== Target Selection + +When no target selection options are given, `cargo test` will build the +following targets of the selected packages: + +- lib — used to link with binaries, examples, integration tests, and doc tests +- bins (only if integration tests are built and required features are + available) +- examples — to ensure they compile +- lib as a unit test +- bins as unit tests +- integration tests +- doc tests for the lib target + +The default behavior can be changed by setting the `test` flag for the target +in the manifest settings. Setting examples to `test = true` will build and run +the example as a test. Setting targets to `test = false` will stop them from +being tested by default. Target selection options that take a target by name +ignore the `test` flag and will always test the given target. + +Doc tests for libraries may be disabled by setting `doctest = false` for the +library in the manifest. + +include::options-targets.adoc[] + +*--doc*:: + Test only the library's documentation. This cannot be mixed with other + target options. + +include::options-features.adoc[] + +=== Compilation Options + +include::options-target-triple.adoc[] + +include::options-release.adoc[] + +=== Output Options + +include::options-target-dir.adoc[] + +=== Display Options + +By default the Rust test harness hides output from test execution to keep +results readable. Test output can be recovered (e.g., for debugging) by passing +`--nocapture` to the test binaries: + + cargo test -- --nocapture + +include::options-display.adoc[] + +include::options-message-format.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +=== Miscellaneous Options + +The `--jobs` argument affects the building of the test executable but does not +affect how many threads are used when running the tests. The Rust test harness +includes an option to control the number of threads used: + + cargo test -j 2 -- --test-threads=2 + +include::options-jobs.adoc[] + +include::section-profiles.adoc[] + +Unit tests are separate executable artifacts which use the `test`/`bench` +profiles. Example targets are built the same as with `cargo build` (using the +`dev`/`release` profiles) unless you are building them with the test harness +(by setting `test = true` in the manifest or using the `--example` flag) in +which case they use the `test`/`bench` profiles. Library targets are built +with the `dev`/`release` profiles when linked to an integration test, binary, +or doctest. + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Execute all the unit and integration tests of the current package: + + cargo test + +. Run only a specific test within a specific integration test: + + cargo test --test int_test_name -- modname::test_name + +== SEE ALSO +man:cargo[1], man:cargo-bench[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-uninstall.adoc cargo-0.35.0/src/doc/man/cargo-uninstall.adoc --- cargo-0.33.0/src/doc/man/cargo-uninstall.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-uninstall.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,57 @@ += cargo-uninstall(1) +:idprefix: cargo_uninstall_ +:doctype: manpage + +== NAME + +cargo-uninstall - Remove a Rust binary + +== SYNOPSIS + +`cargo uninstall [_OPTIONS_] [_SPEC_...]` + +== DESCRIPTION + +This command removes a package installed with man:cargo-install[1]. The _SPEC_ +argument is a package ID specification of the package to remove (see +man:cargo-pkgid[1]). + +By default all binaries are removed for a crate but the `--bin` and +`--example` flags can be used to only remove particular binaries. + +include::description-install-root.adoc[] + +== OPTIONS + +=== Install Options + +*-p*:: +*--package* _SPEC_...:: + Package to uninstall. + +*--bin* _NAME_...:: + Only uninstall the binary _NAME_. + +*--root* _DIR_:: + Directory to uninstall packages from. + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Uninstall a previously installed package. + + cargo uninstall ripgrep + +== SEE ALSO +man:cargo[1], man:cargo-install[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-update.adoc cargo-0.35.0/src/doc/man/cargo-update.adoc --- cargo-0.33.0/src/doc/man/cargo-update.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-update.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,81 @@ += cargo-update(1) +:idprefix: cargo_update_ +:doctype: manpage + +== NAME + +cargo-update - Update dependencies as recorded in the local lock file + +== SYNOPSIS + +`cargo update [_OPTIONS_]` + +== DESCRIPTION + +This command will update dependencies in the `Cargo.lock` file to the latest +version. It requires that the `Cargo.lock` file already exists as generated +by commands such as man:cargo-build[1] or man:cargo-generate-lockfile[1]. + +== OPTIONS + +=== Update Options + +*-p* _SPEC_...:: +*--package* _SPEC_...:: + Update only the specified packages. This flag may be specified + multiple times. See man:cargo-pkgid[1] for the SPEC format. ++ +If packages are specified with the `-p` flag, then a conservative update of +the lockfile will be performed. This means that only the dependency specified +by SPEC will be updated. Its transitive dependencies will be updated only if +SPEC cannot be updated without updating dependencies. All other dependencies +will remain locked at their currently recorded versions. ++ +If `-p` is not specified, all dependencies are updated. + +*--aggressive*:: + When used with `-p`, dependencies of _SPEC_ are forced to update as well. + Cannot be used with `--precise`. + +*--precise* _PRECISE_:: + When used with `-p`, allows you to specify a specific version number to + set the package to. If the package comes from a git repository, this can + be a git revision (such as a SHA hash or tag). + +*--dry-run*:: + Displays what would be updated, but doesn't actually write the lockfile. + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Update all dependencies in the lockfile: + + cargo update + +. Update only specific dependencies: + + cargo update -p foo -p bar + +. Set a specific dependency to a specific version: + + cargo update -p foo --precise 1.2.3 + +== SEE ALSO +man:cargo[1], man:cargo-generate-lockfile[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-verify-project.adoc cargo-0.35.0/src/doc/man/cargo-verify-project.adoc --- cargo-0.33.0/src/doc/man/cargo-verify-project.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-verify-project.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,57 @@ += cargo-verify-project(1) +:idprefix: cargo_verify-project_ +:doctype: manpage + +== NAME + +cargo-verify-project - Check correctness of crate manifest + +== SYNOPSIS + +`cargo verify-project [_OPTIONS_]` + +== DESCRIPTION + +This command will parse the local manifest and check its validity. It emits a +JSON object with the result. A successful validation will display: + + {"success":"true"} + +An invalid workspace will display: + + {"invalid":"human-readable error message"} + +== OPTIONS + +=== Display Options + +include::options-display.adoc[] + +=== Manifest Options + +include::options-manifest-path.adoc[] + +include::options-locked.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +== Exit Status + +0:: + The workspace is OK. + +1:: + The workspace is invalid. + +== EXAMPLES + +. Check the current workspace for errors: + + cargo verify-project + +== SEE ALSO +man:cargo[1], man:cargo-package[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-version.adoc cargo-0.35.0/src/doc/man/cargo-version.adoc --- cargo-0.33.0/src/doc/man/cargo-version.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-version.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,39 @@ += cargo-version(1) +:idprefix: cargo_version_ +:doctype: manpage + +== NAME + +cargo-version - Show version information + +== SYNOPSIS + +`cargo version [_OPTIONS_]` + +== DESCRIPTION + +Displays the version of Cargo. + +== OPTIONS + +*-v*:: +*--verbose*:: + Display additional version information. + +== EXAMPLES + +. Display the version: + + cargo version + +. The version is also available via flags: + + cargo --version + cargo -V + +. Display extra version information: + + cargo -Vv + +== SEE ALSO +man:cargo[1] diff -Nru cargo-0.33.0/src/doc/man/cargo-yank.adoc cargo-0.35.0/src/doc/man/cargo-yank.adoc --- cargo-0.33.0/src/doc/man/cargo-yank.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/cargo-yank.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,64 @@ += cargo-yank(1) +:idprefix: cargo_yank_ +:doctype: manpage + +== NAME + +cargo-yank - Remove a pushed crate from the index + +== SYNOPSIS + +`cargo yank [_OPTIONS_] --vers _VERSION_ [_CRATE_]` + +== DESCRIPTION + +The yank command removes a previously published crate's version from the +server's index. This command does not delete any data, and the crate will +still be available for download via the registry's download link. + +Note that existing crates locked to a yanked version will still be able to +download the yanked version to use it. Cargo will, however, not allow any new +crates to be locked to any yanked version. + +This command requires you to be authenticated with either the `--token` option +or using man:cargo-login[1]. + +If the crate name is not specified, it will use the package name from the +current directory. + +== OPTIONS + +=== Owner Options + +*--vers* _VERSION_:: + The version to yank or un-yank. + +*--undo*:: + Undo a yank, putting a version back into the index. + +include::options-token.adoc[] + +include::options-index.adoc[] + +include::options-registry.adoc[] + +=== Display Options + +include::options-display.adoc[] + +=== Common Options + +include::options-common.adoc[] + +include::section-environment.adoc[] + +include::section-exit-status.adoc[] + +== EXAMPLES + +. Yank a crate from the index: + + cargo yank --vers 1.0.7 foo + +== SEE ALSO +man:cargo[1], man:cargo-login[1], man:cargo-publish[1] diff -Nru cargo-0.33.0/src/doc/man/description-install-root.adoc cargo-0.35.0/src/doc/man/description-install-root.adoc --- cargo-0.33.0/src/doc/man/description-install-root.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/description-install-root.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,7 @@ +The installation root is determined, in order of precedence: + +- `--root` option +- `CARGO_INSTALL_ROOT` environment variable +- `install.root` Cargo linkcargo:reference/config.html[config value] +- `CARGO_HOME` environment variable +- `$HOME/.cargo` diff -Nru cargo-0.33.0/src/doc/man/description-new-authors.adoc cargo-0.35.0/src/doc/man/description-new-authors.adoc --- cargo-0.33.0/src/doc/man/description-new-authors.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/description-new-authors.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,24 @@ +The "authors" field in the manifest is determined from the environment or +configuration settings. A name is required and is determined from (first match +wins): + +- `cargo-new.name` Cargo config value +- `CARGO_NAME` environment variable +- `GIT_AUTHOR_NAME` environment variable +- `GIT_COMMITTER_NAME` environment variable +- `user.name` git configuration value +- `USER` environment variable +- `USERNAME` environment variable +- `NAME` environment variable + +The email address is optional and is determined from: + +- `cargo-new.email` Cargo config value +- `CARGO_EMAIL` environment variable +- `GIT_AUTHOR_EMAIL` environment variable +- `GIT_COMMITTER_EMAIL` environment variable +- `user.email` git configuration value +- `EMAIL` environment variable + +See linkcargo:reference/config.html[the reference] for more information about +configuration files. diff -Nru cargo-0.33.0/src/doc/man/description-one-target.adoc cargo-0.35.0/src/doc/man/description-one-target.adoc --- cargo-0.33.0/src/doc/man/description-one-target.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/description-one-target.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,4 @@ +This command requires that only one target is being compiled when additional +arguments are provided. If more than one target is available for the current +package the filters of `--lib`, `--bin`, etc, must be used to select which +target is compiled. diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-bench.html cargo-0.35.0/src/doc/man/generated/cargo-bench.html --- cargo-0.33.0/src/doc/man/generated/cargo-bench.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-bench.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,466 @@ +

NAME

+
+

cargo-bench - Execute benchmarks of a package

+
+
+

SYNOPSIS

+
+
+

cargo bench [OPTIONS] [BENCHNAME] [-- BENCH-OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Compile and execute benchmarks.

+
+
+

The benchmark filtering argument BENCHNAME and all the arguments following +the two dashes (--) are passed to the benchmark binaries and thus to +libtest (rustc’s built in unit-test and micro-benchmarking framework). If +you’re passing arguments to both Cargo and the binary, the ones after -- go +to the binary, the ones before go to Cargo. For details about libtest’s +arguments see the output of cargo bench — --help. As an example, this will +run only the benchmark named foo (and skip other similarly named benchmarks +like foobar):

+
+
+
+
cargo bench -- foo --exact
+
+
+
+

Benchmarks are built with the --test option to rustc which creates an +executable with a main function that automatically runs all functions +annotated with the #[bench] attribute. Cargo passes the --bench flag to +the test harness to tell it to run only benchmarks.

+
+
+

The libtest harness may be disabled by setting harness = false in the target +manifest settings, in which case your code will need to provide its own main +function to handle running benchmarks.

+
+
+
+
+

OPTIONS

+
+
+

Benchmark Options

+
+
+
--no-run
+
+

Compile, but don’t run benchmarks.

+
+
--no-fail-fast
+
+

Run all benchmarks regardless of failure. Without this flag, Cargo will exit +after the first executable fails. The Rust test harness will run all +benchmarks within the executable to completion, this flag only applies to +the executable as a whole.

+
+
+
+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Benchmark only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Benchmark all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo bench will build the +following targets of the selected packages:

+
+
+
    +
  • +

    lib — used to link with binaries and benchmarks

    +
  • +
  • +

    bins (only if benchmark targets are built and required features are +available)

    +
  • +
  • +

    lib as a benchmark

    +
  • +
  • +

    bins as benchmarks

    +
  • +
  • +

    benchmark targets

    +
  • +
+
+
+

The default behavior can be changed by setting the bench flag for the target +in the manifest settings. Setting examples to bench = true will build and +run the example as a benchmark. Setting targets to bench = false will stop +them from being benchmarked by default. Target selection options that take a +target by name ignore the bench flag and will always benchmark the given +target.

+
+
+

Passing target selection flags will benchmark only the +specified targets.

+
+
+
+
--lib
+
+

Benchmark the package’s library.

+
+
--bin NAME…​
+
+

Benchmark the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Benchmark all binary targets.

+
+
--example NAME…​
+
+

Benchmark the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Benchmark all example targets.

+
+
--test NAME…​
+
+

Benchmark the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Benchmark all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Benchmark the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Benchmark all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Benchmark all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Benchmark for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+

By default the Rust test harness hides output from benchmark execution to keep +results readable. Benchmark output can be recovered (e.g., for debugging) by +passing --nocapture to the benchmark binaries:

+
+
+
+
cargo bench -- --nocapture
+
+
+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+

The --jobs argument affects the building of the benchmark executable but +does not affect how many threads are used when running the benchmarks. The +Rust test harness runs benchmarks serially in a single thread.

+
+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Benchmarks are always built with the bench profile. Binary and lib targets +are built separately as benchmarks with the bench profile. Library targets +are built with the release profiles when linked to binaries and benchmarks. +Dependencies use the release profile.

+
+
+

If you need a debug build of a benchmark, try building it with +cargo-build(1) which will use the test profile which is by default +unoptimized and includes debug information. You can then run the debug-enabled +benchmark manually.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build and execute all the benchmarks of the current package:

    +
    +
    +
    cargo bench
    +
    +
    +
  2. +
  3. +

    Run only a specific benchmark within a specific benchmark target:

    +
    +
    +
    cargo bench --bench bench_name -- modname::some_benchmark
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-build.html cargo-0.35.0/src/doc/man/generated/cargo-build.html --- cargo-0.33.0/src/doc/man/generated/cargo-build.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-build.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,425 @@ +

NAME

+
+

cargo-build - Compile the current package

+
+
+

SYNOPSIS

+
+
+

cargo build [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Compile local packages and all of their dependencies.

+
+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Build only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Build all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo build will build all +binary and library targets of the selected packages. Binaries are skipped if +they have required-features that are missing.

+
+
+

Passing target selection flags will build only the +specified targets.

+
+
+
+
--lib
+
+

Build the package’s library.

+
+
--bin NAME…​
+
+

Build the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Build all binary targets.

+
+
--example NAME…​
+
+

Build the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Build all example targets.

+
+
--test NAME…​
+
+

Build the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Build all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Build the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Build all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Build all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Build for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Build optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
--out-dir DIRECTORY
+
+

Copy final artifacts to this directory.

+
+

This option is unstable and available only on the nightly channel and requires +the -Z unstable-options flag to enable.

+
+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
--build-plan
+
+

Outputs a series of JSON messages to stdout that indicate the commands to +run the build.

+
+

This option is unstable and available only on the nightly channel and requires +the -Z unstable-options flag to enable.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build the local package and all of its dependencies:

    +
    +
    +
    cargo build
    +
    +
    +
  2. +
  3. +

    Build with optimizations:

    +
    +
    +
    cargo build --release
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-check.html cargo-0.35.0/src/doc/man/generated/cargo-check.html --- cargo-0.33.0/src/doc/man/generated/cargo-check.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-check.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,420 @@ +

NAME

+
+

cargo-check - Check the current package

+
+
+

SYNOPSIS

+
+
+

cargo check [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Check a local package and all of its dependencies for errors. This will +essentially compile the packages without performing the final step of code +generation, which is faster than running cargo build. The compiler will save +metadata files to disk so that future runs will reuse them if the source has +not been modified.

+
+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Check only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Check all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo check will check all +binary and library targets of the selected packages. Binaries are skipped if +they have required-features that are missing.

+
+
+

Passing target selection flags will check only the +specified targets.

+
+
+
+
--lib
+
+

Check the package’s library.

+
+
--bin NAME…​
+
+

Check the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Check all binary targets.

+
+
--example NAME…​
+
+

Check the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Check all example targets.

+
+
--test NAME…​
+
+

Check the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Check all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Check the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Check all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Check all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Check for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Check optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
--profile NAME
+
+

Changes check behavior. Currently only test is +supported, which will check with the +#[cfg(test)] attribute enabled. This is useful to have it +check unit tests which are usually excluded via +the cfg attribute. This does not change the actual profile used.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Check the local package for errors:

    +
    +
    +
    cargo check
    +
    +
    +
  2. +
  3. +

    Check all targets, including unit tests:

    +
    +
    +
    cargo check --all-targets --profile=test
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-clean.html cargo-0.35.0/src/doc/man/generated/cargo-clean.html --- cargo-0.33.0/src/doc/man/generated/cargo-clean.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-clean.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,224 @@ +

NAME

+
+

cargo-clean - Remove generated artifacts

+
+
+

SYNOPSIS

+
+
+

cargo clean [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Remove artifacts from the target directory that Cargo has generated in the +past.

+
+
+

With no options, cargo clean will delete the entire target directory.

+
+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+

When no packages are selected, all packages and all dependencies in the +workspace are cleaned.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Clean only the specified packages. This flag may be specified +multiple times. See cargo-pkgid(1) for the SPEC format.

+
+
+
+
+
+

Clean Options

+
+
+
--doc
+
+

This option will cause cargo clean to remove only the doc directory in +the target directory.

+
+
--release
+
+

Clean all artifacts that were built with the release or bench +profiles.

+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
--target TRIPLE
+
+

Clean for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Remove the entire target directory:

    +
    +
    +
    cargo clean
    +
    +
    +
  2. +
  3. +

    Remove only the release artifacts:

    +
    +
    +
    cargo clean --release
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-doc.html cargo-0.35.0/src/doc/man/generated/cargo-doc.html --- cargo-0.33.0/src/doc/man/generated/cargo-doc.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-doc.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,381 @@ +

NAME

+
+

cargo-doc - Build a package's documentation

+
+
+

SYNOPSIS

+
+
+

cargo doc [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Build the documentation for the local package and all dependencies. The output +is placed in target/doc in rustdoc’s usual format.

+
+
+
+
+

OPTIONS

+
+
+

Documentation Options

+
+
+
--open
+
+

Open the docs in a browser after building them.

+
+
--no-deps
+
+

Do not build documentation for dependencies.

+
+
--document-private-items
+
+

Include non-public items in the documentation.

+
+
+
+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Document only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Document all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo doc will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +required-features that are missing.

+
+
+

The default behavior can be changed by setting doc = false for the target in +the manifest settings. Using target selection options will ignore the doc +flag and will always document the given target.

+
+
+
+
--lib
+
+

Document the package’s library.

+
+
--bin NAME…​
+
+

Document the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Document all binary targets.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Document for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Document optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build the local package documentation and its dependencies and output to +target/doc.

    +
    +
    +
    cargo doc
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-fetch.html cargo-0.35.0/src/doc/man/generated/cargo-fetch.html --- cargo-0.33.0/src/doc/man/generated/cargo-fetch.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-fetch.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,188 @@ +

NAME

+
+

cargo-fetch - Fetch dependencies of a package from the network

+
+
+

SYNOPSIS

+
+
+

cargo fetch [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

If a Cargo.lock file is available, this command will ensure that all of the +git dependencies and/or registry dependencies are downloaded and locally +available. Subsequent Cargo commands never touch the network after a cargo +fetch unless the lock file changes.

+
+
+

If the lock file is not available, then this command will generate the lock +file before fetching the dependencies.

+
+
+

If --target is not specified, then all target dependencies are fetched.

+
+
+
+
+

OPTIONS

+
+
+

Fetch options

+
+
+
--target TRIPLE
+
+

Fetch for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Fetch all dependencies:

    +
    +
    +
    cargo fetch
    +
    +
    +
  2. +
+
+
+
+ \ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-fix.html cargo-0.35.0/src/doc/man/generated/cargo-fix.html --- cargo-0.33.0/src/doc/man/generated/cargo-fix.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-fix.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,499 @@ +

NAME

+
+

cargo-fix - Automatically fix lint warnings reported by rustc

+
+
+

SYNOPSIS

+
+
+

cargo fix [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This Cargo subcommand will automatically take rustc’s suggestions from +diagnostics like warnings and apply them to your source code. This is intended +to help automate tasks that rustc itself already knows how to tell you to fix! +The cargo fix subcommand is also being developed for the Rust 2018 edition +to provide code the ability to easily opt-in to the new edition without having +to worry about any breakage.

+
+
+

Executing cargo fix will under the hood execute cargo-check(1). Any warnings +applicable to your crate will be automatically fixed (if possible) and all +remaining warnings will be displayed when the check process is finished. For +example if you’d like to prepare for the 2018 edition, you can do so by +executing:

+
+
+
+
cargo fix --edition
+
+
+
+

which behaves the same as cargo check --all-targets. Similarly if you’d like +to fix code for different platforms you can do:

+
+
+
+
cargo fix --edition --target x86_64-pc-windows-gnu
+
+
+
+

or if your crate has optional features:

+
+
+
+
cargo fix --edition --no-default-features --features foo
+
+
+
+

If you encounter any problems with cargo fix or otherwise have any questions +or feature requests please don’t hesitate to file an issue at +https://github.com/rust-lang/cargo

+
+
+
+
+

OPTIONS

+
+
+

Fix options

+
+
+
--broken-code
+
+

Fix code even if it already has compiler errors. This is useful if cargo +fix fails to apply the changes. It will apply the changes and leave the +broken code in the working directory for you to inspect and manually fix.

+
+
--edition
+
+

Apply changes that will update the code to the latest edition. This will +not update the edition in the Cargo.toml manifest, which must be updated +manually.

+
+
--edition-idioms
+
+

Apply suggestions that will update code to the preferred style for the +current edition.

+
+
--allow-no-vcs
+
+

Fix code even if a VCS was not detected.

+
+
--allow-dirty
+
+

Fix code even if the working directory has changes.

+
+
--allow-staged
+
+

Fix code even if the working directory has staged changes.

+
+
+
+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Fix only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Fix all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo fix will fix all targets +(--all-targets implied). Binaries are skipped if they have +required-features that are missing.

+
+
+

Passing target selection flags will fix only the +specified targets.

+
+
+
+
--lib
+
+

Fix the package’s library.

+
+
--bin NAME…​
+
+

Fix the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Fix all binary targets.

+
+
--example NAME…​
+
+

Fix the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Fix all example targets.

+
+
--test NAME…​
+
+

Fix the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Fix all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Fix the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Fix all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Fix all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Fix for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Fix optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
--profile NAME
+
+

Changes fix behavior. Currently only test is +supported, which will fix with the +#[cfg(test)] attribute enabled. This is useful to have it +fix unit tests which are usually excluded via +the cfg attribute. This does not change the actual profile used.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Apply compiler suggestions to the local package:

    +
    +
    +
    cargo fix
    +
    +
    +
  2. +
  3. +

    Convert a 2015 edition to 2018:

    +
    +
    +
    cargo fix --edition
    +
    +
    +
  4. +
  5. +

    Apply suggested idioms for the current edition:

    +
    +
    +
    cargo fix --edition-idioms
    +
    +
    +
  6. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-generate-lockfile.html cargo-0.35.0/src/doc/man/generated/cargo-generate-lockfile.html --- cargo-0.33.0/src/doc/man/generated/cargo-generate-lockfile.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-generate-lockfile.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,166 @@ +

NAME

+
+

cargo-generate-lockfile - Generate the lockfile for a package

+
+
+

SYNOPSIS

+
+
+

cargo generate-lockfile [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will create the Cargo.lock lockfile for the current package or +workspace. If the lockfile already exists, it will be rebuilt if there are any +manifest changes or dependency updates.

+
+
+

See also cargo-update(1) which is also capable of creating a Cargo.lock +lockfile and has more options for controlling update behavior.

+
+
+
+
+

OPTIONS

+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Create or update the lockfile for the current package or workspace:

    +
    +
    +
    cargo generate-lockfile
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-help.html cargo-0.35.0/src/doc/man/generated/cargo-help.html --- cargo-0.33.0/src/doc/man/generated/cargo-help.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-help.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,53 @@ +

NAME

+
+

cargo-help - Get help for a Cargo command

+
+
+

SYNOPSIS

+
+
+

cargo help [SUBCOMMAND]

+
+
+
+
+

DESCRIPTION

+
+
+

Prints a help message for the given command.

+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Get help for a command:

    +
    +
    +
    cargo help build
    +
    +
    +
  2. +
  3. +

    Help is also available with the --help flag:

    +
    +
    +
    cargo build --help
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+
+ +
+
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo.html cargo-0.35.0/src/doc/man/generated/cargo.html --- cargo-0.33.0/src/doc/man/generated/cargo.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,433 @@ +

NAME

+
+

cargo - The Rust package manager

+
+
+

SYNOPSIS

+
+
+

cargo [OPTIONS] COMMAND [ARGS]
+cargo [OPTIONS] --version
+cargo [OPTIONS] --list
+cargo [OPTIONS] --help
+cargo [OPTIONS] --explain CODE

+
+
+
+
+

DESCRIPTION

+
+
+

This program is a package manager and build tool for the Rust language, +available at http://rust-lang.org.

+
+
+
+
+

COMMANDS

+
+
+

Build Commands

+
+
+
cargo-bench(1)
+
+

Execute benchmarks of a package.

+
+
cargo-build(1)
+
+

Compile a package.

+
+
cargo-check(1)
+
+

Check a local package and all of its dependencies for errors.

+
+
cargo-clean(1)
+
+

Remove artifacts that Cargo has generated in the past.

+
+
cargo-doc(1)
+
+

Build a package’s documentation.

+
+
cargo-fetch(1)
+
+

Fetch dependencies of a package from the network.

+
+
cargo-fix(1)
+
+

Automatically fix lint warnings reported by rustc.

+
+
cargo-run(1)
+
+

Run a binary or example of the local package.

+
+
cargo-rustc(1)
+
+

Compile a package, and pass extra options to the compiler.

+
+
cargo-rustdoc(1)
+
+

Build a package’s documentation, using specified custom flags.

+
+
cargo-test(1)
+
+

Execute unit and integration tests of a package.

+
+
+
+
+
+

Manifest Commands

+
+
+
cargo-generate-lockfile(1)
+
+

Generate Cargo.lock for a project.

+
+
cargo-locate-project(1)
+
+

Print a JSON representation of a Cargo.toml file’s location.

+
+
cargo-metadata(1)
+
+

Output the resolved dependencies of a package, the concrete used versions +including overrides, in machine-readable format.

+
+
cargo-pkgid(1)
+
+

Print a fully qualified package specification.

+
+
cargo-update(1)
+
+

Update dependencies as recorded in the local lock file.

+
+
cargo-verify-project(1)
+
+

Check correctness of crate manifest.

+
+
+
+
+
+

Package Commands

+
+
+
cargo-init(1)
+
+

Create a new Cargo package in an existing directory.

+
+
cargo-install(1)
+
+

Build and install a Rust binary.

+
+
cargo-new(1)
+
+

Create a new Cargo package.

+
+
cargo-search(1)
+
+

Search packages in crates.io.

+
+
cargo-uninstall(1)
+
+

Remove a Rust binary.

+
+
+
+
+
+

Publishing Commands

+
+
+
cargo-login(1)
+
+

Save an API token from the registry locally.

+
+
cargo-owner(1)
+
+

Manage the owners of a crate on the registry.

+
+
cargo-package(1)
+
+

Assemble the local package into a distributable tarball.

+
+
cargo-publish(1)
+
+

Upload a package to the registry.

+
+
cargo-yank(1)
+
+

Remove a pushed crate from the index.

+
+
+
+
+
+

General Commands

+
+
+
cargo-help(1)
+
+

Display help information about Cargo.

+
+
cargo-version(1)
+
+

Show version information.

+
+
+
+
+
+
+
+

OPTIONS

+
+
+

Special Options

+
+
+
-V
+
--version
+
+

Print version info and exit. If used with --verbose, prints extra +information.

+
+
--list
+
+

List all installed Cargo subcommands. If used with --verbose, prints +extra information.

+
+
--explain CODE
+
+

Run rustc --explain CODE which will print out a detailed explanation of +an error message (for example, E0004).

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

FILES

+
+
+
+
~/.cargo/
+
+

Default location for Cargo’s "home" directory where it stores various +files. The location can be changed with the CARGO_HOME environment +variable.

+
+
$CARGO_HOME/bin/
+
+

Binaries installed by cargo-install(1) will be located here. If using +rustup, executables distributed with Rust are also located here.

+
+
$CARGO_HOME/config
+
+

The global configuration file. See the reference +for more information about configuration files.

+
+
.cargo/config
+
+

Cargo automatically searches for a file named .cargo/config in the +current directory, and all parent directories. These configuration files +will be merged with the global configuration file.

+
+
$CARGO_HOME/credentials
+
+

Private authentication information for logging in to a registry.

+
+
$CARGO_HOME/registry/
+
+

This directory contains cached downloads of the registry index and any +downloaded dependencies.

+
+
$CARGO_HOME/git/
+
+

This directory contains cached downloads of git dependencies.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build a local package and all of its dependencies:

    +
    +
    +
    cargo build
    +
    +
    +
  2. +
  3. +

    Build a package with optimizations:

    +
    +
    +
    cargo build --release
    +
    +
    +
  4. +
  5. +

    Run tests for a cross-compiled target:

    +
    +
    +
    cargo test --target i686-unknown-linux-gnu
    +
    +
    +
  6. +
  7. +

    Create a new package that builds an executable:

    +
    +
    +
    cargo new foobar
    +
    +
    +
  8. +
  9. +

    Create a package in the current directory:

    +
    +
    +
    mkdir foo && cd foo
    +cargo init .
    +
    +
    +
  10. +
  11. +

    Learn about a command’s options and usage:

    +
    +
    +
    cargo help clean
    +
    +
    +
  12. +
+
+
+
+
+

BUGS

+ +
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-init.html cargo-0.35.0/src/doc/man/generated/cargo-init.html --- cargo-0.33.0/src/doc/man/generated/cargo-init.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-init.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,255 @@ +

NAME

+
+

cargo-init - Create a new Cargo package in an existing directory

+
+
+

SYNOPSIS

+
+
+

cargo init [OPTIONS] [PATH]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will create a new Cargo manifest in the current directory. Give a +path as an argument to create in the given directory.

+
+
+

If there are typically-named Rust source files already in the directory, those +will be used. If not, then a sample src/main.rs file will be created, or +src/lib.rs if --lib is passed.

+
+
+

If the directory is not already in a VCS repository, then a new repository +is created (see --vcs below).

+
+
+

The "authors" field in the manifest is determined from the environment or +configuration settings. A name is required and is determined from (first match +wins):

+
+
+
    +
  • +

    cargo-new.name Cargo config value

    +
  • +
  • +

    CARGO_NAME environment variable

    +
  • +
  • +

    GIT_AUTHOR_NAME environment variable

    +
  • +
  • +

    GIT_COMMITTER_NAME environment variable

    +
  • +
  • +

    user.name git configuration value

    +
  • +
  • +

    USER environment variable

    +
  • +
  • +

    USERNAME environment variable

    +
  • +
  • +

    NAME environment variable

    +
  • +
+
+
+

The email address is optional and is determined from:

+
+
+
    +
  • +

    cargo-new.email Cargo config value

    +
  • +
  • +

    CARGO_EMAIL environment variable

    +
  • +
  • +

    GIT_AUTHOR_EMAIL environment variable

    +
  • +
  • +

    GIT_COMMITTER_EMAIL environment variable

    +
  • +
  • +

    user.email git configuration value

    +
  • +
  • +

    EMAIL environment variable

    +
  • +
+
+
+

See the reference for more information about +configuration files.

+
+
+

See cargo-new(1) for a similar command which will create a new package in +a new directory.

+
+
+
+
+

OPTIONS

+
+
+

Init Options

+
+
+
--bin
+
+

Create a package with a binary target (src/main.rs). +This is the default behavior.

+
+
--lib
+
+

Create a package with a library target (src/lib.rs).

+
+
--edition EDITION
+
+

Specify the Rust edition to use. Default is 2018. +Possible values: 2015, 2018

+
+
--name NAME
+
+

Set the package name. Defaults to the directory name.

+
+
--vcs VCS
+
+

Initialize a new VCS repository for the given version control system (git, +hg, pijul, or fossil) or do not initialize any version control at all +(none). If not specified, defaults to git or the configuration value +cargo-new.vcs, or none if already inside a VCS repository.

+
+
--registry REGISTRY
+
+

This sets the publish field in Cargo.toml to the given registry name +which will restrict publishing only to that registry.

+
+

Registry names are defined in Cargo config files. +If not specified, the default registry defined by the registry.default +config key is used. If the default registry is not set and --registry is not +used, the publish field will not be set which means that publishing will not +be restricted.

+
+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Create a binary Cargo package in the current directory:

    +
    +
    +
    cargo init
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-install.html cargo-0.35.0/src/doc/man/generated/cargo-install.html --- cargo-0.33.0/src/doc/man/generated/cargo-install.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-install.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,322 @@ +

NAME

+
+

cargo-install - Build and install a Rust binary

+
+
+

SYNOPSIS

+
+
+

cargo install [OPTIONS] CRATE…​
+cargo install [OPTIONS] --path PATH
+cargo install [OPTIONS] --git URL [CRATE…​]
+cargo install [OPTIONS] --list

+
+
+
+
+

DESCRIPTION

+
+
+

This command manages Cargo’s local set of installed binary crates. Only packages +which have [[bin]] targets can be installed, and all binaries are installed into +the installation root’s bin folder.

+
+
+

The installation root is determined, in order of precedence:

+
+
+
    +
  • +

    --root option

    +
  • +
  • +

    CARGO_INSTALL_ROOT environment variable

    +
  • +
  • +

    install.root Cargo config value

    +
  • +
  • +

    CARGO_HOME environment variable

    +
  • +
  • +

    $HOME/.cargo

    +
  • +
+
+
+

There are multiple sources from which a crate can be installed. The default +location is crates.io but the --git and --path flags can change this +source. If the source contains more than one package (such as crates.io or a +git repository with multiple crates) the CRATE argument is required to +indicate which crate should be installed.

+
+
+

Crates from crates.io can optionally specify the version they wish to install +via the --version flags, and similarly packages from git repositories can +optionally specify the branch, tag, or revision that should be installed. If a +crate has multiple binaries, the --bin argument can selectively install only +one of them, and if you’d rather install examples the --example argument can +be used as well.

+
+
+

If the source is crates.io or --git then by default the crate will be built +in a temporary target directory. To avoid this, the target directory can be +specified by setting the CARGO_TARGET_DIR environment variable to a relative +path. In particular, this can be useful for caching build artifacts on +continuous integration systems.

+
+
+
+
+

OPTIONS

+
+
+

Install Options

+
+
+
--vers VERSION
+
--version VERSION
+
+

Specify a version to install from crates.io.

+
+
--git URL
+
+

Git URL to install the specified crate from.

+
+
--branch BRANCH
+
+

Branch to use when installing from git.

+
+
--tag TAG
+
+

Tag to use when installing from git.

+
+
--rev SHA
+
+

Specific commit to use when installing from git.

+
+
--path PATH
+
+

Filesystem path to local crate to install.

+
+
--list
+
+

List all installed packages and their versions.

+
+
-f
+
--force
+
+

Force overwriting existing crates or binaries. This can be used to +reinstall or upgrade a crate.

+
+
--bin NAME…​
+
+

Install only the specified binary.

+
+
--bins
+
+

Install all binaries.

+
+
--example NAME…​
+
+

Install only the specified example.

+
+
--examples
+
+

Install all examples.

+
+
--root DIR
+
+

Directory to install packages into.

+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Install for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--debug
+
+

Build with the dev profile instead the release profile.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Install a package from crates.io:

    +
    +
    +
    cargo install ripgrep
    +
    +
    +
  2. +
  3. +

    Reinstall or upgrade a package:

    +
    +
    +
    cargo install ripgrep --force
    +
    +
    +
  4. +
+
+
+
+ \ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-locate-project.html cargo-0.35.0/src/doc/man/generated/cargo-locate-project.html --- cargo-0.33.0/src/doc/man/generated/cargo-locate-project.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-locate-project.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,152 @@ +

NAME

+
+

cargo-locate-project - Print a JSON representation of a Cargo.toml file's location

+
+
+

SYNOPSIS

+
+
+

cargo locate-project [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will print a JSON object to stdout with the full path to the +Cargo.toml manifest.

+
+
+

See also cargo-metadata(1) which is capable of returning the path to a +workspace root.

+
+
+
+
+

OPTIONS

+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Display the path to the manifest based on the current directory:

    +
    +
    +
    cargo locate-project
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-login.html cargo-0.35.0/src/doc/man/generated/cargo-login.html --- cargo-0.33.0/src/doc/man/generated/cargo-login.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-login.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,160 @@ +

NAME

+
+

cargo-login - Save an API token from the registry locally

+
+
+

SYNOPSIS

+
+
+

cargo login [OPTIONS] [TOKEN]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will save the API token to disk so that commands that require +authentication, such as cargo-publish(1), will be automatically +authenticated. The token is saved in $CARGO_HOME/credentials. CARGO_HOME +defaults to .cargo in your home directory.

+
+
+

If the TOKEN argument is not specified, it will be read from stdin.

+
+
+

The API token for crates.io may be retrieved from https://crates.io/me.

+
+
+

Take care to keep the token secret, it should not be shared with anyone else.

+
+
+
+
+

OPTIONS

+
+
+

Login Options

+
+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Save the API token to disk:

    +
    +
    +
    cargo login
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-metadata.html cargo-0.35.0/src/doc/man/generated/cargo-metadata.html --- cargo-0.33.0/src/doc/man/generated/cargo-metadata.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-metadata.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,438 @@ +

NAME

+
+

cargo-metadata - Machine-readable metadata about the current package

+
+
+

SYNOPSIS

+
+
+

cargo metadata [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Output the resolved dependencies of a package, the concrete used versions +including overrides, in JSON to stdout.

+
+
+

It is recommended to include the --format-version flag to future-proof +your code to ensure the output is in the format you are expecting.

+
+
+

See the cargo_metadata crate +for a Rust API for reading the metadata.

+
+
+
+
+

OUTPUT FORMAT

+
+
+

The output has the following format:

+
+
+
+
{
+    /* Array of all packages in the workspace.
+       It also includes all feature-enabled dependencies unless --no-deps is used.
+    */
+    "packages": [
+        {
+            /* The name of the package. */
+            "name": "my-package",
+            /* The version of the package. */
+            "version": "0.1.0",
+            /* The Package ID, a unique identifier for referring to the package. */
+            "id": "my-package 0.1.0 (path+file:///path/to/my-package)",
+            /* The license value from the manifest, or null. */
+            "license": "MIT/Apache-2.0",
+            /* The license-file value from the manifest, or null. */
+            "license_file": "LICENSE",
+            /* The description value from the manifest, or null. */
+            "description": "Package description.",
+            /* The source ID of the package. This represents where
+               a package is retrieved from.
+               This is null for path dependencies and workspace members.
+               For other dependencies, it is a string with the format:
+               - "registry+URL" for registry-based dependencies.
+                 Example: "registry+https://github.com/rust-lang/crates.io-index"
+               - "git+URL" for git-based dependencies.
+                 Example: "git+https://github.com/rust-lang/cargo?rev=5e85ba14aaa20f8133863373404cb0af69eeef2c#5e85ba14aaa20f8133863373404cb0af69eeef2c"
+            */
+            "source": null,
+            /* Array of dependencies declared in the package's manifest. */
+            "dependencies": [
+                {
+                    /* The name of the dependency. */
+                    "name": "bitflags",
+                    /* The source ID of the dependency. May be null, see
+                       description for the package source.
+                    */
+                    "source": "registry+https://github.com/rust-lang/crates.io-index",
+                    /* The version requirement for the dependency.
+                       Dependencies without a version requirement have a value of "*".
+                    */
+                    "req": "^1.0",
+                    /* The dependency kind.
+                       "dev", "build", or null for a normal dependency.
+                    */
+                    "kind": null,
+                    /* If the dependency is renamed, this is the new name for
+                       the dependency as a string.  null if it is not renamed.
+                    */
+                    "rename": null,
+                    /* Boolean of whether or not this is an optional dependency. */
+                    "optional": false,
+                    /* Boolean of whether or not default features are enabled. */
+                    "uses_default_features": true,
+                    /* Array of features enabled. */
+                    "features": [],
+                    /* The target platform for the dependency.
+                       null if not a target dependency.
+                    */
+                    "target": "cfg(windows)",
+                    /* A string of the URL of the registry this dependency is from.
+                       If not specified or null, the dependency is from the default
+                       registry (crates.io).
+                    */
+                    "registry": null
+                }
+            ],
+            /* Array of Cargo targets. */
+            "targets": [
+                {
+                    /* Array of target kinds.
+                       - lib targets list the `crate-type` values from the
+                         manifest such as "lib", "rlib", "dylib",
+                         "proc-macro", etc. (default ["lib"])
+                       - binary is ["bin"]
+                       - example is ["example"]
+                       - integration test is ["test"]
+                       - benchmark is ["bench"]
+                       - build script is ["custom-build"]
+                    */
+                    "kind": [
+                        "bin"
+                    ],
+                    /* Array of crate types.
+                       - lib and example libraries list the `crate-type` values
+                         from the manifest such as "lib", "rlib", "dylib",
+                         "proc-macro", etc. (default ["lib"])
+                       - all other target kinds are ["bin"]
+                    */
+                    "crate_types": [
+                        "bin"
+                    ],
+                    /* The name of the target. */
+                    "name": "my-package",
+                    /* Absolute path to the root source file of the target. */
+                    "src_path": "/path/to/my-package/src/main.rs",
+                    /* The Rust edition of the target.
+                       Defaults to the package edition.
+                    */
+                    "edition": "2018",
+                    /* Array of required features.
+                       This property is not included if no required features are set.
+                    */
+                    "required-features": ["feat1"]
+                }
+            ],
+            /* Set of features defined for the package.
+               Each feature maps to an array of features or dependencies it
+               enables.
+            */
+            "features": {
+                "default": [
+                    "feat1"
+                ],
+                "feat1": [],
+                "feat2": []
+            },
+            /* Absolute path to this package's manifest. */
+            "manifest_path": "/path/to/my-package/Cargo.toml",
+            /* Package metadata.
+               This is null if no metadata is specified.
+            */
+            "metadata": {
+                "docs": {
+                    "rs": {
+                        "all-features": true
+                    }
+                }
+            },
+            /* Array of authors from the manifest.
+               Empty array if no authors specified.
+            */
+            "authors": [
+                "Jane Doe <user@example.com>"
+            ],
+            /* Array of categories from the manifest. */
+            "categories": [
+                "command-line-utilities"
+            ],
+            /* Array of keywords from the manifest. */
+            "keywords": [
+                "cli"
+            ],
+            /* The readme value from the manifest or null if not specified. */
+            "readme": "README.md",
+            /* The repository value from the manifest or null if not specified. */
+            "repository": "https://github.com/rust-lang/cargo",
+            /* The default edition of the package.
+               Note that individual targets may have different editions.
+            */
+            "edition": "2018",
+            /* Optional string that is the name of a native library the package
+               is linking to.
+            */
+            "links": null,
+        }
+    ],
+    /* Array of members of the workspace.
+       Each entry is the Package ID for the package.
+    */
+    "workspace_members": [
+        "my-package 0.1.0 (path+file:///path/to/my-package)",
+    ],
+    /* The resolved dependency graph, with the concrete versions and features
+       selected. The set depends on the enabled features.
+       This is null if --no-deps is specified.
+    */
+    "resolve": {
+        /* Array of nodes within the dependency graph.
+           Each node is a package.
+        */
+        "nodes": [
+            {
+                /* The Package ID of this node. */
+                "id": "my-package 0.1.0 (path+file:///path/to/my-package)",
+                /* The dependencies of this package, an array of Package IDs. */
+                "dependencies": [
+                    "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)"
+                ],
+                /* The dependencies of this package. This is an alternative to
+                   "dependencies" which contains additional information. In
+                   particular, this handles renamed dependencies.
+                */
+                "deps": [
+                    {
+                        /* The name of the dependency.
+                           If this is a renamed dependency, this is the new
+                           name.
+                        */
+                        "name": "bitflags",
+                        /* The Package ID of the dependency. */
+                        "pkg": "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)"
+                    }
+                ],
+                /* Array of features enabled on this package. */
+                "features": [
+                    "default"
+                ]
+            }
+        ],
+        /* The root package of the workspace.
+           This is null if this is a virtual workspace. Otherwise it is
+           the Package ID of the root package.
+        */
+        "root": "my-package 0.1.0 (path+file:///path/to/my-package)"
+    },
+    /* The absolute path to the build directory where Cargo places its output. */
+    "target_directory": "/path/to/my-package/target",
+    /* The version of the schema for this metadata structure.
+       This will be changed if incompatible changes are ever made.
+    */
+    "version": 1,
+    /* The absolute path to the root of the workspace. */
+    "workspace_root": "/path/to/my-package"
+}
+
+
+
+
+
+

OPTIONS

+
+
+

Output Options

+
+
+
--no-deps
+
+

Output information only about the workspace members and don’t fetch +dependencies.

+
+
--format-version VERSION
+
+

Specify the version of the output format to use. Currently 1 is the only +possible value.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Output JSON about the current package:

    +
    +
    +
    cargo metadata --format-version=1
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+
+ +
+
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-new.html cargo-0.35.0/src/doc/man/generated/cargo-new.html --- cargo-0.33.0/src/doc/man/generated/cargo-new.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-new.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,248 @@ +

NAME

+
+

cargo-new - Create a new Cargo package

+
+
+

SYNOPSIS

+
+
+

cargo new [OPTIONS] PATH

+
+
+
+
+

DESCRIPTION

+
+
+

This command will create a new Cargo package in the given directory. This +includes a simple template with a Cargo.toml manifest, sample source file, +and a VCS ignore file. If the directory is not already in a VCS repository, +then a new repository is created (see --vcs below).

+
+
+

The "authors" field in the manifest is determined from the environment or +configuration settings. A name is required and is determined from (first match +wins):

+
+
+
    +
  • +

    cargo-new.name Cargo config value

    +
  • +
  • +

    CARGO_NAME environment variable

    +
  • +
  • +

    GIT_AUTHOR_NAME environment variable

    +
  • +
  • +

    GIT_COMMITTER_NAME environment variable

    +
  • +
  • +

    user.name git configuration value

    +
  • +
  • +

    USER environment variable

    +
  • +
  • +

    USERNAME environment variable

    +
  • +
  • +

    NAME environment variable

    +
  • +
+
+
+

The email address is optional and is determined from:

+
+
+
    +
  • +

    cargo-new.email Cargo config value

    +
  • +
  • +

    CARGO_EMAIL environment variable

    +
  • +
  • +

    GIT_AUTHOR_EMAIL environment variable

    +
  • +
  • +

    GIT_COMMITTER_EMAIL environment variable

    +
  • +
  • +

    user.email git configuration value

    +
  • +
  • +

    EMAIL environment variable

    +
  • +
+
+
+

See the reference for more information about +configuration files.

+
+
+

See cargo-init(1) for a similar command which will create a new manifest +in an existing directory.

+
+
+
+
+

OPTIONS

+
+
+

New Options

+
+
+
--bin
+
+

Create a package with a binary target (src/main.rs). +This is the default behavior.

+
+
--lib
+
+

Create a package with a library target (src/lib.rs).

+
+
--edition EDITION
+
+

Specify the Rust edition to use. Default is 2018. +Possible values: 2015, 2018

+
+
--name NAME
+
+

Set the package name. Defaults to the directory name.

+
+
--vcs VCS
+
+

Initialize a new VCS repository for the given version control system (git, +hg, pijul, or fossil) or do not initialize any version control at all +(none). If not specified, defaults to git or the configuration value +cargo-new.vcs, or none if already inside a VCS repository.

+
+
--registry REGISTRY
+
+

This sets the publish field in Cargo.toml to the given registry name +which will restrict publishing only to that registry.

+
+

Registry names are defined in Cargo config files. +If not specified, the default registry defined by the registry.default +config key is used. If the default registry is not set and --registry is not +used, the publish field will not be set which means that publishing will not +be restricted.

+
+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Create a binary Cargo package in the given directory:

    +
    +
    +
    cargo new foo
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-owner.html cargo-0.35.0/src/doc/man/generated/cargo-owner.html --- cargo-0.33.0/src/doc/man/generated/cargo-owner.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-owner.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,212 @@ +

NAME

+
+

cargo-owner - Manage the owners of a crate on the registry

+
+
+

SYNOPSIS

+
+
+

cargo owner [OPTIONS] --add LOGIN [CRATE]
+cargo owner [OPTIONS] --remove LOGIN [CRATE]
+cargo owner [OPTIONS] --list [CRATE]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will modify the owners for a crate on the registry. Owners of a +crate can upload new versions and yank old versions. Non-team owners can also +modify the set of owners, so take care!

+
+
+

This command requires you to be authenticated with either the --token option +or using cargo-login(1).

+
+
+

If the crate name is not specified, it will use the package name from the +current directory.

+
+
+

See the reference for more +information about owners and publishing.

+
+
+
+
+

OPTIONS

+
+
+

Owner Options

+
+
+
-a
+
--add LOGIN…​
+
+

Invite the given user or team as an owner.

+
+
-r
+
--remove LOGIN…​
+
+

Remove the given user or team as an owner.

+
+
-l
+
--list
+
+

List owners of a crate.

+
+
--token TOKEN
+
+

API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by cargo-login(1)).

+
+

Cargo config environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the CARGO_REGISTRY_TOKEN environment +variable. Tokens for other registries may be specified with environment +variables of the form CARGO_REGISTRIES_NAME_TOKEN where NAME is the name +of the registry in all capital letters.

+
+
+
--index INDEX
+
+

The URL of the registry index to use.

+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    List owners of a package:

    +
    +
    +
    cargo owner --list foo
    +
    +
    +
  2. +
  3. +

    Invite an owner to a package:

    +
    +
    +
    cargo owner --add username foo
    +
    +
    +
  4. +
  5. +

    Remove an owner from a package:

    +
    +
    +
    cargo owner --remove username foo
    +
    +
    +
  6. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-package.html cargo-0.35.0/src/doc/man/generated/cargo-package.html --- cargo-0.33.0/src/doc/man/generated/cargo-package.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-package.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,301 @@ +

NAME

+
+

cargo-package - Assemble the local package into a distributable tarball

+
+
+

SYNOPSIS

+
+
+

cargo package [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will create a distributable, compressed .crate file with the +source code of the package in the current directory. The resulting file will +be stored in the target/package directory. This performs the following +steps:

+
+
+
    +
  1. +

    Load and check the current workspace, performing some basic checks.

    +
    +
      +
    • +

      Path dependencies are not allowed unless they have a version key. Cargo +will ignore the path key for dependencies in published packages.

      +
    • +
    +
    +
  2. +
  3. +

    Create the compressed .crate file.

    +
    +
      +
    • +

      The original Cargo.toml file is rewritten and normalized.

      +
    • +
    • +

      [patch], [replace], and [workspace] sections are removed from the +manifest.

      +
    • +
    • +

      A .cargo_vcs_info.json file is included that contains information +about the current VCS checkout hash if available (not included with +--allow-dirty).

      +
    • +
    +
    +
  4. +
  5. +

    Extract the .crate file and build it to verify it can build.

    +
  6. +
  7. +

    Check that build scripts did not modify any source files.

    +
  8. +
+
+
+

The list of files included can be controlled with the include and exclude +fields in the manifest.

+
+
+

See the reference for more details about +packaging and publishing.

+
+
+
+
+

OPTIONS

+
+
+

Package Options

+
+
+
-l
+
--list
+
+

Print files included in a package without making one.

+
+
--no-verify
+
+

Don’t verify the contents by building them.

+
+
--no-metadata
+
+

Ignore warnings about a lack of human-usable metadata (such as the +description or the license).

+
+
--allow-dirty
+
+

Allow working directories with uncommitted VCS changes to be packaged.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Package for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Create a compressed .crate file of the current package:

    +
    +
    +
    cargo package
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-pkgid.html cargo-0.35.0/src/doc/man/generated/cargo-pkgid.html --- cargo-0.33.0/src/doc/man/generated/cargo-pkgid.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-pkgid.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,241 @@ +

NAME

+
+

cargo-pkgid - Print a fully qualified package specification

+
+
+

SYNOPSIS

+
+
+

cargo pkgid [OPTIONS] [SPEC]

+
+
+
+
+

DESCRIPTION

+
+
+

Given a SPEC argument, print out the fully qualified package ID specifier +for a package or dependency in the current workspace. This command will +generate an error if SPEC is ambiguous as to which package it refers to in +the dependency graph. If no SPEC is given, then the specifier for the local +package is printed.

+
+
+

This command requires that a lockfile is available and dependencies have been +fetched.

+
+
+

A package specifier consists of a name, version, and source URL. You are +allowed to use partial specifiers to succinctly match a specific package as +long as it matches only one package. The format of a SPEC can be one of the +following:

+
+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. SPEC Query Format
SPEC StructureExample SPEC

NAME

bitflags

NAME:VERSION

bitflags:1.0.4

URL

https://github.com/rust-lang/cargo

URL#VERSION

https://github.com/rust-lang/cargo#0.33.0

URL#NAME

https://github.com/rust-lang/crates.io-index#bitflags

URL#NAME:VERSION

https://github.com/rust-lang/cargo#crates-io:0.21.0

+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+
+
-p SPEC
+
--package SPEC
+
+

Get the package ID for the given package instead of the current package.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Retrieve package specification for foo package:

    +
    +
    +
    cargo pkgid foo
    +
    +
    +
  2. +
  3. +

    Retrieve package specification for version 1.0.0 of foo:

    +
    +
    +
    cargo pkgid foo:1.0.0
    +
    +
    +
  4. +
  5. +

    Retrieve package specification for foo from crates.io:

    +
    +
    +
    cargo pkgid https://github.com/rust-lang/crates.io-index#foo
    +
    +
    +
  6. +
+
+
+
+ \ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-publish.html cargo-0.35.0/src/doc/man/generated/cargo-publish.html --- cargo-0.33.0/src/doc/man/generated/cargo-publish.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-publish.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,300 @@ +

NAME

+
+

cargo-publish - Upload a package to the registry

+
+
+

SYNOPSIS

+
+
+

cargo package [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will create a distributable, compressed .crate file with the +source code of the package in the current directory and upload it to a +registry. The default registry is https://crates.io. This performs the +following steps:

+
+
+
    +
  1. +

    Performs a few checks, including:

    +
    +
      +
    • +

      Checks the package.publish key in the manifest for restrictions on which +registries you are allowed to publish to.

      +
    • +
    +
    +
  2. +
  3. +

    Create a .crate file by following the steps in cargo-package(1).

    +
  4. +
  5. +

    Upload the crate to the registry. Note that the server will perform +additional checks on the crate.

    +
  6. +
+
+
+

This command requires you to be authenticated with either the --token option +or using cargo-login(1).

+
+
+

See the reference for more details about +packaging and publishing.

+
+
+
+
+

OPTIONS

+
+
+

Publish Options

+
+
+
--dry-run
+
+

Perform all checks without uploading.

+
+
--token TOKEN
+
+

API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by cargo-login(1)).

+
+

Cargo config environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the CARGO_REGISTRY_TOKEN environment +variable. Tokens for other registries may be specified with environment +variables of the form CARGO_REGISTRIES_NAME_TOKEN where NAME is the name +of the registry in all capital letters.

+
+
+
--no-verify
+
+

Don’t verify the contents by building them.

+
+
--allow-dirty
+
+

Allow working directories with uncommitted VCS changes to be packaged.

+
+
--index INDEX
+
+

The URL of the registry index to use.

+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Publish for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Publish the current package:

    +
    +
    +
    cargo publish
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-run.html cargo-0.35.0/src/doc/man/generated/cargo-run.html --- cargo-0.33.0/src/doc/man/generated/cargo-run.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-run.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,350 @@ +

NAME

+
+

cargo-run - Run the current package

+
+
+

SYNOPSIS

+
+
+

cargo run [OPTIONS] [-- ARGS]

+
+
+
+
+

DESCRIPTION

+
+
+

Run a binary or example of the local package.

+
+
+

All the arguments following the two dashes (--) are passed to the binary to +run. If you’re passing arguments to both Cargo and the binary, the ones after +-- go to the binary, the ones before go to Cargo.

+
+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+

By default, the package in the current working directory is selected. The -p +flag can be used to choose a different package in a workspace.

+
+
+
+
-p SPEC
+
--package SPEC
+
+

The package to run. See cargo-pkgid(1) for +the SPEC format.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo run will run the binary +target. If there are multiple binary targets, you must pass a target flag to +choose one.

+
+
+
+
--bin NAME
+
+

Run the specified binary.

+
+
--example NAME
+
+

Run the specified example.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Run for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Run optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build the local package and run its main target (assuming only one binary):

    +
    +
    +
    cargo run
    +
    +
    +
  2. +
  3. +

    Run an example with extra arguments:

    +
    +
    +
    cargo run --example exname -- --exoption exarg1 exarg2
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-rustc.html cargo-0.35.0/src/doc/man/generated/cargo-rustc.html --- cargo-0.33.0/src/doc/man/generated/cargo-rustc.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-rustc.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,413 @@ +

NAME

+
+

cargo-rustc - Compile the current package, and pass extra options to the compiler

+
+
+

SYNOPSIS

+
+
+

cargo rustc [OPTIONS] [-- ARGS]

+
+
+
+
+

DESCRIPTION

+
+
+

The specified target for the current package (or package specified by -p if +provided) will be compiled along with all of its dependencies. The specified +ARGS will all be passed to the final compiler invocation, not any of the +dependencies. Note that the compiler will still unconditionally receive +arguments such as -L, --extern, and --crate-type, and the specified +ARGS will simply be added to the compiler invocation.

+
+
+

See https://doc.rust-lang.org/rustc/index.html for documentation on rustc +flags.

+
+
+

This command requires that only one target is being compiled when additional +arguments are provided. If more than one target is available for the current +package the filters of --lib, --bin, etc, must be used to select which +target is compiled. +To pass flags to all compiler processes spawned by Cargo, use the RUSTFLAGS +environment variable or the build.rustflags +config value.

+
+
+
+
+

OPTIONS

+
+
+

Package Selection

+
+

By default, the package in the current working directory is selected. The -p +flag can be used to choose a different package in a workspace.

+
+
+
+
-p SPEC
+
--package SPEC
+
+

The package to build. See cargo-pkgid(1) for +the SPEC format.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo rustc will build all +binary and library targets of the selected package.

+
+
+

Passing target selection flags will build only the +specified targets.

+
+
+
+
--lib
+
+

Build the package’s library.

+
+
--bin NAME…​
+
+

Build the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Build all binary targets.

+
+
--example NAME…​
+
+

Build the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Build all example targets.

+
+
--test NAME…​
+
+

Build the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Build all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Build the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Build all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Build all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Build for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Build optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Check if your package (not including dependencies) uses unsafe code:

    +
    +
    +
    cargo rustc --lib -- -D unsafe-code
    +
    +
    +
  2. +
  3. +

    Try an experimental flag on the nightly compiler, such as this which prints +the size of every type:

    +
    +
    +
    cargo rustc --lib -- -Z print-type-sizes
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-rustdoc.html cargo-0.35.0/src/doc/man/generated/cargo-rustdoc.html --- cargo-0.33.0/src/doc/man/generated/cargo-rustdoc.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-rustdoc.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,417 @@ +

NAME

+
+

cargo-rustdoc - Build a package's documentation, using specified custom flags

+
+
+

SYNOPSIS

+
+
+

cargo rustdoc [OPTIONS] [-- ARGS]

+
+
+
+
+

DESCRIPTION

+
+
+

The specified target for the current package (or package specified by -p if +provided) will be documented with the specified ARGS being passed to the +final rustdoc invocation. Dependencies will not be documented as part of this +command. Note that rustdoc will still unconditionally receive arguments such +as -L, --extern, and --crate-type, and the specified ARGS will simply +be added to the rustdoc invocation.

+
+
+

See https://doc.rust-lang.org/rustdoc/index.html for documentation on rustdoc +flags.

+
+
+

This command requires that only one target is being compiled when additional +arguments are provided. If more than one target is available for the current +package the filters of --lib, --bin, etc, must be used to select which +target is compiled. +To pass flags to all rustdoc processes spawned by Cargo, use the +RUSTDOCFLAGS environment variable or the build.rustdocflags configuration +option.

+
+
+
+
+

OPTIONS

+
+
+

Documentation Options

+
+
+
--open
+
+

Open the docs in a browser after building them.

+
+
+
+
+
+

Package Selection

+
+

By default, the package in the current working directory is selected. The -p +flag can be used to choose a different package in a workspace.

+
+
+
+
-p SPEC
+
--package SPEC
+
+

The package to document. See cargo-pkgid(1) for +the SPEC format.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo rustdoc will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +required-features that are missing.

+
+
+

Passing target selection flags will document only the +specified targets.

+
+
+
+
--lib
+
+

Document the package’s library.

+
+
--bin NAME…​
+
+

Document the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Document all binary targets.

+
+
--example NAME…​
+
+

Document the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Document all example targets.

+
+
--test NAME…​
+
+

Document the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Document all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Document the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Document all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Document all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Document for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Document optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Build documentation with custom CSS included from a given file:

    +
    +
    +
    cargo rustdoc --lib -- --extend-css extra.css
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-search.html cargo-0.35.0/src/doc/man/generated/cargo-search.html --- cargo-0.33.0/src/doc/man/generated/cargo-search.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-search.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,158 @@ +

NAME

+
+

cargo-search - Search packages in crates.io

+
+
+

SYNOPSIS

+
+
+

cargo search [OPTIONS] [QUERY…​]

+
+
+
+
+

DESCRIPTION

+
+
+

This performs a textual search for crates on https://crates.io. The matching +crates will be displayed along with their description in TOML format suitable +for copying into a Cargo.toml manifest.

+
+
+
+
+

OPTIONS

+
+
+

Search Options

+
+
+
--limit LIMIT
+
+

Limit the number of results (default: 10, max: 100).

+
+
--index INDEX
+
+

The URL of the registry index to use.

+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Search for a package from crates.io:

    +
    +
    +
    cargo search serde
    +
    +
    +
  2. +
+
+
+
+ \ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-test.html cargo-0.35.0/src/doc/man/generated/cargo-test.html --- cargo-0.33.0/src/doc/man/generated/cargo-test.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-test.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,528 @@ +

NAME

+
+

cargo-test - Execute unit and integration tests of a package

+
+
+

SYNOPSIS

+
+
+

cargo test [OPTIONS] [TESTNAME] [-- TEST-OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Compile and execute unit and integration tests.

+
+
+

The test filtering argument TESTNAME and all the arguments following the two +dashes (--) are passed to the test binaries and thus to libtest (rustc’s +built in unit-test and micro-benchmarking framework). If you’re passing +arguments to both Cargo and the binary, the ones after -- go to the binary, +the ones before go to Cargo. For details about libtest’s arguments see the +output of cargo test — --help. As an example, this will run all tests with +foo in their name on 3 threads in parallel:

+
+
+
+
cargo test foo -- --test-threads 3
+
+
+
+

Tests are built with the --test option to rustc which creates an +executable with a main function that automatically runs all functions +annotated with the #[test] attribute in multiple threads. #[bench] +annotated functions will also be run with one iteration to verify that they +are functional.

+
+
+

The libtest harness may be disabled by setting harness = false in the target +manifest settings, in which case your code will need to provide its own main +function to handle running tests.

+
+
+

Documentation tests are also run by default, which is handled by rustdoc. It +extracts code samples from documentation comments and executes them. See the +rustdoc book for more information on +writing doc tests.

+
+
+
+
+

OPTIONS

+
+
+

Test Options

+
+
+
--no-run
+
+

Compile, but don’t run tests.

+
+
--no-fail-fast
+
+

Run all tests regardless of failure. Without this flag, Cargo will exit +after the first executable fails. The Rust test harness will run all +tests within the executable to completion, this flag only applies to +the executable as a whole.

+
+
+
+
+
+

Package Selection

+
+

By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (--all is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the workspace.default-members key in the root Cargo.toml +manifest.

+
+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Test only the specified packages. See cargo-pkgid(1) for the +SPEC format. This flag may be specified multiple times.

+
+
--all
+
+

Test all members in the workspace.

+
+
--exclude SPEC…​
+
+

Exclude the specified packages. Must be used in conjunction with the +--all flag. This flag may be specified multiple times.

+
+
+
+
+
+

Target Selection

+
+

When no target selection options are given, cargo test will build the +following targets of the selected packages:

+
+
+
    +
  • +

    lib — used to link with binaries, examples, integration tests, and doc tests

    +
  • +
  • +

    bins (only if integration tests are built and required features are +available)

    +
  • +
  • +

    examples — to ensure they compile

    +
  • +
  • +

    lib as a unit test

    +
  • +
  • +

    bins as unit tests

    +
  • +
  • +

    integration tests

    +
  • +
  • +

    doc tests for the lib target

    +
  • +
+
+
+

The default behavior can be changed by setting the test flag for the target +in the manifest settings. Setting examples to test = true will build and run +the example as a test. Setting targets to test = false will stop them from +being tested by default. Target selection options that take a target by name +ignore the test flag and will always test the given target.

+
+
+

Doc tests for libraries may be disabled by setting doctest = false for the +library in the manifest.

+
+
+

Passing target selection flags will test only the +specified targets.

+
+
+
+
--lib
+
+

Test the package’s library.

+
+
--bin NAME…​
+
+

Test the specified binary. This flag may be specified multiple times.

+
+
--bins
+
+

Test all binary targets.

+
+
--example NAME…​
+
+

Test the specified example. This flag may be specified multiple times.

+
+
--examples
+
+

Test all example targets.

+
+
--test NAME…​
+
+

Test the specified integration test. This flag may be specified multiple +times.

+
+
--tests
+
+

Test all targets in test mode that have the test = true manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the test flag in the +manifest settings for the target.

+
+
--bench NAME…​
+
+

Test the specified benchmark. This flag may be specified multiple times.

+
+
--benches
+
+

Test all targets in benchmark mode that have the bench = true +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the bench flag in the +manifest settings for the target.

+
+
--all-targets
+
+

Test all targets. This is equivalent to specifying --lib --bins +--tests --benches --examples.

+
+
--doc
+
+

Test only the library’s documentation. This cannot be mixed with other +target options.

+
+
+
+
+
+

Feature Selection

+
+

When no feature options are given, the default feature is activated for +every selected package.

+
+
+
+
--features FEATURES
+
+

Space or comma separated list of features to activate. These features only +apply to the current directory’s package. Features of direct dependencies +may be enabled with <dep-name>/<feature-name> syntax.

+
+
--all-features
+
+

Activate all available features of all selected packages.

+
+
--no-default-features
+
+

Do not activate the default feature of the current directory’s +package.

+
+
+
+
+
+

Compilation Options

+
+
+
--target TRIPLE
+
+

Test for the given architecture. The default is the host +architecture. The general format of the triple is +<arch><sub>-<vendor>-<sys>-<abi>. Run rustc --print target-list for a +list of supported targets.

+
+

This may also be specified with the build.target +config value.

+
+
+
--release
+
+

Test optimized artifacts with the release profile. See the +PROFILES section for details on how this affects profile selection.

+
+
+
+
+
+

Output Options

+
+
+
--target-dir DIRECTORY
+
+

Directory for all generated artifacts and intermediate files. May also be +specified with the CARGO_TARGET_DIR environment variable, or the +build.target-dir config value. Defaults +to target in the root of the workspace.

+
+
+
+
+
+

Display Options

+
+

By default the Rust test harness hides output from test execution to keep +results readable. Test output can be recovered (e.g., for debugging) by passing +--nocapture to the test binaries:

+
+
+
+
cargo test -- --nocapture
+
+
+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
--message-format FMT
+
+

The output format for diagnostic messages. Valid values:

+
+
    +
  • +

    human (default): Display in a human-readable text format.

    +
  • +
  • +

    json: Emit JSON messages to stdout.

    +
  • +
  • +

    short: Emit shorter, human-readable text messages.

    +
  • +
+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+

Miscellaneous Options

+
+

The --jobs argument affects the building of the test executable but does not +affect how many threads are used when running the tests. The Rust test harness +includes an option to control the number of threads used:

+
+
+
+
cargo test -j 2 -- --test-threads=2
+
+
+
+
+
-j N
+
--jobs N
+
+

Number of parallel jobs to run. May also be specified with the +build.jobs config value. Defaults to +the number of CPUs.

+
+
+
+
+
+
+
+

PROFILES

+
+
+

Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +the reference +for more details.

+
+
+

Profile selection depends on the target and crate being built. By default the +dev or test profiles are used. If the --release flag is given, then the +release or bench profiles are used.

+
+ +++++ + + + + + + + + + + + + + + + + + + + +
TargetDefault Profile--release Profile

lib, bin, example

dev

release

test, bench, or any target
+ in "test" or "bench" mode

test

bench

+
+

Dependencies use the dev/release profiles.

+
+
+

Unit tests are separate executable artifacts which use the test/bench +profiles. Example targets are built the same as with cargo build (using the +dev/release profiles) unless you are building them with the test harness +(by setting test = true in the manifest or using the --example flag) in +which case they use the test/bench profiles. Library targets are built +with the dev/release profiles when linked to an integration test, binary, +or doctest.

+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Execute all the unit and integration tests of the current package:

    +
    +
    +
    cargo test
    +
    +
    +
  2. +
  3. +

    Run only a specific test within a specific integration test:

    +
    +
    +
    cargo test --test int_test_name -- modname::test_name
    +
    +
    +
  4. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-uninstall.html cargo-0.35.0/src/doc/man/generated/cargo-uninstall.html --- cargo-0.33.0/src/doc/man/generated/cargo-uninstall.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-uninstall.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,183 @@ +

NAME

+
+

cargo-uninstall - Remove a Rust binary

+
+
+

SYNOPSIS

+
+
+

cargo uninstall [OPTIONS] [SPEC…​]

+
+
+
+
+

DESCRIPTION

+
+
+

This command removes a package installed with cargo-install(1). The SPEC +argument is a package ID specification of the package to remove (see +cargo-pkgid(1)).

+
+
+

By default all binaries are removed for a crate but the --bin and +--example flags can be used to only remove particular binaries.

+
+
+

The installation root is determined, in order of precedence:

+
+
+
    +
  • +

    --root option

    +
  • +
  • +

    CARGO_INSTALL_ROOT environment variable

    +
  • +
  • +

    install.root Cargo config value

    +
  • +
  • +

    CARGO_HOME environment variable

    +
  • +
  • +

    $HOME/.cargo

    +
  • +
+
+
+
+
+

OPTIONS

+
+
+

Install Options

+
+
+
-p
+
--package SPEC…​
+
+

Package to uninstall.

+
+
--bin NAME…​
+
+

Only uninstall the binary NAME.

+
+
--root DIR
+
+

Directory to uninstall packages from.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Uninstall a previously installed package.

    +
    +
    +
    cargo uninstall ripgrep
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-update.html cargo-0.35.0/src/doc/man/generated/cargo-update.html --- cargo-0.33.0/src/doc/man/generated/cargo-update.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-update.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,216 @@ +

NAME

+
+

cargo-update - Update dependencies as recorded in the local lock file

+
+
+

SYNOPSIS

+
+
+

cargo update [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will update dependencies in the Cargo.lock file to the latest +version. It requires that the Cargo.lock file already exists as generated +by commands such as cargo-build(1) or cargo-generate-lockfile(1).

+
+
+
+
+

OPTIONS

+
+
+

Update Options

+
+
+
-p SPEC…​
+
--package SPEC…​
+
+

Update only the specified packages. This flag may be specified +multiple times. See cargo-pkgid(1) for the SPEC format.

+
+

If packages are specified with the -p flag, then a conservative update of +the lockfile will be performed. This means that only the dependency specified +by SPEC will be updated. Its transitive dependencies will be updated only if +SPEC cannot be updated without updating dependencies. All other dependencies +will remain locked at their currently recorded versions.

+
+
+

If -p is not specified, all dependencies are updated.

+
+
+
--aggressive
+
+

When used with -p, dependencies of SPEC are forced to update as well. +Cannot be used with --precise.

+
+
--precise PRECISE
+
+

When used with -p, allows you to specify a specific version number to +set the package to. If the package comes from a git repository, this can +be a git revision (such as a SHA hash or tag).

+
+
--dry-run
+
+

Displays what would be updated, but doesn’t actually write the lockfile.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Update all dependencies in the lockfile:

    +
    +
    +
    cargo update
    +
    +
    +
  2. +
  3. +

    Update only specific dependencies:

    +
    +
    +
    cargo update -p foo -p bar
    +
    +
    +
  4. +
  5. +

    Set a specific dependency to a specific version:

    +
    +
    +
    cargo update -p foo --precise 1.2.3
    +
    +
    +
  6. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-verify-project.html cargo-0.35.0/src/doc/man/generated/cargo-verify-project.html --- cargo-0.33.0/src/doc/man/generated/cargo-verify-project.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-verify-project.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,174 @@ +

NAME

+
+

cargo-verify-project - Check correctness of crate manifest

+
+
+

SYNOPSIS

+
+
+

cargo verify-project [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

This command will parse the local manifest and check its validity. It emits a +JSON object with the result. A successful validation will display:

+
+
+
+
{"success":"true"}
+
+
+
+

An invalid workspace will display:

+
+
+
+
{"invalid":"human-readable error message"}
+
+
+
+
+
+

OPTIONS

+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Manifest Options

+
+
+
--manifest-path PATH
+
+

Path to the Cargo.toml file. By default, Cargo searches in the current +directory or any parent directory for the Cargo.toml file.

+
+
--frozen
+
--locked
+
+

Either of these flags requires that the Cargo.lock file is +up-to-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The --frozen flag also prevents Cargo from +attempting to access the network to determine if it is out-of-date.

+
+

These may be used in environments where you want to assert that the +Cargo.lock file is up-to-date (such as a CI build) or want to avoid network +access.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

The workspace is OK.

+
+
1
+
+

The workspace is invalid.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Check the current workspace for errors:

    +
    +
    +
    cargo verify-project
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-version.html cargo-0.35.0/src/doc/man/generated/cargo-version.html --- cargo-0.33.0/src/doc/man/generated/cargo-version.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-version.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,76 @@ +

NAME

+
+

cargo-version - Show version information

+
+
+

SYNOPSIS

+
+
+

cargo version [OPTIONS]

+
+
+
+
+

DESCRIPTION

+
+
+

Displays the version of Cargo.

+
+
+
+
+

OPTIONS

+
+
+
+
-v
+
--verbose
+
+

Display additional version information.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Display the version:

    +
    +
    +
    cargo version
    +
    +
    +
  2. +
  3. +

    The version is also available via flags:

    +
    +
    +
    cargo --version
    +cargo -V
    +
    +
    +
  4. +
  5. +

    Display extra version information:

    +
    +
    +
    cargo -Vv
    +
    +
    +
  6. +
+
+
+
+
+

SEE ALSO

+
+ +
+
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/generated/cargo-yank.html cargo-0.35.0/src/doc/man/generated/cargo-yank.html --- cargo-0.33.0/src/doc/man/generated/cargo-yank.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/generated/cargo-yank.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,188 @@ +

NAME

+
+

cargo-yank - Remove a pushed crate from the index

+
+
+

SYNOPSIS

+
+
+

cargo yank [OPTIONS] --vers VERSION [CRATE]

+
+
+
+
+

DESCRIPTION

+
+
+

The yank command removes a previously published crate’s version from the +server’s index. This command does not delete any data, and the crate will +still be available for download via the registry’s download link.

+
+
+

Note that existing crates locked to a yanked version will still be able to +download the yanked version to use it. Cargo will, however, not allow any new +crates to be locked to any yanked version.

+
+
+

This command requires you to be authenticated with either the --token option +or using cargo-login(1).

+
+
+

If the crate name is not specified, it will use the package name from the +current directory.

+
+
+
+
+

OPTIONS

+
+
+

Owner Options

+
+
+
--vers VERSION
+
+

The version to yank or un-yank.

+
+
--undo
+
+

Undo a yank, putting a version back into the index.

+
+
--token TOKEN
+
+

API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by cargo-login(1)).

+
+

Cargo config environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the CARGO_REGISTRY_TOKEN environment +variable. Tokens for other registries may be specified with environment +variables of the form CARGO_REGISTRIES_NAME_TOKEN where NAME is the name +of the registry in all capital letters.

+
+
+
--index INDEX
+
+

The URL of the registry index to use.

+
+
--registry REGISTRY
+
+

Name of the registry to use. Registry names are defined in Cargo config files. +If not specified, the default registry is used, which is defined by the +registry.default config key which defaults to crates-io.

+
+
+
+
+
+

Display Options

+
+
+
-v
+
--verbose
+
+

Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the term.verbose +config value.

+
+
-q
+
--quiet
+
+

No output printed to stdout.

+
+
--color WHEN
+
+

Control when colored output is used. Valid values:

+
+
    +
  • +

    auto (default): Automatically detect if color support is available on the +terminal.

    +
  • +
  • +

    always: Always display colors.

    +
  • +
  • +

    never: Never display colors.

    +
  • +
+
+
+

May also be specified with the term.color +config value.

+
+
+
+
+
+
+

Common Options

+
+
+
-h
+
--help
+
+

Prints help information.

+
+
-Z FLAG…​
+
+

Unstable (nightly-only) flags to Cargo. Run cargo -Z help for +details.

+
+
+
+
+
+
+
+

ENVIRONMENT

+
+
+

See the reference for +details on environment variables that Cargo reads.

+
+
+
+
+

Exit Status

+
+
+
+
0
+
+

Cargo succeeded.

+
+
101
+
+

Cargo failed to complete.

+
+
+
+
+
+
+

EXAMPLES

+
+
+
    +
  1. +

    Yank a crate from the index:

    +
    +
    +
    cargo yank --vers 1.0.7 foo
    +
    +
    +
  2. +
+
+
+
+
+

SEE ALSO

+ +
\ No newline at end of file diff -Nru cargo-0.33.0/src/doc/man/options-common.adoc cargo-0.35.0/src/doc/man/options-common.adoc --- cargo-0.33.0/src/doc/man/options-common.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-common.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,7 @@ +*-h*:: +*--help*:: + Prints help information. + +*-Z* _FLAG_...:: + Unstable (nightly-only) flags to Cargo. Run `cargo -Z help` for + details. diff -Nru cargo-0.33.0/src/doc/man/options-display.adoc cargo-0.35.0/src/doc/man/options-display.adoc --- cargo-0.33.0/src/doc/man/options-display.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-display.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,22 @@ +*-v*:: +*--verbose*:: + Use verbose output. May be specified twice for "very verbose" output which + includes extra output such as dependency warnings and build script output. + May also be specified with the `term.verbose` + linkcargo:reference/config.html[config value]. + +*-q*:: +*--quiet*:: + No output printed to stdout. + +*--color* _WHEN_:: + Control when colored output is used. Valid values: ++ +- `auto` (default): Automatically detect if color support is available on the + terminal. +- `always`: Always display colors. +- `never`: Never display colors. + ++ +May also be specified with the `term.color` +linkcargo:reference/config.html[config value]. diff -Nru cargo-0.33.0/src/doc/man/options-features.adoc cargo-0.35.0/src/doc/man/options-features.adoc --- cargo-0.33.0/src/doc/man/options-features.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-features.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,16 @@ +=== Feature Selection + +When no feature options are given, the `default` feature is activated for +every selected package. + +*--features* _FEATURES_:: + Space or comma separated list of features to activate. These features only + apply to the current directory's package. Features of direct dependencies + may be enabled with `/` syntax. + +*--all-features*:: + Activate all available features of all selected packages. + +*--no-default-features*:: + Do not activate the `default` feature of the current directory's + package. diff -Nru cargo-0.33.0/src/doc/man/options-index.adoc cargo-0.35.0/src/doc/man/options-index.adoc --- cargo-0.33.0/src/doc/man/options-index.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-index.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,2 @@ +*--index* _INDEX_:: + The URL of the registry index to use. diff -Nru cargo-0.33.0/src/doc/man/options-jobs.adoc cargo-0.35.0/src/doc/man/options-jobs.adoc --- cargo-0.33.0/src/doc/man/options-jobs.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-jobs.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,5 @@ +*-j* _N_:: +*--jobs* _N_:: + Number of parallel jobs to run. May also be specified with the + `build.jobs` linkcargo:reference/config.html[config value]. Defaults to + the number of CPUs. diff -Nru cargo-0.33.0/src/doc/man/options-locked.adoc cargo-0.35.0/src/doc/man/options-locked.adoc --- cargo-0.33.0/src/doc/man/options-locked.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-locked.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,10 @@ +*--frozen*:: +*--locked*:: + Either of these flags requires that the `Cargo.lock` file is + up-to-date. If the lock file is missing, or it needs to be updated, Cargo will + exit with an error. The `--frozen` flag also prevents Cargo from + attempting to access the network to determine if it is out-of-date. ++ +These may be used in environments where you want to assert that the +`Cargo.lock` file is up-to-date (such as a CI build) or want to avoid network +access. diff -Nru cargo-0.33.0/src/doc/man/options-manifest-path.adoc cargo-0.35.0/src/doc/man/options-manifest-path.adoc --- cargo-0.33.0/src/doc/man/options-manifest-path.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-manifest-path.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +*--manifest-path* _PATH_:: + Path to the `Cargo.toml` file. By default, Cargo searches in the current + directory or any parent directory for the `Cargo.toml` file. diff -Nru cargo-0.33.0/src/doc/man/options-message-format.adoc cargo-0.35.0/src/doc/man/options-message-format.adoc --- cargo-0.33.0/src/doc/man/options-message-format.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-message-format.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,6 @@ +*--message-format* _FMT_:: + The output format for diagnostic messages. Valid values: ++ +- `human` (default): Display in a human-readable text format. +- `json`: Emit JSON messages to stdout. +- `short`: Emit shorter, human-readable text messages. diff -Nru cargo-0.33.0/src/doc/man/options-new.adoc cargo-0.35.0/src/doc/man/options-new.adoc --- cargo-0.33.0/src/doc/man/options-new.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-new.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,29 @@ +*--bin*:: + Create a package with a binary target (`src/main.rs`). + This is the default behavior. + +*--lib*:: + Create a package with a library target (`src/lib.rs`). + +*--edition* _EDITION_:: + Specify the Rust edition to use. Default is 2018. + Possible values: 2015, 2018 + +*--name* _NAME_:: + Set the package name. Defaults to the directory name. + +*--vcs* _VCS_:: + Initialize a new VCS repository for the given version control system (git, + hg, pijul, or fossil) or do not initialize any version control at all + (none). If not specified, defaults to `git` or the configuration value + `cargo-new.vcs`, or `none` if already inside a VCS repository. + +*--registry* _REGISTRY_:: + This sets the `publish` field in `Cargo.toml` to the given registry name + which will restrict publishing only to that registry. ++ +Registry names are defined in linkcargo:reference/config.html[Cargo config files]. +If not specified, the default registry defined by the `registry.default` +config key is used. If the default registry is not set and `--registry` is not +used, the `publish` field will not be set which means that publishing will not +be restricted. diff -Nru cargo-0.33.0/src/doc/man/options-package.adoc cargo-0.35.0/src/doc/man/options-package.adoc --- cargo-0.33.0/src/doc/man/options-package.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-package.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,7 @@ +By default, the package in the current working directory is selected. The `-p` +flag can be used to choose a different package in a workspace. + +*-p* _SPEC_:: +*--package* _SPEC_:: + The package to convert:lowercase[{actionverb}]. See man:cargo-pkgid[1] for + the SPEC format. diff -Nru cargo-0.33.0/src/doc/man/options-packages.adoc cargo-0.35.0/src/doc/man/options-packages.adoc --- cargo-0.33.0/src/doc/man/options-packages.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-packages.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,18 @@ +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (`--all` is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the `workspace.default-members` key in the root `Cargo.toml` +manifest. + +*-p* _SPEC_...:: +*--package* _SPEC_...:: + {actionverb} only the specified packages. See man:cargo-pkgid[1] for the + SPEC format. This flag may be specified multiple times. + +*--all*:: + {actionverb} all members in the workspace. + +*--exclude* _SPEC_...:: + Exclude the specified packages. Must be used in conjunction with the + `--all` flag. This flag may be specified multiple times. diff -Nru cargo-0.33.0/src/doc/man/options-profile.adoc cargo-0.35.0/src/doc/man/options-profile.adoc --- cargo-0.33.0/src/doc/man/options-profile.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-profile.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,6 @@ +*--profile* _NAME_:: + Changes convert:lowercase[{actionverb}] behavior. Currently only `test` is + supported, which will convert:lowercase[{actionverb}] with the + `#[cfg(test)]` attribute enabled. This is useful to have it + convert:lowercase[{actionverb}] unit tests which are usually excluded via + the `cfg` attribute. This does not change the actual profile used. diff -Nru cargo-0.33.0/src/doc/man/options-registry.adoc cargo-0.35.0/src/doc/man/options-registry.adoc --- cargo-0.33.0/src/doc/man/options-registry.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-registry.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,4 @@ +*--registry* _REGISTRY_:: + Name of the registry to use. Registry names are defined in linkcargo:reference/config.html[Cargo config files]. + If not specified, the default registry is used, which is defined by the + `registry.default` config key which defaults to `crates-io`. diff -Nru cargo-0.33.0/src/doc/man/options-release.adoc cargo-0.35.0/src/doc/man/options-release.adoc --- cargo-0.33.0/src/doc/man/options-release.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-release.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +*--release*:: + {actionverb} optimized artifacts with the `release` profile. See the + <> section for details on how this affects profile selection. diff -Nru cargo-0.33.0/src/doc/man/options-target-dir.adoc cargo-0.35.0/src/doc/man/options-target-dir.adoc --- cargo-0.33.0/src/doc/man/options-target-dir.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-target-dir.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,5 @@ +*--target-dir* _DIRECTORY_:: + Directory for all generated artifacts and intermediate files. May also be + specified with the `CARGO_TARGET_DIR` environment variable, or the + `build.target-dir` linkcargo:reference/config.html[config value]. Defaults + to `target` in the root of the workspace. diff -Nru cargo-0.33.0/src/doc/man/options-targets.adoc cargo-0.35.0/src/doc/man/options-targets.adoc --- cargo-0.33.0/src/doc/man/options-targets.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-targets.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,39 @@ +Passing target selection flags will convert:lowercase[{actionverb}] only the +specified targets. + +include::options-targets-lib-bin.adoc[] + +*--example* _NAME_...:: + {actionverb} the specified example. This flag may be specified multiple times. + +*--examples*:: + {actionverb} all example targets. + +*--test* _NAME_...:: + {actionverb} the specified integration test. This flag may be specified multiple + times. + +*--tests*:: + {actionverb} all targets in test mode that have the `test = true` manifest + flag set. By default this includes the library and binaries built as + unittests, and integration tests. Be aware that this will also build any + required dependencies, so the lib target may be built twice (once as a + unittest, and once as a dependency for binaries, integration tests, etc.). + Targets may be enabled or disabled by setting the `test` flag in the + manifest settings for the target. + +*--bench* _NAME_...:: + {actionverb} the specified benchmark. This flag may be specified multiple times. + +*--benches*:: + {actionverb} all targets in benchmark mode that have the `bench = true` + manifest flag set. By default this includes the library and binaries built + as benchmarks, and bench targets. Be aware that this will also build any + required dependencies, so the lib target may be built twice (once as a + benchmark, and once as a dependency for binaries, benchmarks, etc.). + Targets may be enabled or disabled by setting the `bench` flag in the + manifest settings for the target. + +*--all-targets*:: + {actionverb} all targets. This is equivalent to specifying `--lib --bins + --tests --benches --examples`. diff -Nru cargo-0.33.0/src/doc/man/options-targets-lib-bin.adoc cargo-0.35.0/src/doc/man/options-targets-lib-bin.adoc --- cargo-0.33.0/src/doc/man/options-targets-lib-bin.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-targets-lib-bin.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,8 @@ +*--lib*:: + {actionverb} the package's library. + +*--bin* _NAME_...:: + {actionverb} the specified binary. This flag may be specified multiple times. + +*--bins*:: + {actionverb} all binary targets. diff -Nru cargo-0.33.0/src/doc/man/options-target-triple.adoc cargo-0.35.0/src/doc/man/options-target-triple.adoc --- cargo-0.33.0/src/doc/man/options-target-triple.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-target-triple.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,8 @@ +*--target* _TRIPLE_:: + {actionverb} for the given architecture. The default is the host + architecture. The general format of the triple is + `---`. Run `rustc --print target-list` for a + list of supported targets. ++ +This may also be specified with the `build.target` +linkcargo:reference/config.html[config value]. diff -Nru cargo-0.33.0/src/doc/man/options-test.adoc cargo-0.35.0/src/doc/man/options-test.adoc --- cargo-0.33.0/src/doc/man/options-test.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-test.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,8 @@ +*--no-run*:: + Compile, but don't run {nouns}. + +*--no-fail-fast*:: + Run all {nouns} regardless of failure. Without this flag, Cargo will exit + after the first executable fails. The Rust test harness will run all + {nouns} within the executable to completion, this flag only applies to + the executable as a whole. diff -Nru cargo-0.33.0/src/doc/man/options-token.adoc cargo-0.35.0/src/doc/man/options-token.adoc --- cargo-0.33.0/src/doc/man/options-token.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/options-token.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,10 @@ +*--token* _TOKEN_:: + API token to use when authenticating. This overrides the token stored in + the credentials file (which is created by man:cargo-login[1]). ++ +linkcargo:reference/config.html[Cargo config] environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the `CARGO_REGISTRY_TOKEN` environment +variable. Tokens for other registries may be specified with environment +variables of the form `CARGO_REGISTRIES_NAME_TOKEN` where `NAME` is the name +of the registry in all capital letters. diff -Nru cargo-0.33.0/src/doc/man/section-environment.adoc cargo-0.35.0/src/doc/man/section-environment.adoc --- cargo-0.33.0/src/doc/man/section-environment.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/section-environment.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,4 @@ +== ENVIRONMENT + +See linkcargo:reference/environment-variables.html[the reference] for +details on environment variables that Cargo reads. diff -Nru cargo-0.33.0/src/doc/man/section-exit-status.adoc cargo-0.35.0/src/doc/man/section-exit-status.adoc --- cargo-0.33.0/src/doc/man/section-exit-status.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/section-exit-status.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,7 @@ +== Exit Status + +0:: + Cargo succeeded. + +101:: + Cargo failed to complete. diff -Nru cargo-0.33.0/src/doc/man/section-profiles.adoc cargo-0.35.0/src/doc/man/section-profiles.adoc --- cargo-0.33.0/src/doc/man/section-profiles.adoc 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/man/section-profiles.adoc 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,26 @@ +== PROFILES + +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +linkcargo:reference/manifest.html#the-profile-sections[the reference] +for more details. + +Profile selection depends on the target and crate being built. By default the +`dev` or `test` profiles are used. If the `--release` flag is given, then the +`release` or `bench` profiles are used. + +[%autowidth] +|=== +|Target |Default Profile |`--release` Profile + +|lib, bin, example +|`dev` +|`release` + +|test, bench, or any target + + in "test" or "bench" mode +|`test` +|`bench` +|=== + +Dependencies use the `dev`/`release` profiles. diff -Nru cargo-0.33.0/src/doc/src/appendix/glossary.md cargo-0.35.0/src/doc/src/appendix/glossary.md --- cargo-0.33.0/src/doc/src/appendix/glossary.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/appendix/glossary.md 2019-04-01 21:32:07.000000000 +0000 @@ -63,7 +63,7 @@ The *package root* is the directory where the package's `Cargo.toml` manifest is located. -The [*package id specification*][pkgid-spec], or *SPEC*, is a string used to +The [*package ID specification*][pkgid-spec], or *SPEC*, is a string used to uniquely reference a specific version of a package from a specific source. ### Project @@ -97,7 +97,7 @@ ### Spec -See [package id specification](#package). +See [package ID specification](#package). ### Target @@ -108,20 +108,33 @@ test, and benchmark targets. The [list of targets][targets] are configured in the `Cargo.toml` manifest, often inferred automatically by the [directory layout] of the source files. -- **Target Architecture** — The OS and machine architecture for the built - artifacts are typically referred to as a *target*. -- **Target Triple** — A triple is a specific format for specifying a target - architecture. See the [clang documentation] for details. Triples may be - referred to as a *target triple* which is the architecture for the artifact - produced, and the *host triple* which is the architecture that the compiler - is running on. The target triple can be specified with the `--target` - command-line option or the `build.target` [config option]. - **Target Directory** — Cargo places all built artifacts and intermediate files in the *target* directory. By default this is a directory named `target` at the workspace root, or the package root if not using a - workspace. The directory be changed with the `--target-dir` command-line option, - the `CARGO_TARGET_DIR` [environment variable], or the `build.target-dir` - [config option]. + workspace. The directory may be changed with the `--target-dir` command-line + option, the `CARGO_TARGET_DIR` [environment variable], or the + `build.target-dir` [config option]. +- **Target Architecture** — The OS and machine architecture for the built + artifacts are typically referred to as a *target*. +- **Target Triple** — A triple is a specific format for specifying a target + architecture. Triples may be referred to as a *target triple* which is the + architecture for the artifact produced, and the *host triple* which is the + architecture that the compiler is running on. The target triple can be + specified with the `--target` command-line option or the `build.target` + [config option]. The general format of the triple is + `---` where: + + - `arch` = The base CPU architecture, for example `x86_64`, `i686`, `arm`, + `thumb`, `mips`, etc. + - `sub` = The CPU sub-architecture, for example `arm` has `v7`, `v7s`, + `v5te`, etc. + - `vendor` = The vendor, for example `unknown`, `apple`, `pc`, `linux`, etc. + - `sys` = The system name, for example `linux`, `windows`, etc. `none` is + typically used for bare-metal without an OS. + - `abi` = The ABI, for example `gnu`, `android`, `eabi`, etc. + + Some parameters may be omitted. Run `rustc --print target-list` for a list of + supported targets. ### Test Targets @@ -157,7 +170,6 @@ [Local Registry Sources]: reference/source-replacement.html#local-registry-sources [Source Replacement]: reference/source-replacement.html [cargo-unstable]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html -[clang documentation]: http://clang.llvm.org/docs/CrossCompilation.html#target-triple [config option]: reference/config.html [directory layout]: reference/manifest.html#the-project-layout [edition guide]: https://rust-lang-nursery.github.io/edition-guide/ diff -Nru cargo-0.33.0/src/doc/src/commands/build-commands.md cargo-0.35.0/src/doc/src/commands/build-commands.md --- cargo-0.33.0/src/doc/src/commands/build-commands.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/build-commands.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1 @@ +# Build Commands diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-bench.md cargo-0.35.0/src/doc/src/commands/cargo-bench.md --- cargo-0.33.0/src/doc/src/commands/cargo-bench.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-bench.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo bench +{{#include command-common.html}} +{{#include ../../man/generated/cargo-bench.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-build.md cargo-0.35.0/src/doc/src/commands/cargo-build.md --- cargo-0.33.0/src/doc/src/commands/cargo-build.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-build.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo build +{{#include command-common.html}} +{{#include ../../man/generated/cargo-build.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-check.md cargo-0.35.0/src/doc/src/commands/cargo-check.md --- cargo-0.33.0/src/doc/src/commands/cargo-check.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-check.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo check +{{#include command-common.html}} +{{#include ../../man/generated/cargo-check.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-clean.md cargo-0.35.0/src/doc/src/commands/cargo-clean.md --- cargo-0.33.0/src/doc/src/commands/cargo-clean.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-clean.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo clean +{{#include command-common.html}} +{{#include ../../man/generated/cargo-clean.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-doc.md cargo-0.35.0/src/doc/src/commands/cargo-doc.md --- cargo-0.33.0/src/doc/src/commands/cargo-doc.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-doc.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo doc +{{#include command-common.html}} +{{#include ../../man/generated/cargo-doc.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-fetch.md cargo-0.35.0/src/doc/src/commands/cargo-fetch.md --- cargo-0.33.0/src/doc/src/commands/cargo-fetch.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-fetch.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo fetch +{{#include command-common.html}} +{{#include ../../man/generated/cargo-fetch.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-fix.md cargo-0.35.0/src/doc/src/commands/cargo-fix.md --- cargo-0.33.0/src/doc/src/commands/cargo-fix.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-fix.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo fix +{{#include command-common.html}} +{{#include ../../man/generated/cargo-fix.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-generate-lockfile.md cargo-0.35.0/src/doc/src/commands/cargo-generate-lockfile.md --- cargo-0.33.0/src/doc/src/commands/cargo-generate-lockfile.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-generate-lockfile.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo generate-lockfile +{{#include command-common.html}} +{{#include ../../man/generated/cargo-generate-lockfile.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-help.md cargo-0.35.0/src/doc/src/commands/cargo-help.md --- cargo-0.33.0/src/doc/src/commands/cargo-help.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-help.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo help +{{#include command-common.html}} +{{#include ../../man/generated/cargo-help.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-init.md cargo-0.35.0/src/doc/src/commands/cargo-init.md --- cargo-0.33.0/src/doc/src/commands/cargo-init.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-init.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo init +{{#include command-common.html}} +{{#include ../../man/generated/cargo-init.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-install.md cargo-0.35.0/src/doc/src/commands/cargo-install.md --- cargo-0.33.0/src/doc/src/commands/cargo-install.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-install.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo install +{{#include command-common.html}} +{{#include ../../man/generated/cargo-install.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-locate-project.md cargo-0.35.0/src/doc/src/commands/cargo-locate-project.md --- cargo-0.33.0/src/doc/src/commands/cargo-locate-project.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-locate-project.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo locate-project +{{#include command-common.html}} +{{#include ../../man/generated/cargo-locate-project.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-login.md cargo-0.35.0/src/doc/src/commands/cargo-login.md --- cargo-0.33.0/src/doc/src/commands/cargo-login.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-login.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo login +{{#include command-common.html}} +{{#include ../../man/generated/cargo-login.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-metadata.md cargo-0.35.0/src/doc/src/commands/cargo-metadata.md --- cargo-0.33.0/src/doc/src/commands/cargo-metadata.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-metadata.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo metadata +{{#include command-common.html}} +{{#include ../../man/generated/cargo-metadata.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-new.md cargo-0.35.0/src/doc/src/commands/cargo-new.md --- cargo-0.33.0/src/doc/src/commands/cargo-new.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-new.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo new +{{#include command-common.html}} +{{#include ../../man/generated/cargo-new.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-owner.md cargo-0.35.0/src/doc/src/commands/cargo-owner.md --- cargo-0.33.0/src/doc/src/commands/cargo-owner.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-owner.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo owner +{{#include command-common.html}} +{{#include ../../man/generated/cargo-owner.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-package.md cargo-0.35.0/src/doc/src/commands/cargo-package.md --- cargo-0.33.0/src/doc/src/commands/cargo-package.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-package.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo package +{{#include command-common.html}} +{{#include ../../man/generated/cargo-package.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-pkgid.md cargo-0.35.0/src/doc/src/commands/cargo-pkgid.md --- cargo-0.33.0/src/doc/src/commands/cargo-pkgid.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-pkgid.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo pkgid +{{#include command-common.html}} +{{#include ../../man/generated/cargo-pkgid.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-publish.md cargo-0.35.0/src/doc/src/commands/cargo-publish.md --- cargo-0.33.0/src/doc/src/commands/cargo-publish.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-publish.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo publish +{{#include command-common.html}} +{{#include ../../man/generated/cargo-publish.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-run.md cargo-0.35.0/src/doc/src/commands/cargo-run.md --- cargo-0.33.0/src/doc/src/commands/cargo-run.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-run.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo run +{{#include command-common.html}} +{{#include ../../man/generated/cargo-run.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-rustc.md cargo-0.35.0/src/doc/src/commands/cargo-rustc.md --- cargo-0.33.0/src/doc/src/commands/cargo-rustc.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-rustc.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo rustc +{{#include command-common.html}} +{{#include ../../man/generated/cargo-rustc.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-rustdoc.md cargo-0.35.0/src/doc/src/commands/cargo-rustdoc.md --- cargo-0.33.0/src/doc/src/commands/cargo-rustdoc.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-rustdoc.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo rustdoc +{{#include command-common.html}} +{{#include ../../man/generated/cargo-rustdoc.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-search.md cargo-0.35.0/src/doc/src/commands/cargo-search.md --- cargo-0.33.0/src/doc/src/commands/cargo-search.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-search.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo search +{{#include command-common.html}} +{{#include ../../man/generated/cargo-search.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-test.md cargo-0.35.0/src/doc/src/commands/cargo-test.md --- cargo-0.33.0/src/doc/src/commands/cargo-test.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-test.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo test +{{#include command-common.html}} +{{#include ../../man/generated/cargo-test.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-uninstall.md cargo-0.35.0/src/doc/src/commands/cargo-uninstall.md --- cargo-0.33.0/src/doc/src/commands/cargo-uninstall.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-uninstall.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo uninstall +{{#include command-common.html}} +{{#include ../../man/generated/cargo-uninstall.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-update.md cargo-0.35.0/src/doc/src/commands/cargo-update.md --- cargo-0.33.0/src/doc/src/commands/cargo-update.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-update.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo update +{{#include command-common.html}} +{{#include ../../man/generated/cargo-update.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-verify-project.md cargo-0.35.0/src/doc/src/commands/cargo-verify-project.md --- cargo-0.33.0/src/doc/src/commands/cargo-verify-project.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-verify-project.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo verify-project +{{#include command-common.html}} +{{#include ../../man/generated/cargo-verify-project.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-version.md cargo-0.35.0/src/doc/src/commands/cargo-version.md --- cargo-0.33.0/src/doc/src/commands/cargo-version.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-version.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo version +{{#include command-common.html}} +{{#include ../../man/generated/cargo-version.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/cargo-yank.md cargo-0.35.0/src/doc/src/commands/cargo-yank.md --- cargo-0.33.0/src/doc/src/commands/cargo-yank.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/cargo-yank.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo yank +{{#include command-common.html}} +{{#include ../../man/generated/cargo-yank.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/command-common.html cargo-0.35.0/src/doc/src/commands/command-common.html --- cargo-0.33.0/src/doc/src/commands/command-common.html 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/command-common.html 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,18 @@ + diff -Nru cargo-0.33.0/src/doc/src/commands/general-commands.md cargo-0.35.0/src/doc/src/commands/general-commands.md --- cargo-0.33.0/src/doc/src/commands/general-commands.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/general-commands.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1 @@ +# General Commands diff -Nru cargo-0.33.0/src/doc/src/commands/index.md cargo-0.35.0/src/doc/src/commands/index.md --- cargo-0.33.0/src/doc/src/commands/index.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/index.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,3 @@ +# cargo +{{#include command-common.html}} +{{#include ../../man/generated/cargo.html}} diff -Nru cargo-0.33.0/src/doc/src/commands/manifest-commands.md cargo-0.35.0/src/doc/src/commands/manifest-commands.md --- cargo-0.33.0/src/doc/src/commands/manifest-commands.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/manifest-commands.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1 @@ +# Manifest Commands diff -Nru cargo-0.33.0/src/doc/src/commands/package-commands.md cargo-0.35.0/src/doc/src/commands/package-commands.md --- cargo-0.33.0/src/doc/src/commands/package-commands.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/package-commands.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1 @@ +# Package Commands diff -Nru cargo-0.33.0/src/doc/src/commands/publishing-commands.md cargo-0.35.0/src/doc/src/commands/publishing-commands.md --- cargo-0.33.0/src/doc/src/commands/publishing-commands.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/commands/publishing-commands.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1 @@ +# Publishing Commands diff -Nru cargo-0.33.0/src/doc/src/getting-started/first-steps.md cargo-0.35.0/src/doc/src/getting-started/first-steps.md --- cargo-0.33.0/src/doc/src/getting-started/first-steps.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/getting-started/first-steps.md 2019-04-01 21:32:07.000000000 +0000 @@ -29,6 +29,9 @@ name = "hello_world" version = "0.1.0" authors = ["Your Name "] +edition = "2018" + +[dependencies] ``` This is called a **manifest**, and it contains all of the metadata that Cargo diff -Nru cargo-0.33.0/src/doc/src/getting-started/installation.md cargo-0.35.0/src/doc/src/getting-started/installation.md --- cargo-0.33.0/src/doc/src/getting-started/installation.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/getting-started/installation.md 2019-04-01 21:32:07.000000000 +0000 @@ -3,19 +3,19 @@ ### Install Rust and Cargo The easiest way to get Cargo is to install the current stable release of [Rust] -by using `rustup`. +by using `rustup`. Installing Rust using `rustup` will also install `cargo`. On Linux and macOS systems, this is done as follows: ```console -$ curl -sSf https://static.rust-lang.org/rustup.sh | sh +$ curl https://sh.rustup.rs -sSf | sh ``` It will download a script, and start the installation. If everything goes well, you’ll see this appear: ```console -Rust is installed now. Great! +Rust is installed now. Great! ``` On Windows, download and run [rustup-init.exe]. It will start the installation @@ -33,5 +33,5 @@ [rust]: https://www.rust-lang.org/ [rustup-init.exe]: https://win.rustup.rs/ -[install-rust]: https://www.rust-lang.org/install.html +[install-rust]: https://www.rust-lang.org/tools/install [compiling-from-source]: https://github.com/rust-lang/cargo#compiling-from-source diff -Nru cargo-0.33.0/src/doc/src/guide/cargo-toml-vs-cargo-lock.md cargo-0.35.0/src/doc/src/guide/cargo-toml-vs-cargo-lock.md --- cargo-0.33.0/src/doc/src/guide/cargo-toml-vs-cargo-lock.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/guide/cargo-toml-vs-cargo-lock.md 2019-04-01 21:32:07.000000000 +0000 @@ -8,11 +8,11 @@ * `Cargo.lock` contains exact information about your dependencies. It is maintained by Cargo and should not be manually edited. -If you’re building a library that other packages will depend on, put -`Cargo.lock` in your `.gitignore`. If you’re building an executable like a -command-line tool or an application, check `Cargo.lock` into `git`. If you're -curious about why that is, see ["Why do binaries have `Cargo.lock` in version -control, but not libraries?" in the +If you’re building a non-end product, such as a rust library that other rust packages will depend on, put +`Cargo.lock` in your `.gitignore`. If you’re building an end product, which are executable +like command-line tool or an application, or a system library with crate-type of `staticlib` or `cdylib`, +check `Cargo.lock` into `git`. If you're curious about why that is, see +["Why do binaries have `Cargo.lock` in version control, but not libraries?" in the FAQ](faq.html#why-do-binaries-have-cargolock-in-version-control-but-not-libraries). Let’s dig in a little bit more. diff -Nru cargo-0.33.0/src/doc/src/guide/continuous-integration.md cargo-0.35.0/src/doc/src/guide/continuous-integration.md --- cargo-0.33.0/src/doc/src/guide/continuous-integration.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/guide/continuous-integration.md 2019-04-01 21:32:07.000000000 +0000 @@ -48,3 +48,41 @@ breakage in nightly will not fail your overall build. Please see the [GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html) for more information. + +### builds.sr.ht + +To test your package on sr.ht, here is a sample `.build.yml` file. +Be sure to change `` and `` to the repo to clone and +the directory where it was cloned. + +```yaml +image: archlinux +packages: + - rustup +sources: + - +tasks: + - setup: | + rustup toolchain install nightly stable + cd / + rustup run stable cargo fetch + - stable: | + rustup default stable + cd / + cargo build --verbose + cargo test --verbose + - nightly: | + rustup default nightly + cd / + cargo build --verbose ||: + cargo test --verbose ||: + - docs: | + cd / + rustup run stable cargo doc --no-deps + rustup run nightly cargo doc --no-deps ||: +``` + +This will test and build documentation on the stable channel and nightly +channel, but any breakage in nightly will not fail your overall build. Please +see the [builds.sr.ht documentation](https://man.sr.ht/builds.sr.ht/) for more +information. diff -Nru cargo-0.33.0/src/doc/src/guide/creating-a-new-project.md cargo-0.35.0/src/doc/src/guide/creating-a-new-project.md --- cargo-0.33.0/src/doc/src/guide/creating-a-new-project.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/guide/creating-a-new-project.md 2019-04-01 21:32:07.000000000 +0000 @@ -30,6 +30,10 @@ name = "hello_world" version = "0.1.0" authors = ["Your Name "] +edition = "2018" + +[dependencies] + ``` This is called a **manifest**, and it contains all of the metadata that Cargo diff -Nru cargo-0.33.0/src/doc/src/reference/config.md cargo-0.35.0/src/doc/src/reference/config.md --- cargo-0.33.0/src/doc/src/reference/config.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/config.md 2019-04-01 21:32:07.000000000 +0000 @@ -1,12 +1,11 @@ ## Configuration This document will explain how Cargo’s configuration system works, as well as -available keys or configuration. For configuration of a package through its +available keys or configuration. For configuration of a package through its manifest, see the [manifest format](reference/manifest.html). ### Hierarchical structure - Cargo allows local configuration for a particular package as well as global configuration, like git. Cargo extends this to a hierarchical strategy. If, for example, Cargo were invoked in `/projects/foo/bar/baz`, then the @@ -17,7 +16,7 @@ * `/projects/foo/.cargo/config` * `/projects/.cargo/config` * `/.cargo/config` -* `$HOME/.cargo/config` +* `$CARGO_HOME/config` (`$CARGO_HOME` defaults to `$HOME/.cargo`) With this structure, you can specify configuration per-package, and even possibly check it into version control. You can also specify personal defaults @@ -53,9 +52,9 @@ name = "..." email = "..." -# By default `cargo new` will initialize a new Git repository. This key can be -# set to `hg` to create a Mercurial repository, or `none` to disable this -# behavior. +# By default `cargo new` will initialize a new Git repository. This key can +# be set to change the version control system used. Valid values are `git`, +# `hg` (for Mecurial), `pijul`, `fossil`, or `none` to disable this behavior. vcs = "none" # For the following sections, $triple refers to any valid target triple, not the @@ -91,13 +90,20 @@ # Configuration keys related to the registry [registry] -index = "..." # URL of the registry index (defaults to the central repository) -token = "..." # Access token (found on the central repo’s website) -default = "..." # Default alternative registry to use (can be overriden with --registry) +index = "..." # URL of the registry index (defaults to the index of crates.io) +default = "..." # Name of the default registry to use (can be overridden with + # --registry) + +# Configuration keys for registries other than crates.io. +# `$name` should be the name of the registry, which will be used for +# dependencies in `Cargo.toml` files and the `--registry` command-line flag. +# Registry names should only contain alphanumeric characters, `-`, or `_`. +[registries.$name] +index = "..." # URL of the registry index [http] proxy = "host:port" # HTTP proxy to use for HTTP requests (defaults to none) - # in libcurl format, e.g. "socks5h://host:port" + # in libcurl format, e.g., "socks5h://host:port" timeout = 30 # Timeout for each HTTP request, in seconds cainfo = "cert.pem" # Path to Certificate Authority (CA) bundle (optional) check-revoke = true # Indicates whether SSL certs are checked for revocation @@ -121,7 +127,10 @@ target = "triple" # build for the target triple (ignored by `cargo install`) target-dir = "target" # path of where to place all generated artifacts rustflags = ["..", ".."] # custom flags to pass to all compiler invocations +rustdocflags = ["..", ".."] # custom flags to pass to rustdoc incremental = true # whether or not to enable incremental compilation + # If `incremental` is not set, then the value from + # the profile is used. dep-info-basedir = ".." # full path for the base directory for targets in depfiles [term] @@ -133,10 +142,11 @@ retry = 2 # number of times a network call will automatically retried git-fetch-with-cli = false # if `true` we'll use `git`-the-CLI to fetch git repos -# Alias cargo commands. The first 3 aliases are built in. If your +# Alias cargo commands. The first 4 aliases are built in. If your # command requires grouped whitespace use the list format. [alias] b = "build" +c = "check" t = "test" r = "run" rr = "run --release" @@ -158,5 +168,34 @@ In addition to the system above, Cargo recognizes a few other specific [environment variables][env]. +### Credentials + +Configuration values with sensitive information are stored in the +`$CARGO_HOME/credentials` file. This file is automatically created and updated +by [`cargo login`]. It follows the same format as Cargo config files. + +```toml +[registry] +token = "..." # Access token for crates.io + +# `$name` should be a registry name (see above for more information about +# configuring registries). +[registries.$name] +token = "..." # Access token for the named registry +``` + +Tokens are used by some Cargo commands such as [`cargo publish`] for +authenticating with remote registries. Care should be taken to protect the +tokens and to keep them secret. + +As with most other config values, tokens may be specified with environment +variables. The token for crates.io may be specified with the +`CARGO_REGISTRY_TOKEN` environment variable. Tokens for other registries may +be specified with environment variables of the form +`CARGO_REGISTRIES_NAME_TOKEN` where `NAME` is the name of the registry in all +capital letters. + +[`cargo login`]: commands/cargo-login.html +[`cargo publish`]: commands/cargo-publish.html [env]: reference/environment-variables.html [source]: reference/source-replacement.html diff -Nru cargo-0.33.0/src/doc/src/reference/environment-variables.md cargo-0.35.0/src/doc/src/reference/environment-variables.md --- cargo-0.33.0/src/doc/src/reference/environment-variables.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/environment-variables.md 2019-04-01 21:32:07.000000000 +0000 @@ -10,7 +10,7 @@ system: * `CARGO_HOME` — Cargo maintains a local cache of the registry index and of git - checkouts of crates. By default these are stored under `$HOME/.cargo`, but + checkouts of crates. By default these are stored under `$HOME/.cargo`, but this variable overrides the location of this directory. Once a crate is cached it is not removed by the clean command. * `CARGO_TARGET_DIR` — Location of where to place all generated artifacts, @@ -65,7 +65,7 @@ * `CARGO_PKG_HOMEPAGE` - The home page from the manifest of your package. * `CARGO_PKG_REPOSITORY` - The repository from the manifest of your package. * `OUT_DIR` - If the package has a build script, this is set to the folder where the build - script should place its output. See below for more information. + script should place its output. See below for more information. ### Environment variables Cargo sets for build scripts @@ -104,8 +104,8 @@ inside the build directory for the package being built, and it is unique for the package in question. * `TARGET` - the target triple that is being compiled for. Native code should be - compiled for this triple. Some more information about target - triples can be found in [clang’s own documentation][clang]. + compiled for this triple. See the [Target Triple] description + for more information. * `HOST` - the host triple of the rust compiler. * `NUM_JOBS` - the parallelism specified as the top-level parallelism. This can be useful to pass a `-j` parameter to a system like `make`. Note @@ -132,9 +132,9 @@ [links]: reference/build-scripts.html#the-links-manifest-key [configuration]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation -[clang]: http://clang.llvm.org/docs/CrossCompilation.html#target-triple [jobserver]: https://www.gnu.org/software/make/manual/html_node/Job-Slots.html [cargo-config]: reference/config.html +[Target Triple]: appendix/glossary.html#target ### Environment variables Cargo sets for 3rd party subcommands diff -Nru cargo-0.33.0/src/doc/src/reference/manifest.md cargo-0.35.0/src/doc/src/reference/manifest.md --- cargo-0.33.0/src/doc/src/reference/manifest.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/manifest.md 2019-04-01 21:32:07.000000000 +0000 @@ -14,7 +14,20 @@ authors = ["Alice ", "Bob "] ``` -All three of these fields are mandatory. +#### The `name` field + +The package name is an identifier used to refer to the package. It is used +when listed as a dependency in another package, and as the default name of +inferred lib and bin targets. + +The name must not be empty, use only [alphanumeric] characters or `-` or `_`. +Note that `cargo new` and `cargo init` impose some additional restrictions on +the package name, such as enforcing that it is a valid Rust identifier and not +a keyword. [crates.io][cratesio] imposes even more restrictions, such as +enforcing only ASCII characters, not a reserved name, not a special Windows +name such as "nul", is not too long, etc. + +[alphanumeric]: https://doc.rust-lang.org/std/primitive.char.html#method.is_alphanumeric #### The `version` field @@ -31,10 +44,19 @@ traits, fields, types, functions, methods or anything else. * Use version numbers with three numeric parts such as 1.0.0 rather than 1.0. +#### The `authors` field (optional) + +The `authors` field lists people or organizations that are considered the +"authors" of the package. The exact meaning is open to interpretation — it may +list the original or primary authors, current maintainers, or owners of the +package. These names will be listed on the crate's page on +[crates.io][cratesio]. An optional email address may be included within angled +brackets at the end of each author. + #### The `edition` field (optional) You can opt in to a specific Rust Edition for your package with the -`edition` key in `Cargo.toml`. If you don't specify the edition, it will +`edition` key in `Cargo.toml`. If you don't specify the edition, it will default to 2015. ```toml @@ -86,7 +108,7 @@ Documentation links from specific hosts are blacklisted. Hosts are added to the blacklist if they are known to not be hosting documentation and are -possibly of malicious intent e.g. ad tracking networks. URLs from the +possibly of malicious intent e.g., ad tracking networks. URLs from the following hosts are blacklisted: * rust-ci.org @@ -144,7 +166,8 @@ #### The `publish` field (optional) The `publish` field can be used to prevent a package from being published to a -package registry (like *crates.io*) by mistake. +package registry (like *crates.io*) by mistake, for instance to keep a package +private in a company. ```toml [package] @@ -152,6 +175,15 @@ publish = false ``` +The value many also be an array of strings which are registry names that are +allowed to be published to. + +```toml +[package] +# ... +publish = ["some-registry-name"] +``` + #### The `workspace` field (optional) The `workspace` field can be used to configure the workspace that this package @@ -201,13 +233,13 @@ # they must match exactly. categories = ["...", "..."] -# This is an SPDX 2.1 license expression for this package. Currently +# This is an SPDX 2.1 license expression for this package. Currently # crates.io will validate the license provided against a whitelist of # known license and exception identifiers from the SPDX license list -# 2.4. Parentheses are not currently supported. +# 2.4. Parentheses are not currently supported. # # Multiple licenses can be separated with a `/`, although that usage -# is deprecated. Instead, use a license expression with AND and OR +# is deprecated. Instead, use a license expression with AND and OR # operators to get more explicit semantics. license = "..." @@ -219,7 +251,7 @@ # Optional specification of badges to be displayed on crates.io. # # - The badges pertaining to build status that are currently available are -# Appveyor, CircleCI, GitLab, and TravisCI. +# Appveyor, CircleCI, GitLab, Azure DevOps and TravisCI. # - Available badges pertaining to code test coverage are Codecov and # Coveralls. # - There are also maintenance-related badges based on isitmaintained.com @@ -243,6 +275,10 @@ # GitLab: `repository` is required. `branch` is optional; default is `master` gitlab = { repository = "...", branch = "master" } +# Azure DevOps: `project` is required. `pipeline` is required. `build` is optional; default is `1` +# Note: project = `organization/project`, pipeline = `name_of_pipeline`, build = `definitionId` +azure-devops = { project = "...", pipeline = "...", build="2" } + # Travis CI: `repository` in format "/" is required. # `branch` is optional; default is `master` travis-ci = { repository = "...", branch = "master" } @@ -275,7 +311,7 @@ published crate. SPDX 2.1 license expressions are documented -[here][spdx-2.1-license-expressions]. The current version of the +[here][spdx-2.1-license-expressions]. The current version of the license list is available [here][spdx-license-list], and version 2.4 is available [here][spdx-license-list-2.4]. @@ -332,17 +368,20 @@ # string is specified like 'thin' then `-C lto=thin` will # be passed. debug-assertions = true # controls whether debug assertions are enabled - # (e.g. debug_assert!() and arithmetic overflow checks) + # (e.g., debug_assert!() and arithmetic overflow checks) codegen-units = 16 # if > 1 enables parallel code generation which improves # compile times, but prevents some optimizations. # Passes `-C codegen-units`. panic = 'unwind' # panic strategy (`-C panic=...`), can also be 'abort' incremental = true # whether or not incremental compilation is enabled + # This can be overridden globally with the CARGO_INCREMENTAL + # environment variable or `build.incremental` config + # variable. Incremental is only used for path sources. overflow-checks = true # use overflow checks for integer arithmetic. # Passes the `-C overflow-checks=...` flag to the compiler. # The release profile, used for `cargo build --release` (and the dependencies -# for `cargo test --release`, including the local library or binary). +# for `cargo test --release`, including the local library or binary). [profile.release] opt-level = 3 debug = false @@ -531,7 +570,7 @@ * The *root crate*'s `Cargo.toml` contains the `[workspace]` table, but is not required to have other configuration. * Whenever any crate in the workspace is compiled, output is placed in the - *workspace root*. i.e. next to the *root crate*'s `Cargo.toml`. + *workspace root* (i.e., next to the *root crate*'s `Cargo.toml`). * The lock file for all crates in the workspace resides in the *workspace root*. * The `[patch]`, `[replace]` and `[profile.*]` sections in `Cargo.toml` are only recognized @@ -599,7 +638,7 @@ with a name of the parent directory. Do note, however, once you add a `[[bin]]` section ([see below](#configuring-a-target)), Cargo will no longer automatically build files -located in `src/bin/*.rs`. Instead you must create a `[[bin]]` section for +located in `src/bin/*.rs`. Instead you must create a `[[bin]]` section for each file you want to build. Your package can optionally contain folders named `examples`, `tests`, and @@ -741,6 +780,12 @@ # 2018 edition or only compiling one unit test with the 2015 edition. By default # all targets are compiled with the edition specified in `[package]`. edition = '2015' + +# Here's an example of a TOML "array of tables" section, in this case specifying +# a binary target name and path. +[[bin]] +name = "my-cool-binary" +path = "src/my-cool-binary.rs" ``` The `[package]` also includes the optional `autobins`, `autoexamples`, @@ -780,9 +825,7 @@ ``` The available options are `dylib`, `rlib`, `staticlib`, `cdylib`, and -`proc-macro`. You should only use this option in a package. Cargo will always -compile packages (dependencies) based on the requirements of the package that -includes them. +`proc-macro`. You can read more about the different crate types in the [Rust Reference Manual](https://doc.rust-lang.org/reference/linkage.html) @@ -805,11 +848,10 @@ ``` The `[patch]` table is made of dependency-like sub-tables. Each key after -`[patch]` is a URL of the source that's being patched, or `crates-io` if -you're modifying the https://crates.io registry. In the example above -`crates-io` could be replaced with a git URL such as -`https://github.com/rust-lang-nursery/log`; the second `[patch]` -section in the example uses this to specify a source called `baz`. +`[patch]` is a URL of the source that is being patched, or the name of a +registry. The name `crates-io` may be used to override the default registry +[crates.io]. The first `[patch]` in the example above demonstrates overriding +[crates.io], and the second `[patch]` demonstrates overriding a git source. Each entry in these tables is a normal dependency specification, the same as found in the `[dependencies]` section of the manifest. The dependencies listed @@ -829,6 +871,7 @@ technical specification of this feature. [RFC 1969]: https://github.com/rust-lang/rfcs/pull/1969 +[crates.io]: https://crates.io/ [replace]: reference/specifying-dependencies.html#overriding-dependencies ### The `[replace]` Section @@ -842,13 +885,13 @@ "bar:1.0.2" = { path = 'my/local/bar' } ``` -Each key in the `[replace]` table is a [package id -specification](reference/pkgid-spec.html) which allows arbitrarily choosing a node in the +Each key in the `[replace]` table is a [package ID +specification](reference/pkgid-spec.html), which allows arbitrarily choosing a node in the dependency graph to override. The value of each key is the same as the `[dependencies]` syntax for specifying dependencies, except that you can't specify features. Note that when a crate is overridden the copy it's overridden with must have both the same name and version, but it can come from a different -source (e.g. git or a local path). +source (e.g., git or a local path). More information about overriding dependencies can be found in the [overriding dependencies][replace] section of the documentation. diff -Nru cargo-0.33.0/src/doc/src/reference/publishing.md cargo-0.35.0/src/doc/src/reference/publishing.md --- cargo-0.33.0/src/doc/src/reference/publishing.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/publishing.md 2019-04-01 21:32:07.000000000 +0000 @@ -21,7 +21,7 @@ ``` This command will inform Cargo of your API token and store it locally in your -`~/.cargo/credentials` (previously it was `~/.cargo/config`). Note that this +`~/.cargo/credentials` (previously it was `~/.cargo/config`). Note that this token is a **secret** and should not be shared with anyone else. If it leaks for any reason, you should regenerate it immediately. @@ -49,7 +49,7 @@ Now’s a good time to take a look at the `*.crate` file to make sure you didn’t accidentally package up that 2GB video asset, or large data files used for code -generation, integration tests, or benchmarking. There is currently a 10MB +generation, integration tests, or benchmarking. There is currently a 10MB upload size limit on `*.crate` files. So, if the size of `tests` and `benches` directories and their dependencies are up to a couple of MBs, you can keep them in your package; otherwise, better to exclude them. @@ -151,21 +151,21 @@ The owner IDs given to these commands must be GitHub user names or GitHub teams. -If a user name is given to `--add`, that user becomes a “named” owner, with +If a user name is given to `--add`, that user is invited as a “named” owner, with full rights to the crate. In addition to being able to publish or yank versions of the crate, they have the ability to add or remove owners, *including* the owner that made *them* an owner. Needless to say, you shouldn’t make people you don’t fully trust into a named owner. In order to become a named owner, a user must have logged into [crates.io] previously. -If a team name is given to `--add`, that team becomes a “team” owner, with +If a team name is given to `--add`, that team is invited as a “team” owner, with restricted right to the crate. While they have permission to publish or yank versions of the crate, they *do not* have the ability to add or remove owners. In addition to being more convenient for managing groups of owners, teams are just a bit more secure against owners becoming malicious. The syntax for teams is currently `github:org:team` (see examples above). -In order to add a team as an owner one must be a member of that team. No +In order to invite a team as an owner one must be a member of that team. No such restriction applies to removing a team as an owner. ### GitHub permissions @@ -203,7 +203,7 @@ https://github.com/organizations/:org/settings/oauth_application_policy -where `:org` is the name of the organization (e.g. rust-lang). You may see +where `:org` is the name of the organization (e.g., `rust-lang`). You may see something like: ![Organization Access Control](images/org-level-acl.png) diff -Nru cargo-0.33.0/src/doc/src/reference/registries.md cargo-0.35.0/src/doc/src/reference/registries.md --- cargo-0.33.0/src/doc/src/reference/registries.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/registries.md 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,590 @@ +## Registries + +Cargo installs crates and fetches dependencies from a "registry". The default +registry is [crates.io]. A registry contains an "index" which contains a +searchable list of available crates. A registry may also provide a web API to +support publishing new crates directly from Cargo. + +> Note: If you are interested in mirroring or vendoring an existing registry, +> take a look at [Source Replacement]. + +### Using an Alternate Registry + +To use a registry other than [crates.io], the name and index URL of the +registry must be added to a [`.cargo/config` file][config]. The `registries` +table has a key for each registry, for example: + +```toml +[registries] +my-registry = { index = "https://my-intranet:8080/git/index" } +``` + +The `index` key should be a URL to a git repository with the registry's index. +A crate can then depend on a crate from another registry by specifying the +`registry` key and a value of the registry's name in that dependency's entry +in `Cargo.toml`: + +```toml +# Sample Cargo.toml +[package] +name = "my-project" +version = "0.1.0" + +[dependencies] +other-crate = { version = "1.0", registry = "my-registry" } +``` + +As with most config values, the index may be specified with an environment +variable instead of a config file. For example, setting the following +environment variable will accomplish the same thing as defining a config file: + +``` +CARGO_REGISTRIES_MY_REGISTRY_INDEX=https://my-intranet:8080/git/index +``` + +> Note: [crates.io] does not accept packages that depend on crates from other +> registries. + +### Publishing to an Alternate Registry + +If the registry supports web API access, then packages can be published +directly to the registry from Cargo. Several of Cargo's commands such as +[`cargo publish`] take a `--registry` command-line flag to indicate which +registry to use. For example, to publish the package in the current directory: + +1. `cargo login --registry=my-registry` + + This only needs to be done once. You must enter the secret API token + retrieved from the registry's website. Alternatively the token may be + passed directly to the `publish` command with the `--token` command-line + flag or an environment variable with the name of the registry such as + `CARGO_REGISTRIES_MY_REGISTRY_TOKEN`. + +2. `cargo publish --registry=my-registry` + +Instead of always passing the `--registry` command-line option, the default +registry may be set in [`.cargo/config`][config] with the `registry.default` +key. + +Setting the `package.publish` key in the `Cargo.toml` manifest restricts which +registries the package is allowed to be published to. This is useful to +prevent accidentally publishing a closed-source package to [crates.io]. The +value may be a list of registry names, for example: + +```toml +[package] +# ... +publish = ["my-registry"] +``` + +The `publish` value may also be `false` to restrict all publishing, which is +the same as an empty list. + +The authentication information saved by [`cargo login`] is stored in the +`credentials` file in the Cargo home directory (default `$HOME/.cargo`). It +has a separate table for each registry, for example: + +```toml +[registries.my-registry] +token = "854DvwSlUwEHtIo3kWy6x7UCPKHfzCmy" +``` + +### Running a Registry + +A minimal registry can be implemented by having a git repository that contains +an index, and a server that contains the compressed `.crate` files created by +[`cargo package`]. Users won't be able to use Cargo to publish to it, but this +may be sufficient for closed environments. + +A full-featured registry that supports publishing will additionally need to +have a web API service that conforms to the API used by Cargo. The web API is +documented below. + +At this time, there is no widely used software for running a custom registry. +There is interest in documenting projects that implement registry support, or +existing package caches that add support for Cargo. + +### Index Format + +The following defines the format of the index. New features are occasionally +added, which are only understood starting with the version of Cargo that +introduced them. Older versions of Cargo may not be able to use packages that +make use of new features. However, the format for older packages should not +change, so older versions of Cargo should be able to use them. + +The index is stored in a git repository so that Cargo can efficiently fetch +incremental updates to the index. In the root of the repository is a file +named `config.json` which contains JSON information used by Cargo for +accessing the registry. This is an example of what the [crates.io] config file +looks like: + +```javascript +{ + "dl": "https://crates.io/api/v1/crates", + "api": "https://crates.io" +} +``` + +The keys are: +- `dl`: This is the URL for downloading crates listed in the index. The value + may have the markers `{crate}` and `{version}` which are replaced with the + name and version of the crate to download. If the markers are not present, + then the value `/{crate}/{version}/download` is appended to the end. +- `api`: This is the base URL for the web API. This key is optional, and if it + is not specified, commands such as [`cargo publish`] will not work. The web + API is described below. + +The download endpoint should send the `.crate` file for the requested package. +Cargo supports https, http, and file URLs, HTTP redirects, HTTP1 and HTTP2. +The exact specifics of TLS support depend on the platform that Cargo is +running on, the version of Cargo, and how it was compiled. + +The rest of the index repository contains one file for each package, where the +filename is the name of the package in lowercase. Each version of the package +has a separate line in the file. The files are organized in a tier of +directories: + +- Packages with 1 character names are placed in a directory named `1`. +- Packages with 2 character names are placed in a directory named `2`. +- Packages with 3 character names are placed in the directory + `3/{first-character}` where `{first-character}` is the first character of + the package name. +- All other packages are stored in directories named + `{first-two}/{second-two}` where the top directory is the first two + characters of the package name, and the next subdirectory is the third and + fourth characters of the package name. For example, `cargo` would be stored + in a file named `ca/rg/cargo`. + +> Note: Although the index filenames are in lowercase, the fields that contain +> package names in `Cargo.toml` and the index JSON data are case-sensitive and +> may contain upper and lower case characters. + +Registries may want to consider enforcing limitations on package names added +to their index. Cargo itself allows names with any [alphanumeric], `-`, or `_` +character. For example, [crates.io] imposes relatively strict limitations, +such as requiring it to be a valid Rust identifier, only allowing ASCII +characters, under a specific length, and rejects reserved names such as +Windows special filenames like "nul". + +Each line in a package file contains a JSON object that describes a published +version of the package. The following is a pretty-printed example with comments +explaining the format of the entry. + +```javascript +{ + // The name of the package. + // This must only contain alphanumeric, `-`, or `_` characters. + "name": "foo", + // The version of the package this row is describing. + // This must be a valid version number according to the Semantic + // Versioning 2.0.0 spec at https://semver.org/. + "vers": "0.1.0", + // Array of direct dependencies of the package. + "deps": [ + { + // Name of the dependency. + // If the dependency is renamed from the original package name, + // this is the new name. The original package name is stored in + // the `package` field. + "name": "rand", + // The semver requirement for this dependency. + // This must be a valid version requirement defined at + // https://github.com/steveklabnik/semver#requirements. + "req": "^0.6", + // Array of features (as strings) enabled for this dependency. + "features": ["i128_support"], + // Boolean of whether or not this is an optional dependency. + "optional": false, + // Boolean of whether or not default features are enabled. + "default_features": true, + // The target platform for the dependency. + // null if not a target dependency. + // Otherwise, a string such as "cfg(windows)". + "target": null, + // The dependency kind. + // "dev", "build", or "normal". + // Note: this is a required field, but a small number of entries + // exist in the crates.io index with either a missing or null + // `kind` field due to implementation bugs. + "kind": "normal", + // The URL of the index of the registry where this dependency is + // from as a string. If not specified or null, it is assumed the + // dependency is in the current registry. + "registry": null, + // If the dependency is renamed, this is a string of the actual + // package name. If not specified or null, this dependency is not + // renamed. + "package": null, + } + ], + // A SHA256 checksum of the `.crate` file. + "cksum": "d867001db0e2b6e0496f9fac96930e2d42233ecd3ca0413e0753d4c7695d289c", + // Set of features defined for the package. + // Each feature maps to an array of features or dependencies it enables. + "features": { + "extras": ["rand/simd_support"] + }, + // Boolean of whether or not this version has been yanked. + "yanked": false, + // The `links` string value from the package's manifest, or null if not + // specified. This field is optional and defaults to null. + "links": null +} +``` + +The JSON objects should not be modified after they are added except for the +`yanked` field whose value may change at any time. + +### Web API + +A registry may host a web API at the location defined in `config.json` to +support any of the actions listed below. + +Cargo includes the `Authorization` header for requests that require +authentication. The header value is the API token. The server should respond +with a 403 response code if the token is not valid. Users are expected to +visit the registry's website to obtain a token, and Cargo can store the token +using the [`cargo login`] command, or by passing the token on the +command-line. + +Responses use a 200 response code for both success and errors. Cargo looks at +the JSON response to determine if there was success or failure. Failure +responses have a JSON object with the following structure: + +```javascript +{ + // Array of errors to display to the user. + "errors": [ + { + // The error message as a string. + "detail": "error message text" + } + ] +} +``` + +Servers may also respond with a 404 response code to indicate the requested +resource is not found (for example, an unknown crate name). However, using a +200 response with an `errors` object allows a registry to provide a more +detailed error message if desired. + +For backwards compatibility, servers should ignore any unexpected query +parameters or JSON fields. If a JSON field is missing, it should be assumed to +be null. The endpoints are versioned with the `v1` component of the path, and +Cargo is responsible for handling backwards compatibility fallbacks should any +be required in the future. + +Cargo sets the following headers for all requests: + +- `Content-Type`: `application/json` +- `Accept`: `application/json` +- `User-Agent`: The Cargo version such as `cargo 1.32.0 (8610973aa + 2019-01-02)`. This may be modified by the user in a configuration value. + Added in 1.29. + +#### Publish + +- Endpoint: `/api/v1/crates/new` +- Method: PUT +- Authorization: Included + +The publish endpoint is used to publish a new version of a crate. The server +should validate the crate, make it available for download, and add it to the +index. + +The body of the data sent by Cargo is: + +- 32-bit unsigned little-endian integer of the length of JSON data. +- Metadata of the package as a JSON object. +- 32-bit unsigned little-endian integer of the length of the `.crate` file. +- The `.crate` file. + +The following is a commented example of the JSON object. Some notes of some +restrictions imposed by [crates.io] are included only to illustrate some +suggestions on types of validation that may be done, and should not be +considered as an exhaustive list of restrictions [crates.io] imposes. + +```javascript +{ + // The name of the package. + "name": "foo", + // The version of the package being published. + "vers": "0.1.0", + // Array of direct dependencies of the package. + "deps": [ + { + // Name of the dependency. + // If the dependency is renamed from the original package name, + // this is the original name. The new package name is stored in + // the `explicit_name_in_toml` field. + "name": "rand", + // The semver requirement for this dependency. + "version_req": "^0.6", + // Array of features (as strings) enabled for this dependency. + "features": ["i128_support"], + // Boolean of whether or not this is an optional dependency. + "optional": false, + // Boolean of whether or not default features are enabled. + "default_features": true, + // The target platform for the dependency. + // null if not a target dependency. + // Otherwise, a string such as "cfg(windows)". + "target": null, + // The dependency kind. + // "dev", "build", or "normal". + "kind": "normal", + // The URL of the index of the registry where this dependency is + // from as a string. If not specified or null, it is assumed the + // dependency is in the current registry. + "registry": null, + // If the dependency is renamed, this is a string of the new + // package name. If not specified or null, this dependency is not + // renamed. + "explicit_name_in_toml": null, + } + ], + // Set of features defined for the package. + // Each feature maps to an array of features or dependencies it enables. + // Cargo does not impose limitations on feature names, but crates.io + // requires alphanumeric ASCII, `_` or `-` characters. + "features": { + "extras": ["rand/simd_support"] + }, + // List of strings of the authors. + // May be empty. crates.io requires at least one entry. + "authors": ["Alice "], + // Description field from the manifest. + // May be null. crates.io requires at least some content. + "description": null, + // String of the URL to the website for this package's documentation. + // May be null. + "documentation": null, + // String of the URL to the website for this package's home page. + // May be null. + "homepage": null, + // String of the content of the README file. + // May be null. + "readme": null, + // String of a relative path to a README file in the crate. + // May be null. + "readme_file": null, + // Array of strings of keywords for the package. + "keywords": [], + // Array of strings of categories for the package. + "categories": [], + // String of the license for the package. + // May be null. crates.io requires either `license` or `license_file` to be set. + "license": null, + // String of a relative path to a license file in the crate. + // May be null. + "license_file": null, + // String of the URL to the website for the source repository of this package. + // May be null. + "repository": null, + // Optional object of "status" badges. Each value is an object of + // arbitrary string to string mappings. + // crates.io has special interpretation of the format of the badges. + "badges": { + "travis-ci": { + "branch": "master", + "repository": "rust-lang/cargo" + } + }, + // The `links` string value from the package's manifest, or null if not + // specified. This field is optional and defaults to null. + "links": null, +} +``` + +A successful response includes the JSON object: + +```javascript +{ + // Optional object of warnings to display to the user. + "warnings": { + // Array of strings of categories that are invalid and ignored. + "invalid_categories": [], + // Array of strings of badge names that are invalid and ignored. + "invalid_badges": [], + // Array of strings of arbitrary warnings to display to the user. + "other": [] + } +} +``` + +#### Yank + +- Endpoint: `/api/v1/crates/{crate_name}/{version}/yank` +- Method: DELETE +- Authorization: Included + +The yank endpoint will set the `yank` field of the given version of a crate to +`true` in the index. + +A successful response includes the JSON object: + +```javascript +{ + // Indicates the delete succeeded, always true. + "ok": true, +} +``` + +#### Unyank + +- Endpoint: `/api/v1/crates/{crate_name}/{version}/unyank` +- Method: PUT +- Authorization: Included + +The unyank endpoint will set the `yank` field of the given version of a crate +to `false` in the index. + +A successful response includes the JSON object: + +```javascript +{ + // Indicates the delete succeeded, always true. + "ok": true, +} +``` + +#### Owners + +Cargo does not have an inherent notion of users and owners, but it does +provide the `owner` command to assist managing who has authorization to +control a crate. It is up to the registry to decide exactly how users and +owners are handled. See the [publishing documentation] for a description of +how [crates.io] handles owners via GitHub users and teams. + +##### Owners: List + +- Endpoint: `/api/v1/crates/{crate_name}/owners` +- Method: GET +- Authorization: Included + +The owners endpoint returns a list of owners of the crate. + +A successful response includes the JSON object: + +```javascript +{ + // Array of owners of the crate. + "users": [ + { + // Unique unsigned 32-bit integer of the owner. + "id": 70, + // The unique username of the owner. + "login": "github:rust-lang:core", + // Name of the owner. + // This is optional and may be null. + "name": "Core", + } + ] +} +``` + +##### Owners: Add + +- Endpoint: `/api/v1/crates/{crate_name}/owners` +- Method: PUT +- Authorization: Included + +A PUT request will send a request to the registry to add a new owner to a +crate. It is up to the registry how to handle the request. For example, +[crates.io] sends an invite to the user that they must accept before being +added. + +The request should include the following JSON object: + +```javascript +{ + // Array of `login` strings of owners to add. + "users": ["login_name"] +} +``` + +A successful response includes the JSON object: + +```javascript +{ + // Indicates the add succeeded, always true. + "ok": true, + // A string to be displayed to the user. + "msg": "user ehuss has been invited to be an owner of crate cargo" +} +``` + +##### Owners: Remove + +- Endpoint: `/api/v1/crates/{crate_name}/owners` +- Method: DELETE +- Authorization: Included + +A DELETE request will remove an owner from a crate. The request should include +the following JSON object: + +```javascript +{ + // Array of `login` strings of owners to remove. + "users": ["login_name"] +} +``` + +A successful response includes the JSON object: + +```javascript +{ + // Indicates the remove succeeded, always true. + "ok": true +} +``` + +#### Search + +- Endpoint: `/api/v1/crates` +- Method: GET +- Query Parameters: + - `q`: The search query string. + - `per_page`: Number of results, default 10, max 100. + +The search request will perform a search for crates, using criteria defined on +the server. + +A successful response includes the JSON object: + +```javascript +{ + // Array of results. + "crates": [ + { + // Name of the crate. + "name": "rand", + // The highest version available. + "max_version": "0.6.1", + // Textual description of the crate. + "description": "Random number generators and other randomness functionality.\n", + } + ], + "meta": { + // Total number of results available on the server. + "total": 119 + } +} +``` + +#### Login + +- Endpoint: `/me` + +The "login" endpoint is not an actual API request. It exists solely for the +[`cargo login`] command to display a URL to instruct a user to visit in a web +browser to log in and retrieve an API token. + +[Source Replacement]: reference/source-replacement.html +[`cargo login`]: commands/cargo-login.html +[`cargo package`]: commands/cargo-package.html +[`cargo publish`]: commands/cargo-publish.html +[alphanumeric]: https://doc.rust-lang.org/std/primitive.char.html#method.is_alphanumeric +[config]: reference/config.html +[crates.io]: https://crates.io/ +[publishing documentation]: reference/publishing.html#cargo-owner diff -Nru cargo-0.33.0/src/doc/src/reference/specifying-dependencies.md cargo-0.35.0/src/doc/src/reference/specifying-dependencies.md --- cargo-0.33.0/src/doc/src/reference/specifying-dependencies.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/specifying-dependencies.md 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,12 @@ ## Specifying Dependencies -Your crates can depend on other libraries from [crates.io], `git` repositories, or -subdirectories on your local file system. You can also temporarily override the -location of a dependency— for example, to be able to test out a bug fix in the -dependency that you are working on locally. You can have different -dependencies for different platforms, and dependencies that are only used during -development. Let's take a look at how to do each of these. +Your crates can depend on other libraries from [crates.io] or other +registries, `git` repositories, or subdirectories on your local file system. +You can also temporarily override the location of a dependency — for example, +to be able to test out a bug fix in the dependency that you are working on +locally. You can have different dependencies for different platforms, and +dependencies that are only used during development. Let's take a look at how +to do each of these. ### Specifying dependencies from crates.io @@ -98,9 +99,23 @@ ### Multiple requirements -Multiple version requirements can also be separated with a comma, e.g. `>= 1.2, +Multiple version requirements can also be separated with a comma, e.g., `>= 1.2, < 1.5`. +### Specifying dependencies from other registries + +To specify a dependency from a registry other than [crates.io], first the +registry must be configured in a `.cargo/config` file. See the [registries +documentation] for more information. In the dependency, set the `registry` key +to the name of the registry to use. + +```toml +[dependencies] +some-crate = { version = "1.0", registry = "my-registry" } +``` + +[registries documentation]: reference/registries.html + ### Specifying dependencies from `git` repositories To depend on a library located in a `git` repository, the minimum information diff -Nru cargo-0.33.0/src/doc/src/reference/unstable.md cargo-0.35.0/src/doc/src/reference/unstable.md --- cargo-0.33.0/src/doc/src/reference/unstable.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/reference/unstable.md 2019-04-01 21:32:07.000000000 +0000 @@ -1,78 +1,25 @@ ## Unstable Features -Experimental Cargo features are only available on the nightly channel. You -typically use one of the `-Z` flags to enable them. Run `cargo -Z help` to +Experimental Cargo features are only available on the nightly channel. You +typically use one of the `-Z` flags to enable them. Run `cargo -Z help` to see a list of flags available. `-Z unstable-options` is a generic flag for enabling other unstable -command-line flags. Options requiring this will be called out below. +command-line flags. Options requiring this will be called out below. Some unstable features will require you to specify the `cargo-features` key in `Cargo.toml`. -### Alternate Registries -* RFC: [#2141](https://github.com/rust-lang/rfcs/blob/master/text/2141-alternative-registries.md) -* Tracking Issue: [rust-lang/rust#44931](https://github.com/rust-lang/rust/issues/44931) - -Alternate registries allow you to use registries other than crates.io. - -The name of a registry is defined in `.cargo/config` under the `registries` -table: - -```toml -[registries] -my-registry = { index = "https://my-intranet:8080/git/index" } -``` - -Authentication information for alternate registries can be added to -`.cargo/credentials`: - -```toml -[registries.my-registry] -token = "api-token" -``` - -Inside `Cargo.toml` you can specify which registry a dependency comes from -using the `registry` key. First you need to include the appropriate -`cargo-features` at the top of the file: - -```toml -cargo-features = ["alternative-registries"] - -[package] -... - -[dependencies] -other-create = { version = "1.0", registry = "my-registry"} -``` - -A `--registry` flag has been added to commands that interact with registries -such as `publish`, `login`, etc. Example: - -``` -cargo +nightly publish -Z unstable-options --registry my-registry -``` - -The `publish` field in `Cargo.toml` has been extended to accept a list of -registries that will restrict publishing only to those registries. - -```toml -[package] -... -publish = ["my-registry"] -``` - - ### publish-lockfile * Original Issue: [#2263](https://github.com/rust-lang/cargo/issues/2263) * PR: [#5093](https://github.com/rust-lang/cargo/pull/5093) * Tracking Issue: [#5654](https://github.com/rust-lang/cargo/issues/5654) When creating a `.crate` file for distribution, Cargo has historically -not included the `Cargo.lock` file. This can cause problems with -using `cargo install` with a binary. You can specify that your package +not included the `Cargo.lock` file. This can cause problems with +using `cargo install` with a binary. You can specify that your package should include the `Cargo.lock` file when using `cargo package` or `cargo publish` -by specifying the `publish-lockfile` key in `Cargo.toml`. This also requires the +by specifying the `publish-lockfile` key in `Cargo.toml`. This also requires the appropriate `cargo-features`: ```toml @@ -89,18 +36,18 @@ * Tracking Issue: [#5655](https://github.com/rust-lang/cargo/issues/5655) The `-Z offline` flag prevents Cargo from attempting to access the network for -any reason. Typically Cargo will stop with an error if it wants to access the +any reason. Typically Cargo will stop with an error if it wants to access the network and it is not available. Beware that this may result in different dependency resolution than online -mode. Cargo will restrict itself to crates that are available locally, even +mode. Cargo will restrict itself to crates that are available locally, even if there might be a newer version as indicated in the local copy of the index. ### no-index-update * Original Issue: [#3479](https://github.com/rust-lang/cargo/issues/3479) The `-Z no-index-update` flag ensures that Cargo does not attempt to update -the registry index. This is intended for tools such as Crater that issue many +the registry index. This is intended for tools such as Crater that issue many Cargo commands, and you want to avoid the network latency for updating the index each time. @@ -110,8 +57,8 @@ When running commands such as `cargo install` or `cargo build`, Cargo currently requires dev-dependencies to be downloaded, even if they are not -used. The `-Z avoid-dev-deps` flag allows Cargo to avoid downloading -dev-dependencies if they are not needed. The `Cargo.lock` file will not be +used. The `-Z avoid-dev-deps` flag allows Cargo to avoid downloading +dev-dependencies if they are not needed. The `Cargo.lock` file will not be generated if dev-dependencies are skipped. ### minimal-versions @@ -132,12 +79,12 @@ * Original Issue: [#4875](https://github.com/rust-lang/cargo/issues/4875) This feature allows you to specify the directory where artifacts will be -copied to after they are built. Typically artifacts are only written to the -`target/release` or `target/debug` directories. However, determining the +copied to after they are built. Typically artifacts are only written to the +`target/release` or `target/debug` directories. However, determining the exact filename can be tricky since you need to parse JSON output. The `--out-dir` flag makes it easier to predictably access the artifacts. Note that the artifacts are copied, so the originals are still in the `target` -directory. Example: +directory. Example: ``` cargo +nightly build --out-dir=out -Z unstable-options @@ -183,9 +130,9 @@ * Tracking Issue: [rust-lang/rust#48683](https://github.com/rust-lang/rust/issues/48683) * RFC: [#2282](https://github.com/rust-lang/rfcs/blob/master/text/2282-profile-dependencies.md) -Profiles can be specified in `.cargo/config` files. The `-Z config-profile` -command-line flag is required to use this feature. The format is the same as -in a `Cargo.toml` manifest. If found in multiple config files, settings will +Profiles can be specified in `.cargo/config` files. The `-Z config-profile` +command-line flag is required to use this feature. The format is the same as +in a `Cargo.toml` manifest. If found in multiple config files, settings will be merged using the regular [config hierarchy](reference/config.html#hierarchical-structure). Config settings take precedence over manifest settings. @@ -255,15 +202,15 @@ * Tracking Issue: [rust-lang/rust#49803](https://github.com/rust-lang/rust/issues/49803) * RFC: [#2196](https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md) -Metabuild is a feature to have declarative build scripts. Instead of writing +Metabuild is a feature to have declarative build scripts. Instead of writing a `build.rs` script, you specify a list of build dependencies in the -`metabuild` key in `Cargo.toml`. A build script is automatically generated -that runs each build dependency in order. Metabuild packages can then read +`metabuild` key in `Cargo.toml`. A build script is automatically generated +that runs each build dependency in order. Metabuild packages can then read metadata from `Cargo.toml` to specify their behavior. -Include `cargo-features` at the top of `Cargo.toml`, a `metadata` key in the +Include `cargo-features` at the top of `Cargo.toml`, a `metabuild` key in the `package`, list the dependencies in `build-dependencies`, and add any metadata -that the metabuild packages require. Example: +that the metabuild packages require under `package.metadata`. Example: ```toml cargo-features = ["metabuild"] diff -Nru cargo-0.33.0/src/doc/src/SUMMARY.md cargo-0.35.0/src/doc/src/SUMMARY.md --- cargo-0.33.0/src/doc/src/SUMMARY.md 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/doc/src/SUMMARY.md 2019-04-01 21:32:07.000000000 +0000 @@ -27,7 +27,44 @@ * [Package ID Specifications](reference/pkgid-spec.md) * [Source Replacement](reference/source-replacement.md) * [External Tools](reference/external-tools.md) + * [Registries](reference/registries.md) * [Unstable Features](reference/unstable.md) +* [Cargo Commands](commands/index.md) + * [Build Commands](commands/build-commands.md) + * [bench](commands/cargo-bench.md) + * [build](commands/cargo-build.md) + * [check](commands/cargo-check.md) + * [clean](commands/cargo-clean.md) + * [doc](commands/cargo-doc.md) + * [fetch](commands/cargo-fetch.md) + * [fix](commands/cargo-fix.md) + * [run](commands/cargo-run.md) + * [rustc](commands/cargo-rustc.md) + * [rustdoc](commands/cargo-rustdoc.md) + * [test](commands/cargo-test.md) + * [Manifest Commands](commands/manifest-commands.md) + * [generate-lockfile](commands/cargo-generate-lockfile.md) + * [locate-project](commands/cargo-locate-project.md) + * [metadata](commands/cargo-metadata.md) + * [pkgid](commands/cargo-pkgid.md) + * [update](commands/cargo-update.md) + * [verify-project](commands/cargo-verify-project.md) + * [Package Commands](commands/package-commands.md) + * [init](commands/cargo-init.md) + * [install](commands/cargo-install.md) + * [new](commands/cargo-new.md) + * [search](commands/cargo-search.md) + * [uninstall](commands/cargo-uninstall.md) + * [Publishing Commands](commands/publishing-commands.md) + * [login](commands/cargo-login.md) + * [owner](commands/cargo-owner.md) + * [package](commands/cargo-package.md) + * [publish](commands/cargo-publish.md) + * [yank](commands/cargo-yank.md) + * [General Commands](commands/general-commands.md) + * [help](commands/cargo-help.md) + * [version](commands/cargo-version.md) + * [FAQ](faq.md) * [Appendix: Glossary](appendix/glossary.md) diff -Nru cargo-0.33.0/src/etc/cargo.bashcomp.sh cargo-0.35.0/src/etc/cargo.bashcomp.sh --- cargo-0.33.0/src/etc/cargo.bashcomp.sh 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/cargo.bashcomp.sh 2019-04-01 21:32:07.000000000 +0000 @@ -8,7 +8,7 @@ # Skip past - and + options to find the command. local nwords=${#words[@]} - local cmd_i cmd + local cmd_i cmd dd_i for (( cmd_i=1; cmd_i<$nwords; cmd_i++ )); do if [[ ! "${words[$cmd_i]}" =~ ^[+-] ]]; then @@ -16,16 +16,24 @@ break fi done + # Find the location of the -- separator. + for (( dd_i=1; dd_i<$nwords-1; dd_i++ )); + do + if [[ "${words[$dd_i]}" = "--" ]]; then + break + fi + done - local vcs='git hg none' + local vcs='git hg none pijul fossil' local color='auto always never' - local msg_format='human json' + local msg_format='human json short' local opt_help='-h --help' local opt_verbose='-v --verbose' local opt_quiet='-q --quiet' local opt_color='--color' local opt_common="$opt_help $opt_verbose $opt_quiet $opt_color" + local opt_pkg_spec='-p --package --all --exclude' local opt_pkg='-p --package' local opt_feat='--features --all-features --no-default-features' local opt_mani='--manifest-path' @@ -33,40 +41,51 @@ local opt_force='-f --force' local opt_test='--test --bench' local opt_lock='--frozen --locked' + local opt_targets="--lib --bin --bins --example --examples --test --tests --bench --benches --all-targets" - local opt___nocmd="$opt_common -V --version --list" - local opt__bench="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --no-run" - local opt__build="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release" - local opt__check="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release" - local opt__clean="$opt_common $opt_pkg $opt_mani $opt_lock --target --release" - local opt__doc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --bin --lib --target --open --no-deps --release" + local opt___nocmd="$opt_common -V --version --list --explain" + local opt__bench="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --target --no-run --no-fail-fast --target-dir" + local opt__build="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --target --release --target-dir" + local opt__check="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --target --release --profile --target-dir" + local opt__clean="$opt_common $opt_pkg $opt_mani $opt_lock --target --release --doc --target-dir" + local opt__doc="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --bin --bins --lib --target --open --no-deps --release --document-private-items --target-dir" local opt__fetch="$opt_common $opt_mani $opt_lock" + local opt__fix="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_jobs $opt_targets $opt_lock --release --target --message-format --prepare-for --broken-code --edition --edition-idioms --allow-no-vcs --allow-dirty --allow-staged --profile --target-dir" local opt__generate_lockfile="${opt__fetch}" local opt__git_checkout="$opt_common $opt_lock --reference --url" local opt__help="$opt_help" - local opt__init="$opt_common $opt_lock --bin --lib --name --vcs" - local opt__install="$opt_common $opt_feat $opt_jobs $opt_lock $opt_force --bin --branch --debug --example --git --list --path --rev --root --tag --vers" + local opt__init="$opt_common $opt_lock --bin --lib --name --vcs --edition --registry" + local opt__install="$opt_common $opt_feat $opt_jobs $opt_lock $opt_force --bin --bins --branch --debug --example --examples --git --list --path --rev --root --tag --version --registry --target" local opt__locate_project="$opt_mani -h --help" - local opt__login="$opt_common $opt_lock --host" - local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version --no-deps" - local opt__new="$opt_common $opt_lock --vcs --bin --lib --name" - local opt__owner="$opt_common $opt_lock -a --add -r --remove -l --list --index --token" - local opt__package="$opt_common $opt_mani $opt_lock $opt_jobs --allow-dirty -l --list --no-verify --no-metadata" + local opt__login="$opt_common $opt_lock --host --registry" + local opt__metadata="$opt_common $opt_feat $opt_mani $opt_lock --format-version=1 --no-deps" + local opt__new="$opt_common $opt_lock --vcs --bin --lib --name --edition --registry" + local opt__owner="$opt_common $opt_lock -a --add -r --remove -l --list --index --token --registry" + local opt__package="$opt_common $opt_mani $opt_feat $opt_lock $opt_jobs --allow-dirty -l --list --no-verify --no-metadata --target --target-dir" local opt__pkgid="${opt__fetch} $opt_pkg" - local opt__publish="$opt_common $opt_mani $opt_lock $opt_jobs --allow-dirty --dry-run --host --token --no-verify" - local opt__read_manifest="$opt_help $opt_verbose $opt_mani $opt_color --no-deps" - local opt__run="$opt_common $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --target --bin --example --release" - local opt__rustc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --profile --target --lib --bin --example --release" - local opt__rustdoc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --target --lib --bin --example --release --open" - local opt__search="$opt_common $opt_lock --host --limit" - local opt__test="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test --message-format --all --doc --target --lib --bin --example --no-run --release --no-fail-fast" - local opt__uninstall="$opt_common $opt_lock --bin --root" - local opt__update="$opt_common $opt_pkg $opt_mani $opt_lock --aggressive --precise" + local opt__publish="$opt_common $opt_mani $opt_feat $opt_lock $opt_jobs --allow-dirty --dry-run --host --token --no-verify --index --registry --target --target-dir" + local opt__read_manifest="$opt_help $opt_quiet $opt_verbose $opt_mani $opt_color " + local opt__run="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs --message-format --target --bin --example --release --target-dir" + local opt__rustc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --profile --target --release --target-dir" + local opt__rustdoc="$opt_common $opt_pkg $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --target --release --open --target-dir" + local opt__search="$opt_common $opt_lock --host --limit --index --limit --registry" + local opt__test="$opt_common $opt_pkg_spec $opt_feat $opt_mani $opt_lock $opt_jobs $opt_test $opt_targets --message-format --doc --target --no-run --release --no-fail-fast --target-dir" + local opt__uninstall="$opt_common $opt_lock $opt_pkg_spec --bin --root" + local opt__update="$opt_common $opt_pkg_spec $opt_mani $opt_lock --aggressive --precise --dry-run" local opt__verify_project="${opt__fetch}" local opt__version="$opt_help $opt_verbose $opt_color" - local opt__yank="$opt_common $opt_lock --vers --undo --index --token" + local opt__yank="$opt_common $opt_lock --vers --undo --index --token --registry" + local opt__libtest="--help --include-ignored --ignored --test --bench --list --logfile --nocapture --test-threads --skip -q --quiet --exact --color --format" - if [[ $cmd_i -ge $nwords-1 ]]; then + if [[ $cword -gt $dd_i ]]; then + # Completion after -- separator. + if [[ "${cmd}" = @(test|bench) ]]; then + COMPREPLY=( $( compgen -W "${opt__libtest}" -- "$cur" ) ) + else + # Fallback to filename completion, useful with `cargo run`. + _filedir + fi + elif [[ $cword -le $cmd_i ]]; then # Completion before or at the command. if [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W "${opt___nocmd}" -- "$cur" ) ) @@ -104,12 +123,20 @@ --target) COMPREPLY=( $( compgen -W "$(_get_targets)" -- "$cur" ) ) ;; + --target-dir) + _filedir -d + ;; help) COMPREPLY=( $( compgen -W "$__cargo_commands" -- "$cur" ) ) ;; *) local opt_var=opt__${cmd//-/_} - COMPREPLY=( $( compgen -W "${!opt_var}" -- "$cur" ) ) + if [[ -z "${!opt_var}" ]]; then + # Fallback to filename completion. + _filedir + else + COMPREPLY=( $( compgen -W "${!opt_var}" -- "$cur" ) ) + fi ;; esac fi @@ -120,7 +147,7 @@ } && complete -F _cargo cargo -__cargo_commands=$(cargo --list 2>/dev/null | tail -n +2) +__cargo_commands=$(cargo --list 2>/dev/null | awk 'NR>1 {print $1}') _locate_manifest(){ local manifest=`cargo locate-project 2>/dev/null` @@ -184,7 +211,10 @@ } _get_examples(){ - local files=($(dirname $(_locate_manifest))/examples/*.rs) + local manifest=$(_locate_manifest) + [ -z "$manifest" ] && return 0 + + local files=("${manifest%/*}"/examples/*.rs) local names=("${files[@]##*/}") local names=("${names[@]%.*}") # "*" means no examples found @@ -194,31 +224,15 @@ } _get_targets(){ - local CURRENT_PATH - if [ `uname -o` == "Cygwin" -a -f "$PWD"/Cargo.toml ]; then - CURRENT_PATH=$PWD - else - CURRENT_PATH=$(_locate_manifest) - fi - if [[ -z "$CURRENT_PATH" ]]; then - return 1 - fi - local TARGETS=() - local FIND_PATHS=( "/" ) - local FIND_PATH LINES LINE - while [[ "$CURRENT_PATH" != "/" ]]; do - FIND_PATHS+=( "$CURRENT_PATH" ) - CURRENT_PATH=$(dirname $CURRENT_PATH) - done - for FIND_PATH in ${FIND_PATHS[@]}; do - if [[ -f "$FIND_PATH"/.cargo/config ]]; then - LINES=( `grep "$FIND_PATH"/.cargo/config -e "^\[target\."` ) - for LINE in ${LINES[@]}; do - TARGETS+=(`sed 's/^\[target\.\(.*\)\]$/\1/' <<< $LINE`) - done + local result=() + local targets=$(rustup target list) + while read line + do + if [[ "$line" =~ default|installed ]]; then + result+=("${line%% *}") fi - done - echo "${TARGETS[@]}" + done <<< "$targets" + echo "${result[@]}" } _toolchains(){ diff -Nru cargo-0.33.0/src/etc/man/cargo.1 cargo-0.35.0/src/etc/man/cargo.1 --- cargo-0.33.0/src/etc/man/cargo.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,206 +1,473 @@ -.TH "CARGO" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-02-05 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO" "1" "2019-02-05" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo \- The Rust package manager -.SH SYNOPSIS -.PP -\f[I]cargo\f[] [...] -.SH DESCRIPTION -.PP -This program is a package manager for the Rust language, available at -. -.SH OPTIONS -.TP -.B \-h, \-\-help -Display a help message. -.RS -.RE -.TP -.B \-V, \-\-version -Print version information and exit. -.RS -.RE -.TP -.B \-\-list -List all available cargo commands. -.RS -.RE -.TP -.B \-\-explain CODE -Run \f[C]rustc\ \-\-explain\ CODE\f[] -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-\-color -Configure coloring of output. -.RS -.RE -.SH COMMANDS -.PP -To get extended information about commands, run \f[I]cargo help -\f[] or \f[I]man cargo\-command\f[] -.TP -.B cargo\-build(1) -Compile the current package. -.RS -.RE -.TP -.B cargo\-clean(1) -Remove the target directory with build output. -.RS -.RE -.TP -.B cargo\-doc(1) -Build this package\[aq]s and its dependencies\[aq] documentation. -.RS -.RE -.TP -.B cargo\-init(1) -Create a new cargo package in the current directory. -.RS -.RE -.TP -.B cargo\-install(1) -Install a Rust binary. -.RS -.RE -.TP -.B cargo\-new(1) -Create a new cargo package. -.RS -.RE -.TP -.B cargo\-run(1) -Build and execute src/main.rs. -.RS -.RE -.TP -.B cargo\-test(1) -Run the tests for the package. -.RS -.RE -.TP -.B cargo\-bench(1) -Run the benchmarks for the package. -.RS -.RE -.TP -.B cargo\-update(1) -Update dependencies in Cargo.lock. -.RS -.RE -.TP -.B cargo\-rustc(1) -Compile the current package, and optionally pass additional rustc parameters -.RS -.RE -.TP -.B cargo\-package(1) -Generate a source tarball for the current package. -.RS -.RE -.TP -.B cargo\-publish(1) -Package and upload this package to the registry. -.RS +.SH "SYNOPSIS" +.sp +\fBcargo [\fIOPTIONS\fP] \fICOMMAND\fP [\fIARGS\fP]\fP +.br +\fBcargo [\fIOPTIONS\fP] \-\-version\fP +.br +\fBcargo [\fIOPTIONS\fP] \-\-list\fP +.br +\fBcargo [\fIOPTIONS\fP] \-\-help\fP +.br +\fBcargo [\fIOPTIONS\fP] \-\-explain \fICODE\fP\fP +.SH "DESCRIPTION" +.sp +This program is a package manager and build tool for the Rust language, +available at \c +.URL "http://rust\-lang.org" "" "." +.SH "COMMANDS" +.SS "Build Commands" +.sp +\fBcargo\-bench\fP(1) +.RS 4 +Execute benchmarks of a package. +.RE +.sp +\fBcargo\-build\fP(1) +.RS 4 +Compile a package. +.RE +.sp +\fBcargo\-check\fP(1) +.RS 4 +Check a local package and all of its dependencies for errors. +.RE +.sp +\fBcargo\-clean\fP(1) +.RS 4 +Remove artifacts that Cargo has generated in the past. +.RE +.sp +\fBcargo\-doc\fP(1) +.RS 4 +Build a package\(cqs documentation. +.RE +.sp +\fBcargo\-fetch\fP(1) +.RS 4 +Fetch dependencies of a package from the network. +.RE +.sp +\fBcargo\-fix\fP(1) +.RS 4 +Automatically fix lint warnings reported by rustc. +.RE +.sp +\fBcargo\-run\fP(1) +.RS 4 +Run a binary or example of the local package. +.RE +.sp +\fBcargo\-rustc\fP(1) +.RS 4 +Compile a package, and pass extra options to the compiler. +.RE +.sp +\fBcargo\-rustdoc\fP(1) +.RS 4 +Build a package\(cqs documentation, using specified custom flags. +.RE +.sp +\fBcargo\-test\fP(1) +.RS 4 +Execute unit and integration tests of a package. +.RE +.SS "Manifest Commands" +.sp +\fBcargo\-generate\-lockfile\fP(1) +.RS 4 +Generate \fBCargo.lock\fP for a project. +.RE +.sp +\fBcargo\-locate\-project\fP(1) +.RS 4 +Print a JSON representation of a \fBCargo.toml\fP file\(cqs location. +.RE +.sp +\fBcargo\-metadata\fP(1) +.RS 4 +Output the resolved dependencies of a package, the concrete used versions +including overrides, in machine\-readable format. +.RE +.sp +\fBcargo\-pkgid\fP(1) +.RS 4 +Print a fully qualified package specification. +.RE +.sp +\fBcargo\-update\fP(1) +.RS 4 +Update dependencies as recorded in the local lock file. +.RE +.sp +\fBcargo\-verify\-project\fP(1) +.RS 4 +Check correctness of crate manifest. +.RE +.SS "Package Commands" +.sp +\fBcargo\-init\fP(1) +.RS 4 +Create a new Cargo package in an existing directory. +.RE +.sp +\fBcargo\-install\fP(1) +.RS 4 +Build and install a Rust binary. +.RE +.sp +\fBcargo\-new\fP(1) +.RS 4 +Create a new Cargo package. +.RE +.sp +\fBcargo\-search\fP(1) +.RS 4 +Search packages in crates.io. +.RE +.sp +\fBcargo\-uninstall\fP(1) +.RS 4 +Remove a Rust binary. .RE -.TP -.B cargo\-owner(1) +.SS "Publishing Commands" +.sp +\fBcargo\-login\fP(1) +.RS 4 +Save an API token from the registry locally. +.RE +.sp +\fBcargo\-owner\fP(1) +.RS 4 Manage the owners of a crate on the registry. -.RS -.RE -.TP -.B cargo\-uninstall(1) -Remove a Rust binary. -.RS .RE -.TP -.B cargo\-search(1) -Search registry for crates. -.RS -.RE -.TP -.B cargo\-help(1) -Display help for a cargo command -.RS -.RE -.TP -.B cargo\-version(1) -Print cargo\[aq]s version and exit. -.RS -.RE -.SH FILES -.TP -.B ~/.cargo -Directory in which Cargo stores repository data. -Cargo can be instructed to use a \f[I]\&.cargo\f[] subdirectory in a -different location by setting the \f[B]CARGO_HOME\f[] environment +.sp +\fBcargo\-package\fP(1) +.RS 4 +Assemble the local package into a distributable tarball. +.RE +.sp +\fBcargo\-publish\fP(1) +.RS 4 +Upload a package to the registry. +.RE +.sp +\fBcargo\-yank\fP(1) +.RS 4 +Remove a pushed crate from the index. +.RE +.SS "General Commands" +.sp +\fBcargo\-help\fP(1) +.RS 4 +Display help information about Cargo. +.RE +.sp +\fBcargo\-version\fP(1) +.RS 4 +Show version information. +.RE +.SH "OPTIONS" +.SS "Special Options" +.sp +\fB\-V\fP, \fB\-\-version\fP +.RS 4 +Print version info and exit. If used with \fB\-\-verbose\fP, prints extra +information. +.RE +.sp +\fB\-\-list\fP +.RS 4 +List all installed Cargo subcommands. If used with \fB\-\-verbose\fP, prints +extra information. +.RE +.sp +\fB\-\-explain \fICODE\fP\fP +.RS 4 +Run \fBrustc \-\-explain CODE\fP which will print out a detailed explanation of +an error message (for example, \fBE0004\fP). +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 +No output printed to stdout. +.RE +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "FILES" +.sp +\fB~/.cargo/\fP +.RS 4 +Default location for Cargo\(cqs "home" directory where it stores various +files. The location can be changed with the \fBCARGO_HOME\fP environment variable. -.RS .RE -.SH EXAMPLES -.PP -Build a local package and all of its dependencies -.IP -.nf -\f[C] -$\ cargo\ build -\f[] -.fi -.PP -Build a package with optimizations -.IP -.nf -\f[C] -$\ cargo\ build\ \-\-release -\f[] -.fi -.PP -Run tests for a cross\-compiled target -.IP -.nf -\f[C] -$\ cargo\ test\ \-\-target\ i686\-unknown\-linux\-gnu -\f[] -.fi -.PP -Create a new package that builds an executable -.IP -.nf -\f[C] -$\ cargo\ new\ \-\-bin\ foobar -\f[] -.fi -.PP -Create a package in the current directory -.IP -.nf -\f[C] -$\ mkdir\ foo\ &&\ cd\ foo -$\ cargo\ init\ . -\f[] -.fi -.PP -Learn about a command\[aq]s options and usage -.IP -.nf -\f[C] -$\ cargo\ help\ clean -\f[] -.fi -.SH SEE ALSO -.PP -rustc(1), rustdoc(1) -.SH BUGS -.PP -See for issues. -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB$CARGO_HOME/bin/\fP +.RS 4 +Binaries installed by \fBcargo\-install\fP(1) will be located here. If using +rustup, executables distributed with Rust are also located here. +.RE +.sp +\fB$CARGO_HOME/config\fP +.RS 4 +The global configuration file. See \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "the reference" +for more information about configuration files. +.RE +.sp +\fB.cargo/config\fP +.RS 4 +Cargo automatically searches for a file named \fB.cargo/config\fP in the +current directory, and all parent directories. These configuration files +will be merged with the global configuration file. +.RE +.sp +\fB$CARGO_HOME/credentials\fP +.RS 4 +Private authentication information for logging in to a registry. +.RE +.sp +\fB$CARGO_HOME/registry/\fP +.RS 4 +This directory contains cached downloads of the registry index and any +downloaded dependencies. +.RE +.sp +\fB$CARGO_HOME/git/\fP +.RS 4 +This directory contains cached downloads of git dependencies. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build a local package and all of its dependencies: +.sp +.if n .RS 4 +.nf +cargo build +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Build a package with optimizations: +.sp +.if n .RS 4 +.nf +cargo build \-\-release +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Run tests for a cross\-compiled target: +.sp +.if n .RS 4 +.nf +cargo test \-\-target i686\-unknown\-linux\-gnu +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 4." 4.2 +.\} +Create a new package that builds an executable: +.sp +.if n .RS 4 +.nf +cargo new foobar +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 5.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 5." 4.2 +.\} +Create a package in the current directory: +.sp +.if n .RS 4 +.nf +mkdir foo && cd foo +cargo init . +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 6.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 6." 4.2 +.\} +Learn about a command\(cqs options and usage: +.sp +.if n .RS 4 +.nf +cargo help clean +.fi +.if n .RE +.RE +.SH "BUGS" +.sp +See \c +.URL "https://github.com/rust\-lang/cargo/issues" "" " " +for issues. +.SH "SEE ALSO" +.sp +\fBrustc\fP(1), \fBrustdoc\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-bench.1 cargo-0.35.0/src/etc/man/cargo-bench.1 --- cargo-0.33.0/src/etc/man/cargo-bench.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-bench.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,143 +1,501 @@ -.TH "CARGO\-BENCH" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-bench +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-BENCH" "1" "2018-12-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-bench \- Execute benchmarks of a package -.SH SYNOPSIS -.PP -\f[I]cargo bench\f[] [OPTIONS] [\-\-] [...] -.SH DESCRIPTION -.PP -Execute all benchmarks of a local package. -.PP -All of the trailing arguments are passed to the benchmark binaries -generated for filtering benchmarks and generally providing options -configuring how they run. -.PP -If the \f[B]\-\-package\f[] argument is given, then \f[I]SPEC\f[] is a -package id specification which indicates which package should be built. -If it is not given, then the current package is built. -For more information on \f[I]SPEC\f[] and its format, see the "cargo -help pkgid" command. -.PP -The \f[B]\-\-jobs\f[] argument affects the building of the benchmark -executable but does not affect how many jobs are used when running the -benchmarks. -.PP -Compilation can be customized with the \[aq]bench\[aq] profile in the +.SH "SYNOPSIS" +.sp +\fBcargo bench [\fIOPTIONS\fP] [BENCHNAME] [\-\- \fIBENCH\-OPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Compile and execute benchmarks. +.sp +The benchmark filtering argument \fBBENCHNAME\fP and all the arguments following +the two dashes (\fB\-\-\fP) are passed to the benchmark binaries and thus to +\fIlibtest\fP (rustc\(cqs built in unit\-test and micro\-benchmarking framework). If +you\(cqre passing arguments to both Cargo and the binary, the ones after \fB\-\-\fP go +to the binary, the ones before go to Cargo. For details about libtest\(cqs +arguments see the output of \fBcargo bench \(em \-\-help\fP. As an example, this will +run only the benchmark named \fBfoo\fP (and skip other similarly named benchmarks +like \fBfoobar\fP): +.sp +.if n .RS 4 +.nf +cargo bench \-\- foo \-\-exact +.fi +.if n .RE +.sp +Benchmarks are built with the \fB\-\-test\fP option to \fBrustc\fP which creates an +executable with a \fBmain\fP function that automatically runs all functions +annotated with the \fB#[bench]\fP attribute. Cargo passes the \fB\-\-bench\fP flag to +the test harness to tell it to run only benchmarks. +.sp +The libtest harness may be disabled by setting \fBharness = false\fP in the target +manifest settings, in which case your code will need to provide its own \fBmain\fP +function to handle running benchmarks. +.SH "OPTIONS" +.SS "Benchmark Options" +.sp +\fB\-\-no\-run\fP +.RS 4 +Compile, but don\(cqt run benchmarks. +.RE +.sp +\fB\-\-no\-fail\-fast\fP +.RS 4 +Run all benchmarks regardless of failure. Without this flag, Cargo will exit +after the first executable fails. The Rust test harness will run all +benchmarks within the executable to completion, this flag only applies to +the executable as a whole. +.RE +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP manifest. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-lib -Benchmark only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Benchmark only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Benchmark only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Benchmark only the specified test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Benchmark only the specified bench target. -.RS -.RE -.TP -.B \-\-no\-run -Compile, but don\[aq]t run benchmarks. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to benchmarks for. -.RS -.RE -.TP -.B \-j \f[I]IN\f[], \-\-jobs \f[I]IN\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also build. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Benchmark only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Benchmark all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo bench\fP will build the +following targets of the selected packages: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +lib — used to link with binaries and benchmarks +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +bins (only if benchmark targets are built and required features are +available) +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +lib as a benchmark +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +bins as benchmarks +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +benchmark targets +.RE +.sp +The default behavior can be changed by setting the \fBbench\fP flag for the target +in the manifest settings. Setting examples to \fBbench = true\fP will build and +run the example as a benchmark. Setting targets to \fBbench = false\fP will stop +them from being benchmarked by default. Target selection options that take a +target by name ignore the \fBbench\fP flag and will always benchmark the given +target. +.sp +Passing target selection flags will benchmark only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Benchmark the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Benchmark the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Benchmark all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Benchmark the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Benchmark all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Benchmark the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Benchmark all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Benchmark the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Benchmark all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Benchmark all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Benchmark for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +By default the Rust test harness hides output from benchmark execution to keep +results readable. Benchmark output can be recovered (e.g., for debugging) by +passing \fB\-\-nocapture\fP to the benchmark binaries: +.sp +.if n .RS 4 +.nf +cargo bench \-\- \-\-nocapture +.fi +.if n .RE +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Execute all the benchmarks of the current package -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +The \fB\-\-jobs\fP argument affects the building of the benchmark executable but +does not affect how many threads are used when running the benchmarks. The +Rust test harness runs benchmarks serially in a single thread. +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Benchmarks are always built with the \fBbench\fP profile. Binary and lib targets +are built separately as benchmarks with the \fBbench\fP profile. Library targets +are built with the \fBrelease\fP profiles when linked to binaries and benchmarks. +Dependencies use the \fBrelease\fP profile. +.sp +If you need a debug build of a benchmark, try building it with +\fBcargo\-build\fP(1) which will use the \fBtest\fP profile which is by default +unoptimized and includes debug information. You can then run the debug\-enabled +benchmark manually. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build and execute all the benchmarks of the current package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ bench -\f[] +cargo bench .fi -.PP -Execute the BENCH benchmark -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Run only a specific benchmark within a specific benchmark target: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ bench\ \-\-bench\ BENCH -\f[] +cargo bench \-\-bench bench_name \-\- modname::some_benchmark .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-build(1), cargo\-test(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-test\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-build.1 cargo-0.35.0/src/etc/man/cargo-build.1 --- cargo-0.33.0/src/etc/man/cargo-build.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-build.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,132 +1,443 @@ -.TH "CARGO\-BUILD" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-build +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-BUILD" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-build \- Compile the current package -.SH SYNOPSIS -.PP -\f[I]cargo build\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Compile a local package and all of its dependencies. -.PP -If the \f[B]\-\-package\f[] argument is given, then \f[I]SPEC\f[] is a -package id specification which indicates which package should be built. -If it is not given, then the current package is built. -For more information on \f[I]SPEC\f[] and its format, see the "cargo -help pkgid" command. -.PP -Compilation can be configured via the use of profiles which are -configured in the manifest. -The default profile for this command is \f[I]dev\f[], but passing the -\f[B]\-\-release\f[] flag will use the \f[I]release\f[] profile instead. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to build. -.RS -.RE -.TP -.B \-j \f[I]IN\f[], \-\-jobs \f[I]IN\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-lib -Build only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Build only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Build only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Build only the specified test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Build only the specified benchmark target. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also build. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.SH "SYNOPSIS" +.sp +\fBcargo build [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Compile local packages and all of their dependencies. +.SH "OPTIONS" +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP +manifest. +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Build only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Build all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo build\fP will build all +binary and library targets of the selected packages. Binaries are skipped if +they have \fBrequired\-features\fP that are missing. +.sp +Passing target selection flags will build only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Build the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Build the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Build all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Build the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Build all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Build the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Build all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Build the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Build all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Build for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Build optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.sp +\fB\-\-out\-dir\fP \fIDIRECTORY\fP +.RS 4 +Copy final artifacts to this directory. +.sp +This option is unstable and available only on the nightly channel and requires +the \fB\-Z unstable\-options\fP flag to enable. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Build a local package and all of its dependencies -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.sp +\fB\-\-build\-plan\fP +.RS 4 +Outputs a series of JSON messages to stdout that indicate the commands to +run the build. +.sp +This option is unstable and available only on the nightly channel and requires +the \fB\-Z unstable\-options\fP flag to enable. +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build the local package and all of its dependencies: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ build -\f[] +cargo build .fi -.PP -Build a package with optimizations -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Build with optimizations: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ build\ \-\-release -\f[] +cargo build \-\-release .fi -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-rustc\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-check.1 cargo-0.35.0/src/etc/man/cargo-check.1 --- cargo-0.33.0/src/etc/man/cargo-check.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-check.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,132 +1,439 @@ -.TH "CARGO\-CHECK" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-check +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-CHECK" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-check \- Check the current package -.SH SYNOPSIS -.PP -\f[I]cargo check\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Check a local package and all of its dependencies. -.PP -If the \f[B]\-\-package\f[] argument is given, then \f[I]SPEC\f[] is a -package id specification which indicates which package should be checked. -If it is not given, then the current package is checked. -For more information on \f[I]SPEC\f[] and its format, see the "cargo -help pkgid" command. -.PP -Compilation can be configured via the use of profiles which are -configured in the manifest. -The default profile for this command is \f[I]dev\f[], but passing the -\f[B]\-\-release\f[] flag will use the \f[I]release\f[] profile instead. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to check. -.RS -.RE -.TP -.B \-j \f[I]IN\f[], \-\-jobs \f[I]IN\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-lib -Check only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Check only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Check only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Check only the specified test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Check only the specified benchmark target. -.RS -.RE -.TP -.B \-\-release -Check artifacts in release mode. -.RS -.RE -.TP -.B \-\-all\-features -Check with all available features. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also check. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not check the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Check for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.SH "SYNOPSIS" +.sp +\fBcargo check [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Check a local package and all of its dependencies for errors. This will +essentially compile the packages without performing the final step of code +generation, which is faster than running \fBcargo build\fP. The compiler will save +metadata files to disk so that future runs will reuse them if the source has +not been modified. +.SH "OPTIONS" +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP +manifest. +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Check only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Check all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo check\fP will check all +binary and library targets of the selected packages. Binaries are skipped if +they have \fBrequired\-features\fP that are missing. +.sp +Passing target selection flags will check only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Check the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Check the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Check all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Check the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Check all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Check the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Check all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Check the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Check all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Check all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Check for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Check optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.sp +\fB\-\-profile\fP \fINAME\fP +.RS 4 +Changes check behavior. Currently only \fBtest\fP is +supported, which will check with the +\fB#[cfg(test)]\fP attribute enabled. This is useful to have it +check unit tests which are usually excluded via +the \fBcfg\fP attribute. This does not change the actual profile used. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Check a local package and all of its dependencies -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Check the local package for errors: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ check -\f[] +cargo check .fi -.PP -Check a package with optimizations -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Check all targets, including unit tests: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ check\ \-\-release -\f[] +cargo check \-\-all\-targets \-\-profile=test .fi -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-build\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-clean.1 cargo-0.35.0/src/etc/man/cargo-clean.1 --- cargo-0.33.0/src/etc/man/cargo-clean.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-clean.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,82 +1,227 @@ -.TH "CARGO\-CLEAN" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-clean +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-CLEAN" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-clean \- Remove generated artifacts -.SH SYNOPSIS -.PP -\f[I]cargo clean\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Remove artifacts that cargo has generated in the past. -.PP -If the \f[B]\-\-package\f[] argument is given, then \f[I]SPEC\f[] is a -package id specification which indicates which package should be built. -If it is not given, then the current package is built. -For more information on \f[I]SPEC\f[] and its format, see the "cargo -help pkgid" command. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to clean artifacts for. -.RS -.RE -.TP -.B \-\-manifest\-path PATH -Path to the manifest to the package to clean. -.RS -.RE -.TP -.B \-\-target TRIPLE -Target triple to clean output for (default all). -.RS -.RE -.TP -.B \-\-release -Whether or not to clean release artifacts. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.SH "SYNOPSIS" +.sp +\fBcargo clean [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Remove artifacts from the target directory that Cargo has generated in the +past. +.sp +With no options, \fBcargo clean\fP will delete the entire target directory. +.SH "OPTIONS" +.SS "Package Selection" +.sp +When no packages are selected, all packages and all dependencies in the +workspace are cleaned. +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Clean only the specified packages. This flag may be specified +multiple times. See \fBcargo\-pkgid\fP(1) for the SPEC format. +.RE +.SS "Clean Options" +.sp +\fB\-\-doc\fP +.RS 4 +This option will cause \fBcargo clean\fP to remove only the \fBdoc\fP directory in +the target directory. +.RE +.sp +\fB\-\-release\fP +.RS 4 +Clean all artifacts that were built with the \fBrelease\fP or \fBbench\fP +profiles. +.RE +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Clean for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Remove local package generated artifacts -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Remove the entire target directory: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ clean -\f[] +cargo clean .fi -.PP -Clean release artifacts -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Remove only the release artifacts: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ clean\ \-\-release -\f[] +cargo clean \-\-release .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-build(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-build\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-doc.1 cargo-0.35.0/src/etc/man/cargo-doc.1 --- cargo-0.33.0/src/etc/man/cargo-doc.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-doc.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,109 +1,380 @@ -.TH "CARGO\-DOC" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-doc \- Build a package\[aq]s documentation -.SH SYNOPSIS -.PP -\f[I]cargo doc\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Build a package\[aq]s documentation. -.PP -By default the documentation for the local package and all dependencies -is built. -The output is all placed in \[aq]target/doc\[aq] in rustdoc\[aq]s usual -format. -.PP -If the \f[B]\-\-package\f[] argument is given, then \f[I]SPEC\f[] is a -package id specification which indicates which package should be built. -If it is not given, then the current package is built. -For more information on \f[I]SPEC\f[] and its format, see the "cargo -help pkgid" command. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to document. -.RS -.RE -.TP -.B \-\-open -Opens the docs in a browser after the operation. -.RS -.RE -.TP -.B \-\-no\-deps -Don\[aq]t build documentation for dependencies. -.RS -.RE -.TP -.B \-j \f[I]N\f[], \-\-jobs \f[I]N\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also build. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +'\" t +.\" Title: cargo-doc +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-DOC" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-doc \- Build a package\(aqs documentation +.SH "SYNOPSIS" +.sp +\fBcargo doc [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Build the documentation for the local package and all dependencies. The output +is placed in \fBtarget/doc\fP in rustdoc\(cqs usual format. +.SH "OPTIONS" +.SS "Documentation Options" +.sp +\fB\-\-open\fP +.RS 4 +Open the docs in a browser after building them. +.RE +.sp +\fB\-\-no\-deps\fP +.RS 4 +Do not build documentation for dependencies. +.RE +.sp +\fB\-\-document\-private\-items\fP +.RS 4 +Include non\-public items in the documentation. +.RE +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP +manifest. +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Document only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Document all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo doc\fP will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +\fBrequired\-features\fP that are missing. +.sp +The default behavior can be changed by setting \fBdoc = false\fP for the target in +the manifest settings. Using target selection options will ignore the \fBdoc\fP +flag and will always document the given target. +.sp +\fB\-\-lib\fP +.RS 4 +Document the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Document the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Document all binary targets. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Document for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Document optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Build a local package documentation in \[aq]target/doc\[aq] -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build the local package documentation and its dependencies and output to +\fBtarget/doc\fP. +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ doc -\f[] +cargo doc .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-build(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-rustdoc\fP(1), \fBrustdoc\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-fetch.1 cargo-0.35.0/src/etc/man/cargo-fetch.1 --- cargo-0.33.0/src/etc/man/cargo-fetch.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-fetch.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,52 +1,183 @@ -.TH "CARGO\-FETCH" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-fetch +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-FETCH" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-fetch \- Fetch dependencies of a package from the network -.SH SYNOPSIS -.PP -\f[I]cargo fetch\f[] [OPTIONS] -.SH DESCRIPTION -.PP -If a lockfile is available, this command will ensure that all of the git -dependencies and/or registries dependencies are downloaded and locally -available. The network is never touched after a `cargo fetch` unless -the lockfile changes. - -If the lockfile is not available, then this is the equivalent of -`cargo generate-lockfile`. A lockfile is generated and dependencies are also -all updated. -.PP -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-manifest-path \f[I]PATH\f[] -Path to the manifest to fetch dependencies for. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.SH "SYNOPSIS" +.sp +\fBcargo fetch [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +If a \fBCargo.lock\fP file is available, this command will ensure that all of the +git dependencies and/or registry dependencies are downloaded and locally +available. Subsequent Cargo commands never touch the network after a \fBcargo +fetch\fP unless the lock file changes. +.sp +If the lock file is not available, then this command will generate the lock +file before fetching the dependencies. +.sp +If \fB\-\-target\fP is not specified, then all target dependencies are fetched. +.SH "OPTIONS" +.SS "Fetch options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Fetch for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." .RE -.TP -.B \-q, \-\-quiet +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-update(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Fetch all dependencies: +.sp +.if n .RS 4 +.nf +cargo fetch +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-update\fP(1), \fBcargo\-generate\-lockfile\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-fix.1 cargo-0.35.0/src/etc/man/cargo-fix.1 --- cargo-0.33.0/src/etc/man/cargo-fix.1 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-fix.1 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,526 @@ +'\" t +.\" Title: cargo-fix +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-FIX" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-fix \- Automatically fix lint warnings reported by rustc +.SH "SYNOPSIS" +.sp +\fBcargo fix [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This Cargo subcommand will automatically take rustc\(cqs suggestions from +diagnostics like warnings and apply them to your source code. This is intended +to help automate tasks that rustc itself already knows how to tell you to fix! +The \fBcargo fix\fP subcommand is also being developed for the Rust 2018 edition +to provide code the ability to easily opt\-in to the new edition without having +to worry about any breakage. +.sp +Executing \fBcargo fix\fP will under the hood execute \fBcargo\-check\fP(1). Any warnings +applicable to your crate will be automatically fixed (if possible) and all +remaining warnings will be displayed when the check process is finished. For +example if you\(cqd like to prepare for the 2018 edition, you can do so by +executing: +.sp +.if n .RS 4 +.nf +cargo fix \-\-edition +.fi +.if n .RE +.sp +which behaves the same as \fBcargo check \-\-all\-targets\fP. Similarly if you\(cqd like +to fix code for different platforms you can do: +.sp +.if n .RS 4 +.nf +cargo fix \-\-edition \-\-target x86_64\-pc\-windows\-gnu +.fi +.if n .RE +.sp +or if your crate has optional features: +.sp +.if n .RS 4 +.nf +cargo fix \-\-edition \-\-no\-default\-features \-\-features foo +.fi +.if n .RE +.sp +If you encounter any problems with \fBcargo fix\fP or otherwise have any questions +or feature requests please don\(cqt hesitate to file an issue at +.URL "https://github.com/rust\-lang/cargo" "" "" +.SH "OPTIONS" +.SS "Fix options" +.sp +\fB\-\-broken\-code\fP +.RS 4 +Fix code even if it already has compiler errors. This is useful if \fBcargo +fix\fP fails to apply the changes. It will apply the changes and leave the +broken code in the working directory for you to inspect and manually fix. +.RE +.sp +\fB\-\-edition\fP +.RS 4 +Apply changes that will update the code to the latest edition. This will +not update the edition in the \fBCargo.toml\fP manifest, which must be updated +manually. +.RE +.sp +\fB\-\-edition\-idioms\fP +.RS 4 +Apply suggestions that will update code to the preferred style for the +current edition. +.RE +.sp +\fB\-\-allow\-no\-vcs\fP +.RS 4 +Fix code even if a VCS was not detected. +.RE +.sp +\fB\-\-allow\-dirty\fP +.RS 4 +Fix code even if the working directory has changes. +.RE +.sp +\fB\-\-allow\-staged\fP +.RS 4 +Fix code even if the working directory has staged changes. +.RE +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP +manifest. +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Fix only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Fix all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo fix\fP will fix all targets +(\fB\-\-all\-targets\fP implied). Binaries are skipped if they have +\fBrequired\-features\fP that are missing. +.sp +Passing target selection flags will fix only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Fix the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Fix the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Fix all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Fix the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Fix all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Fix the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Fix all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Fix the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Fix all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Fix all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Fix for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Fix optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.sp +\fB\-\-profile\fP \fINAME\fP +.RS 4 +Changes fix behavior. Currently only \fBtest\fP is +supported, which will fix with the +\fB#[cfg(test)]\fP attribute enabled. This is useful to have it +fix unit tests which are usually excluded via +the \fBcfg\fP attribute. This does not change the actual profile used. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 +No output printed to stdout. +.RE +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Apply compiler suggestions to the local package: +.sp +.if n .RS 4 +.nf +cargo fix +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Convert a 2015 edition to 2018: +.sp +.if n .RS 4 +.nf +cargo fix \-\-edition +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Apply suggested idioms for the current edition: +.sp +.if n .RS 4 +.nf +cargo fix \-\-edition\-idioms +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-check\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-generate-lockfile.1 cargo-0.35.0/src/etc/man/cargo-generate-lockfile.1 --- cargo-0.33.0/src/etc/man/cargo-generate-lockfile.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-generate-lockfile.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,41 +1,168 @@ -.TH "CARGO\-GENERATE LOCKFILE" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-generate-lockfile \- Generate the lockfile for a package -.SH SYNOPSIS -.PP -\f[I]cargo generate-lockfile\f[] [OPTIONS] -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-manifest-path \f[I]PATH\f[] -Path to the manifest to generate a lockfile for. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +'\" t +.\" Title: cargo-generate-lockfile +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-GENERATE\-LOCKFILE" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-generate\-lockfile \- Generate the lockfile for a package +.SH "SYNOPSIS" +.sp +\fBcargo generate\-lockfile [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will create the \fBCargo.lock\fP lockfile for the current package or +workspace. If the lockfile already exists, it will be rebuilt if there are any +manifest changes or dependency updates. +.sp +See also \fBcargo\-update\fP(1) which is also capable of creating a \fBCargo.lock\fP +lockfile and has more options for controlling update behavior. +.SH "OPTIONS" +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." .RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Create or update the lockfile for the current package or workspace: +.sp +.if n .RS 4 +.nf +cargo generate\-lockfile +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-update\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-help.1 cargo-0.35.0/src/etc/man/cargo-help.1 --- cargo-0.33.0/src/etc/man/cargo-help.1 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-help.1 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,75 @@ +'\" t +.\" Title: cargo-help +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-HELP" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-help \- Get help for a Cargo command +.SH "SYNOPSIS" +.sp +\fBcargo help [\fISUBCOMMAND\fP]\fP +.SH "DESCRIPTION" +.sp +Prints a help message for the given command. +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Get help for a command: +.sp +.if n .RS 4 +.nf +cargo help build +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Help is also available with the \fB\-\-help\fP flag: +.sp +.if n .RS 4 +.nf +cargo build \-\-help +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-init.1 cargo-0.35.0/src/etc/man/cargo-init.1 --- cargo-0.33.0/src/etc/man/cargo-init.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-init.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,68 +1,364 @@ -.TH "CARGO\-INIT" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-init \- Create a new cargo package in the current directory -.SH SYNOPSIS -.PP -\f[I]cargo init\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Create a new cargo package in the current directory. -.PP -Use the \f[B]\-\-vcs\f[] option to control the version control system to -use. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-vcs \f[I]VCS\f[] -Initialize a new repository for the given version control system (git or -hg) or do not initialize any version control at all (none) overriding a -global configuration. -.RS -.RE -.TP -.B \-\-bin -Use a binary instead of a library template. -.RS -.RE -.TP -.B \-\-name \f[I]NAME\f[] -Set the resulting package name. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +'\" t +.\" Title: cargo-init +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-INIT" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-init \- Create a new Cargo package in an existing directory +.SH "SYNOPSIS" +.sp +\fBcargo init [\fIOPTIONS\fP] [\fIPATH\fP]\fP +.SH "DESCRIPTION" +.sp +This command will create a new Cargo manifest in the current directory. Give a +path as an argument to create in the given directory. +.sp +If there are typically\-named Rust source files already in the directory, those +will be used. If not, then a sample \fBsrc/main.rs\fP file will be created, or +\fBsrc/lib.rs\fP if \fB\-\-lib\fP is passed. +.sp +If the directory is not already in a VCS repository, then a new repository +is created (see \fB\-\-vcs\fP below). +.sp +The "authors" field in the manifest is determined from the environment or +configuration settings. A name is required and is determined from (first match +wins): +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBcargo\-new.name\fP Cargo config value .RE -.TP -.B \-q, \-\-quiet +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_AUTHOR_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_COMMITTER_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBuser.name\fP git configuration value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBUSER\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBUSERNAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBNAME\fP environment variable +.RE +.sp +The email address is optional and is determined from: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBcargo\-new.email\fP Cargo config value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_AUTHOR_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_COMMITTER_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBuser.email\fP git configuration value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBEMAIL\fP environment variable +.RE +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "the reference" " " +for more information about +configuration files. +.sp +See \fBcargo\-new\fP(1) for a similar command which will create a new package in +a new directory. +.SH "OPTIONS" +.SS "Init Options" +.sp +\fB\-\-bin\fP +.RS 4 +Create a package with a binary target (\fBsrc/main.rs\fP). +This is the default behavior. +.RE +.sp +\fB\-\-lib\fP +.RS 4 +Create a package with a library target (\fBsrc/lib.rs\fP). +.RE +.sp +\fB\-\-edition\fP \fIEDITION\fP +.RS 4 +Specify the Rust edition to use. Default is 2018. +Possible values: 2015, 2018 +.RE +.sp +\fB\-\-name\fP \fINAME\fP +.RS 4 +Set the package name. Defaults to the directory name. +.RE +.sp +\fB\-\-vcs\fP \fIVCS\fP +.RS 4 +Initialize a new VCS repository for the given version control system (git, +hg, pijul, or fossil) or do not initialize any version control at all +(none). If not specified, defaults to \fBgit\fP or the configuration value +\fBcargo\-new.vcs\fP, or \fBnone\fP if already inside a VCS repository. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +This sets the \fBpublish\fP field in \fBCargo.toml\fP to the given registry name +which will restrict publishing only to that registry. +.sp +Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry defined by the \fBregistry.default\fP +config key is used. If the default registry is not set and \fB\-\-registry\fP is not +used, the \fBpublish\fP field will not be set which means that publishing will not +be restricted. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Initialize a binary cargo package in the current directory -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Create a binary Cargo package in the current directory: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ init\ \-\-bin -\f[] +cargo init .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-new(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-new\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-install.1 cargo-0.35.0/src/etc/man/cargo-install.1 --- cargo-0.33.0/src/etc/man/cargo-install.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-install.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,161 +1,370 @@ -.TH "CARGO\-INSTALL" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-install \- Install a Rust binary -.SH SYNOPSIS -.PP -\f[I]cargo install\f[] [OPTIONS] -.PP -\f[I]cargo install\f[] [OPTIONS] \-\-list -.SH DESCRIPTION -.PP -Install a Rust binary -.PP -This command manages Cargo\[aq]s local set of install binary crates. -Only packages which have [[bin]] targets can be installed, and all -binaries are installed into the installation root\[aq]s \f[I]bin\f[] -folder. -The installation root is determined, in order of precedence, by -\f[B]\-\-root\f[], \f[I]$CARGO_INSTALL_ROOT\f[], the -\f[I]install.root\f[] configuration key, and finally the home directory -(which is either \f[I]$CARGO_HOME\f[] if set or \f[I]$HOME/.cargo\f[] by -default). -.PP -There are multiple sources from which a crate can be installed. -The default location is crates.io but the \f[B]\-\-git\f[] and -\f[B]\-\-path\f[] flags can change this source. -If the source contains more than one package (such as \f[I]crates.io\f[] -or a git repository with multiple crates) the \f[B]\f[] argument is -required to indicate which crate should be installed. -.PP -Crates from crates.io can optionally specify the version they wish to -install via the \f[B]\-\-vers\f[] flags, and similarly packages from git -repositories can optionally specify the branch, tag, or revision that -should be installed. -If a crate has multiple binaries, the \f[B]\-\-bin\f[] argument can -selectively install only one of them, and if you\[aq]d rather install -examples the \f[B]\-\-example\f[] argument can be used as well. -.PP -As a special convenience, omitting the specification entirely -will install the crate in the current directory. -That is, \f[I]install\f[] is equivalent to the more explicit "install -\-\-path .". -.PP -If the source is crates.io or \f[B]\-\-git\f[] then by default the crate will be built in a temporary target directory. -To avoid this, the target directory can be specified by setting the \f[B]CARGO_TARGET_DIR\f[] environment variable to a relative path. -In particular, this can be useful for caching build artifacts on continuous integration systems. -.PP -The \f[B]\-\-list\f[] option will list all installed packages (and their -versions). -.SH OPTIONS -.SS Query options -.TP -.B \-\-list -List all installed packages (and their versions). -.RS -.RE -.SS Specifying what crate to install -.TP -.B \-\-vers \f[I]VERS\f[] +'\" t +.\" Title: cargo-install +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-INSTALL" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-install \- Build and install a Rust binary +.SH "SYNOPSIS" +.sp +\fBcargo install [\fIOPTIONS\fP] \fICRATE\fP...\fP +.br +\fBcargo install [\fIOPTIONS\fP] \-\-path \fIPATH\fP\fP +.br +\fBcargo install [\fIOPTIONS\fP] \-\-git \fIURL\fP [\fICRATE\fP...]\fP +.br +\fBcargo install [\fIOPTIONS\fP] \-\-list\fP +.SH "DESCRIPTION" +.sp +This command manages Cargo\(cqs local set of installed binary crates. Only packages +which have \fB[[bin]]\fP targets can be installed, and all binaries are installed into +the installation root\(cqs \fBbin\fP folder. +.sp +The installation root is determined, in order of precedence: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fB\-\-root\fP option +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_INSTALL_ROOT\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBinstall.root\fP Cargo \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "" +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_HOME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fB$HOME/.cargo\fP +.RE +.sp +There are multiple sources from which a crate can be installed. The default +location is crates.io but the \fB\-\-git\fP and \fB\-\-path\fP flags can change this +source. If the source contains more than one package (such as crates.io or a +git repository with multiple crates) the \fICRATE\fP argument is required to +indicate which crate should be installed. +.sp +Crates from crates.io can optionally specify the version they wish to install +via the \fB\-\-version\fP flags, and similarly packages from git repositories can +optionally specify the branch, tag, or revision that should be installed. If a +crate has multiple binaries, the \fB\-\-bin\fP argument can selectively install only +one of them, and if you\(cqd rather install examples the \fB\-\-example\fP argument can +be used as well. +.sp +If the source is crates.io or \fB\-\-git\fP then by default the crate will be built +in a temporary target directory. To avoid this, the target directory can be +specified by setting the \fBCARGO_TARGET_DIR\fP environment variable to a relative +path. In particular, this can be useful for caching build artifacts on +continuous integration systems. +.SH "OPTIONS" +.SS "Install Options" +.sp +\fB\-\-vers\fP \fIVERSION\fP, \fB\-\-version\fP \fIVERSION\fP +.RS 4 Specify a version to install from crates.io. -.RS .RE -.TP -.B \-\-git \f[I]URL\f[] +.sp +\fB\-\-git\fP \fIURL\fP +.RS 4 Git URL to install the specified crate from. -.RS .RE -.TP -.B \-\-branch \f[I]BRANCH\f[] +.sp +\fB\-\-branch\fP \fIBRANCH\fP +.RS 4 Branch to use when installing from git. -.RS .RE -.TP -.B \-\-tag \f[I]TAG\f[] +.sp +\fB\-\-tag\fP \fITAG\fP +.RS 4 Tag to use when installing from git. -.RS .RE -.TP -.B \-\-rev \f[I]SHA\f[] +.sp +\fB\-\-rev\fP \fISHA\fP +.RS 4 Specific commit to use when installing from git. -.RS .RE -.TP -.B \-\-path \f[I]PATH\f[] +.sp +\fB\-\-path\fP \fIPATH\fP +.RS 4 Filesystem path to local crate to install. -.RS .RE -.SS Built and install options -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-j \f[I]N\f[], \-\-jobs \f[I]N\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to activate. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-f, \-\-force -Force overwriting existing crates or binaries -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-debug -Build in debug mode instead of release mode. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Only install the binary NAME. -.RS -.RE -.TP -.B \-\-example \f[I]EXAMPLE\f[] -Install the example EXAMPLE instead of binaries. -.RS -.RE -.TP -.B \-\-root \f[I]DIR\f[] +.sp +\fB\-\-list\fP +.RS 4 +List all installed packages and their versions. +.RE +.sp +\fB\-f\fP, \fB\-\-force\fP +.RS 4 +Force overwriting existing crates or binaries. This can be used to +reinstall or upgrade a crate. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Install only the specified binary. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Install all binaries. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Install only the specified example. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Install all examples. +.RE +.sp +\fB\-\-root\fP \fIDIR\fP +.RS 4 Directory to install packages into. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS .RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Install for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-debug\fP +.RS 4 +Build with the \fBdev\fP profile instead the \fBrelease\fP profile. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-search(1), cargo\-publish(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Install a package from crates.io: +.sp +.if n .RS 4 +.nf +cargo install ripgrep +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Reinstall or upgrade a package: +.sp +.if n .RS 4 +.nf +cargo install ripgrep \-\-force +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-uninstall\fP(1), \fBcargo\-search\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-locate-project.1 cargo-0.35.0/src/etc/man/cargo-locate-project.1 --- cargo-0.33.0/src/etc/man/cargo-locate-project.1 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-locate-project.1 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,155 @@ +'\" t +.\" Title: cargo-locate-project +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-LOCATE\-PROJECT" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-locate\-project \- Print a JSON representation of a Cargo.toml file\(aqs location +.SH "SYNOPSIS" +.sp +\fBcargo locate\-project [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will print a JSON object to stdout with the full path to the +\fBCargo.toml\fP manifest. +.sp +See also \fBcargo\-metadata\fP(1) which is capable of returning the path to a +workspace root. +.SH "OPTIONS" +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 +No output printed to stdout. +.RE +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Display the path to the manifest based on the current directory: +.sp +.if n .RS 4 +.nf +cargo locate\-project +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-metadata\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-login.1 cargo-0.35.0/src/etc/man/cargo-login.1 --- cargo-0.33.0/src/etc/man/cargo-login.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-login.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,41 +1,163 @@ -.TH "CARGO\-LOGIN" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-login +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-LOGIN" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-login \- Save an API token from the registry locally -.SH SYNOPSIS -.PP -\f[I]cargo login\f[] [OPTIONS] [] -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-host \f[I]HOST\f[] -Host to set the token for -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.SH "SYNOPSIS" +.sp +\fBcargo login [\fIOPTIONS\fP] [\fITOKEN\fP]\fP +.SH "DESCRIPTION" +.sp +This command will save the API token to disk so that commands that require +authentication, such as \fBcargo\-publish\fP(1), will be automatically +authenticated. The token is saved in \fB$CARGO_HOME/credentials\fP. \fBCARGO_HOME\fP +defaults to \fB.cargo\fP in your home directory. +.sp +If the \fITOKEN\fP argument is not specified, it will be read from stdin. +.sp +The API token for crates.io may be retrieved from \c +.URL "https://crates.io/me" "" "." +.sp +Take care to keep the token secret, it should not be shared with anyone else. +.SH "OPTIONS" +.SS "Login Options" +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. .RE -.TP -.B \-q, \-\-quiet +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-publish(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Save the API token to disk: +.sp +.if n .RS 4 +.nf +cargo login +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-metadata.1 cargo-0.35.0/src/etc/man/cargo-metadata.1 --- cargo-0.33.0/src/etc/man/cargo-metadata.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-metadata.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,71 +1,428 @@ -.TH "CARGO\-METADATA" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-metadata \- Machine-readable metadata about the current package -.SH SYNOPSIS -.PP -\f[I]cargo metadata\f[] [OPTIONS] -.SH DESCRIPTION -.PP +'\" t +.\" Title: cargo-metadata +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-05 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-METADATA" "1" "2019-01-05" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-metadata \- Machine\-readable metadata about the current package +.SH "SYNOPSIS" +.sp +\fBcargo metadata [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp Output the resolved dependencies of a package, the concrete used versions -including overrides, in machine-readable format. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space-separated list of features. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not include the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-no\-deps -Output information only about the root package and don\[aq]t fetch +including overrides, in JSON to stdout. +.sp +It is recommended to include the \fB\-\-format\-version\fP flag to future\-proof +your code to ensure the output is in the format you are expecting. +.sp +See the \c +.URL "https://crates.io/crates/cargo_metadata" "cargo_metadata crate" +for a Rust API for reading the metadata. +.SH "OUTPUT FORMAT" +.sp +The output has the following format: +.sp +.if n .RS 4 +.nf +{ + /* Array of all packages in the workspace. + It also includes all feature\-enabled dependencies unless \-\-no\-deps is used. + */ + "packages": [ + { + /* The name of the package. */ + "name": "my\-package", + /* The version of the package. */ + "version": "0.1.0", + /* The Package ID, a unique identifier for referring to the package. */ + "id": "my\-package 0.1.0 (path+file:///path/to/my\-package)", + /* The license value from the manifest, or null. */ + "license": "MIT/Apache\-2.0", + /* The license\-file value from the manifest, or null. */ + "license_file": "LICENSE", + /* The description value from the manifest, or null. */ + "description": "Package description.", + /* The source ID of the package. This represents where + a package is retrieved from. + This is null for path dependencies and workspace members. + For other dependencies, it is a string with the format: + \- "registry+URL" for registry\-based dependencies. + Example: "registry+https://github.com/rust\-lang/crates.io\-index" + \- "git+URL" for git\-based dependencies. + Example: "git+https://github.com/rust\-lang/cargo?rev=5e85ba14aaa20f8133863373404cb0af69eeef2c#5e85ba14aaa20f8133863373404cb0af69eeef2c" + */ + "source": null, + /* Array of dependencies declared in the package\(aqs manifest. */ + "dependencies": [ + { + /* The name of the dependency. */ + "name": "bitflags", + /* The source ID of the dependency. May be null, see + description for the package source. + */ + "source": "registry+https://github.com/rust\-lang/crates.io\-index", + /* The version requirement for the dependency. + Dependencies without a version requirement have a value of "*". + */ + "req": "^1.0", + /* The dependency kind. + "dev", "build", or null for a normal dependency. + */ + "kind": null, + /* If the dependency is renamed, this is the new name for + the dependency as a string. null if it is not renamed. + */ + "rename": null, + /* Boolean of whether or not this is an optional dependency. */ + "optional": false, + /* Boolean of whether or not default features are enabled. */ + "uses_default_features": true, + /* Array of features enabled. */ + "features": [], + /* The target platform for the dependency. + null if not a target dependency. + */ + "target": "cfg(windows)", + /* A string of the URL of the registry this dependency is from. + If not specified or null, the dependency is from the default + registry (crates.io). + */ + "registry": null + } + ], + /* Array of Cargo targets. */ + "targets": [ + { + /* Array of target kinds. + \- lib targets list the `crate\-type` values from the + manifest such as "lib", "rlib", "dylib", + "proc\-macro", etc. (default ["lib"]) + \- binary is ["bin"] + \- example is ["example"] + \- integration test is ["test"] + \- benchmark is ["bench"] + \- build script is ["custom\-build"] + */ + "kind": [ + "bin" + ], + /* Array of crate types. + \- lib and example libraries list the `crate\-type` values + from the manifest such as "lib", "rlib", "dylib", + "proc\-macro", etc. (default ["lib"]) + \- all other target kinds are ["bin"] + */ + "crate_types": [ + "bin" + ], + /* The name of the target. */ + "name": "my\-package", + /* Absolute path to the root source file of the target. */ + "src_path": "/path/to/my\-package/src/main.rs", + /* The Rust edition of the target. + Defaults to the package edition. + */ + "edition": "2018", + /* Array of required features. + This property is not included if no required features are set. + */ + "required\-features": ["feat1"] + } + ], + /* Set of features defined for the package. + Each feature maps to an array of features or dependencies it + enables. + */ + "features": { + "default": [ + "feat1" + ], + "feat1": [], + "feat2": [] + }, + /* Absolute path to this package\(aqs manifest. */ + "manifest_path": "/path/to/my\-package/Cargo.toml", + /* Package metadata. + This is null if no metadata is specified. + */ + "metadata": { + "docs": { + "rs": { + "all\-features": true + } + } + }, + /* Array of authors from the manifest. + Empty array if no authors specified. + */ + "authors": [ + "Jane Doe " + ], + /* Array of categories from the manifest. */ + "categories": [ + "command\-line\-utilities" + ], + /* Array of keywords from the manifest. */ + "keywords": [ + "cli" + ], + /* The readme value from the manifest or null if not specified. */ + "readme": "README.md", + /* The repository value from the manifest or null if not specified. */ + "repository": "https://github.com/rust\-lang/cargo", + /* The default edition of the package. + Note that individual targets may have different editions. + */ + "edition": "2018", + /* Optional string that is the name of a native library the package + is linking to. + */ + "links": null, + } + ], + /* Array of members of the workspace. + Each entry is the Package ID for the package. + */ + "workspace_members": [ + "my\-package 0.1.0 (path+file:///path/to/my\-package)", + ], + /* The resolved dependency graph, with the concrete versions and features + selected. The set depends on the enabled features. + This is null if \-\-no\-deps is specified. + */ + "resolve": { + /* Array of nodes within the dependency graph. + Each node is a package. + */ + "nodes": [ + { + /* The Package ID of this node. */ + "id": "my\-package 0.1.0 (path+file:///path/to/my\-package)", + /* The dependencies of this package, an array of Package IDs. */ + "dependencies": [ + "bitflags 1.0.4 (registry+https://github.com/rust\-lang/crates.io\-index)" + ], + /* The dependencies of this package. This is an alternative to + "dependencies" which contains additional information. In + particular, this handles renamed dependencies. + */ + "deps": [ + { + /* The name of the dependency. + If this is a renamed dependency, this is the new + name. + */ + "name": "bitflags", + /* The Package ID of the dependency. */ + "pkg": "bitflags 1.0.4 (registry+https://github.com/rust\-lang/crates.io\-index)" + } + ], + /* Array of features enabled on this package. */ + "features": [ + "default" + ] + } + ], + /* The root package of the workspace. + This is null if this is a virtual workspace. Otherwise it is + the Package ID of the root package. + */ + "root": "my\-package 0.1.0 (path+file:///path/to/my\-package)" + }, + /* The absolute path to the build directory where Cargo places its output. */ + "target_directory": "/path/to/my\-package/target", + /* The version of the schema for this metadata structure. + This will be changed if incompatible changes are ever made. + */ + "version": 1, + /* The absolute path to the root of the workspace. */ + "workspace_root": "/path/to/my\-package" +} +.fi +.if n .RE +.SH "OPTIONS" +.SS "Output Options" +.sp +\fB\-\-no\-deps\fP +.RS 4 +Output information only about the workspace members and don\(cqt fetch dependencies. -.RS .RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the manifest. -.RS -.RE -.TP -.B \-\-format\-version \f[I]VERSION\f[] -Format version [default: 1]. Valid values: 1. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.sp +\fB\-\-format\-version\fP \fIVERSION\fP +.RS 4 +Specify the version of the output format to use. Currently \fB1\fP is the only +possible value. .RE -.TP -.B \-q, \-\-quiet +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Output JSON about the current package: +.sp +.if n .RS 4 +.nf +cargo metadata \-\-format\-version=1 +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-new.1 cargo-0.35.0/src/etc/man/cargo-new.1 --- cargo-0.33.0/src/etc/man/cargo-new.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-new.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,68 +1,359 @@ -.TH "CARGO\-NEW" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-new \- Create a new cargo package -.SH SYNOPSIS -.PP -\f[I]cargo new\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Create a new cargo package at . -.PP -Use the \f[B]\-\-vcs\f[] option to control the version control system to -use. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-vcs \f[I]VCS\f[] -Initialize a new repository for the given version control system (git or -hg) or do not initialize any version control at all (none) overriding a -global configuration. -.RS -.RE -.TP -.B \-\-bin -Use a binary instead of a library template. -.RS -.RE -.TP -.B \-\-name \f[I]NAME\f[] -Set the resulting package name. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +'\" t +.\" Title: cargo-new +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-NEW" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-new \- Create a new Cargo package +.SH "SYNOPSIS" +.sp +\fBcargo new [\fIOPTIONS\fP] \fIPATH\fP\fP +.SH "DESCRIPTION" +.sp +This command will create a new Cargo package in the given directory. This +includes a simple template with a \fBCargo.toml\fP manifest, sample source file, +and a VCS ignore file. If the directory is not already in a VCS repository, +then a new repository is created (see \fB\-\-vcs\fP below). +.sp +The "authors" field in the manifest is determined from the environment or +configuration settings. A name is required and is determined from (first match +wins): +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBcargo\-new.name\fP Cargo config value .RE -.TP -.B \-q, \-\-quiet +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_AUTHOR_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_COMMITTER_NAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBuser.name\fP git configuration value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBUSER\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBUSERNAME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBNAME\fP environment variable +.RE +.sp +The email address is optional and is determined from: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBcargo\-new.email\fP Cargo config value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_AUTHOR_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBGIT_COMMITTER_EMAIL\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBuser.email\fP git configuration value +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBEMAIL\fP environment variable +.RE +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "the reference" " " +for more information about +configuration files. +.sp +See \fBcargo\-init\fP(1) for a similar command which will create a new manifest +in an existing directory. +.SH "OPTIONS" +.SS "New Options" +.sp +\fB\-\-bin\fP +.RS 4 +Create a package with a binary target (\fBsrc/main.rs\fP). +This is the default behavior. +.RE +.sp +\fB\-\-lib\fP +.RS 4 +Create a package with a library target (\fBsrc/lib.rs\fP). +.RE +.sp +\fB\-\-edition\fP \fIEDITION\fP +.RS 4 +Specify the Rust edition to use. Default is 2018. +Possible values: 2015, 2018 +.RE +.sp +\fB\-\-name\fP \fINAME\fP +.RS 4 +Set the package name. Defaults to the directory name. +.RE +.sp +\fB\-\-vcs\fP \fIVCS\fP +.RS 4 +Initialize a new VCS repository for the given version control system (git, +hg, pijul, or fossil) or do not initialize any version control at all +(none). If not specified, defaults to \fBgit\fP or the configuration value +\fBcargo\-new.vcs\fP, or \fBnone\fP if already inside a VCS repository. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +This sets the \fBpublish\fP field in \fBCargo.toml\fP to the given registry name +which will restrict publishing only to that registry. +.sp +Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry defined by the \fBregistry.default\fP +config key is used. If the default registry is not set and \fB\-\-registry\fP is not +used, the \fBpublish\fP field will not be set which means that publishing will not +be restricted. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Create a binary cargo package in the current directory -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Create a binary Cargo package in the given directory: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ new\ \-\-bin\ ./ -\f[] +cargo new foo .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-init(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-init\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-owner.1 cargo-0.35.0/src/etc/man/cargo-owner.1 --- cargo-0.33.0/src/etc/man/cargo-owner.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-owner.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,88 +1,238 @@ -.TH "CARGO\-OWNER" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-owner \- Manage the owners of a crate of the registry -.SH SYNOPSIS -.PP -\f[I]cargo owner\f[] [OPTIONS] [] -.SH DESCRIPTION -.PP -This command will modify the owners for a package on the specified -registry (or default). Note that owners of a package can upload new -versions, and yank old versions. Explicitly named owners can also modify -the set of owners, so take caution! -.PP -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-a, \-\-add \f[I]LOGIN\f[] -Name of a user or team to add as an owner. -.RS -.RE -.TP -.B \-r, \-\-remove \f[I]LOGIN\f[] -Name of a user or team to remove as an owner. -.RS -.RE -.TP -.B \-l, \-\-list +'\" t +.\" Title: cargo-owner +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-02-05 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-OWNER" "1" "2019-02-05" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-owner \- Manage the owners of a crate on the registry +.SH "SYNOPSIS" +.sp +\fBcargo owner [\fIOPTIONS\fP] \-\-add \fILOGIN\fP [\fICRATE\fP]\fP +.br +\fBcargo owner [\fIOPTIONS\fP] \-\-remove \fILOGIN\fP [\fICRATE\fP]\fP +.br +\fBcargo owner [\fIOPTIONS\fP] \-\-list [\fICRATE\fP]\fP +.SH "DESCRIPTION" +.sp +This command will modify the owners for a crate on the registry. Owners of a +crate can upload new versions and yank old versions. Non\-team owners can also +modify the set of owners, so take care! +.sp +This command requires you to be authenticated with either the \fB\-\-token\fP option +or using \fBcargo\-login\fP(1). +.sp +If the crate name is not specified, it will use the package name from the +current directory. +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/publishing.html#cargo\-owner" "the reference" " " +for more +information about owners and publishing. +.SH "OPTIONS" +.SS "Owner Options" +.sp +\fB\-a\fP, \fB\-\-add\fP \fILOGIN\fP... +.RS 4 +Invite the given user or team as an owner. +.RE +.sp +\fB\-r\fP, \fB\-\-remove\fP \fILOGIN\fP... +.RS 4 +Remove the given user or team as an owner. +.RE +.sp +\fB\-l\fP, \fB\-\-list\fP +.RS 4 List owners of a crate. -.RS -.RE -.TP -.B \-\-index \f[I]INDEX\f[] -Registry index to modify owners for. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS .RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-\-token\fP \fITOKEN\fP +.RS 4 +API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by \fBcargo\-login\fP(1)). +.sp +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config" " " +environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the \fBCARGO_REGISTRY_TOKEN\fP environment +variable. Tokens for other registries may be specified with environment +variables of the form \fBCARGO_REGISTRIES_NAME_TOKEN\fP where \fBNAME\fP is the name +of the registry in all capital letters. +.RE +.sp +\fB\-\-index\fP \fIINDEX\fP +.RS 4 +The URL of the registry index to use. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Add user as an owner of the current package -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +List owners of a package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ owner\ \-\-add\ user -\f[] +cargo owner \-\-list foo .fi -.PP -Remove user as an owner of the current package -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Invite an owner to a package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ owner\ \-\-remove\ user -\f[] +cargo owner \-\-add username foo .fi -.PP -Use a certain API token to authenticate with -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Remove an owner from a package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ owner\ \-\-token\ U6WHXacP3Qqwd5kze1fohr4JEOmGCuRK2 -\f[] +cargo owner \-\-remove username foo .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-publish(1), cargo\-login(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-login\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-package.1 cargo-0.35.0/src/etc/man/cargo-package.1 --- cargo-0.33.0/src/etc/man/cargo-package.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-package.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,59 +1,342 @@ -.TH "CARGO\-PACKAGE" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-package \- Create a distributable tarball -.SH SYNOPSIS -.PP -\f[I]cargo package\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Assemble the local package into a distributable tarball. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS +'\" t +.\" Title: cargo-package +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-02-13 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-PACKAGE" "1" "2019-02-13" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-package \- Assemble the local package into a distributable tarball +.SH "SYNOPSIS" +.sp +\fBcargo package [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will create a distributable, compressed \fB.crate\fP file with the +source code of the package in the current directory. The resulting file will +be stored in the \fBtarget/package\fP directory. This performs the following +steps: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Load and check the current workspace, performing some basic checks. +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +Path dependencies are not allowed unless they have a version key. Cargo +will ignore the path key for dependencies in published packages. .RE -.TP -.B \-l, \-\-list +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Create the compressed \fB.crate\fP file. +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The original \fBCargo.toml\fP file is rewritten and normalized. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fB[patch]\fP, \fB[replace]\fP, and \fB[workspace]\fP sections are removed from the +manifest. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +A \fB.cargo_vcs_info.json\fP file is included that contains information +about the current VCS checkout hash if available (not included with +\fB\-\-allow\-dirty\fP). +.RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Extract the \fB.crate\fP file and build it to verify it can build. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 4." 4.2 +.\} +Check that build scripts did not modify any source files. +.RE +.sp +The list of files included can be controlled with the \fBinclude\fP and \fBexclude\fP +fields in the manifest. +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/publishing.html" "the reference" " " +for more details about +packaging and publishing. +.SH "OPTIONS" +.SS "Package Options" +.sp +\fB\-l\fP, \fB\-\-list\fP +.RS 4 Print files included in a package without making one. -.RS .RE -.TP -.B \-\-no\-verify -Don\[aq]t verify the contents by building them. -.RS -.RE -.TP -.B \-\-no\-metadata -Ignore warnings about a lack of human\-usable metadata. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.sp +\fB\-\-no\-verify\fP +.RS 4 +Don\(cqt verify the contents by building them. +.RE +.sp +\fB\-\-no\-metadata\fP +.RS 4 +Ignore warnings about a lack of human\-usable metadata (such as the +description or the license). +.RE +.sp +\fB\-\-allow\-dirty\fP +.RS 4 +Allow working directories with uncommitted VCS changes to be packaged. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Package for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. .RE -.TP -.B \-q, \-\-quiet +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-build(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Create a compressed \fB.crate\fP file of the current package: +.sp +.if n .RS 4 +.nf +cargo package +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-pkgid.1 cargo-0.35.0/src/etc/man/cargo-pkgid.1 --- cargo-0.33.0/src/etc/man/cargo-pkgid.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-pkgid.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,75 +1,279 @@ -.TH "CARGO\-PKGID" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-pkgid +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-PKGID" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-pkgid \- Print a fully qualified package specification -.SH SYNOPSIS -.PP -\f[I]cargo pkgid\f[] [OPTIONS] [] -.SH DESCRIPTION -.PP -Given a argument, print out the fully qualified package id -specifier. This command will generate an error if is ambiguous as -to which package it refers to in the dependency graph. If no is -given, then the pkgid for the local package is printed. -.PP -This command requires that a lockfile is available and dependencies have -been fetched. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the manifest to the package to clean. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.SH "SYNOPSIS" +.sp +\fBcargo pkgid [\fIOPTIONS\fP] [\fISPEC\fP]\fP +.SH "DESCRIPTION" +.sp +Given a \fISPEC\fP argument, print out the fully qualified package ID specifier +for a package or dependency in the current workspace. This command will +generate an error if \fISPEC\fP is ambiguous as to which package it refers to in +the dependency graph. If no \fISPEC\fP is given, then the specifier for the local +package is printed. +.sp +This command requires that a lockfile is available and dependencies have been +fetched. +.sp +A package specifier consists of a name, version, and source URL. You are +allowed to use partial specifiers to succinctly match a specific package as +long as it matches only one package. The format of a \fISPEC\fP can be one of the +following: +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table 1. SPEC Query Format +.TS +allbox tab(:); +lt lt. +T{ +.sp +SPEC Structure +T}:T{ +.sp +Example SPEC +T} +T{ +.sp +\fINAME\fP +T}:T{ +.sp +\fBbitflags\fP +T} +T{ +.sp +\fINAME\fP\fB:\fP\fIVERSION\fP +T}:T{ +.sp +\fBbitflags:1.0.4\fP +T} +T{ +.sp +\fIURL\fP +T}:T{ +.sp +\fB\c +.URL "https://github.com/rust\-lang/cargo" "" "\fP" +T} +T{ +.sp +\fIURL\fP\fB#\fP\fIVERSION\fP +T}:T{ +.sp +\fB\c +.URL "https://github.com/rust\-lang/cargo#0.33.0" "" "\fP" +T} +T{ +.sp +\fIURL\fP\fB#\fP\fINAME\fP +T}:T{ +.sp +\fB\c +.URL "https://github.com/rust\-lang/crates.io\-index#bitflags" "" "\fP" +T} +T{ +.sp +\fIURL\fP\fB#\fP\fINAME\fP\fB:\fP\fIVERSION\fP +T}:T{ +.sp +\fB\c +.URL "https://github.com/rust\-lang/cargo#crates\-io:0.21.0" "" "\fP" +T} +.TE +.sp +.SH "OPTIONS" +.SS "Package Selection" +.sp +\fB\-p\fP \fISPEC\fP, \fB\-\-package\fP \fISPEC\fP +.RS 4 +Get the package ID for the given package instead of the current package. .RE -.TP -.B \-q, \-\-quiet +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Retrieve package specification for foo package -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Retrieve package specification for \fBfoo\fP package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ pkgid\ foo -\f[] +cargo pkgid foo .fi -.PP -Retrieve package specification for version 1.0.0 of foo -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Retrieve package specification for version 1.0.0 of \fBfoo\fP: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ pkgid\ foo:1.0.0 -\f[] +cargo pkgid foo:1.0.0 .fi -.PP -Retrieve package specification for foo from crates.io -.IP +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Retrieve package specification for \fBfoo\fP from crates.io: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ pkgid\ crates.io/foo -\f[] +cargo pkgid https://github.com/rust\-lang/crates.io\-index#foo .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-generate\-lockfile(1), cargo-search(1), cargo-metadata(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-generate\-lockfile\fP(1), \fBcargo\-metadata\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-publish.1 cargo-0.35.0/src/etc/man/cargo-publish.1 --- cargo-0.33.0/src/etc/man/cargo-publish.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-publish.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,59 +1,319 @@ -.TH "CARGO\-PUBLISH" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-publish \- Upload a package to the registry. -.SH SYNOPSIS -.PP -\f[I]cargo publish\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Upload a package to the registry. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-host \f[I]HOST\f[] -Host to upload the package to. -.RS -.RE -.TP -.B \-\-token \f[I]TOKEN\f[] -Token to use when uploading. -.RS -.RE -.TP -.B \-\-no\-verify -Don\[aq]t verify package tarball before publish. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the manifest of the package to publish. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +'\" t +.\" Title: cargo-publish +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-02-13 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-PUBLISH" "1" "2019-02-13" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-publish \- Upload a package to the registry +.SH "SYNOPSIS" +.sp +\fBcargo package [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will create a distributable, compressed \fB.crate\fP file with the +source code of the package in the current directory and upload it to a +registry. The default registry is \c +.URL "https://crates.io" "" "." +This performs the +following steps: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Performs a few checks, including: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +Checks the \fBpackage.publish\fP key in the manifest for restrictions on which +registries you are allowed to publish to. .RE -.TP -.B \-q, \-\-quiet +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Create a \fB.crate\fP file by following the steps in \fBcargo\-package\fP(1). +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Upload the crate to the registry. Note that the server will perform +additional checks on the crate. +.RE +.sp +This command requires you to be authenticated with either the \fB\-\-token\fP option +or using \fBcargo\-login\fP(1). +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/publishing.html" "the reference" " " +for more details about +packaging and publishing. +.SH "OPTIONS" +.SS "Publish Options" +.sp +\fB\-\-dry\-run\fP +.RS 4 +Perform all checks without uploading. +.RE +.sp +\fB\-\-token\fP \fITOKEN\fP +.RS 4 +API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by \fBcargo\-login\fP(1)). +.sp +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config" " " +environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the \fBCARGO_REGISTRY_TOKEN\fP environment +variable. Tokens for other registries may be specified with environment +variables of the form \fBCARGO_REGISTRIES_NAME_TOKEN\fP where \fBNAME\fP is the name +of the registry in all capital letters. +.RE +.sp +\fB\-\-no\-verify\fP +.RS 4 +Don\(cqt verify the contents by building them. +.RE +.sp +\fB\-\-allow\-dirty\fP +.RS 4 +Allow working directories with uncommitted VCS changes to be packaged. +.RE +.sp +\fB\-\-index\fP \fIINDEX\fP +.RS 4 +The URL of the registry index to use. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Publish for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-install(1), cargo\-search(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Publish the current package: +.sp +.if n .RS 4 +.nf +cargo publish +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-package\fP(1), \fBcargo\-login\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-run.1 cargo-0.35.0/src/etc/man/cargo-run.1 --- cargo-0.33.0/src/etc/man/cargo-run.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-run.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,103 +1,358 @@ -.TH "CARGO\-RUN" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-run +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-02-05 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-RUN" "1" "2019-02-05" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-run \- Run the current package -.SH SYNOPSIS -.PP -\f[I]cargo run\f[] [OPTIONS] [\-\-] [...] -.SH DESCRIPTION -.PP -Run the main binary of the local package (src/main.rs). -.PP -If neither \f[B]\-\-bin\f[] nor \f[B]\-\-example\f[] are given, then if -the package only has one bin target it will be run. -Otherwise \f[B]\-\-bin\f[] specifies the bin target to run, and -\f[B]\-\-example\f[] specifies the example target to run. -At most one of \f[B]\-\-bin\f[] or \f[B]\-\-example\f[] can be provided. -.PP -All of the trailing arguments are passed to the binary to run. -If you\[aq]re passing arguments to both Cargo and the binary, the ones -after \f[B]\-\-\f[] go to the binary, the ones before go to Cargo. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Name of the bin target to run. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Name of the example target to run. -.RS -.RE -.TP -.B \-j \f[I]IN\f[], \-\-jobs \f[I]IN\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also build. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.SH "SYNOPSIS" +.sp +\fBcargo run [\fIOPTIONS\fP] [\-\- \fIARGS\fP]\fP +.SH "DESCRIPTION" +.sp +Run a binary or example of the local package. +.sp +All the arguments following the two dashes (\fB\-\-\fP) are passed to the binary to +run. If you\(cqre passing arguments to both Cargo and the binary, the ones after +\fB\-\-\fP go to the binary, the ones before go to Cargo. +.SH "OPTIONS" +.SS "Package Selection" +.sp +By default, the package in the current working directory is selected. The \fB\-p\fP +flag can be used to choose a different package in a workspace. +.sp +\fB\-p\fP \fISPEC\fP, \fB\-\-package\fP \fISPEC\fP +.RS 4 +The package to run. See \fBcargo\-pkgid\fP(1) for +the SPEC format. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo run\fP will run the binary +target. If there are multiple binary targets, you must pass a target flag to +choose one. +.sp +\fB\-\-bin\fP \fINAME\fP +.RS 4 +Run the specified binary. +.RE +.sp +\fB\-\-example\fP \fINAME\fP +.RS 4 +Run the specified example. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Run for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Run optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Run the main binary of the current package -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build the local package and run its main target (assuming only one binary): +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ run -\f[] +cargo run .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-new(1), cargo\-init(1), cargo\-build(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Run an example with extra arguments: +.sp +.if n .RS 4 +.nf +cargo run \-\-example exname \-\- \-\-exoption exarg1 exarg2 +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-build\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-rustc.1 cargo-0.35.0/src/etc/man/cargo-rustc.1 --- cargo-0.33.0/src/etc/man/cargo-rustc.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-rustc.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,126 +1,429 @@ -.TH "CARGO\-RUSTC" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-rustc \- Compile a package and all of its dependencies -.SH SYNOPSIS -.PP -\f[I]cargo rustc\f[] [OPTIONS] [\-\-] [...] -.SH DESCRIPTION -.PP -.PP -The specified target for the current package (or package specified by -SPEC if provided) will be compiled along with all of its dependencies. -The specified ... -will all be passed to the final compiler invocation, not any of the -dependencies. -Note that the compiler will still unconditionally receive arguments such -as \-L, \-\-extern, and \-\-crate\-type, and the specified ... -will simply be added to the compiler invocation. -.PP -This command requires that only one target is being compiled. -If more than one target is available for the current package the filters -of \-\-lib, \-\-bin, etc, must be used to select which target is -compiled. -To pass flags to all compiler processes spawned by Cargo, use the -$RUSTFLAGS environment variable or the \f[C]build.rustflags\f[] -configuration option. -.PP -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package SPEC\f[] -The profile to compiler for. -.RS -.RE -.TP -.B \-j \f[I]N\f[], \-\-jobs \f[I]N\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-lib -Build only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Build only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Build only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Build only the specified test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Build only the specified benchmark target. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-profile \f[I]PROFILE -Profile to build the selected target for. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -The version to yank or un\-yank. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not compile default features for the package. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Target triple which compiles will be for. -.RS -.RE -.TP -.B \-\-manifest-path \f[I]PATH\f[] -Path to the manifest to fetch dependencies for. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +'\" t +.\" Title: cargo-rustc +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-RUSTC" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-rustc \- Compile the current package, and pass extra options to the compiler +.SH "SYNOPSIS" +.sp +\fBcargo rustc [\fIOPTIONS\fP] [\-\- \fIARGS\fP]\fP +.SH "DESCRIPTION" +.sp +The specified target for the current package (or package specified by \fB\-p\fP if +provided) will be compiled along with all of its dependencies. The specified +\fIARGS\fP will all be passed to the final compiler invocation, not any of the +dependencies. Note that the compiler will still unconditionally receive +arguments such as \fB\-L\fP, \fB\-\-extern\fP, and \fB\-\-crate\-type\fP, and the specified +\fIARGS\fP will simply be added to the compiler invocation. +.sp +See \c +.URL "https://doc.rust\-lang.org/rustc/index.html" "" " " +for documentation on rustc +flags. +.sp +This command requires that only one target is being compiled when additional +arguments are provided. If more than one target is available for the current +package the filters of \fB\-\-lib\fP, \fB\-\-bin\fP, etc, must be used to select which +target is compiled. +To pass flags to all compiler processes spawned by Cargo, use the \fBRUSTFLAGS\fP +environment variable or the \fBbuild.rustflags\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.SH "OPTIONS" +.SS "Package Selection" +.sp +By default, the package in the current working directory is selected. The \fB\-p\fP +flag can be used to choose a different package in a workspace. +.sp +\fB\-p\fP \fISPEC\fP, \fB\-\-package\fP \fISPEC\fP +.RS 4 +The package to build. See \fBcargo\-pkgid\fP(1) for +the SPEC format. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo rustc\fP will build all +binary and library targets of the selected package. +.sp +Passing target selection flags will build only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Build the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Build the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Build all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Build the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Build all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Build the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Build all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Build the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Build all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Build for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Build optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-run(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Check if your package (not including dependencies) uses unsafe code: +.sp +.if n .RS 4 +.nf +cargo rustc \-\-lib \-\- \-D unsafe\-code +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Try an experimental flag on the nightly compiler, such as this which prints +the size of every type: +.sp +.if n .RS 4 +.nf +cargo rustc \-\-lib \-\- \-Z print\-type\-sizes +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-build\fP(1), \fBrustc\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-rustdoc.1 cargo-0.35.0/src/etc/man/cargo-rustdoc.1 --- cargo-0.33.0/src/etc/man/cargo-rustdoc.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-rustdoc.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,124 +1,419 @@ -.TH "CARGO\-RUSTDOC" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-rustdoc \- Build a package\[aq]s documentation, using specified -custom flags. - -.SH SYNOPSIS -.PP -\f[I]cargo rustdoc\f[] [OPTIONS] [\-\-] [...] -.SH DESCRIPTION -.PP -The specified target for the current package (or package specified by -SPEC if provided) will be documented with the specified ... -being passed to the final rustdoc invocation. -Dependencies will not be documented as part of this command. -Note that rustdoc will still unconditionally receive arguments such as -\-L, \-\-extern, and \-\-crate\-type, and the specified ... -will simply be added to the rustdoc invocation. -.PP -If the \-\-package argument is given, then SPEC is a package id -specification which indicates which package should be documented. -If it is not given, then the current package is documented. -For more information on SPEC and its format, see the -\f[C]cargo\ help\ pkgid\f[] command. - -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-open -Open the docs in a browser after the operation. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC\f[] -Package to document. -.RS -.RE -.TP -.B \-j \f[I]N\f[], \-\-jobs \f[I]N\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-lib -Build only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Build only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Build only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Build only the specified test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Build only the specified benchmark target. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space-separated list of features to also build. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the manifest to document. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +'\" t +.\" Title: cargo-rustdoc +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-RUSTDOC" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-rustdoc \- Build a package\(aqs documentation, using specified custom flags +.SH "SYNOPSIS" +.sp +\fBcargo rustdoc [\fIOPTIONS\fP] [\-\- \fIARGS\fP]\fP +.SH "DESCRIPTION" +.sp +The specified target for the current package (or package specified by \fB\-p\fP if +provided) will be documented with the specified \fIARGS\fP being passed to the +final rustdoc invocation. Dependencies will not be documented as part of this +command. Note that rustdoc will still unconditionally receive arguments such +as \fB\-L\fP, \fB\-\-extern\fP, and \fB\-\-crate\-type\fP, and the specified \fIARGS\fP will simply +be added to the rustdoc invocation. +.sp +See \c +.URL "https://doc.rust\-lang.org/rustdoc/index.html" "" " " +for documentation on rustdoc +flags. +.sp +This command requires that only one target is being compiled when additional +arguments are provided. If more than one target is available for the current +package the filters of \fB\-\-lib\fP, \fB\-\-bin\fP, etc, must be used to select which +target is compiled. +To pass flags to all rustdoc processes spawned by Cargo, use the +\fBRUSTDOCFLAGS\fP environment variable or the \fBbuild.rustdocflags\fP configuration +option. +.SH "OPTIONS" +.SS "Documentation Options" +.sp +\fB\-\-open\fP +.RS 4 +Open the docs in a browser after building them. +.RE +.SS "Package Selection" +.sp +By default, the package in the current working directory is selected. The \fB\-p\fP +flag can be used to choose a different package in a workspace. +.sp +\fB\-p\fP \fISPEC\fP, \fB\-\-package\fP \fISPEC\fP +.RS 4 +The package to document. See \fBcargo\-pkgid\fP(1) for +the SPEC format. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo rustdoc\fP will document all +binary and library targets of the selected package. The binary will be skipped +if its name is the same as the lib target. Binaries are skipped if they have +\fBrequired\-features\fP that are missing. +.sp +Passing target selection flags will document only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Document the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Document the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Document all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Document the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Document all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Document the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Document all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Document the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Document all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Document all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Document for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Document optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo-doc(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Build documentation with custom CSS included from a given file: +.sp +.if n .RS 4 +.nf +cargo rustdoc \-\-lib \-\- \-\-extend\-css extra.css +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-doc\fP(1), \fBrustdoc\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-search.1 cargo-0.35.0/src/etc/man/cargo-search.1 --- cargo-0.33.0/src/etc/man/cargo-search.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-search.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,49 +1,167 @@ -.TH "CARGO\-SEARCH" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-search +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-SEARCH" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-search \- Search packages in crates.io -.SH SYNOPSIS -.PP -\f[I]cargo search\f[] [OPTIONS] ... -.SH DESCRIPTION -.PP -Search packages in \f[I]crates.io\f[]. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-host \f[I]HOST\f[] -Host of a registry to search in. -.RS -.RE -.TP -.B \-\-limit \f[I]LIMIT\f[] +.SH "SYNOPSIS" +.sp +\fBcargo search [\fIOPTIONS\fP] [\fIQUERY\fP...]\fP +.SH "DESCRIPTION" +.sp +This performs a textual search for crates on \c +.URL "https://crates.io" "" "." +The matching +crates will be displayed along with their description in TOML format suitable +for copying into a \fBCargo.toml\fP manifest. +.SH "OPTIONS" +.SS "Search Options" +.sp +\fB\-\-limit\fP \fILIMIT\fP +.RS 4 Limit the number of results (default: 10, max: 100). -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS .RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-\-index\fP \fIINDEX\fP +.RS 4 +The URL of the registry index to use. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-install(1), cargo\-publish(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Search for a package from crates.io: +.sp +.if n .RS 4 +.nf +cargo search serde +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-install\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-test.1 cargo-0.35.0/src/etc/man/cargo-test.1 --- cargo-0.33.0/src/etc/man/cargo-test.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-test.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,172 +1,590 @@ -.TH "CARGO\-TEST" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-test +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-TEST" "1" "2018-12-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-test \- Execute unit and integration tests of a package -.SH SYNOPSIS -.PP -\f[I]cargo test\f[] [OPTIONS] [\-\-] [...] -.SH DESCRIPTION -.PP -Execute all unit and integration tests of a local package. -.PP -All of the trailing arguments are passed to the test binaries generated -for filtering tests and generally providing options configuring how they -run. -For example, this will run all tests with the name \[aq]foo\[aq] in -their name: -.IP +.SH "SYNOPSIS" +.sp +\fBcargo test [\fIOPTIONS\fP] [TESTNAME] [\-\- \fITEST\-OPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Compile and execute unit and integration tests. +.sp +The test filtering argument \fBTESTNAME\fP and all the arguments following the two +dashes (\fB\-\-\fP) are passed to the test binaries and thus to \fIlibtest\fP (rustc\(cqs +built in unit\-test and micro\-benchmarking framework). If you\(cqre passing +arguments to both Cargo and the binary, the ones after \fB\-\-\fP go to the binary, +the ones before go to Cargo. For details about libtest\(cqs arguments see the +output of \fBcargo test \(em \-\-help\fP. As an example, this will run all tests with +\fBfoo\fP in their name on 3 threads in parallel: +.sp +.if n .RS 4 .nf -\f[C] -cargo\ test\ foo -\f[] +cargo test foo \-\- \-\-test\-threads 3 .fi -.PP -If the \f[B]\-\-package\f[] argument is given, then \[aq]SPEC\[aq] is a -package id specification which indicates which package should be tested. -If it is not given, then the current package is tested. -For more information on \[aq]SPEC\[aq] and its format, see the "cargo -help pkgid" command. -.PP -The \f[B]\-\-jobs\f[] argument affects the building of the test -executable but does not affect how many jobs are used when running the -tests. -.PP -Compilation can be configured via the \[aq]test\[aq] profile in the +.if n .RE +.sp +Tests are built with the \fB\-\-test\fP option to \fBrustc\fP which creates an +executable with a \fBmain\fP function that automatically runs all functions +annotated with the \fB#[test]\fP attribute in multiple threads. \fB#[bench]\fP +annotated functions will also be run with one iteration to verify that they +are functional. +.sp +The libtest harness may be disabled by setting \fBharness = false\fP in the target +manifest settings, in which case your code will need to provide its own \fBmain\fP +function to handle running tests. +.sp +Documentation tests are also run by default, which is handled by \fBrustdoc\fP. It +extracts code samples from documentation comments and executes them. See the +.URL "https://doc.rust\-lang.org/rustdoc/" "rustdoc book" " " +for more information on +writing doc tests. +.SH "OPTIONS" +.SS "Test Options" +.sp +\fB\-\-no\-run\fP +.RS 4 +Compile, but don\(cqt run tests. +.RE +.sp +\fB\-\-no\-fail\-fast\fP +.RS 4 +Run all tests regardless of failure. Without this flag, Cargo will exit +after the first executable fails. The Rust test harness will run all +tests within the executable to completion, this flag only applies to +the executable as a whole. +.RE +.SS "Package Selection" +.sp +By default, when no package selection options are given, the packages selected +depend on the current working directory. In the root of a virtual workspace, +all workspace members are selected (\fB\-\-all\fP is implied). Otherwise, only the +package in the current directory will be selected. The default packages may be +overridden with the \fBworkspace.default\-members\fP key in the root \fBCargo.toml\fP manifest. -.PP -By default the rust test harness hides output from test execution to -keep results readable. -Test output can be recovered (e.g. -for debugging) by passing \f[B]\-\-nocapture\f[] to the test binaries: -.IP +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Test only the specified packages. See \fBcargo\-pkgid\fP(1) for the +SPEC format. This flag may be specified multiple times. +.RE +.sp +\fB\-\-all\fP +.RS 4 +Test all members in the workspace. +.RE +.sp +\fB\-\-exclude\fP \fISPEC\fP... +.RS 4 +Exclude the specified packages. Must be used in conjunction with the +\fB\-\-all\fP flag. This flag may be specified multiple times. +.RE +.SS "Target Selection" +.sp +When no target selection options are given, \fBcargo test\fP will build the +following targets of the selected packages: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +lib — used to link with binaries, examples, integration tests, and doc tests +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +bins (only if integration tests are built and required features are +available) +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +examples — to ensure they compile +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +lib as a unit test +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +bins as unit tests +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +integration tests +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +doc tests for the lib target +.RE +.sp +The default behavior can be changed by setting the \fBtest\fP flag for the target +in the manifest settings. Setting examples to \fBtest = true\fP will build and run +the example as a test. Setting targets to \fBtest = false\fP will stop them from +being tested by default. Target selection options that take a target by name +ignore the \fBtest\fP flag and will always test the given target. +.sp +Doc tests for libraries may be disabled by setting \fBdoctest = false\fP for the +library in the manifest. +.sp +Passing target selection flags will test only the +specified targets. +.sp +\fB\-\-lib\fP +.RS 4 +Test the package\(cqs library. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Test the specified binary. This flag may be specified multiple times. +.RE +.sp +\fB\-\-bins\fP +.RS 4 +Test all binary targets. +.RE +.sp +\fB\-\-example\fP \fINAME\fP... +.RS 4 +Test the specified example. This flag may be specified multiple times. +.RE +.sp +\fB\-\-examples\fP +.RS 4 +Test all example targets. +.RE +.sp +\fB\-\-test\fP \fINAME\fP... +.RS 4 +Test the specified integration test. This flag may be specified multiple +times. +.RE +.sp +\fB\-\-tests\fP +.RS 4 +Test all targets in test mode that have the \fBtest = true\fP manifest +flag set. By default this includes the library and binaries built as +unittests, and integration tests. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +unittest, and once as a dependency for binaries, integration tests, etc.). +Targets may be enabled or disabled by setting the \fBtest\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-bench\fP \fINAME\fP... +.RS 4 +Test the specified benchmark. This flag may be specified multiple times. +.RE +.sp +\fB\-\-benches\fP +.RS 4 +Test all targets in benchmark mode that have the \fBbench = true\fP +manifest flag set. By default this includes the library and binaries built +as benchmarks, and bench targets. Be aware that this will also build any +required dependencies, so the lib target may be built twice (once as a +benchmark, and once as a dependency for binaries, benchmarks, etc.). +Targets may be enabled or disabled by setting the \fBbench\fP flag in the +manifest settings for the target. +.RE +.sp +\fB\-\-all\-targets\fP +.RS 4 +Test all targets. This is equivalent to specifying \fB\-\-lib \-\-bins +\-\-tests \-\-benches \-\-examples\fP. +.RE +.sp +\fB\-\-doc\fP +.RS 4 +Test only the library\(cqs documentation. This cannot be mixed with other +target options. +.RE +.SS "Feature Selection" +.sp +When no feature options are given, the \fBdefault\fP feature is activated for +every selected package. +.sp +\fB\-\-features\fP \fIFEATURES\fP +.RS 4 +Space or comma separated list of features to activate. These features only +apply to the current directory\(cqs package. Features of direct dependencies +may be enabled with \fB/\fP syntax. +.RE +.sp +\fB\-\-all\-features\fP +.RS 4 +Activate all available features of all selected packages. +.RE +.sp +\fB\-\-no\-default\-features\fP +.RS 4 +Do not activate the \fBdefault\fP feature of the current directory\(cqs +package. +.RE +.SS "Compilation Options" +.sp +\fB\-\-target\fP \fITRIPLE\fP +.RS 4 +Test for the given architecture. The default is the host +architecture. The general format of the triple is +\fB\-\-\-\fP. Run \fBrustc \-\-print target\-list\fP for a +list of supported targets. +.sp +This may also be specified with the \fBbuild.target\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-release\fP +.RS 4 +Test optimized artifacts with the \fBrelease\fP profile. See the +PROFILES section for details on how this affects profile selection. +.RE +.SS "Output Options" +.sp +\fB\-\-target\-dir\fP \fIDIRECTORY\fP +.RS 4 +Directory for all generated artifacts and intermediate files. May also be +specified with the \fBCARGO_TARGET_DIR\fP environment variable, or the +\fBbuild.target\-dir\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults +to \fBtarget\fP in the root of the workspace. +.RE +.SS "Display Options" +.sp +By default the Rust test harness hides output from test execution to keep +results readable. Test output can be recovered (e.g., for debugging) by passing +\fB\-\-nocapture\fP to the test binaries: +.sp +.if n .RS 4 .nf -\f[C] -cargo\ test\ \-\-\ \-\-nocapture -\f[] +cargo test \-\- \-\-nocapture .fi -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-lib -Test only this package\[aq]s library. -.RS -.RE -.TP -.B \-\-doc -Test only this library\[aq]s documentation -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Test only the specified binary. -.RS -.RE -.TP -.B \-\-example \f[I]NAME\f[] -Test only the specified example. -.RS -.RE -.TP -.B \-\-test \f[I]NAME\f[] -Test only the specified integration test target. -.RS -.RE -.TP -.B \-\-bench \f[I]NAME\f[] -Test only the specified benchmark target. -.RS -.RE -.TP -.B \-\-no\-run -Compile, but don\[aq]t run tests. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to run tests for. -.RS -.RE -.TP -.B \-j \f[I]IN\f[], \-\-jobs \f[I]IN\f[] -Number of parallel jobs, defaults to # of CPUs. -.RS -.RE -.TP -.B \-\-release -Build artifacts in release mode, with optimizations. -.RS -.RE -.TP -.B \-\-features \f[I]FEATURES\f[] -Space\-separated list of features to also build. -.RS -.RE -.TP -.B \-\-all\-features -Build all available features. -.RS -.RE -.TP -.B \-\-no\-default\-features -Do not build the \f[C]default\f[] feature. -.RS -.RE -.TP -.B \-\-target \f[I]TRIPLE\f[] -Build for the target triple. -.RS -.RE -.TP -.B \-\-manifest\-path \f[I]PATH\f[] -Path to the Cargo.toml to compile. -.RS -.RE -.TP -.B \-\-no\-fail\-fast -Run all tests regardless of failure. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +.if n .RE +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH EXAMPLES -.PP -Execute all the unit and integration tests of the current package -.IP +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-\-message\-format\fP \fIFMT\fP +.RS 4 +The output format for diagnostic messages. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBhuman\fP (default): Display in a human\-readable text format. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBjson\fP: Emit JSON messages to stdout. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBshort\fP: Emit shorter, human\-readable text messages. +.RE +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SS "Miscellaneous Options" +.sp +The \fB\-\-jobs\fP argument affects the building of the test executable but does not +affect how many threads are used when running the tests. The Rust test harness +includes an option to control the number of threads used: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ test -\f[] +cargo test \-j 2 \-\- \-\-test\-threads=2 .fi -.PP -Execute the BENCH benchmark -.IP +.if n .RE +.sp +\fB\-j\fP \fIN\fP, \fB\-\-jobs\fP \fIN\fP +.RS 4 +Number of parallel jobs to run. May also be specified with the +\fBbuild.jobs\fP \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +Defaults to +the number of CPUs. +.RE +.SH "PROFILES" +.sp +Profiles may be used to configure compiler options such as optimization levels +and debug settings. See +\c +.URL "https://doc.rust\-lang.org/cargo/reference/manifest.html#the\-profile\-sections" "the reference" +for more details. +.sp +Profile selection depends on the target and crate being built. By default the +\fBdev\fP or \fBtest\fP profiles are used. If the \fB\-\-release\fP flag is given, then the +\fBrelease\fP or \fBbench\fP profiles are used. +.TS +allbox tab(:); +lt lt lt. +T{ +.sp +Target +T}:T{ +.sp +Default Profile +T}:T{ +.sp +\fB\-\-release\fP Profile +T} +T{ +.sp +lib, bin, example +T}:T{ +.sp +\fBdev\fP +T}:T{ +.sp +\fBrelease\fP +T} +T{ +.sp +test, bench, or any target +.br +in "test" or "bench" mode +T}:T{ +.sp +\fBtest\fP +T}:T{ +.sp +\fBbench\fP +T} +.TE +.sp +.sp +Dependencies use the \fBdev\fP/\fBrelease\fP profiles. +.sp +Unit tests are separate executable artifacts which use the \fBtest\fP/\fBbench\fP +profiles. Example targets are built the same as with \fBcargo build\fP (using the +\fBdev\fP/\fBrelease\fP profiles) unless you are building them with the test harness +(by setting \fBtest = true\fP in the manifest or using the \fB\-\-example\fP flag) in +which case they use the \fBtest\fP/\fBbench\fP profiles. Library targets are built +with the \fBdev\fP/\fBrelease\fP profiles when linked to an integration test, binary, +or doctest. +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Execute all the unit and integration tests of the current package: +.sp +.if n .RS 4 .nf -\f[C] -$\ cargo\ test\ \-\-bench\ BENCH -\f[] +cargo test .fi -.SH SEE ALSO -.PP -cargo(1), cargo\-build(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Run only a specific test within a specific integration test: +.sp +.if n .RS 4 +.nf +cargo test \-\-test int_test_name \-\- modname::test_name +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-bench\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-uninstall.1 cargo-0.35.0/src/etc/man/cargo-uninstall.1 --- cargo-0.33.0/src/etc/man/cargo-uninstall.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-uninstall.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,56 +1,223 @@ -.TH "CARGO\-UNINSTALL" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-uninstall +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-UNINSTALL" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-uninstall \- Remove a Rust binary -.SH SYNOPSIS -.PP -\f[I]cargo uninstall\f[] [OPTIONS] -.PP -\f[I]cargo uninstall\f[] (\-h | \-\-help) -.SH DESCRIPTION -.PP -The argument SPEC is a package id specification (see -\f[C]cargo\ help\ pkgid\f[]) to specify which crate should be -uninstalled. -By default all binaries are uninstalled for a crate but the -\f[C]\-\-bin\f[] and \f[C]\-\-example\f[] flags can be used to only -uninstall particular binaries. -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-root \f[I]DIR\f[] +.SH "SYNOPSIS" +.sp +\fBcargo uninstall [\fIOPTIONS\fP] [\fISPEC\fP...]\fP +.SH "DESCRIPTION" +.sp +This command removes a package installed with \fBcargo\-install\fP(1). The \fISPEC\fP +argument is a package ID specification of the package to remove (see +\fBcargo\-pkgid\fP(1)). +.sp +By default all binaries are removed for a crate but the \fB\-\-bin\fP and +\fB\-\-example\fP flags can be used to only remove particular binaries. +.sp +The installation root is determined, in order of precedence: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fB\-\-root\fP option +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_INSTALL_ROOT\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBinstall.root\fP Cargo \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "" +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBCARGO_HOME\fP environment variable +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fB$HOME/.cargo\fP +.RE +.SH "OPTIONS" +.SS "Install Options" +.sp +\fB\-p\fP, \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Package to uninstall. +.RE +.sp +\fB\-\-bin\fP \fINAME\fP... +.RS 4 +Only uninstall the binary \fINAME\fP. +.RE +.sp +\fB\-\-root\fP \fIDIR\fP +.RS 4 Directory to uninstall packages from. -.RS -.RE -.TP -.B \-\-bin \f[I]NAME\f[] -Only uninstall the binary NAME. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS .RE -.TP -.B \-q, \-\-quiet +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo-install(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Uninstall a previously installed package. +.sp +.if n .RS 4 +.nf +cargo uninstall ripgrep +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-install\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-update.1 cargo-0.35.0/src/etc/man/cargo-update.1 --- cargo-0.33.0/src/etc/man/cargo-update.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-update.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,80 +1,232 @@ -.TH "CARGO\-UPDATE" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP -cargo\-update \- Update the package dependencies -.SH SYNOPSIS -.PP -\f[I]cargo update\f[] [OPTIONS] -.SH DESCRIPTION -.PP -Update dependencies as recorded in the local lock file. -.PP -This command requires that a \f[I]Cargo.lock\f[] already exists as -generated by \f[I]cargo build\f[] or related commands. -.PP -If \f[I]SPEC\f[] is given, then a conservative update of the -\f[I]lockfile\f[] will be performed. -This means that only the dependency specified by \f[I]SPEC\f[] will be -updated. -Its transitive dependencies will be updated only if \f[I]SPEC\f[] cannot -be updated without updating dependencies. -All other dependencies will remain locked at their currently recorded -versions. -.PP -If \f[I]PRECISE\f[] is specified, then \f[B]\-\-aggressive\f[] must not -also be specified. -The argument \f[I]PRECISE\f[] is a string representing a precise -revision that the package being updated should be updated to. -For example, if the package comes from a git repository, then -\f[I]PRECISE\f[] would be the exact revision that the repository should -be updated to. -.PP -If \f[I]SPEC\f[] is not given, then all dependencies will be -re\-resolved and updated. -.PP -For more information about package id specifications, see "cargo help -pkgid". -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-p \f[I]SPEC\f[], \-\-package \f[I]SPEC ...\f[] -Package to update. -.RS -.RE -.TP -.B \-\-aggressive -Force updating all dependencies of as well. -.RS -.RE -.TP -.B \-\-precise \f[I]PRECISE\f[] -Update a single dependency to exactly \f[I]PRECISE\f[]. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS -.RE -.TP -.B \-q, \-\-quiet +'\" t +.\" Title: cargo-update +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-UPDATE" "1" "2018-12-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-update \- Update dependencies as recorded in the local lock file +.SH "SYNOPSIS" +.sp +\fBcargo update [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will update dependencies in the \fBCargo.lock\fP file to the latest +version. It requires that the \fBCargo.lock\fP file already exists as generated +by commands such as \fBcargo\-build\fP(1) or \fBcargo\-generate\-lockfile\fP(1). +.SH "OPTIONS" +.SS "Update Options" +.sp +\fB\-p\fP \fISPEC\fP..., \fB\-\-package\fP \fISPEC\fP... +.RS 4 +Update only the specified packages. This flag may be specified +multiple times. See \fBcargo\-pkgid\fP(1) for the SPEC format. +.sp +If packages are specified with the \fB\-p\fP flag, then a conservative update of +the lockfile will be performed. This means that only the dependency specified +by SPEC will be updated. Its transitive dependencies will be updated only if +SPEC cannot be updated without updating dependencies. All other dependencies +will remain locked at their currently recorded versions. +.sp +If \fB\-p\fP is not specified, all dependencies are updated. +.RE +.sp +\fB\-\-aggressive\fP +.RS 4 +When used with \fB\-p\fP, dependencies of \fISPEC\fP are forced to update as well. +Cannot be used with \fB\-\-precise\fP. +.RE +.sp +\fB\-\-precise\fP \fIPRECISE\fP +.RS 4 +When used with \fB\-p\fP, allows you to specify a specific version number to +set the package to. If the package comes from a git repository, this can +be a git revision (such as a SHA hash or tag). +.RE +.sp +\fB\-\-dry\-run\fP +.RS 4 +Displays what would be updated, but doesn\(cqt actually write the lockfile. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Update all dependencies in the lockfile: +.sp +.if n .RS 4 +.nf +cargo update +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +Update only specific dependencies: +.sp +.if n .RS 4 +.nf +cargo update \-p foo \-p bar +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Set a specific dependency to a specific version: +.sp +.if n .RS 4 +.nf +cargo update \-p foo \-\-precise 1.2.3 +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-generate\-lockfile\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-verify-project.1 cargo-0.35.0/src/etc/man/cargo-verify-project.1 --- cargo-0.33.0/src/etc/man/cargo-verify-project.1 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-verify-project.1 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,178 @@ +'\" t +.\" Title: cargo-verify-project +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-VERIFY\-PROJECT" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" +cargo\-verify\-project \- Check correctness of crate manifest +.SH "SYNOPSIS" +.sp +\fBcargo verify\-project [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +This command will parse the local manifest and check its validity. It emits a +JSON object with the result. A successful validation will display: +.sp +.if n .RS 4 +.nf +{"success":"true"} +.fi +.if n .RE +.sp +An invalid workspace will display: +.sp +.if n .RS 4 +.nf +{"invalid":"human\-readable error message"} +.fi +.if n .RE +.SH "OPTIONS" +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 +No output printed to stdout. +.RE +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Manifest Options" +.sp +\fB\-\-manifest\-path\fP \fIPATH\fP +.RS 4 +Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current +directory or any parent directory for the \fBCargo.toml\fP file. +.RE +.sp +\fB\-\-frozen\fP, \fB\-\-locked\fP +.RS 4 +Either of these flags requires that the \fBCargo.lock\fP file is +up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will +exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from +attempting to access the network to determine if it is out\-of\-date. +.sp +These may be used in environments where you want to assert that the +\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network +access. +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +The workspace is OK. +.RE +.sp +1 +.RS 4 +The workspace is invalid. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Check the current workspace for errors: +.sp +.if n .RS 4 +.nf +cargo verify\-project +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-package\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-version.1 cargo-0.35.0/src/etc/man/cargo-version.1 --- cargo-0.33.0/src/etc/man/cargo-version.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-version.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,31 +1,99 @@ -.TH "CARGO\-VERSION" "1" "May 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-version +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2018-12-20 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-VERSION" "1" "2018-12-20" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-version \- Show version information -.SH SYNOPSIS -.PP -\f[I]cargo version\f[] [OPTIONS] -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS +.SH "SYNOPSIS" +.sp +\fBcargo version [\fIOPTIONS\fP]\fP +.SH "DESCRIPTION" +.sp +Displays the version of Cargo. +.SH "OPTIONS" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Display additional version information. .RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Display the version: +.sp +.if n .RS 4 +.nf +cargo version +.fi +.if n .RE .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 2." 4.2 +.\} +The version is also available via flags: +.sp +.if n .RS 4 +.nf +cargo \-\-version +cargo \-V +.fi +.if n .RE .RE -.SH SEE ALSO -.PP -cargo(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +Display extra version information: +.sp +.if n .RS 4 +.nf +cargo \-Vv +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/src/etc/man/cargo-yank.1 cargo-0.35.0/src/etc/man/cargo-yank.1 --- cargo-0.33.0/src/etc/man/cargo-yank.1 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/src/etc/man/cargo-yank.1 2019-04-01 21:32:07.000000000 +0000 @@ -1,68 +1,194 @@ -.TH "CARGO\-YANK" "1" "July 2016" "The Rust package manager" "Cargo Manual" -.hy -.SH NAME -.PP +'\" t +.\" Title: cargo-yank +.\" Author: [see the "AUTHOR(S)" section] +.\" Generator: Asciidoctor 1.5.8 +.\" Date: 2019-01-23 +.\" Manual: \ \& +.\" Source: \ \& +.\" Language: English +.\" +.TH "CARGO\-YANK" "1" "2019-01-23" "\ \&" "\ \&" +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.ss \n[.ss] 0 +.nh +.ad l +.de URL +\fI\\$2\fP <\\$1>\\$3 +.. +.als MTO URL +.if \n[.g] \{\ +. mso www.tmac +. am URL +. ad l +. . +. am MTO +. ad l +. . +. LINKSTYLE blue R < > +.\} +.SH "NAME" cargo\-yank \- Remove a pushed crate from the index -.SH SYNOPSIS -.PP -\f[I]cargo yank\f[] [OPTIONS] [] -.SH DESCRIPTION -.PP -The yank command removes a previously pushed crate\[aq]s version from -the server\[aq]s index. -This command does not delete any data, and the crate will still be -available for download via the registry\[aq]s download link. -.PP -Note that existing crates locked to a yanked version will still be able -to download the yanked version to use it. -Cargo will, however, not allow any new crates to be locked to any yanked -version. -.PP -.SH OPTIONS -.TP -.B \-h, \-\-help -Print this message. -.RS -.RE -.TP -.B \-\-vers \f[I]VERSION\f[] -The version to yank or un-yank. -.RS -.RE -.TP -.B \-\-undo +.SH "SYNOPSIS" +.sp +\fBcargo yank [\fIOPTIONS\fP] \-\-vers \fIVERSION\fP [\fICRATE\fP]\fP +.SH "DESCRIPTION" +.sp +The yank command removes a previously published crate\(cqs version from the +server\(cqs index. This command does not delete any data, and the crate will +still be available for download via the registry\(cqs download link. +.sp +Note that existing crates locked to a yanked version will still be able to +download the yanked version to use it. Cargo will, however, not allow any new +crates to be locked to any yanked version. +.sp +This command requires you to be authenticated with either the \fB\-\-token\fP option +or using \fBcargo\-login\fP(1). +.sp +If the crate name is not specified, it will use the package name from the +current directory. +.SH "OPTIONS" +.SS "Owner Options" +.sp +\fB\-\-vers\fP \fIVERSION\fP +.RS 4 +The version to yank or un\-yank. +.RE +.sp +\fB\-\-undo\fP +.RS 4 Undo a yank, putting a version back into the index. -.RS -.RE -.TP -.B \-\-index \f[I]INDEX\f[] -Registry index to yank from. -.RS -.RE -.TP -.B \-\-token \f[I]TOKEN\f[] -API token to use when authenticating. -.RS -.RE -.TP -.B \-v, \-\-verbose -Use verbose output. -.RS .RE -.TP -.B \-q, \-\-quiet +.sp +\fB\-\-token\fP \fITOKEN\fP +.RS 4 +API token to use when authenticating. This overrides the token stored in +the credentials file (which is created by \fBcargo\-login\fP(1)). +.sp +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config" " " +environment variables can be +used to override the tokens stored in the credentials file. The token for +crates.io may be specified with the \fBCARGO_REGISTRY_TOKEN\fP environment +variable. Tokens for other registries may be specified with environment +variables of the form \fBCARGO_REGISTRIES_NAME_TOKEN\fP where \fBNAME\fP is the name +of the registry in all capital letters. +.RE +.sp +\fB\-\-index\fP \fIINDEX\fP +.RS 4 +The URL of the registry index to use. +.RE +.sp +\fB\-\-registry\fP \fIREGISTRY\fP +.RS 4 +Name of the registry to use. Registry names are defined in \c +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "Cargo config files" "." +If not specified, the default registry is used, which is defined by the +\fBregistry.default\fP config key which defaults to \fBcrates\-io\fP. +.RE +.SS "Display Options" +.sp +\fB\-v\fP, \fB\-\-verbose\fP +.RS 4 +Use verbose output. May be specified twice for "very verbose" output which +includes extra output such as dependency warnings and build script output. +May also be specified with the \fBterm.verbose\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.sp +\fB\-q\fP, \fB\-\-quiet\fP +.RS 4 No output printed to stdout. -.RS .RE -.TP -.B \-\-color \f[I]WHEN\f[] -Coloring: auto, always, never. -.RS -.RE -.SH SEE ALSO -.PP -cargo(1), cargo\-owner(1), cargo\-version(1) -.SH COPYRIGHT -.PP -This work is dual\-licensed under Apache 2.0 and MIT terms. -See \f[I]COPYRIGHT\f[] file in the cargo source distribution. +.sp +\fB\-\-color\fP \fIWHEN\fP +.RS 4 +Control when colored output is used. Valid values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBauto\fP (default): Automatically detect if color support is available on the +terminal. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBalways\fP: Always display colors. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +\fBnever\fP: Never display colors. +.RE +.sp +May also be specified with the \fBterm.color\fP +.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "." +.RE +.SS "Common Options" +.sp +\fB\-h\fP, \fB\-\-help\fP +.RS 4 +Prints help information. +.RE +.sp +\fB\-Z\fP \fIFLAG\fP... +.RS 4 +Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for +details. +.RE +.SH "ENVIRONMENT" +.sp +See \c +.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " " +for +details on environment variables that Cargo reads. +.SH "EXIT STATUS" +.sp +0 +.RS 4 +Cargo succeeded. +.RE +.sp +101 +.RS 4 +Cargo failed to complete. +.RE +.SH "EXAMPLES" +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 1." 4.2 +.\} +Yank a crate from the index: +.sp +.if n .RS 4 +.nf +cargo yank \-\-vers 1.0.7 foo +.fi +.if n .RE +.RE +.SH "SEE ALSO" +.sp +\fBcargo\fP(1), \fBcargo\-login\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file diff -Nru cargo-0.33.0/tests/testsuite/alt_registry.rs cargo-0.35.0/tests/testsuite/alt_registry.rs --- cargo-0.33.0/tests/testsuite/alt_registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/alt_registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,34 +1,9 @@ -use std::fs::File; +use crate::support::publish::validate_alt_upload; +use crate::support::registry::{self, Package}; +use crate::support::{basic_manifest, git, paths, project}; +use cargo::util::ToUrl; +use std::fs::{self, File}; use std::io::Write; -use support::registry::{self, alt_api_path, Package}; -use support::{basic_manifest, paths, project}; - -#[test] -fn is_feature_gated() { - let p = project() - .file( - "Cargo.toml", - r#" - [project] - name = "foo" - version = "0.0.1" - authors = [] - - [dependencies.bar] - version = "0.0.1" - registry = "alternative" - "#, - ).file("src/main.rs", "fn main() {}") - .build(); - - Package::new("bar", "0.0.1").alternative(true).publish(); - - p.cargo("build") - .masquerade_as_nightly_cargo() - .with_status(101) - .with_stderr_contains(" feature `alternative-registries` is required") - .run(); -} #[test] fn depend_on_alt_registry() { @@ -36,8 +11,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -47,13 +20,13 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").alternative(true).publish(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr(&format!( "\ [UPDATING] `{reg}` index @@ -64,20 +37,21 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", reg = registry::alt_registry_path().to_str().unwrap() - )).run(); + )) + .run(); - p.cargo("clean").masquerade_as_nightly_cargo().run(); + p.cargo("clean").run(); // Don't download a second time p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr( "\ [COMPILING] bar v0.0.1 (registry `[ROOT][..]`) [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -86,8 +60,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -97,17 +69,17 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").alternative(true).publish(); Package::new("bar", "0.0.1") - .dep("baz", "0.0.1") + .registry_dep("baz", "0.0.1") .alternative(true) .publish(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr(&format!( "\ [UPDATING] `{reg}` index @@ -120,7 +92,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", reg = registry::alt_registry_path().to_str().unwrap() - )).run(); + )) + .run(); } #[test] @@ -129,8 +102,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -140,17 +111,17 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").alternative(true).publish(); Package::new("bar", "0.0.1") - .registry_dep("baz", "0.0.1", registry::alt_registry().as_str()) + .registry_dep("baz", "0.0.1") .alternative(true) .publish(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr(&format!( "\ [UPDATING] `{reg}` index @@ -163,7 +134,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", reg = registry::alt_registry_path().to_str().unwrap() - )).run(); + )) + .run(); } #[test] @@ -172,8 +144,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -183,32 +153,33 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); Package::new("bar", "0.0.1") - .registry_dep("baz", "0.0.1", registry::registry().as_str()) + .dep("baz", "0.0.1") .alternative(true) .publish(); p.cargo("build") - .masquerade_as_nightly_cargo() - .with_stderr(&format!( + .with_stderr_unordered(&format!( "\ [UPDATING] `{alt_reg}` index [UPDATING] `{reg}` index [DOWNLOADING] crates ... -[DOWNLOADED] [..] v0.0.1 (registry `[ROOT][..]`) -[DOWNLOADED] [..] v0.0.1 (registry `[ROOT][..]`) -[COMPILING] baz v0.0.1 (registry `[ROOT][..]`) +[DOWNLOADED] baz v0.0.1 (registry `[ROOT][..]`) +[DOWNLOADED] bar v0.0.1 (registry `[ROOT][..]`) +[COMPILING] baz v0.0.1 [COMPILING] bar v0.0.1 (registry `[ROOT][..]`) [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", alt_reg = registry::alt_registry_path().to_str().unwrap(), reg = registry::registry_path().to_str().unwrap() - )).run(); + )) + .run(); } #[test] @@ -219,8 +190,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -230,20 +199,21 @@ path = "bar" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr( "\ [COMPILING] bar v0.0.1 ([CWD]/bar) [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -254,8 +224,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -265,20 +233,27 @@ git = "" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("build").masquerade_as_nightly_cargo().with_status(101) - .with_stderr_contains(" dependency (bar) specification is ambiguous. Only one of `git` or `registry` is allowed.").run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains( + " dependency (bar) specification is ambiguous. \ + Only one of `git` or `registry` is allowed.", + ) + .run(); } #[test] fn cannot_publish_to_crates_io_with_registry_dependency() { + let fakeio_path = paths::root().join("fake.io"); + let fakeio_url = fakeio_path.to_url().unwrap(); let p = project() .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] [project] name = "foo" version = "0.0.1" @@ -287,15 +262,42 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") + .file( + ".cargo/config", + &format!( + r#" + [registries.fakeio] + index = "{}" + "#, + fakeio_url + ), + ) .build(); Package::new("bar", "0.0.1").alternative(true).publish(); + // Since this can't really call plain `publish` without fetching the real + // crates.io index, create a fake one that points to the real crates.io. + git::repo(&fakeio_path) + .file( + "config.json", + r#" + {"dl": "https://crates.io/api/v1/crates", "api": "https://crates.io"} + "#, + ) + .build(); + + p.cargo("publish --registry fakeio") + .with_status(101) + .with_stderr_contains("[ERROR] crates cannot be published to crates.io[..]") + .run(); + p.cargo("publish --index") - .arg(registry::registry().to_string()) - .masquerade_as_nightly_cargo() + .arg(fakeio_url.to_string()) .with_status(101) + .with_stderr_contains("[ERROR] crates cannot be published to crates.io[..]") .run(); } @@ -305,8 +307,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -316,19 +316,50 @@ version = "0.0.1" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").alternative(true).publish(); // Login so that we have the token available - p.cargo("login --registry alternative TOKEN -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("login --registry alternative TOKEN").run(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("publish --registry alternative").run(); + + validate_alt_upload( + r#"{ + "authors": [], + "badges": {}, + "categories": [], + "deps": [ + { + "default_features": true, + "features": [], + "kind": "normal", + "name": "bar", + "optional": false, + "target": null, + "version_req": "^0.0.1" + } + ], + "description": null, + "documentation": null, + "features": {}, + "homepage": null, + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.0.1" + }"#, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + ); } #[test] @@ -337,8 +368,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -351,7 +380,8 @@ version = "0.1.0" registry = "alternative" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("crates_io_dep", "0.0.1").publish(); @@ -360,13 +390,14 @@ .publish(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_stderr_contains(format!( "[UPDATING] `{}` index", registry::alt_registry_path().to_str().unwrap() - )).with_stderr_contains(&format!( + )) + .with_stderr_contains(&format!( "[UPDATING] `{}` index", - registry::registry_path().to_str().unwrap())) + registry::registry_path().to_str().unwrap() + )) .with_stderr_contains("[DOWNLOADED] crates_io_dep v0.0.1 (registry `[ROOT][..]`)") .with_stderr_contains("[DOWNLOADED] alt_reg_dep v0.1.0 (registry `[ROOT][..]`)") .with_stderr_contains("[COMPILING] alt_reg_dep v0.1.0 (registry `[ROOT][..]`)") @@ -383,9 +414,10 @@ // Setup the registry by publishing a package Package::new("bar", "0.0.1").alternative(true).publish(); + fs::remove_file(paths::home().join(".cargo/credentials")).unwrap(); + // Now perform the actual publish - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + p.cargo("publish --registry alternative") .with_status(101) .with_stderr_contains("error: no upload token found, please run `cargo login`") .run(); @@ -393,35 +425,40 @@ #[test] fn publish_to_alt_registry() { - let p = project() - .file( - "Cargo.toml", - r#" - cargo-features = ["alternative-registries"] - - [project] - name = "foo" - version = "0.0.1" - authors = [] - "#, - ).file("src/main.rs", "fn main() {}") - .build(); + let p = project().file("src/main.rs", "fn main() {}").build(); // Setup the registry by publishing a package Package::new("bar", "0.0.1").alternative(true).publish(); // Login so that we have the token available - p.cargo("login --registry alternative TOKEN -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("login --registry alternative TOKEN").run(); // Now perform the actual publish - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("publish --registry alternative").run(); - // Ensure that the crate is uploaded - assert!(alt_api_path().join("api/v1/crates/new").exists()); + validate_alt_upload( + r#"{ + "authors": [], + "badges": {}, + "categories": [], + "deps": [], + "description": null, + "documentation": null, + "features": {}, + "homepage": null, + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.0.1" + }"#, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + ); } #[test] @@ -430,8 +467,6 @@ .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" @@ -442,19 +477,51 @@ [dependencies.bar] version = "0.0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); // Login so that we have the token available - p.cargo("login --registry alternative TOKEN -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("login --registry alternative TOKEN").run(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("publish --registry alternative").run(); + + validate_alt_upload( + r#"{ + "authors": ["me"], + "badges": {}, + "categories": [], + "deps": [ + { + "default_features": true, + "features": [], + "kind": "normal", + "name": "bar", + "optional": false, + "registry": "https://github.com/rust-lang/crates.io-index", + "target": null, + "version_req": "^0.0.1" + } + ], + "description": "foo", + "documentation": null, + "features": {}, + "homepage": null, + "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.0.1" + }"#, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + ); } #[test] @@ -470,25 +537,598 @@ [registries.alternative] index = "ssh://git:secret@foobar.com" "#, - ).unwrap(); + ) + .unwrap(); + let p = project().file("src/main.rs", "fn main() {}").build(); + + p.cargo("publish --registry alternative") + .with_status(101) + .with_stderr_contains("error: Registry URLs may not contain passwords") + .run(); +} + +#[test] +fn patch_alt_reg() { + Package::new("bar", "0.1.0").publish(); let p = project() .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] + [package] + name = "foo" + version = "0.0.1" + [dependencies] + bar = { version = "0.1.0", registry = "alternative" } + + [patch.alternative] + bar = { path = "bar" } + "#, + ) + .file( + "src/lib.rs", + " + extern crate bar; + pub fn f() { bar::bar(); } + ", + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + .file("bar/src/lib.rs", "pub fn bar() {}") + .build(); + + p.cargo("build") + .with_stderr( + "\ +[UPDATING] `[ROOT][..]` index +[COMPILING] bar v0.1.0 ([CWD]/bar) +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); +} + +#[test] +fn bad_registry_name() { + let p = project() + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" authors = [] + + [dependencies.bar] + version = "0.0.1" + registry = "bad name" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + p.cargo("build") .with_status(101) - .with_stderr_contains("error: Registry URLs may not contain passwords") + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + Invalid character ` ` in registry name: `bad name`", + ) + .run(); + + for cmd in &[ + "init", "install", "login", "owner", "publish", "search", "yank", + ] { + p.cargo(cmd) + .arg("--registry") + .arg("bad name") + .with_status(101) + .with_stderr("[ERROR] Invalid character ` ` in registry name: `bad name`") + .run(); + } +} + +#[test] +fn no_api() { + Package::new("bar", "0.0.1").alternative(true).publish(); + // Configure without `api`. + let repo = git2::Repository::open(registry::alt_registry_path()).unwrap(); + let cfg_path = registry::alt_registry_path().join("config.json"); + fs::write( + cfg_path, + format!(r#"{{"dl": "{}"}}"#, registry::alt_dl_url()), + ) + .unwrap(); + git::add(&repo); + git::commit(&repo); + + // First check that a dependency works. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies.bar] + version = "0.0.1" + registry = "alternative" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("build") + .with_stderr(&format!( + "\ +[UPDATING] `{reg}` index +[DOWNLOADING] crates ... +[DOWNLOADED] bar v0.0.1 (registry `[ROOT][..]`) +[COMPILING] bar v0.0.1 (registry `[ROOT][..]`) +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s +", + reg = registry::alt_registry_path().to_str().unwrap() + )) + .run(); + + // Check all of the API commands. + let err = format!( + "[ERROR] registry `{}` does not support API commands", + registry::alt_registry_path().display() + ); + + p.cargo("login --registry alternative TOKEN") + .with_status(101) + .with_stderr_contains(&err) + .run(); + + p.cargo("publish --registry alternative") + .with_status(101) + .with_stderr_contains(&err) + .run(); + + p.cargo("search --registry alternative") + .with_status(101) + .with_stderr_contains(&err) + .run(); + + p.cargo("owner --registry alternative --list") + .with_status(101) + .with_stderr_contains(&err) + .run(); + + p.cargo("yank --registry alternative --vers=0.0.1 bar") + .with_status(101) + .with_stderr_contains(&err) + .run(); + + p.cargo("yank --registry alternative --vers=0.0.1 bar") + .with_stderr_contains(&err) + .with_status(101) + .run(); +} + +#[test] +fn alt_reg_metadata() { + // Check for "registry" entries in `cargo metadata` with alternative registries. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + altdep = { version = "0.0.1", registry = "alternative" } + iodep = { version = "0.0.1" } + "#, + ) + .file("src/lib.rs", "") + .build(); + + Package::new("bar", "0.0.1").publish(); + Package::new("altdep", "0.0.1") + .dep("bar", "0.0.1") + .alternative(true) + .publish(); + Package::new("altdep2", "0.0.1").alternative(true).publish(); + Package::new("iodep", "0.0.1") + .registry_dep("altdep2", "0.0.1") + .publish(); + + // The important thing to check here is the "registry" value in `deps`. + // They should be: + // foo -> altdep: alternative-registry + // foo -> iodep: null (because it is in crates.io) + // altdep -> bar: null (because it is in crates.io) + // iodep -> altdep2: alternative-registry + p.cargo("metadata --format-version=1 --no-deps") + .with_json( + r#" + { + "packages": [ + { + "name": "foo", + "version": "0.0.1", + "id": "foo 0.0.1 (path+file:[..]/foo)", + "license": null, + "license_file": null, + "description": null, + "source": null, + "dependencies": [ + { + "name": "altdep", + "source": "registry+file:[..]/alternative-registry", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": "file:[..]/alternative-registry" + }, + { + "name": "iodep", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/foo/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + } + ], + "workspace_members": [ + "foo 0.0.1 (path+file:[..]/foo)" + ], + "resolve": null, + "target_directory": "[..]/foo/target", + "version": 1, + "workspace_root": "[..]/foo" + }"#, + ) + .run(); + + // --no-deps uses a different code path, make sure both work. + p.cargo("metadata --format-version=1") + .with_json( + r#" + { + "packages": [ + { + "name": "altdep2", + "version": "0.0.1", + "id": "altdep2 0.0.1 (registry+file:[..]/alternative-registry)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+file:[..]/alternative-registry", + "dependencies": [], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/altdep2-0.0.1/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "altdep", + "version": "0.0.1", + "id": "altdep 0.0.1 (registry+file:[..]/alternative-registry)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+file:[..]/alternative-registry", + "dependencies": [ + { + "name": "bar", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/altdep-0.0.1/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "foo", + "version": "0.0.1", + "id": "foo 0.0.1 (path+file:[..]/foo)", + "license": null, + "license_file": null, + "description": null, + "source": null, + "dependencies": [ + { + "name": "altdep", + "source": "registry+file:[..]/alternative-registry", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": "file:[..]/alternative-registry" + }, + { + "name": "iodep", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/foo/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "iodep", + "version": "0.0.1", + "id": "iodep 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { + "name": "altdep2", + "source": "registry+file:[..]/alternative-registry", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": "file:[..]/alternative-registry" + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/iodep-0.0.1/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "bar", + "version": "0.0.1", + "id": "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/bar-0.0.1/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + } + ], + "workspace_members": [ + "foo 0.0.1 (path+file:[..]/foo)" + ], + "resolve": "{...}", + "target_directory": "[..]/foo/target", + "version": 1, + "workspace_root": "[..]/foo" + }"#, + ) + .run(); +} + +#[test] +fn unknown_registry() { + // A known registry refers to an unknown registry. + // foo -> bar(crates.io) -> baz(alt) + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + version = "0.0.1" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("baz", "0.0.1").alternative(true).publish(); + Package::new("bar", "0.0.1") + .registry_dep("baz", "0.0.1") + .publish(); + + // Remove "alternative" from config. + let cfg_path = paths::home().join(".cargo/config"); + let mut config = fs::read_to_string(&cfg_path).unwrap(); + let start = config.find("[registries.alternative]").unwrap(); + config.insert(start, '#'); + let start_index = &config[start..].find("index =").unwrap(); + config.insert(start + start_index, '#'); + fs::write(&cfg_path, config).unwrap(); + + p.cargo("build").run(); + + // Important parts: + // foo -> bar registry = null + // bar -> baz registry = alternate + p.cargo("metadata --format-version=1") + .with_json( + r#" + { + "packages": [ + { + "name": "baz", + "version": "0.0.1", + "id": "baz 0.0.1 (registry+file://[..]/alternative-registry)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+file://[..]/alternative-registry", + "dependencies": [], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "foo", + "version": "0.0.1", + "id": "foo 0.0.1 (path+file://[..]/foo)", + "license": null, + "license_file": null, + "description": null, + "source": null, + "dependencies": [ + { + "name": "bar", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": null + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]/foo/Cargo.toml", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + }, + { + "name": "bar", + "version": "0.0.1", + "id": "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "license": null, + "license_file": null, + "description": null, + "source": "registry+https://github.com/rust-lang/crates.io-index", + "dependencies": [ + { + "name": "baz", + "source": "registry+file://[..]/alternative-registry", + "req": "^0.0.1", + "kind": null, + "rename": null, + "optional": false, + "uses_default_features": true, + "features": [], + "target": null, + "registry": "file:[..]/alternative-registry" + } + ], + "targets": "{...}", + "features": {}, + "manifest_path": "[..]", + "metadata": null, + "authors": [], + "categories": [], + "keywords": [], + "readme": null, + "repository": null, + "edition": "2015", + "links": null + } + ], + "workspace_members": [ + "foo 0.0.1 (path+file://[..]/foo)" + ], + "resolve": "{...}", + "target_directory": "[..]/foo/target", + "version": 1, + "workspace_root": "[..]/foo" + } + "#, + ) .run(); } diff -Nru cargo-0.33.0/tests/testsuite/bad_config.rs cargo-0.35.0/tests/testsuite/bad_config.rs --- cargo-0.33.0/tests/testsuite/bad_config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/bad_config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; #[test] fn bad1() { @@ -11,7 +11,8 @@ [target] nonexistent-target = "foo" "#, - ).build(); + ) + .build(); p.cargo("build -v --target=nonexistent-target") .with_status(101) .with_stderr( @@ -19,7 +20,8 @@ [ERROR] expected table for configuration key `target.nonexistent-target`, \ but found string in [..]config ", - ).run(); + ) + .run(); } #[test] @@ -32,7 +34,8 @@ [http] proxy = 3.0 "#, - ).build(); + ) + .build(); p.cargo("publish -v") .with_status(101) .with_stderr( @@ -51,7 +54,8 @@ Caused by: found TOML configuration value of unknown type `float` ", - ).run(); + ) + .run(); } #[test] @@ -64,7 +68,8 @@ [http] proxy = true "#, - ).build(); + ) + .build(); Package::new("foo", "1.0.0").publish(); p.cargo("publish -v") @@ -76,7 +81,8 @@ Caused by: error in [..]config: `http.proxy` expected a string, but found a boolean ", - ).run(); + ) + .run(); } #[test] @@ -88,7 +94,8 @@ [cargo-new] name = false "#, - ).build(); + ) + .build(); p.cargo("new -v foo") .with_status(101) .with_stderr( @@ -98,7 +105,8 @@ Caused by: error in [..]config: `cargo-new.name` expected a string, but found a boolean ", - ).run(); + ) + .run(); } #[test] @@ -111,7 +119,8 @@ [http] user-agent = true "#, - ).build(); + ) + .build(); Package::new("foo", "1.0.0").publish(); p.cargo("publish -v") @@ -123,7 +132,8 @@ Caused by: error in [..]config: `http.user-agent` expected a string, but found a boolean ", - ).run(); + ) + .run(); } #[test] @@ -136,7 +146,8 @@ [build] jobs = -1 "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_status(101) .with_stderr( @@ -145,7 +156,8 @@ could not load config key `build.jobs`: \ invalid value: integer `-1`, expected u32 ", - ).run(); + ) + .run(); } #[test] @@ -158,7 +170,8 @@ [build] jobs = 1 "#, - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -172,7 +185,8 @@ [build] jobs = 4 "#, - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -190,7 +204,8 @@ [dependencies] foo = "0.1.0" "#, - ).file(".cargo/config", "4") + ) + .file(".cargo/config", "4") .file("src/lib.rs", "") .build(); @@ -209,7 +224,8 @@ Caused by: expected an equals, found eof at line 1 ", - ).run(); + ) + .run(); } #[test] @@ -228,7 +244,8 @@ Caused by: missing field `name` for key `package` ", - ).run(); + ) + .run(); } #[test] @@ -247,7 +264,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", r#" @@ -268,7 +286,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -279,7 +298,8 @@ Caused by: package `bar` is specified twice in the lockfile ", - ).run(); + ) + .run(); } #[test] @@ -298,7 +318,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", r#" @@ -314,7 +335,8 @@ version = "0.1.0" source = "You shall not parse" "#, - ).build(); + ) + .build(); p.cargo("build --verbose") .with_status(101) @@ -325,7 +347,8 @@ Caused by: invalid source `You shall not parse` for key `package.source` ", - ).run(); + ) + .run(); } #[test] @@ -342,7 +365,8 @@ "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -361,7 +385,8 @@ [dependencies] foo = { git = "file:.." } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") @@ -380,7 +405,8 @@ Caused by: [..]'file:///' is not a valid local file URI[..] ", - ).run(); + ) + .run(); } #[test] @@ -397,14 +423,16 @@ [lib] crate-type = ["bad_type", "rlib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_status(101) .with_stderr_contains( "error: failed to run `rustc` to learn about crate-type bad_type information", - ).run(); + ) + .run(); } #[test] @@ -423,7 +451,8 @@ foo: "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -438,7 +467,8 @@ Caused by: expected a table key, found a newline at line 8 ", - ).run(); + ) + .run(); } #[test] @@ -460,7 +490,8 @@ name = "e" path = "b.rs" "#, - ).file("a.rs", r#"fn main() -> () {}"#) + ) + .file("a.rs", r#"fn main() -> () {}"#) .file("b.rs", r#"fn main() -> () {}"#) .build(); @@ -473,7 +504,8 @@ Caused by: found duplicate binary name e, but all binary targets must have a unique name ", - ).run(); + ) + .run(); } #[test] @@ -495,7 +527,8 @@ name = "ex" path = "examples/ex2.rs" "#, - ).file("examples/ex.rs", r#"fn main () -> () {}"#) + ) + .file("examples/ex.rs", r#"fn main () -> () {}"#) .file("examples/ex2.rs", r#"fn main () -> () {}"#) .build(); @@ -508,7 +541,8 @@ Caused by: found duplicate example name ex, but all example targets must have a unique name ", - ).run(); + ) + .run(); } #[test] @@ -530,7 +564,8 @@ name = "ex" path = "benches/ex2.rs" "#, - ).file("benches/ex.rs", r#"fn main () {}"#) + ) + .file("benches/ex.rs", r#"fn main () {}"#) .file("benches/ex2.rs", r#"fn main () {}"#) .build(); @@ -543,7 +578,8 @@ Caused by: found duplicate bench name ex, but all bench targets must have a unique name ", - ).run(); + ) + .run(); } #[test] @@ -567,7 +603,8 @@ [target.x86_64-unknown-linux-gnu.dependencies] bar = { path = "linux-bar" } "#, - ).file("src/main.rs", r#"fn main () {}"#) + ) + .file("src/main.rs", r#"fn main () {}"#) .build(); p.cargo("build") @@ -580,7 +617,8 @@ Dependency 'bar' has different source paths depending on the build target. Each dependency must \ have a single canonical source path irrespective of build target. ", - ).run(); + ) + .run(); } #[test] @@ -604,7 +642,8 @@ [target.x86_64-unknown-linux-gnu.dependencies] bar = { path = "linux-bar" } "#, - ).file("src/main.rs", r#"fn main () {}"#) + ) + .file("src/main.rs", r#"fn main () {}"#) .build(); p.cargo("build") @@ -617,7 +656,8 @@ Dependency 'bar' has different source paths depending on the build target. Each dependency must \ have a single canonical source path irrespective of build target. ", - ).run(); + ) + .run(); } #[test] @@ -634,7 +674,8 @@ [target.foo] bar = "3" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -644,7 +685,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p = project() .file( @@ -658,7 +700,8 @@ [profile.debug] debug = 1 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -668,7 +711,8 @@ warning: use `[profile.dev]` to configure debug builds [..] [..]", - ).run(); + ) + .run(); let p = project() .file( @@ -681,7 +725,8 @@ authors = ["wycats@example.com"] bulid = "foo" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .build(); p.cargo("build") .with_stderr( @@ -690,7 +735,8 @@ [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p = project() .at("bar") @@ -706,7 +752,8 @@ [lib] build = "foo" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .build(); p.cargo("build") .with_stderr( @@ -715,7 +762,8 @@ [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -728,7 +776,8 @@ members = ["bar"] bulid = "foo" "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", r"") .build(); p.cargo("build --all") @@ -738,7 +787,8 @@ [COMPILING] bar [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -755,7 +805,8 @@ [dependencies] bar = {} "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); @@ -766,7 +817,8 @@ warning: dependency (bar) specified without providing a local path, Git repository, or version \ to use. This will be considered an error in future versions ", - ).run(); + ) + .run(); } #[test] @@ -782,14 +834,15 @@ warning: TOML file found which contains invalid syntax and will soon not parse at `[..]config`. -The TOML spec requires newlines after table definitions (e.g. `[a] b = 1` is +The TOML spec requires newlines after table definitions (e.g., `[a] b = 1` is invalid), but this file has a table header which does not have a newline after it. A newline needs to be added and this warning will soon become a hard error in the future. [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -808,7 +861,8 @@ branch = "master" tag = "some-tag" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") @@ -819,7 +873,8 @@ Only one of `branch`, `tag` or `rev` is allowed. \ This will be considered an error in future versions ", - ).run(); + ) + .run(); } #[test] @@ -849,7 +904,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -857,7 +913,8 @@ registry = 'http://example.com' replace-with = 'bar' "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -872,7 +929,8 @@ could not find a configured source with the name `bar` \ when attempting to lookup `crates-io` (configuration in [..]) ", - ).run(); + ) + .run(); } #[test] @@ -889,7 +947,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -897,7 +956,8 @@ registry = 'http://example.com' replace-with = 'crates-io' "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -911,7 +971,8 @@ Caused by: detected a cycle of `replace-with` sources, [..] ", - ).run(); + ) + .run(); } #[test] @@ -928,7 +989,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -940,7 +1002,8 @@ registry = 'http://example.com' replace-with = 'crates-io' "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -955,7 +1018,8 @@ detected a cycle of `replace-with` sources, the source `crates-io` is \ eventually replaced with itself (configuration in [..]) ", - ).run(); + ) + .run(); } #[test] @@ -972,7 +1036,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -983,7 +1048,8 @@ [source.bar] registry = 'not a url' "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -994,7 +1060,8 @@ Caused by: invalid url `not a url`: [..] ", - ).run(); + ) + .run(); } #[test] @@ -1012,7 +1079,8 @@ git = "https://127.0.0.1" path = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); foo.cargo("build -v") @@ -1023,7 +1091,8 @@ Only one of `git` or `path` is allowed. \ This will be considered an error in future versions ", - ).run(); + ) + .run(); } #[test] @@ -1040,7 +1109,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -1048,7 +1118,8 @@ registry = 'http://example.com' replace-with = ['not', 'a', 'string'] "#, - ).build(); + ) + .build(); p.cargo("build").with_status(101).with_stderr( "error: expected a string, but found a array for `source.crates-io.replace-with` in [..]", @@ -1071,7 +1142,8 @@ path = "bar" branch = "spam" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); foo.cargo("build -v") @@ -1080,7 +1152,8 @@ "\ [WARNING] key `branch` is ignored for dependency (bar). \ This will be considered an error in future versions", - ).run(); + ) + .run(); } #[test] @@ -1097,7 +1170,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -1105,7 +1179,8 @@ registry = 'http://example.com' local-registry = 'file:///another/file' "#, - ).build(); + ) + .build(); Package::new("bar", "0.1.0").publish(); @@ -1129,7 +1204,8 @@ [dependencies] bar = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -1141,7 +1217,8 @@ Caused by: invalid type: integer `3`, expected a version string like [..] ", - ).run(); + ) + .run(); } #[test] @@ -1158,7 +1235,8 @@ [profile.dev] debug = 'a' "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -1170,7 +1248,8 @@ Caused by: invalid type: string \"a\", expected a boolean or an integer for [..] ", - ).run(); + ) + .run(); } #[test] @@ -1185,7 +1264,8 @@ authors = [] build = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -1197,5 +1277,6 @@ Caused by: invalid type: integer `3`, expected a boolean or a string for key [..] ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/bad_manifest_path.rs cargo-0.35.0/tests/testsuite/bad_manifest_path.rs --- cargo-0.33.0/tests/testsuite/bad_manifest_path.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/bad_manifest_path.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_bin_manifest, main_file, project}; +use crate::support::{basic_bin_manifest, main_file, project}; fn assert_not_a_cargo_toml(command: &str, manifest_path_argument: &str) { let p = project() @@ -14,7 +14,8 @@ .with_stderr( "[ERROR] the manifest-path must be a path \ to a Cargo.toml file", - ).run(); + ) + .run(); } fn assert_cargo_toml_doesnt_exist(command: &str, manifest_path_argument: &str) { @@ -32,7 +33,8 @@ .with_stderr(format!( "[ERROR] manifest path `{}` does not exist", expected_path - )).run(); + )) + .run(); } #[test] @@ -328,7 +330,8 @@ .with_stdout( "{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\ ", - ).run(); + ) + .run(); } #[test] @@ -344,7 +347,8 @@ .with_stdout( "{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\ ", - ).run(); + ) + .run(); } #[test] @@ -360,7 +364,8 @@ .with_stdout( "{\"invalid\":\"the manifest-path must be a path to a Cargo.toml file\"}\ ", - ).run(); + ) + .run(); } #[test] @@ -372,5 +377,6 @@ .with_stdout( "{\"invalid\":\"manifest path `foo[..]bar[..]baz[..]Cargo.toml` does not exist\"}\ ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/bench.rs cargo-0.35.0/tests/testsuite/bench.rs --- cargo-0.33.0/tests/testsuite/bench.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/bench.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ -use support::is_nightly; -use support::paths::CargoPathExt; -use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; +use crate::support::is_nightly; +use crate::support::paths::CargoPathExt; +use crate::support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; #[test] fn cargo_bench_simple() { @@ -29,7 +29,8 @@ fn bench_hello(_b: &mut test::Bencher) { assert_eq!(hello(), "hello") }"#, - ).build(); + ) + .build(); p.cargo("build").run(); assert!(p.bin("foo").is_file()); @@ -42,7 +43,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench_hello ... bench: [..]") + ) + .with_stdout_contains("test bench_hello ... bench: [..]") .run(); } @@ -61,19 +63,22 @@ extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { } fn main() { println!("Hello main!"); }"#, - ).file( + ) + .file( "tests/other.rs", r#" #![feature(test)] extern crate test; #[bench] fn run3(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/mybench.rs", r#" #![feature(test)] extern crate test; #[bench] fn run2(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench --benches") .with_stderr( @@ -83,7 +88,8 @@ [RUNNING] target/release/deps/foo-[..][EXE] [RUNNING] target/release/deps/mybench-[..][EXE] ", - ).with_stdout_contains("test run2 ... bench: [..]") + ) + .with_stdout_contains("test run2 ... bench: [..]") .run(); } @@ -102,19 +108,22 @@ extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { } fn main() { println!("Hello main!"); }"#, - ).file( + ) + .file( "tests/other.rs", r#" #![feature(test)] extern crate test; #[bench] fn run3(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/mybench.rs", r#" #![feature(test)] extern crate test; #[bench] fn run2(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench --bins") .with_stderr( @@ -123,7 +132,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] ", - ).with_stdout_contains("test run1 ... bench: [..]") + ) + .with_stdout_contains("test run1 ... bench: [..]") .run(); } @@ -140,13 +150,15 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/bin2.rs", r#" #![feature(test)] extern crate test; #[bench] fn run2(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench --bench bin2") .with_stderr( @@ -155,7 +167,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/bin2-[..][EXE] ", - ).with_stdout_contains("test run2 ... bench: [..]") + ) + .with_stdout_contains("test run2 ... bench: [..]") .run(); } @@ -172,19 +185,22 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/bin2.rs", r#" #![feature(test)] extern crate test; #[bench] fn run2(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/bin3.rs", r#" #![feature(test)] extern crate test; #[bench] fn run3(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench --bench bin1 --bench bin2") .with_stdout_contains("test run1 ... bench: [..]") @@ -210,7 +226,8 @@ fn main() {} #[bench] fn bench_hello(_b: &mut test::Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench -v hello") .with_stderr( @@ -219,7 +236,8 @@ [RUNNING] `rustc [..] src/main.rs [..]` [FINISHED] release [optimized] target(s) in [..] [RUNNING] `[..]target/release/deps/foo-[..][EXE] hello --bench`", - ).with_stdout_contains("test bench_hello ... bench: [..]") + ) + .with_stdout_contains("test bench_hello ... bench: [..]") .run(); } @@ -239,7 +257,8 @@ pub fn foo() {} #[bench] fn lib_bench(_b: &mut test::Bencher) {} ", - ).file( + ) + .file( "src/main.rs", " #![feature(test)] @@ -250,7 +269,8 @@ fn main() {} #[bench] fn bin_bench(_b: &mut test::Bencher) { foo::foo() } ", - ).file( + ) + .file( "benches/foo.rs", r#" #![feature(test)] @@ -258,7 +278,8 @@ extern crate test; #[bench] fn bench_bench(_b: &mut test::Bencher) { foo::foo() } "#, - ).build(); + ) + .build(); p.cargo("bench") .with_stdout_contains("test bin_bench ... bench: 0 ns/iter (+/- 0)") @@ -293,7 +314,8 @@ fn bench_hello(_b: &mut test::Bencher) { assert_eq!(hello(), "nope") }"#, - ).build(); + ) + .build(); p.cargo("build").run(); assert!(p.bin("foo").is_file()); @@ -308,9 +330,11 @@ [COMPILING] foo v0.5.0 ([CWD])[..] [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_either_contains( + ) + .with_either_contains( "[..]thread '[..]' panicked at 'assertion failed: `(left == right)`[..]", - ).with_either_contains("[..]left: `\"hello\"`[..]") + ) + .with_either_contains("[..]left: `\"hello\"`[..]") .with_either_contains("[..]right: `\"nope\"`[..]") .with_either_contains("[..]src/main.rs:15[..]") .with_status(101) @@ -336,7 +360,8 @@ name = "baz" path = "src/main.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![cfg_attr(test, feature(test))] @@ -353,7 +378,8 @@ pub fn foo(){} #[bench] fn lib_bench(_b: &mut test::Bencher) {} "#, - ).file( + ) + .file( "src/main.rs", " #![feature(test)] @@ -367,7 +393,8 @@ #[bench] fn bin_bench(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -376,7 +403,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] [RUNNING] target/release/deps/baz-[..][EXE]", - ).with_stdout_contains("test lib_bench ... bench: [..]") + ) + .with_stdout_contains("test lib_bench ... bench: [..]") .with_stdout_contains("test bin_bench ... bench: [..]") .run(); } @@ -400,7 +428,8 @@ [dependencies.foo] path = "../foo" "#, - ).file( + ) + .file( "src/lib.rs", " #![cfg_attr(test, feature(test))] @@ -413,7 +442,8 @@ foo::foo(); } ", - ).build(); + ) + .build(); let _p2 = project() .file( "src/lib.rs", @@ -427,7 +457,8 @@ #[bench] fn foo_bench(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -436,7 +467,8 @@ [COMPILING] bar v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/bar-[..][EXE]", - ).with_stdout_contains("test bar_bench ... bench: [..]") + ) + .with_stdout_contains("test bar_bench ... bench: [..]") .run(); } @@ -459,7 +491,8 @@ name = "bench" path = "src/bench.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![cfg_attr(test, feature(test))] @@ -470,7 +503,8 @@ #[bench] fn internal_bench(_b: &mut test::Bencher) {} "#, - ).file( + ) + .file( "src/bench.rs", r#" #![feature(test)] @@ -481,7 +515,8 @@ #[bench] fn external_bench(_b: &mut test::Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -490,7 +525,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] [RUNNING] target/release/deps/bench-[..][EXE]", - ).with_stdout_contains("test internal_bench ... bench: [..]") + ) + .with_stdout_contains("test internal_bench ... bench: [..]") .with_stdout_contains("test external_bench ... bench: [..]") .run(); } @@ -514,7 +550,8 @@ #[bench] fn internal_bench(_b: &mut test::Bencher) {} "#, - ).file( + ) + .file( "benches/external.rs", r#" #![feature(test)] @@ -525,7 +562,8 @@ #[bench] fn external_bench(_b: &mut test::Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -534,7 +572,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] [RUNNING] target/release/deps/external-[..][EXE]", - ).with_stdout_contains("test internal_bench ... bench: [..]") + ) + .with_stdout_contains("test internal_bench ... bench: [..]") .with_stdout_contains("test external_bench ... bench: [..]") .run(); } @@ -559,7 +598,8 @@ name = "bench_magic" required-features = ["magic"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "benches/bench_basic.rs", r#" @@ -571,7 +611,8 @@ #[bench] fn bench_basic(_b: &mut test::Bencher) {} "#, - ).file( + ) + .file( "benches/bench_magic.rs", r#" #![feature(test)] @@ -582,7 +623,8 @@ #[bench] fn bench_magic(_b: &mut test::Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench bench_basic") .with_stderr( @@ -606,7 +648,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] ", - ).run(); + ) + .run(); } #[test] @@ -620,7 +663,8 @@ .file( "examples/dont-run-me-i-will-fail.rs", r#"fn main() { panic!("Examples should not be run by 'cargo test'"); }"#, - ).build(); + ) + .build(); p.cargo("bench").run(); } @@ -641,7 +685,8 @@ #[bench] fn foo(_b: &mut test::Bencher) {} #[bench] fn bar(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("bench bar") .with_stderr( @@ -649,14 +694,16 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bar ... bench: [..]") + ) + .with_stdout_contains("test bar ... bench: [..]") .run(); p.cargo("bench foo") .with_stderr( "[FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test foo ... bench: [..]") + ) + .with_stdout_contains("test foo ... bench: [..]") .run(); } @@ -681,7 +728,8 @@ #[bench] fn dummy_bench(b: &mut test::Bencher) { } "#, - ).build(); + ) + .build(); for _ in 0..2 { p.cargo("bench").run(); @@ -708,7 +756,8 @@ [[bin]] name = "foo" "#, - ).file( + ) + .file( "src/lib.rs", " #![cfg_attr(test, feature(test))] @@ -716,7 +765,8 @@ extern crate test; #[bench] fn lib_bench(_b: &mut test::Bencher) {} ", - ).file( + ) + .file( "src/main.rs", " #![cfg_attr(test, feature(test))] @@ -728,7 +778,8 @@ #[bench] fn bin_bench(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -737,7 +788,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains_n("test [..] ... bench: [..]", 2) + ) + .with_stdout_contains_n("test [..] ... bench: [..]", 2) .run(); } @@ -764,7 +816,8 @@ #[bench] fn foo_bench(_b: &mut test::Bencher) {} ", - ).file( + ) + .file( "benches/bench.rs", " #![feature(test)] @@ -774,7 +827,8 @@ #[bench] fn bench(_b: &mut test::Bencher) { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -783,7 +837,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/syntax-[..][EXE] [RUNNING] target/release/deps/bench-[..][EXE]", - ).with_stdout_contains("test foo_bench ... bench: [..]") + ) + .with_stdout_contains("test foo_bench ... bench: [..]") .with_stdout_contains("test bench ... bench: [..]") .run(); } @@ -808,7 +863,8 @@ bench = false doctest = false "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -823,7 +879,8 @@ #[bench] fn bench(_b: &mut test::Bencher) { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -831,7 +888,8 @@ [COMPILING] syntax v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/syntax-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); } @@ -857,7 +915,8 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![cfg_attr(test, feature(test))] @@ -870,7 +929,8 @@ #[bench] fn foo(_b: &mut test::Bencher) {} "#, - ).file( + ) + .file( "benches/bench.rs", r#" #![feature(test)] @@ -880,7 +940,8 @@ #[bench] fn foo(_b: &mut test::Bencher) { the_foo::bar(); } "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -892,7 +953,8 @@ name = "bar" crate_type = ["dylib"] "#, - ).file("bar/src/lib.rs", "pub fn baz() {}") + ) + .file("bar/src/lib.rs", "pub fn baz() {}") .build(); p.cargo("bench -v") @@ -907,7 +969,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `[..]target/release/deps/foo-[..][EXE] --bench` [RUNNING] `[..]target/release/deps/bench-[..][EXE] --bench`", - ).with_stdout_contains_n("test foo ... bench: [..]", 2) + ) + .with_stdout_contains_n("test foo ... bench: [..]", 2) .run(); p.root().move_into_the_past(); @@ -919,7 +982,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `[..]target/release/deps/foo-[..][EXE] --bench` [RUNNING] `[..]target/release/deps/bench-[..][EXE] --bench`", - ).with_stdout_contains_n("test foo ... bench: [..]", 2) + ) + .with_stdout_contains_n("test foo ... bench: [..]", 2) .run(); } @@ -939,7 +1003,8 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file( "src/lib.rs", " @@ -949,7 +1014,8 @@ #[bench] fn foo(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -957,14 +1023,16 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test foo ... bench: [..]") + ) + .with_stdout_contains("test foo ... bench: [..]") .run(); p.cargo("bench") .with_stderr( "[FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test foo ... bench: [..]") + ) + .with_stdout_contains("test foo ... bench: [..]") .run(); } @@ -989,7 +1057,8 @@ [[bench]] name = "testb1" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![cfg_attr(test, feature(test))] @@ -1009,7 +1078,8 @@ f2(); } "#, - ).file( + ) + .file( "benches/testb1.rs", " #![feature(test)] @@ -1023,7 +1093,8 @@ foo::f2(); } ", - ).file( + ) + .file( "examples/teste1.rs", r#" extern crate foo; @@ -1033,7 +1104,8 @@ foo::f1(); } "#, - ).build(); + ) + .build(); p.cargo("bench -v") .with_stderr( @@ -1045,7 +1117,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `[CWD]/target/release/deps/foo-[..][EXE] --bench` [RUNNING] `[CWD]/target/release/deps/testb1-[..][EXE] --bench`", - ).with_stdout_contains("test bench_bench1 ... bench: [..]") + ) + .with_stdout_contains("test bench_bench1 ... bench: [..]") .with_stdout_contains("test bench_bench2 ... bench: [..]") .run(); } @@ -1074,7 +1147,8 @@ name = "b" test = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("benches/b.rs", "#[test] fn foo() {}") .build(); @@ -1084,7 +1158,8 @@ [COMPILING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/b-[..][EXE]", - ).with_stdout_contains("test foo ... ok") + ) + .with_stdout_contains("test foo ... ok") .run(); } @@ -1108,7 +1183,8 @@ #[bench] fn bench_baz(_: &mut Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench --no-run") .with_stderr( @@ -1116,7 +1192,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1150,7 +1227,8 @@ fn bench_nope(_b: &mut test::Bencher) { assert_eq!("nope", hello()) }"#, - ).build(); + ) + .build(); p.cargo("bench --no-fail-fast -- --test-threads=1") .with_status(101) @@ -1183,7 +1261,8 @@ [dependencies.baz] path = "../baz" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let _bar = project() @@ -1200,7 +1279,8 @@ name = "bbar" test = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "benches/bbar.rs", r#" @@ -1212,7 +1292,8 @@ #[bench] fn bench_bar(_b: &mut Bencher) {} "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") @@ -1228,7 +1309,8 @@ name = "bbaz" test = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "benches/bbaz.rs", r#" @@ -1240,7 +1322,8 @@ #[bench] fn bench_baz(_b: &mut Bencher) {} "#, - ).build(); + ) + .build(); p.cargo("bench -p bar -p baz") .with_stderr_contains("[RUNNING] target/release/deps/bbaz-[..][EXE]") @@ -1269,7 +1352,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "benches/foo.rs", r#" @@ -1281,7 +1365,8 @@ #[bench] fn bench_foo(_: &mut Bencher) -> () { () } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file( "bar/benches/bar.rs", @@ -1294,7 +1379,8 @@ #[bench] fn bench_bar(_: &mut Bencher) -> () { () } "#, - ).build(); + ) + .build(); p.cargo("bench --all") .with_stderr_contains("[RUNNING] target/release/deps/bar-[..][EXE]") @@ -1321,7 +1407,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file( "bar/src/lib.rs", @@ -1335,18 +1422,21 @@ b.iter(|| {}); } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file( "baz/src/lib.rs", "#[test] pub fn baz() { break_the_build(); }", - ).build(); + ) + .build(); p.cargo("bench --all --exclude baz") .with_stdout_contains( "\ running 1 test test bar ... bench: [..] ns/iter (+/- [..])", - ).run(); + ) + .run(); } #[test] @@ -1362,7 +1452,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file( "bar/benches/bar.rs", @@ -1375,7 +1466,8 @@ #[bench] fn bench_bar(_: &mut Bencher) -> () { () } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") .file( "baz/benches/baz.rs", @@ -1388,7 +1480,8 @@ #[bench] fn bench_baz(_: &mut Bencher) -> () { () } "#, - ).build(); + ) + .build(); // The order in which bar and baz are built is not guaranteed p.cargo("bench --all") @@ -1417,7 +1510,8 @@ [[bench]] name = "bench" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/bench.rs", r#" @@ -1429,14 +1523,16 @@ #[bench] fn bench_foo(_: &mut Bencher) -> () { () } "#, - ).build(); + ) + .build(); p.cargo("bench") .with_stderr_contains( "\ [WARNING] path `[..]src/bench.rs` was erroneously implicitly accepted for benchmark `bench`, please set bench.path in Cargo.toml", - ).run(); + ) + .run(); } #[test] @@ -1452,7 +1548,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn foo() {}") .file( "bar/benches/bar.rs", @@ -1463,7 +1560,8 @@ #[bench] fn bench_bar(_: &mut Bencher) -> () { () } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") .file( "baz/benches/baz.rs", @@ -1474,7 +1572,8 @@ #[bench] fn bench_baz(_: &mut Bencher) -> () { () } "#, - ).build(); + ) + .build(); // The order in which bar and baz are built is not guaranteed @@ -1485,3 +1584,48 @@ .with_stdout_contains("test bench_bar ... bench: [..]") .run(); } + +#[test] +fn json_artifact_includes_executable_for_benchmark() { + if !is_nightly() { + return; + } + + let p = project() + .file( + "benches/benchmark.rs", + r#" + #![feature(test)] + extern crate test; + + use test::Bencher; + + #[bench] + fn bench_foo(_: &mut Bencher) -> () { () } + "#, + ) + .build(); + + p.cargo("bench --no-run --message-format=json") + .with_json( + r#" + { + "executable": "[..]/foo/target/release/benchmark-[..][EXE]", + "features": [], + "filenames": [ "[..]/foo/target/release/benchmark-[..][EXE]" ], + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "bench" ], + "edition": "2015", + "name": "benchmark", + "src_path": "[..]/foo/benches/benchmark.rs" + } + } + "#, + ) + .run(); +} diff -Nru cargo-0.33.0/tests/testsuite/build_auth.rs cargo-0.35.0/tests/testsuite/build_auth.rs --- cargo-0.33.0/tests/testsuite/build_auth.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build_auth.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,18 +4,18 @@ use std::net::TcpListener; use std::thread; +use crate::support::paths; +use crate::support::{basic_manifest, project}; use bufstream::BufStream; use git2; -use support::paths; -use support::{basic_manifest, project}; -// Test that HTTP auth is offered from `credential.helper` +// Tests that HTTP auth is offered from `credential.helper`. #[test] fn http_auth_offered() { let server = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = server.local_addr().unwrap(); - fn headers(rdr: &mut BufRead) -> HashSet { + fn headers(rdr: &mut dyn BufRead) -> HashSet { let valid = ["GET", "Authorization", "Accept"]; rdr.lines() .map(|s| s.unwrap()) @@ -34,13 +34,15 @@ WWW-Authenticate: Basic realm=\"wheee\"\r\n \r\n\ ", - ).unwrap(); + ) + .unwrap(); assert_eq!( req, vec![ "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1", "Accept: */*", - ].into_iter() + ] + .into_iter() .map(|s| s.to_string()) .collect() ); @@ -54,14 +56,16 @@ WWW-Authenticate: Basic realm=\"wheee\"\r\n \r\n\ ", - ).unwrap(); + ) + .unwrap(); assert_eq!( req, vec![ "GET /foo/bar/info/refs?service=git-upload-pack HTTP/1.1", "Authorization: Basic Zm9vOmJhcg==", "Accept: */*", - ].into_iter() + ] + .into_iter() .map(|s| s.to_string()) .collect() ); @@ -78,7 +82,8 @@ println!("password=bar"); } "#, - ).build(); + ) + .build(); script.cargo("build -v").run(); let script = script.bin("script"); @@ -104,14 +109,16 @@ "#, addr.port() ), - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file( ".cargo/config", "\ [net] retry = 0 ", - ).build(); + ) + .build(); // This is a "contains" check because the last error differs by platform, // may span multiple lines, and isn't relevant to this test. @@ -135,7 +142,8 @@ Caused by: ", addr = addr - )).run(); + )) + .run(); t.join().ok().unwrap(); } @@ -167,21 +175,24 @@ "#, addr.port() ), - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file( ".cargo/config", "\ [net] retry = 0 ", - ).build(); + ) + .build(); p.cargo("build -v") .with_status(101) .with_stderr_contains(&format!( "[UPDATING] git repository `https://{addr}/foo/bar`", addr = addr - )).with_stderr_contains(&format!( + )) + .with_stderr_contains(&format!( "\ Caused by: {errmsg} @@ -189,19 +200,20 @@ errmsg = if cfg!(windows) { "[..]failed to send request: [..]" } else if cfg!(target_os = "macos") { - // OSX is difficult to tests as some builds may use - // Security.framework and others may use OpenSSL. In that case let's - // just not verify the error message here. + // macOS is difficult to tests as some builds may use Security.framework, + // while others may use OpenSSL. In that case, let's just not verify the error + // message here. "[..]" } else { "[..]SSL error: [..]" } - )).run(); + )) + .run(); t.join().ok().unwrap(); } -// Boy, sure would be nice to have an SSH implementation in rust! +// It would sure be nice to have an SSH implementation in Rust! #[test] fn ssh_something_happens() { let server = TcpListener::bind("127.0.0.1:0").unwrap(); @@ -225,7 +237,8 @@ "#, addr.port() ), - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build -v") @@ -233,11 +246,13 @@ .with_stderr_contains(&format!( "[UPDATING] git repository `ssh://{addr}/foo/bar`", addr = addr - )).with_stderr_contains( + )) + .with_stderr_contains( "\ Caused by: [..]failed to start SSH session: Failed getting banner[..] ", - ).run(); + ) + .run(); t.join().ok().unwrap(); } diff -Nru cargo-0.33.0/tests/testsuite/build_lib.rs cargo-0.35.0/tests/testsuite/build_lib.rs --- cargo-0.33.0/tests/testsuite/build_lib.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build_lib.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_bin_manifest, basic_manifest, project}; +use crate::support::{basic_bin_manifest, basic_manifest, project}; #[test] fn build_lib_only() { @@ -17,7 +17,8 @@ --out-dir [..] \ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -49,12 +50,14 @@ "test-dependency" = { path = "src/test_dependency" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("src/test_dependency/src/lib.rs", r#" "#) .file( "src/test_dependency/Cargo.toml", &basic_manifest("test-dependency", "0.0.1"), - ).build(); + ) + .build(); p.cargo("build").env("CARGO_HOME", "./cargo_home/").run(); } diff -Nru cargo-0.33.0/tests/testsuite/build_plan.rs cargo-0.35.0/tests/testsuite/build_plan.rs --- cargo-0.33.0/tests/testsuite/build_plan.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build_plan.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::registry::Package; -use support::{basic_bin_manifest, basic_manifest, main_file, project}; +use crate::support::registry::Package; +use crate::support::{basic_bin_manifest, basic_manifest, main_file, project}; #[test] fn cargo_build_plan_simple() { @@ -34,7 +34,8 @@ ] } "#, - ).run(); + ) + .run(); assert!(!p.bin("foo").is_file()); } @@ -52,7 +53,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -61,7 +63,8 @@ #[test] fn test() { foo(); } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); p.cargo("build --build-plan -Zunstable-options") @@ -109,7 +112,8 @@ ] } "#, - ).run(); + ) + .run(); } #[test] @@ -125,7 +129,8 @@ authors = ["wycats@example.com"] build = "build.rs" "#, - ).file("src/main.rs", r#"fn main() {}"#) + ) + .file("src/main.rs", r#"fn main() {}"#) .file("build.rs", r#"fn main() {}"#) .build(); @@ -185,7 +190,8 @@ ] } "#, - ).run(); + ) + .run(); } #[test] diff -Nru cargo-0.33.0/tests/testsuite/build.rs cargo-0.35.0/tests/testsuite/build.rs --- cargo-0.33.0/tests/testsuite/build.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,14 +2,14 @@ use std::fs::{self, File}; use std::io::prelude::*; -use cargo::util::paths::dylib_path_envvar; -use support::paths::{root, CargoPathExt}; -use support::registry::Package; -use support::ProjectBuilder; -use support::{ +use crate::support::paths::{root, CargoPathExt}; +use crate::support::registry::Package; +use crate::support::ProjectBuilder; +use crate::support::{ basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, rustc_host, sleep_ms, }; -use support::{main_file, project, Execs}; +use crate::support::{main_file, project, Execs}; +use cargo::util::paths::dylib_path_envvar; #[test] fn cargo_compile_simple() { @@ -36,8 +36,8 @@ .run(); } -/// Check that the `CARGO_INCREMENTAL` environment variable results in -/// `rustc` getting `-Zincremental` passed to it. +/// Checks that the `CARGO_INCREMENTAL` environment variable results in +/// `rustc` getting `-C incremental` passed to it. #[test] fn cargo_compile_incremental() { let p = project() @@ -49,13 +49,15 @@ .env("CARGO_INCREMENTAL", "1") .with_stderr_contains( "[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n", - ).run(); + ) + .run(); p.cargo("test -v") .env("CARGO_INCREMENTAL", "1") .with_stderr_contains( "[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n", - ).run(); + ) + .run(); } #[test] @@ -75,7 +77,8 @@ [profile.release] incremental = true "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -109,7 +112,8 @@ [build] incremental = false "#, - ).build(); + ) + .build(); p.cargo("build -v") .env_remove("CARGO_INCREMENTAL") @@ -159,7 +163,8 @@ Caused by: virtual manifests must be configured with [workspace] ", - ).run(); + ) + .run(); } #[test] @@ -171,7 +176,8 @@ [project] foo = bar ", - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -185,7 +191,8 @@ Caused by: invalid number at line 3 ", - ).run(); + ) + .run(); } #[test] @@ -204,7 +211,8 @@ Caused by: invalid number at line 1 ", - ).run(); + ) + .run(); } #[test] @@ -225,7 +233,8 @@ [dependencies] "#, - ).file("src/main.rs", "#![allow(warnings)] fn main() {}") + ) + .file("src/main.rs", "#![allow(warnings)] fn main() {}") .build(); p.cargo("build") @@ -235,7 +244,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -253,7 +263,8 @@ Caused by: Expected dot for key `package.version` ", - ).run(); + ) + .run(); } #[test] @@ -271,7 +282,8 @@ Caused by: package name cannot be an empty string ", - ).run(); + ) + .run(); } #[test] @@ -289,7 +301,8 @@ Caused by: Invalid character `:` in package name: `foo::bar` ", - ).run(); + ) + .run(); } #[test] @@ -306,7 +319,8 @@ [[bin]] name = "" "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -317,7 +331,8 @@ Caused by: binary target names cannot be empty ", - ).run(); + ) + .run(); } #[test] @@ -334,7 +349,8 @@ [[bin]] name = "build" "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -345,7 +361,8 @@ Caused by: the binary target name `build` is forbidden ", - ).run(); + ) + .run(); } #[test] @@ -364,7 +381,8 @@ path = "src/foo.rs" crate-type = ["cdylib", "rlib"] "#, - ).file("src/foo.rs", "fn main() {}") + ) + .file("src/foo.rs", "fn main() {}") .build(); p.cargo("build") @@ -376,7 +394,8 @@ Caused by: the target `the_foo_bin` is a binary and can't have any crate-types set \ (currently \"cdylib, rlib\")", - ).run(); + ) + .run(); } #[test] @@ -395,7 +414,8 @@ path = "src/foo.rs" proc-macro = true "#, - ).file("src/foo.rs", "fn main() {}") + ) + .file("src/foo.rs", "fn main() {}") .build(); p.cargo("build") @@ -406,7 +426,8 @@ Caused by: the target `the_foo_bin` is a binary and can't have `proc-macro` set `true`", - ).run(); + ) + .run(); } #[test] @@ -423,7 +444,8 @@ [lib] name = "" "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -434,7 +456,8 @@ Caused by: library target names cannot be empty ", - ).run(); + ) + .run(); } #[test] @@ -450,7 +473,8 @@ [dependencies] crossbeam = "y" "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -464,7 +488,8 @@ Caused by: the given version requirement is invalid ", - ).run(); + ) + .run(); } #[test] @@ -491,7 +516,8 @@ [ERROR] Could not compile `foo`. To learn more, run the command again with --verbose.\n", - ).run(); + ) + .run(); assert!(p.root().join("Cargo.lock").is_file()); } @@ -511,19 +537,24 @@ [dependencies.baz] path = "../baz" "#, - ).file("src/main.rs", "invalid rust code!") + ) + .file("src/main.rs", "invalid rust code!") .build(); let _bar = project() .at("bar") - .file("Cargo.toml", &basic_bin_manifest("bar")) + .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("src/lib.rs", "invalid rust code!") .build(); let _baz = project() .at("baz") - .file("Cargo.toml", &basic_bin_manifest("baz")) + .file("Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("src/lib.rs", "invalid rust code!") .build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]invalid rust code[..]") + .with_stderr_contains("[ERROR] Could not compile [..]") + .run(); } #[test] @@ -557,7 +588,8 @@ name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file( "bar/src/bar.rs", @@ -568,7 +600,8 @@ fn dead() {} "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr_contains("[..]function is never used: `dead`[..]") @@ -597,7 +630,8 @@ [[bin]] name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -610,7 +644,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" extern crate baz; @@ -619,7 +654,8 @@ baz::gimme() } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) .file( "baz/src/lib.rs", r#" @@ -627,7 +663,8 @@ "test passed".to_string() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); @@ -656,7 +693,8 @@ [[bin]] name = "foo" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -669,7 +707,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" extern crate baz; @@ -678,7 +717,8 @@ baz::gimme() } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) .file( "baz/src/lib.rs", r#" @@ -686,7 +726,8 @@ "test passed".to_string() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); @@ -712,7 +753,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -729,7 +771,8 @@ name = "bar" "#, - ).file( + ) + .file( "bar/src/bar.rs", r#" extern crate baz; @@ -738,7 +781,8 @@ baz::gimme() } "#, - ).file("baz/Cargo.toml", &basic_lib_manifest("baz")) + ) + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file( "baz/src/baz.rs", r#" @@ -746,7 +790,8 @@ "test passed".to_string() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); @@ -777,7 +822,8 @@ name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -795,7 +841,8 @@ name = "bar" "#, - ).file( + ) + .file( "bar/src/bar.rs", r#" extern crate baz; @@ -804,7 +851,8 @@ baz::gimme() } "#, - ).file("baz/Cargo.toml", &basic_lib_manifest("baz")) + ) + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file( "baz/src/baz.rs", r#" @@ -812,7 +860,8 @@ "test passed".to_string() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); @@ -845,7 +894,8 @@ path = "bar" "#, - ).file("src/bin/foo.rs", &main_file(r#""i am foo""#, &["bar"])) + ) + .file("src/bin/foo.rs", &main_file(r#""i am foo""#, &["bar"])) .file("bar/Cargo.toml", &basic_bin_manifest("bar")) .file("bar/src/bar.rs", &main_file(r#""i am bar""#, &[])) .build(); @@ -857,7 +907,8 @@ location searched: [CWD]/bar required by package `foo v0.0.1 ([CWD])` "#, - ).run(); + ) + .run(); } #[test] @@ -870,7 +921,8 @@ extern crate foo; fn main() { println!("hello a.rs"); } "#, - ).file("examples/a.rs", r#"fn main() { println!("example"); }"#) + ) + .file("examples/a.rs", r#"fn main() { println!("example"); }"#) .build(); p.cargo("build --bin bin.rs") @@ -885,7 +937,8 @@ [ERROR] no bin target named `a.rs` Did you mean `a`?", - ).run(); + ) + .run(); p.cargo("build --example example.rs") .with_status(101) @@ -899,7 +952,8 @@ [ERROR] no example target named `a.rs` Did you mean `a`?", - ).run(); + ) + .run(); } #[test] @@ -916,7 +970,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -946,7 +1001,8 @@ [dependencies] present_dep = "1.2.3" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); } @@ -963,7 +1019,8 @@ [dependencies] present_dep = "1.2.3" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p2.cargo("build -Zoffline") @@ -973,7 +1030,8 @@ [COMPILING] present_dep v1.2.3 [COMPILING] bar v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -990,7 +1048,8 @@ [dependencies] not_cached_dep = "1.2.5" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -Zoffline") @@ -1003,9 +1062,10 @@ required by package `bar v0.1.0 ([..])` As a reminder, you're using offline mode (-Z offline) \ which can sometimes cause surprising resolution failures, \ -if this error is too confusing you may with to retry \ +if this error is too confusing you may wish to retry \ without the offline flag.", - ).run(); + ) + .run(); } #[test] @@ -1018,7 +1078,8 @@ .file( "src/lib.rs", r#"pub fn get_version()->&'static str {"1.2.3"}"#, - ).publish(); + ) + .publish(); Package::new("present_dep", "1.2.5") .file("Cargo.toml", &basic_manifest("present_dep", "1.2.5")) @@ -1038,7 +1099,8 @@ [dependencies] present_dep = "=1.2.3" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); } @@ -1054,14 +1116,16 @@ [dependencies] present_dep = "1.2" "#, - ).file( + ) + .file( "src/main.rs", "\ extern crate present_dep; fn main(){ println!(\"{}\", present_dep::get_version()); }", - ).build(); + ) + .build(); p2.cargo("run -Zoffline") .masquerade_as_nightly_cargo() @@ -1071,7 +1135,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] Running `[..]`", - ).with_stdout("1.2.3") + ) + .with_stdout("1.2.3") .run(); } @@ -1101,7 +1166,8 @@ baz = "0.1.0" qux = "0.1.0" "#, - ).file("src/main.rs", "fn main(){}") + ) + .file("src/main.rs", "fn main(){}") .build(); p.cargo("build") @@ -1120,7 +1186,8 @@ ... which is depended on by `foo v0.0.1 ([..])` failed to select a version for `bad` which could resolve this conflict", - ).run(); + ) + .run(); } #[test] @@ -1145,7 +1212,8 @@ baz = "0.1.0" bad = ">=1.0.1, <=2.0.0" "#, - ).file("src/main.rs", "fn main(){}") + ) + .file("src/main.rs", "fn main(){}") .build(); p.cargo("build") @@ -1167,7 +1235,8 @@ ... which is depended on by `foo v0.0.1 ([..])` failed to select a version for `bad` which could resolve this conflict", - ).run(); + ) + .run(); } #[test] @@ -1196,11 +1265,15 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/main.rs", "fn main(){}") + ) + .file("src/main.rs", "fn main(){}") .build(); // simulate download bar, but fail to download baz - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]failed to verify the checksum of `baz[..]") + .run(); drop(File::create(baz_path).ok().unwrap().write_all(&content)); @@ -1215,9 +1288,10 @@ ... which is depended on by `foo v0.0.1 ([CWD])` As a reminder, you're using offline mode (-Z offline) \ which can sometimes cause surprising resolution failures, \ -if this error is too confusing you may with to retry \ +if this error is too confusing you may wish to retry \ without the offline flag.", - ).run(); + ) + .run(); } #[test] @@ -1234,7 +1308,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -1288,7 +1363,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "// hi") + ) + .file("src/lib.rs", "// hi") .file( "bar/Cargo.toml", r#" @@ -1301,7 +1377,8 @@ name = "bar" crate_type = ["dylib"] "#, - ).file("bar/src/lib.rs", "// hello") + ) + .file("bar/src/lib.rs", "// hello") .build(); // No metadata on libbar since it's a dylib path dependency @@ -1326,7 +1403,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", prefix = env::consts::DLL_PREFIX, suffix = env::consts::DLL_SUFFIX, - )).run(); + )) + .run(); p.cargo("clean").run(); @@ -1354,7 +1432,8 @@ ", prefix = env::consts::DLL_PREFIX, suffix = env::consts::DLL_SUFFIX, - )).run(); + )) + .run(); } #[test] @@ -1371,7 +1450,8 @@ repository = "http://example.com/repo.git" authors = ["wycats@example.com"] "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate foo; @@ -1403,7 +1483,8 @@ assert_eq!(s, VERSION); } "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn version() -> String { @@ -1415,13 +1496,16 @@ env!("CARGO_MANIFEST_DIR")) } "#, - ).build(); + ) + .build(); println!("build"); p.cargo("build -v").run(); println!("bin"); - p.process(&p.bin("foo")).with_stdout("0-5-1 @ alpha.1 in [CWD]").run(); + p.process(&p.bin("foo")) + .with_stdout("0-5-1 @ alpha.1 in [CWD]") + .run(); println!("test"); p.cargo("test -v").run(); @@ -1438,7 +1522,8 @@ version = "0.5.1-alpha.1" authors = ["wycats@example.com", "neikos@example.com"] "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate foo; @@ -1452,14 +1537,16 @@ assert_eq!(s, AUTHORS); } "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn authors() -> String { format!("{}", env!("CARGO_PKG_AUTHORS")) } "#, - ).build(); + ) + .build(); println!("build"); p.cargo("build -v").run(); @@ -1473,6 +1560,39 @@ p.cargo("test -v").run(); } +#[test] +fn vv_prints_rustc_env_vars() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = ["escape='\"@example.com"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + let mut b = p.cargo("build -vv"); + + if cfg!(windows) { + b.with_stderr_contains( + "[RUNNING] `[..]set CARGO_PKG_NAME=foo&& [..]rustc [..]`" + ).with_stderr_contains( + r#"[RUNNING] `[..]set CARGO_PKG_AUTHORS="escape='\"@example.com"&& [..]rustc [..]`"# + ) + } else { + b.with_stderr_contains("[RUNNING] `[..]CARGO_PKG_NAME=foo [..]rustc [..]`") + .with_stderr_contains( + r#"[RUNNING] `[..]CARGO_PKG_AUTHORS='escape='\''"@example.com' [..]rustc [..]`"#, + ) + }; + + b.run(); +} + // The tester may already have LD_LIBRARY_PATH=::/foo/bar which leads to a false positive error fn setenv_for_removing_empty_component(mut execs: Execs) -> Execs { let v = dylib_path_envvar(); @@ -1501,7 +1621,8 @@ "##, dylib_path_envvar() ), - ).build(); + ) + .build(); setenv_for_removing_empty_component(p.cargo("run")).run(); } @@ -1536,14 +1657,16 @@ name = "foo" crate_type = ["rlib", "dylib"] "#, - ).file("src/foo.rs", "pub fn foo() {}") + ) + .file("src/foo.rs", "pub fn foo() {}") .build(); p.cargo("build") .with_stderr_contains( "\ [WARNING] path `[..]src/foo.rs` was erroneously implicitly accepted for library `foo`, please rename the file to `src/lib.rs` or set lib.path in Cargo.toml", - ).run(); + ) + .run(); assert!(p.root().join("target/debug/libfoo.rlib").is_file()); let fname = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX); @@ -1567,7 +1690,8 @@ name = "foo" crate_type = ["rlib", "dylib"] "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .build(); p.cargo("build").run(); @@ -1596,7 +1720,8 @@ name = "test" path = "src/test.rs" "#, - ).file("src/test.rs", "fn main() {}") + ) + .file("src/test.rs", "fn main() {}") .build(); p.cargo("build") .with_status(101) @@ -1604,7 +1729,8 @@ "\ [ERROR] cyclic package dependency: package `test v0.0.0 ([CWD])` depends on itself. Cycle: package `test v0.0.0 ([CWD])`", - ).run(); + ) + .run(); } #[test] @@ -1638,7 +1764,8 @@ Caused by: no targets specified in the manifest either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present\n", - ).run(); + ) + .run(); } #[test] @@ -1661,7 +1788,8 @@ [profile.release] lto = true "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v --release") .with_stderr( @@ -1676,7 +1804,8 @@ -L dependency=[CWD]/target/release/deps` [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1693,7 +1822,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1711,7 +1841,8 @@ -L dependency=[CWD]/target/release/deps` [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1729,7 +1860,8 @@ [dependencies.foo] path = "foo" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -1743,7 +1875,8 @@ name = "foo" crate_type = ["dylib", "rlib"] "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build -v --release") .with_stderr(&format!( @@ -1770,7 +1903,8 @@ ", prefix = env::consts::DLL_PREFIX, suffix = env::consts::DLL_SUFFIX - )).run(); + )) + .run(); } #[test] @@ -1796,26 +1930,30 @@ name = "goodbye" path = "examples/ex-goodbye.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn get_hello() -> &'static str { "Hello" } pub fn get_goodbye() -> &'static str { "Goodbye" } pub fn get_world() -> &'static str { "World" } "#, - ).file( + ) + .file( "examples/ex-hello.rs", r#" extern crate foo; fn main() { println!("{}, {}!", foo::get_hello(), foo::get_world()); } "#, - ).file( + ) + .file( "examples/ex-goodbye.rs", r#" extern crate foo; fn main() { println!("{}, {}!", foo::get_goodbye(), foo::get_world()); } "#, - ).build(); + ) + .build(); p.cargo("test -v").run(); p.process(&p.bin("examples/hello")) @@ -1844,7 +1982,8 @@ [[example]] name = "hello" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("test -v") @@ -1855,7 +1994,8 @@ Caused by: can't find `hello` example, specify example.path", - ).run(); + ) + .run(); } #[test] @@ -1874,7 +2014,8 @@ Caused by: can't find `foo` bin, specify bin.path", - ).run(); + ) + .run(); } #[test] @@ -1891,7 +2032,8 @@ [[bin]] name = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "fn main() {}") .build(); @@ -1900,7 +2042,8 @@ "\ [WARNING] path `[..]src/main.rs` was erroneously implicitly accepted for binary `bar`, please set bin.path in Cargo.toml", - ).run(); + ) + .run(); let p = project() .file( @@ -1914,7 +2057,8 @@ [[bin]] name = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/bin/main.rs", "fn main() {}") .build(); @@ -1923,7 +2067,8 @@ "\ [WARNING] path `[..]src/bin/main.rs` was erroneously implicitly accepted for binary `bar`, please set bin.path in Cargo.toml", - ).run(); + ) + .run(); let p = project() .file( @@ -1937,7 +2082,8 @@ [[bin]] name = "bar" "#, - ).file("src/bar.rs", "fn main() {}") + ) + .file("src/bar.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -1945,7 +2091,8 @@ "\ [WARNING] path `[..]src/bar.rs` was erroneously implicitly accepted for binary `bar`, please set bin.path in Cargo.toml", - ).run(); + ) + .run(); } #[test] @@ -1958,7 +2105,8 @@ pub fn get_goodbye() -> &'static str { "Goodbye" } pub fn get_world() -> &'static str { "World" } "#, - ).file( + ) + .file( "examples/hello.rs", r#" extern crate foo; @@ -1966,7 +2114,8 @@ println!("{}, {}!", foo::get_hello(), foo::get_world()); } "#, - ).file( + ) + .file( "examples/goodbye.rs", r#" extern crate foo; @@ -1974,7 +2123,8 @@ println!("{}, {}!", foo::get_goodbye(), foo::get_world()); } "#, - ).build(); + ) + .build(); p.cargo("test").run(); p.process(&p.bin("examples/hello")) @@ -2000,7 +2150,8 @@ } } "#, - ).build(); + ) + .build(); p.cargo("build").run(); p.process(&p.bin("foo")).with_stdout("slow\n").run(); @@ -2021,7 +2172,8 @@ } } "#, - ).build(); + ) + .build(); p.cargo("build --release").run(); p.process(&p.release_bin("foo")).with_stdout("fast\n").run(); @@ -2049,14 +2201,18 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() {}") + ) + .file("src/main.rs", "extern crate bar; fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); p.cargo("build").run(); p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]can't find crate for `bar`") + .run(); } #[test] @@ -2078,7 +2234,8 @@ .file( "src/main.rs", "extern crate syntax; fn main() { syntax::foo() }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -2086,7 +2243,8 @@ [COMPILING] syntax v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2104,7 +2262,8 @@ name = "foo" crate-type = ["staticlib"] "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .build(); // env var is a test for #1381 @@ -2126,7 +2285,8 @@ name = "foo" crate-type = ["staticlib", "rlib"] "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file("src/main.rs", "extern crate foo; fn main() { foo::foo(); }") .build(); @@ -2146,7 +2306,8 @@ authors = [] version = "0.0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "bad syntax") .build(); p.cargo("build").run(); @@ -2167,7 +2328,8 @@ name = "foo" path = "src/bar.rs" "#, - ).file("src/bar.rs", "") + ) + .file("src/bar.rs", "") .build(); p.cargo("build").run(); } @@ -2185,7 +2347,8 @@ build = "build.rs" exclude = ["src/b*.rs"] "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .build(); foo.root().move_into_the_past(); @@ -2196,7 +2359,8 @@ [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // Smoke test to make sure it doesn't compile again println!("first pass"); @@ -2220,7 +2384,8 @@ authors = [] build = 'build.rs' "#, - ).file( + ) + .file( "build.rs", r#" use std::env; @@ -2236,7 +2401,8 @@ } } "#, - ).file("src/lib.rs", "pub fn bar() -> i32 { 1 }") + ) + .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .build(); foo.root().move_into_the_past(); @@ -2247,7 +2413,8 @@ [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); File::create(&foo.root().join("src/bar.rs")).unwrap(); foo.cargo("build") @@ -2256,7 +2423,8 @@ [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2273,7 +2441,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "pub fn bar() -> i32 { 1 }") + ) + .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0")) .file("bar/src/main.rs", "") .build(); @@ -2295,7 +2464,8 @@ name = "foo" path = "src/my lib.rs" "#, - ).file("src/my lib.rs", "") + ) + .file("src/my lib.rs", "") .build(); foo.cargo("build").run(); foo.root().move_into_the_past(); @@ -2343,7 +2513,8 @@ Caused by: expected an equals, found an identifier at line 1 ", - ).run(); + ) + .run(); } #[test] @@ -2369,14 +2540,17 @@ "#, host = host ), - ).file("src/main.rs", "extern crate dep; fn main() { dep::dep() }") + ) + .file("src/main.rs", "extern crate dep; fn main() { dep::dep() }") .file( "tests/foo.rs", "extern crate dev; #[test] fn foo() { dev::dev() }", - ).file( + ) + .file( "build.rs", "extern crate build; fn main() { build::build(); }", - ).file("dep/Cargo.toml", &basic_manifest("dep", "0.5.0")) + ) + .file("dep/Cargo.toml", &basic_manifest("dep", "0.5.0")) .file("dep/src/lib.rs", "pub fn dep() {}") .file("build/Cargo.toml", &basic_manifest("build", "0.5.0")) .file("build/src/lib.rs", "pub fn build() {}") @@ -2405,14 +2579,19 @@ [target.wrong-target.dependencies.bar] path = "bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file( "bar/src/lib.rs", - r#"extern crate baz; pub fn gimme() -> String { format!("") }"#, - ).build(); + r#"pub fn gimme() -> String { format!("") }"#, + ) + .build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]can't find crate for `bar`") + .run(); } #[test] @@ -2430,12 +2609,14 @@ [target.non-existing-triplet.dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file( "bar/src/lib.rs", "invalid rust file, should not be compiled", - ).build(); + ) + .build(); p.cargo("build").run(); @@ -2466,7 +2647,8 @@ name = "ex" crate-type = ["lib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); @@ -2489,7 +2671,8 @@ name = "ex" crate-type = ["rlib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); @@ -2512,7 +2695,8 @@ name = "ex" crate-type = ["dylib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); @@ -2539,7 +2723,8 @@ name = "ex" crate-type = ["proc-macro"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "#![feature(proc_macro)]") .build(); @@ -2595,10 +2780,12 @@ [dependencies.aaaaa] path = "a" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bbbbb; extern crate aaaaa; fn main() {}", - ).file( + ) + .file( "a/Cargo.toml", r#" [package] @@ -2609,7 +2796,8 @@ [dependencies.bbbbb] path = "../b" "#, - ).file("a/src/lib.rs", "extern crate bbbbb;") + ) + .file("a/src/lib.rs", "extern crate bbbbb;") .file("b/Cargo.toml", &basic_manifest("bbbbb", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -2634,7 +2822,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -2646,7 +2835,8 @@ [dependencies.foo] path = ".." "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build -v") @@ -2673,7 +2863,8 @@ name = "foo" crate-type = ["dylib", "rlib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v").run(); @@ -2708,11 +2899,22 @@ [lib] name = "foo-bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "extern crate foo_bar; fn main() {}") .build(); - p.cargo("build -v").with_status(101).run(); + p.cargo("build -v") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml` + +Caused by: + library target names cannot contain hyphens: foo-bar +", + ) + .run(); } #[test] @@ -2729,7 +2931,8 @@ Caused by: [..] ", - ).run(); + ) + .run(); assert!(!p.bin("a").is_file()); } @@ -2838,7 +3041,8 @@ [build] target-dir = "foo/target" "#, - ).unwrap(); + ) + .unwrap(); p.cargo("build").env("CARGO_TARGET_DIR", "bar/target").run(); assert!(p.root().join("bar/target/debug").join(&exe_name).is_file()); assert!(p.root().join("foo/target/debug").join(&exe_name).is_file()); @@ -2867,7 +3071,8 @@ [build] target-dir = "foo/target" "#, - ).unwrap(); + ) + .unwrap(); p.cargo("build --target-dir bar/target").run(); assert!(p.root().join("bar/target/debug").join(&exe_name).is_file()); assert!(p.root().join("foo/target/debug").join(&exe_name).is_file()); @@ -2876,12 +3081,11 @@ p.cargo("build --target-dir foobar/target") .env("CARGO_TARGET_DIR", "bar/target") .run(); - assert!( - p.root() - .join("foobar/target/debug") - .join(&exe_name) - .is_file() - ); + assert!(p + .root() + .join("foobar/target/debug") + .join(&exe_name) + .is_file()); assert!(p.root().join("bar/target/debug").join(&exe_name).is_file()); assert!(p.root().join("foo/target/debug").join(&exe_name).is_file()); assert!(p.root().join("target/debug").join(&exe_name).is_file()); @@ -2906,7 +3110,8 @@ [[bin]] name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""i am foo""#, &[])) + ) + .file("src/foo.rs", &main_file(r#""i am foo""#, &[])) .file("d1/Cargo.toml", &basic_bin_manifest("d1")) .file("d1/src/lib.rs", "") .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }") @@ -2922,7 +3127,8 @@ name = "d2" doctest = false "#, - ).file("d2/src/main.rs", "fn main() { println!(\"d2\"); }") + ) + .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }") .build(); p.cargo("build -p d1 -p d2 -p foo").run(); @@ -2963,7 +3169,8 @@ [[bin]] name = "foo" "#, - ).file("src/bin/foo.rs", &main_file(r#""i am foo""#, &[])) + ) + .file("src/bin/foo.rs", &main_file(r#""i am foo""#, &[])) .file("d1/Cargo.toml", &basic_bin_manifest("d1")) .file("d1/src/lib.rs", "") .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }") @@ -2971,12 +3178,12 @@ p.cargo("build -p notAValidDep") .with_status(101) - .with_stderr("[ERROR] package id specification `notAValidDep` matched no packages") + .with_stderr("[ERROR] package ID specification `notAValidDep` matched no packages") .run(); p.cargo("build -p d1 -p notAValidDep") .with_status(101) - .with_stderr("[ERROR] package id specification `notAValidDep` matched no packages") + .with_stderr("[ERROR] package ID specification `notAValidDep` matched no packages") .run(); } @@ -2991,7 +3198,8 @@ version = \"0.0.1\" authors = [] ", - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v").run(); } @@ -3010,7 +3218,8 @@ [profile.dev] panic = 'abort' "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_stderr_contains("[..] -C panic=abort [..]") @@ -3036,7 +3245,8 @@ [RUNNING] `rustc [..] --color never [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -3054,15 +3264,17 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "build.rs", "fn main() { println!(\"cargo:rustc-cfg=xyz\") }", - ).file("src/main.rs", "fn main() { let unused = 92; }") + ) + .file("src/main.rs", "fn main() { let unused = 92; }") .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("bar/src/lib.rs", r#"fn dead() {}"#) .build(); - // Using jobs=1 to ensure that the order of messages is consistent. + // Use `jobs=1` to ensure that the order of messages is consistent. p.cargo("build -v --message-format=json --jobs=1") .with_json( r#" @@ -3083,6 +3295,7 @@ "overflow_checks": true, "test": false }, + "executable": null, "features": [], "filenames": "{...}", "fresh": false @@ -3110,6 +3323,7 @@ "overflow_checks": true, "test": false }, + "executable": null, "features": [], "package_id":"bar 0.5.0 ([..])", "target":{ @@ -3162,12 +3376,14 @@ "overflow_checks": true, "test": false }, + "executable": "[..]/foo/target/debug/foo[EXE]", "features": [], "filenames": "{...}", "fresh": false } "#, - ).run(); + ) + .run(); // With fresh build, we should repeat the artifacts, // but omit compiler warnings. @@ -3191,6 +3407,7 @@ "overflow_checks": true, "test": false }, + "executable": null, "features": [], "filenames": "{...}", "fresh": true @@ -3205,6 +3422,7 @@ "overflow_checks": true, "test": false }, + "executable": null, "features": [], "package_id":"bar 0.5.0 ([..])", "target":{ @@ -3244,12 +3462,14 @@ "overflow_checks": true, "test": false }, + "executable": "[..]/foo/target/debug/foo[EXE]", "features": [], "filenames": "{...}", "fresh": true } "#, - ).run(); + ) + .run(); } #[test] @@ -3266,7 +3486,8 @@ error: 'XML' isn't a valid value for '--message-format ' [possible values: human, json, short] ", - ).run(); + ) + .run(); } #[test] @@ -3309,12 +3530,14 @@ "overflow_checks": false, "test":false }, + "executable": "{...}", "features":[], "filenames": "{...}", "fresh": false } "#, - ).run(); + ) + .run(); } #[test] @@ -3336,13 +3559,15 @@ [package.metadata.another] bar = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .with_stderr( "[..] foo v0.0.1 ([..])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3374,7 +3599,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -3384,7 +3610,8 @@ "[..] Compiling bar v0.1.0 ([..])\n\ [..] Compiling foo v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3400,7 +3627,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) @@ -3429,7 +3657,8 @@ [workspace] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/bin/a.rs", "fn main() {}") .file("src/bin/b.rs", "fn main() {}") .file("examples/c.rs", "fn main() {}") @@ -3447,7 +3676,8 @@ "[..] Compiling bar v0.1.0 ([..])\n\ [..] Compiling foo v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); assert!(!p.bin("a").is_file()); assert!(!p.bin("b").is_file()); assert!(p.bin("examples/c").is_file()); @@ -3467,7 +3697,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -3481,7 +3712,8 @@ "[..] Compiling [..] v0.1.0 ([..])\n\ [..] Compiling [..] v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3493,13 +3725,14 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") .build(); - // The order in which bar and baz are built is not guaranteed + // The order in which `bar` and `baz` are built is not guaranteed. p.cargo("build") .with_stderr_contains("[..] Compiling baz v0.1.0 ([..])") .with_stderr_contains("[..] Compiling bar v0.1.0 ([..])") @@ -3507,7 +3740,8 @@ "[..] Compiling [..] v0.1.0 ([..])\n\ [..] Compiling [..] v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3519,7 +3753,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -3531,7 +3766,8 @@ .with_stderr( "[..] Compiling [..] v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3543,7 +3779,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .file("bar/src/bin/a.rs", "fn main() {}") .file("bar/src/bin/b.rs", "fn main() {}") @@ -3565,7 +3802,8 @@ "[..] Compiling [..] v0.1.0 ([..])\n\ [..] Compiling [..] v0.1.0 ([..])\n\ [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); assert!(!p.bin("a").is_file()); assert!(!p.bin("b").is_file()); assert!(p.bin("examples/c").is_file()); @@ -3585,7 +3823,8 @@ [workspace] members = ["a"] "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -3595,7 +3834,8 @@ [dependencies] a = "0.1.0" "#, - ).file("a/src/lib.rs", "pub fn a() {}") + ) + .file("a/src/lib.rs", "pub fn a() {}") .build(); Package::new("a", "0.1.0").publish(); @@ -3608,7 +3848,8 @@ [COMPILING] a v0.1.0\n\ [COMPILING] a v0.1.0 ([..])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -3626,11 +3867,13 @@ [[bin]] name = "other" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "src/bin/main.rs", r#"fn main() { panic!("This should never be run."); }"#, - ).file("src/bin/other.rs", "fn main() {}") + ) + .file("src/bin/other.rs", "fn main() {}") .build(); p.cargo("run --bin other").run(); @@ -3662,7 +3905,8 @@ [[bin]] name = "bar" "#, - ).file("src/foo.rs", r#"fn main() { println!("foo"); }"#) + ) + .file("src/foo.rs", r#"fn main() { println!("foo"); }"#) .file("src/bar.rs", r#"fn main() { println!("bar"); }"#) .build(); @@ -3686,7 +3930,8 @@ [[bin]] name = "bar" "#, - ).file("src/main.rs", r#"fn main() { println!("main"); }"#) + ) + .file("src/main.rs", r#"fn main() { println!("main"); }"#) .build(); p.cargo("build --all").run(); @@ -3701,24 +3946,18 @@ .file( "src/foo.rs", r#" fn main() { panic!("This should never be run."); }"#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("run --bin foo").run(); } #[test] +// NOTE: we don't have `/usr/bin/env` on Windows. +#[cfg(not(windows))] fn rustc_wrapper() { - // We don't have /usr/bin/env on Windows. - if cfg!(windows) { - return; - } - - let p = project() - .file("Cargo.toml", &basic_bin_manifest("foo")) - .file("src/foo.rs", &main_file(r#""i am foo""#, &[])) - .build(); - + let p = project().file("src/lib.rs", "").build(); p.cargo("build -v") .env("RUSTC_WRAPPER", "/usr/bin/env") .with_stderr_contains("[RUNNING] `/usr/bin/env rustc --crate-name foo [..]") @@ -3726,6 +3965,28 @@ } #[test] +#[cfg(not(windows))] +fn rustc_wrapper_relative() { + let p = project().file("src/lib.rs", "").build(); + p.cargo("build -v") + .env("RUSTC_WRAPPER", "./sccache") + .with_status(101) + .with_stderr_contains("[..]/foo/./sccache rustc[..]") + .run(); +} + +#[test] +#[cfg(not(windows))] +fn rustc_wrapper_from_path() { + let p = project().file("src/lib.rs", "").build(); + p.cargo("build -v") + .env("RUSTC_WRAPPER", "wannabe_sccache") + .with_status(101) + .with_stderr_contains("[..]`wannabe_sccache rustc [..]") + .run(); +} + +#[test] fn cdylib_not_lifted() { let p = project() .file( @@ -3739,7 +4000,8 @@ [lib] crate-type = ["cdylib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -3772,7 +4034,8 @@ [lib] crate-type = ["cdylib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -3793,7 +4056,7 @@ #[test] fn deterministic_cfg_flags() { - // This bug is non-deterministic + // This bug is non-deterministic. let p = project() .file( @@ -3812,7 +4075,8 @@ f_c = [] f_d = [] "#, - ).file( + ) + .file( "build.rs", r#" fn main() { @@ -3823,7 +4087,8 @@ println!("cargo:rustc-cfg=cfg_e"); } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -3837,7 +4102,8 @@ --cfg[..]f_c[..]--cfg[..]f_d[..] \ --cfg cfg_a --cfg cfg_b --cfg cfg_c --cfg cfg_d --cfg cfg_e` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -3857,7 +4123,8 @@ [[bin]] name = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "fn main() {}") .file("src/bin/bar.rs", "fn main() {}") .build(); @@ -3881,7 +4148,8 @@ Caused by: can't find `foo` bin, specify bin.path", - ).run(); + ) + .run(); } #[test] @@ -3928,7 +4196,8 @@ name = "bar" # Note, no `path` key! "#, - ).file("src/bin/bar/main.rs", "fn main() {}") + ) + .file("src/bin/bar/main.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -3983,17 +4252,20 @@ [lib] edition = "2018" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") - .without_status() // passes on nightly, fails on stable, b/c --edition is nightly-only + // Passes on nightly, fails on stable, since `--edition` is nightly-only. + .without_status() .with_stderr_contains( "\ [COMPILING] foo v0.0.1 ([..]) [RUNNING] `rustc [..]--edition=2018 [..] ", - ).run(); + ) + .run(); } #[test] @@ -4011,13 +4283,14 @@ [lib] edition = "2015" "#, - ).file( + ) + .file( "src/lib.rs", " pub fn async() {} pub fn try() {} pub fn await() {} - " + ", ) .build(); @@ -4065,7 +4338,8 @@ [[bin]] name = "a_bin" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); let p = project() @@ -4079,7 +4353,8 @@ [dependencies] testless = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -4103,13 +4378,12 @@ p.cargo("build --bins --examples --tests").run(); assert!(p.bin("foo.dSYM").is_dir()); assert!(p.bin("b.dSYM").is_dir()); - assert!( - p.bin("b.dSYM") - .symlink_metadata() - .expect("read metadata from b.dSYM") - .file_type() - .is_symlink() - ); + assert!(p + .bin("b.dSYM") + .symlink_metadata() + .expect("read metadata from b.dSYM") + .file_type() + .is_symlink()); assert!(!p.bin("c.dSYM").is_dir()); assert!(!p.bin("d.dSYM").is_dir()); } @@ -4133,8 +4407,8 @@ assert!(!p.target_debug_dir().join("d.pdb").is_file()); } -// Make sure that `cargo build` chooses the correct profile for building -// targets based on filters (assuming --profile is not specified). +// Ensure that `cargo build` chooses the correct profile for building +// targets based on filters (assuming `--profile` is not specified). #[test] fn build_filter_infer_profile() { let p = project() @@ -4149,23 +4423,28 @@ .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ --emit=dep-info,link[..]", - ).with_stderr_contains( + ) + .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ --emit=dep-info,link[..]", - ).run(); + ) + .run(); p.root().join("target").rm_rf(); p.cargo("build -v --test=t1") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ --emit=dep-info,link -C debuginfo=2 [..]", - ).with_stderr_contains( + ) + .with_stderr_contains( "[RUNNING] `rustc --crate-name t1 tests/t1.rs --color never --emit=dep-info,link \ - -C debuginfo=2 [..]", - ).with_stderr_contains( + -C debuginfo=2 [..]", + ) + .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ --emit=dep-info,link -C debuginfo=2 [..]", - ).run(); + ) + .run(); p.root().join("target").rm_rf(); // Bench uses test profile without `--release`. @@ -4173,66 +4452,85 @@ .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/lib.rs --color never --crate-type lib \ --emit=dep-info,link -C debuginfo=2 [..]", - ).with_stderr_contains( + ) + .with_stderr_contains( "[RUNNING] `rustc --crate-name b1 benches/b1.rs --color never --emit=dep-info,link \ - -C debuginfo=2 [..]", + -C debuginfo=2 [..]", ) .with_stderr_does_not_contain("opt-level") .with_stderr_contains( "[RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ --emit=dep-info,link -C debuginfo=2 [..]", - ).run(); + ) + .run(); } #[test] fn targets_selected_default() { let p = project().file("src/main.rs", "fn main() {}").build(); p.cargo("build -v") - // bin - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]") - // bench - .with_stderr_does_not_contain("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C opt-level=3 --test [..]") - // unit test - .with_stderr_does_not_contain("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C debuginfo=2 --test [..]").run(); + // Binaries. + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ + --emit=dep-info,link[..]", + ) + // Benchmarks. + .with_stderr_does_not_contain( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C opt-level=3 --test [..]", + ) + // Unit tests. + .with_stderr_does_not_contain( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C debuginfo=2 --test [..]", + ) + .run(); } #[test] fn targets_selected_all() { let p = project().file("src/main.rs", "fn main() {}").build(); p.cargo("build -v --all-targets") - // bin - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]") - // unit test - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C debuginfo=2 --test [..]").run(); + // Binaries. + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ + --emit=dep-info,link[..]", + ) + // Unit tests. + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C debuginfo=2 --test [..]", + ) + .run(); } #[test] fn all_targets_no_lib() { let p = project().file("src/main.rs", "fn main() {}").build(); p.cargo("build -v --all-targets") - // bin - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]") - // unit test - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C debuginfo=2 --test [..]").run(); + // Binaries. + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ + --emit=dep-info,link[..]", + ) + // Unit tests. + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C debuginfo=2 --test [..]", + ) + .run(); } #[test] fn no_linkable_target() { - // Issue 3169. This is currently not an error as per discussion in PR #4797 + // Issue 3169: this is currently not an error as per discussion in PR #4797. let p = project() .file( "Cargo.toml", @@ -4244,7 +4542,8 @@ [dependencies] the_lib = { path = "the_lib" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "the_lib/Cargo.toml", r#" @@ -4255,14 +4554,16 @@ name = "the_lib" crate-type = ["staticlib"] "#, - ).file("the_lib/src/lib.rs", "pub fn foo() {}") + ) + .file("the_lib/src/lib.rs", "pub fn foo() {}") .build(); p.cargo("build") .with_stderr_contains( "\ [WARNING] The package `the_lib` provides no linkable [..] \ while compiling `foo`. [..] in `the_lib`'s Cargo.toml. [..]", - ).run(); + ) + .run(); } #[test] @@ -4280,10 +4581,21 @@ [dev-dependencies] baz = "1.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +[UPDATING] [..] +[ERROR] no matching package named `baz` found +location searched: registry `https://github.com/rust-lang/crates.io-index` +required by package `bar v0.1.0 ([..]/foo)` +", + ) + .run(); p.cargo("build -Zavoid-dev-deps") .masquerade_as_nightly_cargo() .run(); @@ -4312,7 +4624,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_lib_manifest("a")) + ) + .file("a/Cargo.toml", &basic_lib_manifest("a")) .file("a/src/lib.rs", "") .file("a/examples/ex1.rs", "fn main() {}") .file("b/Cargo.toml", &basic_bin_manifest("b")) @@ -4327,16 +4640,15 @@ [ERROR] no example target named `ex` Did you mean `ex1`?", - ).run(); + ) + .run(); ws.cargo("build -v --lib") - .with_status(0) .with_stderr_contains("[RUNNING] `rustc [..]a/src/lib.rs[..]") .with_stderr_contains("[RUNNING] `rustc [..]b/src/lib.rs[..]") .run(); ws.cargo("build -v --example ex1") - .with_status(0) .with_stderr_contains("[RUNNING] `rustc [..]a/examples/ex1.rs[..]") .run(); } @@ -4351,7 +4663,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_bin_manifest("a")) + ) + .file("a/Cargo.toml", &basic_bin_manifest("a")) .file("a/src/main.rs", "fn main() {}") .file("b/Cargo.toml", &basic_bin_manifest("b")) .file("b/src/main.rs", "fn main() {}") @@ -4413,22 +4726,24 @@ .build(); foo.cargo("build") - .with_stderr("\ + .with_stderr( + "\ [COMPILING] pm [..] [COMPILING] foo [..] [ERROR] Could not compile `foo`. Caused by: process didn't exit successfully: `rustc [..]` (signal: 6, SIGABRT: process abort signal) -") +", + ) .with_status(101) .run(); } #[test] fn json_parse_fail() { - // Ensure when json parsing fails, and rustc exits with non-zero exit - // code, that a useful error message is displayed. + // Ensure when JSON parsing fails, and rustc exits with non-zero exit + // code, a useful error message is displayed. let foo = project() .file( "Cargo.toml", diff -Nru cargo-0.33.0/tests/testsuite/build_script_env.rs cargo-0.35.0/tests/testsuite/build_script_env.rs --- cargo-0.33.0/tests/testsuite/build_script_env.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build_script_env.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ use std::fs::File; -use support::project; -use support::sleep_ms; +use crate::support::project; +use crate::support::sleep_ms; #[test] fn rerun_if_env_changes() { @@ -14,7 +14,8 @@ println!("cargo:rerun-if-env-changed=FOO"); } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -22,7 +23,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .env("FOO", "bar") .with_stderr( @@ -30,7 +32,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .env("FOO", "baz") .with_stderr( @@ -38,7 +41,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .env("FOO", "baz") .with_stderr("[FINISHED] [..]") @@ -49,7 +53,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -64,7 +69,8 @@ println!("cargo:rerun-if-changed=foo"); } "#, - ).file("foo", "") + ) + .file("foo", "") .build(); p.cargo("build") @@ -73,7 +79,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .env("FOO", "bar") .with_stderr( @@ -81,7 +88,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .env("FOO", "bar") .with_stderr("[FINISHED] [..]") @@ -95,5 +103,6 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/build_script.rs cargo-0.35.0/tests/testsuite/build_script.rs --- cargo-0.33.0/tests/testsuite/build_script.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/build_script.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,13 +3,12 @@ use std::io; use std::io::prelude::*; use std::thread; -use std::time::Duration; +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::{basic_manifest, cross_compile, project}; +use crate::support::{rustc_host, sleep_ms, slow_cpu_multiplier}; use cargo::util::paths::remove_dir_all; -use support::paths::CargoPathExt; -use support::registry::Package; -use support::{basic_manifest, cross_compile, project}; -use support::{rustc_host, sleep_ms}; #[test] fn custom_build_script_failed() { @@ -24,7 +23,8 @@ authors = ["wycats@example.com"] build = "build.rs" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("build.rs", "fn main() { std::process::exit(101); }") .build(); p.cargo("build -v") @@ -36,7 +36,8 @@ [RUNNING] `[..]/build-script-build` [ERROR] failed to run custom build command for `foo v0.5.0 ([CWD])` process didn't exit successfully: `[..]/build-script-build` (exit code: 101)", - ).run(); + ) + .run(); } #[test] @@ -57,7 +58,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -71,7 +73,8 @@ [features] foo = [] "#, - ).file("bar/src/lib.rs", "pub fn hello() {}"); + ) + .file("bar/src/lib.rs", "pub fn hello() {}"); let file_content = format!( r#" @@ -141,7 +144,8 @@ "#, target ), - ).file( + ) + .file( "build.rs", r#" use std::env; @@ -150,7 +154,8 @@ assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker")); } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); // no crate type set => linker never called => build succeeds if and @@ -171,11 +176,13 @@ authors = ["wycats@example.com"] build = "build.rs" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "build.rs", r#"fn main() { println!("cargo:rustc-flags=-aaa -bbb"); }"#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -183,7 +190,8 @@ "\ [ERROR] Only `-l` and `-L` flags are allowed in build script of `foo v0.5.0 ([CWD])`: \ `-aaa -bbb`", - ).run(); + ) + .run(); } /* @@ -223,7 +231,7 @@ "#, ).build(); - // TODO: TEST FAILS BECAUSE OF WRONG STDOUT (but otherwise, the build works) + // TODO: TEST FAILS BECAUSE OF WRONG STDOUT (but otherwise, the build works). p.cargo("build --verbose") .with_status(101) .with_stderr( @@ -253,7 +261,8 @@ authors = [] links = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -263,7 +272,8 @@ [ERROR] package `foo v0.5.0 ([CWD])` specifies that it links to `a` but does \ not have a custom build script ", - ).run(); + ) + .run(); } #[test] @@ -283,7 +293,8 @@ [dependencies.a-sys] path = "a-sys" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "") .file( "a-sys/Cargo.toml", @@ -295,7 +306,8 @@ links = "a" build = "build.rs" "#, - ).file("a-sys/src/lib.rs", "") + ) + .file("a-sys/src/lib.rs", "") .file("a-sys/build.rs", "") .build(); @@ -329,7 +341,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "") .file( "a/Cargo.toml", @@ -343,7 +356,8 @@ [dependencies.a-sys] path = "a-sys" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file("a/build.rs", "") .file( "a/a-sys/Cargo.toml", @@ -355,7 +369,8 @@ links = "a" build = "build.rs" "#, - ).file("a/a-sys/src/lib.rs", "") + ) + .file("a/a-sys/src/lib.rs", "") .file("a/a-sys/build.rs", "") .build(); @@ -390,7 +405,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -402,7 +418,8 @@ "baz"); } "#, - ).file( + ) + .file( ".cargo/config", &format!( r#" @@ -413,7 +430,8 @@ "#, target ), - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -423,7 +441,8 @@ links = "foo" build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file("a/build.rs", "not valid rust code") .build(); @@ -438,7 +457,8 @@ [RUNNING] `rustc --crate-name foo [..] -L foo -L bar` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -455,7 +475,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .file( ".cargo/config", @@ -468,7 +489,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -488,7 +510,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -498,7 +521,8 @@ assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz"); } "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -508,7 +532,8 @@ links = "foo" build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#" @@ -521,7 +546,8 @@ println!("cargo:bar=baz"); } "#, - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -538,7 +564,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .build(); @@ -556,7 +583,8 @@ [RUNNING] `rustc --crate-name foo [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -573,7 +601,8 @@ links = "foo" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -584,7 +613,8 @@ std::thread::sleep(Duration::from_millis(500)); } "#, - ).build(); + ) + .build(); a.root().move_into_the_past(); let p = project() @@ -603,7 +633,8 @@ "#, a.root().display() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -613,7 +644,8 @@ assert_eq!(env::var("DEP_FOO_BAR").unwrap(), "baz"); } "#, - ).build(); + ) + .build(); p.cargo("build -v").run(); p.root().move_into_the_past(); @@ -636,7 +668,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .build(); @@ -659,7 +692,8 @@ [RUNNING] `[..]/foo-[..][EXE]` [DOCTEST] foo [RUNNING] `rustdoc --test [..]`", - ).with_stdout_contains_n("running 0 tests", 2) + ) + .with_stdout_contains_n("running 0 tests", 2) .run(); println!("doc"); @@ -670,7 +704,8 @@ [RUNNING] `rustdoc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); File::create(&p.root().join("src/main.rs")) .unwrap() @@ -684,7 +719,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo[EXE]` ", - ).run(); + ) + .run(); } #[test] @@ -701,7 +737,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -715,11 +752,13 @@ [dependencies.b] path = "../b" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#"fn main() { println!("cargo:rustc-flags=-L bar"); }"#, - ).file( + ) + .file( "b/Cargo.toml", r#" [project] @@ -729,7 +768,8 @@ links = "foo" build = "build.rs" "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file("b/build.rs", "bad file") .file( ".cargo/config", @@ -740,7 +780,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("build -v -j1") .with_stderr_contains( @@ -749,7 +790,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [RUNNING] `rustc --crate-name foo [..] -L bar -L foo` ", - ).run(); + ) + .run(); } #[test] @@ -766,7 +808,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -780,7 +823,8 @@ [dependencies.b] path = "../b" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#" @@ -788,7 +832,8 @@ println!("cargo:rustc-link-search=bar"); } "#, - ).file( + ) + .file( "b/Cargo.toml", r#" [project] @@ -798,7 +843,8 @@ links = "foo" build = "build.rs" "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file("b/build.rs", "bad file") .file( ".cargo/config", @@ -809,7 +855,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("build -v -j1") .with_stderr_contains( @@ -818,7 +865,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [RUNNING] `rustc --crate-name foo [..] -L bar -L foo` ", - ).run(); + ) + .run(); } #[test] @@ -835,7 +883,8 @@ [build-dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", " @@ -843,7 +892,8 @@ extern crate a; fn main() {} ", - ).file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) .file("a/src/lib.rs", "") .build(); @@ -858,7 +908,8 @@ [RUNNING] `rustc --crate-name foo [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -876,17 +927,20 @@ [build-dependencies.aaaaa] path = "a" "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate aaaaa;", - ).file( + ) + .file( "build.rs", " #[allow(unused_extern_crates)] extern crate aaaaa; fn main() {} ", - ).file("a/Cargo.toml", &basic_manifest("aaaaa", "0.5.0")) + ) + .file("a/Cargo.toml", &basic_manifest("aaaaa", "0.5.0")) .file("a/src/lib.rs", "") .build(); @@ -901,7 +955,8 @@ Caused by: process didn't exit successfully: [..] ", - ).run(); + ) + .run(); } #[test] @@ -919,7 +974,8 @@ [build-dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", " @@ -927,7 +983,8 @@ extern crate a; fn main() {} ", - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -939,11 +996,13 @@ [build-dependencies.b] path = "../b" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", "#[allow(unused_extern_crates)] extern crate b; fn main() {}", - ).file("b/Cargo.toml", &basic_manifest("b", "0.5.0")) + ) + .file("b/Cargo.toml", &basic_manifest("b", "0.5.0")) .file("b/src/lib.rs", "") .build(); @@ -974,7 +1033,8 @@ -L [..]target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -989,7 +1049,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -1001,7 +1062,8 @@ File::create(Path::new(&out).join("foo")).unwrap(); } "#, - ).build(); + ) + .build(); // Make the file p.cargo("build -v").run(); @@ -1019,7 +1081,8 @@ File::open(&Path::new(&out).join("foo")).unwrap(); } "#, - ).unwrap(); + ) + .unwrap(); p.root().move_into_the_past(); p.cargo("build -v").run(); @@ -1043,7 +1106,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -1052,7 +1116,8 @@ println!("cargo:rustc-flags=-l static=foo"); } "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_status(101) .with_stderr_contains( @@ -1063,7 +1128,8 @@ [RUNNING] `rustc --crate-name foo [..] -L foo -l static=foo` [ERROR] could not find native static library [..] ", - ).run(); + ) + .run(); } #[test] @@ -1078,7 +1144,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -1087,7 +1154,8 @@ println!("cargo:rustc-link-lib=static=foo"); } "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_status(101) .with_stderr_contains( @@ -1098,7 +1166,8 @@ [RUNNING] `rustc --crate-name foo [..] -L foo -l static=foo` [ERROR] could not find native static library [..] ", - ).run(); + ) + .run(); } #[cfg(not(windows))] // FIXME(#867) @@ -1114,7 +1183,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "src/main.rs", r#" include!(concat!(env!("OUT_DIR"), "/hello.rs")); @@ -1123,7 +1193,8 @@ println!("{}", message()); } "#, - ).file( + ) + .file( "build.rs", r#" use std::env; @@ -1141,7 +1212,8 @@ ").unwrap(); } "#, - ).build(); + ) + .build(); p.cargo("run") .with_stderr( @@ -1149,7 +1221,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo`", - ).with_stdout("Hello, World!") + ) + .with_stdout("Hello, World!") .run(); p.cargo("test").run(); @@ -1167,13 +1240,15 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" fn main() {} "#, - ).build(); + ) + .build(); p.cargo("build -v --release").run(); } @@ -1190,7 +1265,8 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", r#"fn main() {}"#) + ) + .file("build.rs", r#"fn main() {}"#) .build(); p.cargo("build -v") .with_status(101) @@ -1201,7 +1277,8 @@ Caused by: no targets specified in the manifest either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present", - ).run(); + ) + .run(); } #[test] @@ -1222,7 +1299,8 @@ [build-dependencies.b] path = "b" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .file( "a/Cargo.toml", @@ -1233,7 +1311,8 @@ authors = [] build = "build.rs" "#, - ).file("a/build.rs", "fn main() {}") + ) + .file("a/build.rs", "fn main() {}") .file("a/src/lib.rs", "") .file( "b/Cargo.toml", @@ -1246,7 +1325,8 @@ [dependencies.a] path = "../a" "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .build(); p.cargo("build -v").run(); } @@ -1266,7 +1346,8 @@ [build-dependencies.b] path = "b" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .file( "a/Cargo.toml", @@ -1278,7 +1359,8 @@ links = "foo" build = "build.rs" "#, - ).file("a/build.rs", "fn main() {}") + ) + .file("a/build.rs", "fn main() {}") .file("a/src/lib.rs", "") .file( "b/Cargo.toml", @@ -1295,7 +1377,8 @@ [dependencies.a] path = "../a" "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .build(); p.cargo("build").run(); } @@ -1312,7 +1395,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" include!(concat!(env!("OUT_DIR"), "/foo.rs")); @@ -1324,7 +1408,8 @@ assert_eq!(foo(), 1); } "#, - ).file( + ) + .file( "build.rs", r#" use std::env; @@ -1339,7 +1424,8 @@ ").unwrap(); } "#, - ).build(); + ) + .build(); p.cargo("test").run(); } @@ -1357,7 +1443,8 @@ [dev-dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -1367,7 +1454,8 @@ authors = [] build = "build.rs" "#, - ).file("a/build.rs", "fn main() {}") + ) + .file("a/build.rs", "fn main() {}") .file("a/src/lib.rs", "") .build(); @@ -1390,7 +1478,8 @@ name = "builder" crate-type = ["dylib"] "#, - ).file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") + ) + .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") .build(); let foo = project() @@ -1406,7 +1495,8 @@ [build-dependencies.bar] path = "bar" "#, - ).file("build.rs", "extern crate bar; fn main() { bar::bar() }") + ) + .file("build.rs", "extern crate bar; fn main() { bar::bar() }") .file("src/lib.rs", "") .file( "bar/Cargo.toml", @@ -1417,7 +1507,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "bar/build.rs", r#" use std::env; @@ -1440,7 +1531,8 @@ println!("cargo:rustc-link-search=native={}", out_dir.display()); } "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" pub fn bar() { @@ -1450,7 +1542,8 @@ unsafe { foo() } } "#, - ).build(); + ) + .build(); build .cargo("build -v") @@ -1476,7 +1569,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -1488,7 +1582,8 @@ assert_eq!(env::var("DEBUG").unwrap(), "false"); } "#, - ).build(); + ) + .build(); p.cargo("bench").run(); } @@ -1505,7 +1600,8 @@ [profile.dev] debug = 0 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -1517,7 +1613,8 @@ assert_eq!(env::var("DEBUG").unwrap(), "false"); } "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -1536,7 +1633,8 @@ [profile.dev] lto = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -1560,19 +1658,22 @@ [build-dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate bar; fn main() { bar::do_nothing() } "#, - ).file( + ) + .file( "build.rs", r#" extern crate bar; fn main() { bar::do_nothing() } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn do_nothing() {}") .build(); @@ -1591,11 +1692,13 @@ authors = [] build = "build.rs" "#, - ).file("src/main.rs", "#[cfg(foo)] fn main() {}") + ) + .file("src/main.rs", "#[cfg(foo)] fn main() {}") .file( "build.rs", r#"fn main() { println!("cargo:rustc-cfg=foo"); }"#, - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -1614,7 +1717,8 @@ links = "a" build = "build.rs" "#, - ).file("src/main.rs", "#[cfg(foo)] fn main() {}") + ) + .file("src/main.rs", "#[cfg(foo)] fn main() {}") .file("build.rs", "") .file( ".cargo/config", @@ -1625,7 +1729,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("build -v").run(); } @@ -1642,10 +1747,12 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#"fn main() { println!("cargo:rustc-cfg=foo"); }"#, - ).file( + ) + .file( "src/lib.rs", r#" /// @@ -1666,7 +1773,8 @@ foo() } "#, - ).file("tests/test.rs", "#[cfg(foo)] #[test] fn test_bar() {}") + ) + .file("tests/test.rs", "#[cfg(foo)] #[test] fn test_bar() {}") .build(); p.cargo("test -v") .with_stderr( @@ -1682,7 +1790,8 @@ [RUNNING] `[..]/test-[..][EXE]` [DOCTEST] foo [RUNNING] [..] --cfg foo[..]", - ).with_stdout_contains("test test_foo ... ok") + ) + .with_stdout_contains("test test_foo ... ok") .with_stdout_contains("test test_bar ... ok") .with_stdout_contains_n("test [..] ... ok", 3) .run(); @@ -1703,10 +1812,12 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "build.rs", r#"fn main() { println!("cargo:rustc-cfg=foo"); }"#, - ).file("src/lib.rs", "#[cfg(foo)] pub fn foo() {}") + ) + .file("src/lib.rs", "#[cfg(foo)] pub fn foo() {}") .file( "bar/Cargo.toml", r#" @@ -1716,10 +1827,12 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "bar/build.rs", r#"fn main() { println!("cargo:rustc-cfg=bar"); }"#, - ).file("bar/src/lib.rs", "#[cfg(bar)] pub fn bar() {}") + ) + .file("bar/src/lib.rs", "#[cfg(bar)] pub fn bar() {}") .build(); p.cargo("doc").run(); assert!(p.root().join("target/doc").is_dir()); @@ -1740,7 +1853,8 @@ build = "build.rs" links = "a" "#, - ).file("build.rs", "") + ) + .file("build.rs", "") .file( ".cargo/config", &format!( @@ -1750,7 +1864,8 @@ "#, rustc_host() ), - ).file( + ) + .file( "src/lib.rs", r#" /// @@ -1771,7 +1886,8 @@ foo() } "#, - ).file("tests/test.rs", "#[cfg(foo)] #[test] fn test_bar() {}") + ) + .file("tests/test.rs", "#[cfg(foo)] #[test] fn test_bar() {}") .build(); p.cargo("test -v") .with_stderr( @@ -1785,7 +1901,8 @@ [RUNNING] `[..]/test-[..][EXE]` [DOCTEST] foo [RUNNING] [..] --cfg foo[..]", - ).with_stdout_contains("test test_foo ... ok") + ) + .with_stdout_contains("test test_foo ... ok") .with_stdout_contains("test test_bar ... ok") .with_stdout_contains_n("test [..] ... ok", 3) .run(); @@ -1807,7 +1924,8 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( ".cargo/config", &format!( r#" @@ -1818,7 +1936,8 @@ "#, target = rustc_host() ), - ).file("build.rs", "") + ) + .file("build.rs", "") .file("src/lib.rs", "#[cfg(foo)] pub fn foo() {}") .file( "bar/Cargo.toml", @@ -1830,7 +1949,8 @@ build = "build.rs" links = "b" "#, - ).file("bar/build.rs", "") + ) + .file("bar/build.rs", "") .file("bar/src/lib.rs", "#[cfg(bar)] pub fn bar() {}") .build(); p.cargo("doc").run(); @@ -1851,7 +1971,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "src/main.rs", r#" const FOO: &'static str = env!("FOO"); @@ -1859,10 +1980,12 @@ println!("{}", FOO); } "#, - ).file( + ) + .file( "build.rs", r#"fn main() { println!("cargo:rustc-env=FOO=foo"); }"#, - ).build(); + ) + .build(); p.cargo("build -v").run(); p.cargo("run -v").with_stdout("foo\n").run(); } @@ -1879,13 +2002,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#"fn main() { println!("cargo:rustc-env=FOO=foo"); }"#, - ).file( + ) + .file( "src/lib.rs", r#"pub const FOO: &'static str = env!("FOO"); "#, - ).file( + ) + .file( "tests/test.rs", r#" extern crate foo; @@ -1895,7 +2021,8 @@ assert_eq!("foo", foo::FOO); } "#, - ).build(); + ) + .build(); p.cargo("test -v") .with_stderr( "\ @@ -1910,7 +2037,8 @@ [RUNNING] `[..]/test-[..][EXE]` [DOCTEST] foo [RUNNING] [..] --crate-name foo[..]", - ).with_stdout_contains_n("running 0 tests", 2) + ) + .with_stdout_contains_n("running 0 tests", 2) .with_stdout_contains("test test_foo ... ok") .run(); } @@ -1927,16 +2055,19 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "src/main.rs", r#" const FOO: &'static str = env!("FOO"); fn main() {} "#, - ).file( + ) + .file( "build.rs", r#"fn main() { println!("cargo:rustc-env=FOO=foo"); }"#, - ).build(); + ) + .build(); p.cargo("doc -v").run(); } @@ -1954,7 +2085,8 @@ [dependencies] b = { path = "b" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("tests/foo.rs", "") .file( "b/Cargo.toml", @@ -1966,7 +2098,8 @@ [dependencies] a = { path = "../a" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -1976,7 +2109,8 @@ authors = [] build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#" @@ -1984,7 +2118,8 @@ println!("cargo:rustc-link-search=test"); } "#, - ).build(); + ) + .build(); p.cargo("test -v --test=foo") .with_stderr( @@ -2000,7 +2135,8 @@ [RUNNING] `rustc [..] tests/foo.rs [..] -L test[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]/foo-[..][EXE]`", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); p.cargo("test -v -pb --lib") @@ -2011,7 +2147,8 @@ [RUNNING] `rustc [..] b/src/lib.rs [..] -L test[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]/b-[..][EXE]`", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); } @@ -2030,7 +2167,8 @@ a = { path = "a" } b = { path = "b" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("tests/foo.rs", "") .file( "a/Cargo.toml", @@ -2043,7 +2181,8 @@ b = { path = "../b" } c = { path = "../c" } "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "b/Cargo.toml", r#" @@ -2054,7 +2193,8 @@ [dependencies] c = { path = "../c" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "c/Cargo.toml", r#" @@ -2064,14 +2204,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "c/build.rs", r#" fn main() { println!("cargo:rustc-link-search=native=test"); } "#, - ).file("c/src/lib.rs", "") + ) + .file("c/src/lib.rs", "") .build(); p.cargo("build -v") @@ -2089,7 +2231,8 @@ [RUNNING] `[..]rlib -L native=test` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2106,7 +2249,8 @@ links = "foo" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file(".cargo/config", "") .file( "build.rs", @@ -2115,7 +2259,8 @@ println!("cargo:rustc-link-search=native=foo"); } "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_stderr( @@ -2126,7 +2271,8 @@ [RUNNING] `rustc [..] -L native=foo` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); File::create(p.root().join(".cargo/config")) .unwrap() @@ -2137,8 +2283,10 @@ rustc-link-search = [\"native=bar\"] ", target - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build -v") .with_stderr( @@ -2147,7 +2295,8 @@ [RUNNING] `rustc [..] -L native=bar` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2164,7 +2313,8 @@ links = "foo" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", &format!( @@ -2174,7 +2324,8 @@ ", target ), - ).file("build.rs", "") + ) + .file("build.rs", "") .build(); p.cargo("build -v") @@ -2184,7 +2335,8 @@ [RUNNING] `rustc [..] -L native=foo` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); File::create(p.root().join(".cargo/config")) .unwrap() @@ -2195,8 +2347,10 @@ rustc-link-search = [\"native=bar\"] ", target - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build -v") .with_stderr( @@ -2205,7 +2359,8 @@ [RUNNING] `rustc [..] -L native=bar` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2223,7 +2378,8 @@ links = "nativefoo" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", &format!( @@ -2235,7 +2391,8 @@ ", target ), - ).file("build.rs", "") + ) + .file("build.rs", "") .build(); p.cargo("build -v") @@ -2245,7 +2402,8 @@ [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build -v") .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint=info") @@ -2254,7 +2412,8 @@ [FRESH] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2272,7 +2431,8 @@ links = "foo" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", &format!( @@ -2286,7 +2446,8 @@ ", target ), - ).file("build.rs", "") + ) + .file("build.rs", "") .build(); p.cargo("build -v") @@ -2296,7 +2457,8 @@ [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build -v") .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint=info") @@ -2305,7 +2467,8 @@ [FRESH] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2320,7 +2483,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2329,7 +2493,8 @@ println!("cargo:rerun-if-changed=bar"); } "#, - ).build(); + ) + .build(); p.cargo("build -v").run(); @@ -2343,7 +2508,8 @@ [RUNNING] `rustc [..] src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); sleep_ms(1000); File::create(p.root().join("foo")).unwrap(); @@ -2360,7 +2526,8 @@ [RUNNING] `rustc [..] src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); println!("run with2"); p.cargo("build -v") @@ -2369,7 +2536,8 @@ [FRESH] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); sleep_ms(1000); @@ -2382,7 +2550,8 @@ [FRESH] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // but changing dependent files does println!("run foo change"); @@ -2395,7 +2564,8 @@ [RUNNING] `rustc [..] src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // .. as does deleting a file println!("run foo delete"); @@ -2408,7 +2578,8 @@ [RUNNING] `rustc [..] src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2424,7 +2595,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -2435,7 +2607,8 @@ links = "bar" build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#" @@ -2443,12 +2616,14 @@ println!("cargo:rustc-link-search=native=bar"); } "#, - ).build(); + ) + .build(); p.cargo("test -v") .with_stderr_contains( "[RUNNING] `rustdoc --test [..] --crate-name foo [..]-L native=bar[..]`", - ).run(); + ) + .run(); } #[test] @@ -2466,7 +2641,8 @@ [dependencies] a = { path = 'a' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2474,7 +2650,8 @@ println!("cargo:rustc-link-search=native=foo"); } "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -2484,7 +2661,8 @@ links = "bar" build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", r#" @@ -2492,7 +2670,8 @@ println!("cargo:rustc-link-search=native=bar"); } "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_stderr_contains("[RUNNING] `rustc [..] -L native=foo -L native=bar[..]`") @@ -2511,7 +2690,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#" use std::io::prelude::*; @@ -2528,7 +2708,8 @@ out.write_all(b"\xff\xff\n").unwrap(); } "#, - ).file("src/main.rs", "#[cfg(foo)] fn main() {}") + ) + .file("src/main.rs", "#[cfg(foo)] fn main() {}") .build(); p.cargo("build -v").run(); @@ -2548,14 +2729,16 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" [build] target-dir = 'test' "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -2564,7 +2747,8 @@ authors = [] build = "build.rs" "#, - ).file("a/build.rs", "fn main() {}") + ) + .file("a/build.rs", "fn main() {}") .file("a/src/lib.rs", "") .build(); @@ -2588,10 +2772,12 @@ [dependencies] a = { path = "a" } "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate a;", - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file( "a/Cargo.toml", r#" @@ -2604,11 +2790,13 @@ [build-dependencies] b = { path = "../b" } "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/build.rs", "#[allow(unused_extern_crates)] extern crate b; fn main() {}", - ).file( + ) + .file( "b/Cargo.toml", r#" [project] @@ -2616,7 +2804,8 @@ version = "0.5.0" authors = [] "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .build(); p.cargo("build -v --release").run(); @@ -2640,7 +2829,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2649,7 +2839,8 @@ println!("cargo:warning=bar"); } "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_stderr( @@ -2662,7 +2853,8 @@ [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2676,7 +2868,8 @@ println!("cargo:warning=bar"); } "#, - ).file( + ) + .file( "Cargo.toml", r#" [project] @@ -2685,7 +2878,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); let p = project() @@ -2700,7 +2894,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") @@ -2717,7 +2912,8 @@ [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2731,7 +2927,8 @@ println!("cargo:warning=bar"); } "#, - ).file( + ) + .file( "Cargo.toml", r#" [project] @@ -2740,7 +2937,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); let p = project() @@ -2755,7 +2953,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -vv") @@ -2765,16 +2964,17 @@ [DOWNLOADING] crates ... [DOWNLOADED] bar v0.1.0 ([..]) [COMPILING] bar v0.1.0 -[RUNNING] `rustc [..]` +[RUNNING] `[..] rustc [..]` [RUNNING] `[..]` warning: foo warning: bar -[RUNNING] `rustc [..]` +[RUNNING] `[..] rustc [..]` [COMPILING] foo v0.5.0 ([..]) -[RUNNING] `rustc [..]` +[RUNNING] `[..] rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2789,7 +2989,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2800,20 +3001,22 @@ std::io::stdout().write_all(b"stdout\n").unwrap(); } "#, - ).build(); + ) + .build(); p.cargo("build -vv") .with_stdout("[foo 0.5.0] stdout") .with_stderr( "\ [COMPILING] foo v0.5.0 ([..]) -[RUNNING] `rustc [..]` +[RUNNING] `[..] rustc [..]` [RUNNING] `[..]` [foo 0.5.0] stderr -[RUNNING] `rustc [..]` +[RUNNING] `[..] rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2831,7 +3034,8 @@ build = "build.rs" links = "a.b" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2839,7 +3043,8 @@ println!("cargo:rustc-link-search=bar") } "#, - ).file( + ) + .file( ".cargo/config", &format!( r#" @@ -2848,7 +3053,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("build -v") .with_stderr_contains("[RUNNING] `rustc --crate-name foo [..] [..] -L foo[..]`") @@ -2867,7 +3073,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2878,7 +3085,8 @@ assert_eq!(env::var("RUSTDOC").unwrap(), "rustdoc"); } "#, - ).build(); + ) + .build(); p.cargo("bench").run(); } @@ -2894,7 +3102,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -2909,7 +3118,8 @@ } } "#, - ).build(); + ) + .build(); p.cargo("bench").run(); } @@ -2928,14 +3138,16 @@ [features] foo = [] "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() { println!(include_str!(concat!(env!("OUT_DIR"), "/output"))); } "#, - ).file( + ) + .file( "build.rs", r#" use std::env; @@ -2955,11 +3167,17 @@ } } "#, - ).build(); + ) + .build(); - p.cargo("run -v --features=foo").with_stdout("foo\n").run(); - p.cargo("run -v").with_stdout("bar\n").run(); - p.cargo("run -v --features=foo").with_stdout("foo\n").run(); + p.cargo("build -v --features=foo").run(); + p.rename_run("foo", "with_foo").with_stdout("foo\n").run(); + p.cargo("build -v").run(); + p.rename_run("foo", "without_foo") + .with_stdout("bar\n") + .run(); + p.cargo("build -v --features=foo").run(); + p.rename_run("foo", "with_foo2").with_stdout("foo\n").run(); } #[test] @@ -2974,14 +3192,16 @@ } } "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-cfg=foo"); } "#, - ).build(); + ) + .build(); p.cargo("run -v").run(); } @@ -2998,7 +3218,8 @@ authors = [] build = false "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() { @@ -3007,14 +3228,16 @@ } } "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-cfg=foo"); } "#, - ).build(); + ) + .build(); p.cargo("run -v").run(); } @@ -3034,14 +3257,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-flags=-L native=test1"); } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); Package::new("dep2", "0.1.0") .file( @@ -3053,14 +3278,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-flags=-L native=test2"); } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); Package::new("dep3", "0.1.0") .file( @@ -3072,14 +3299,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-flags=-L native=test3"); } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); Package::new("dep4", "0.1.0") .file( @@ -3091,14 +3320,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", r#" fn main() { println!("cargo:rustc-flags=-L native=test4"); } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); let p = project() @@ -3116,7 +3347,8 @@ dep3 = "*" dep4 = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -3125,7 +3357,8 @@ [RUNNING] `rustc --crate-name foo [..] -L native=test1 -L native=test2 \ -L native=test3 -L native=test4` ", - ).run(); + ) + .run(); } #[test] @@ -3148,7 +3381,8 @@ [dev-dependencies] b = { path = "b" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "") .file( "a/Cargo.toml", @@ -3160,7 +3394,8 @@ links = "a" build = "build.rs" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file("a/build.rs", "") .file( "b/Cargo.toml", @@ -3173,7 +3408,8 @@ [dependencies] foo = { path = ".." } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .build(); p.cargo("build").with_status(101) @@ -3221,7 +3457,8 @@ [lib] crate-type = ["cdylib"] "#, - ).file( + ) + .file( "src/lib.rs", "#[no_mangle] pub extern fn cargo_test_foo() {}", ); @@ -3264,7 +3501,8 @@ dst.parent().unwrap().display()); } "#, - ).file( + ) + .file( "src/main.rs", r#" extern { @@ -3280,11 +3518,15 @@ let p2 = p2.build(); // Move the output `libfoo.so` into the directory of `p2`, and then delete - // the `p` project. On OSX the `libfoo.dylib` artifact references the + // the `p` project. On macOS, the `libfoo.dylib` artifact references the // original path in `p` so we want to make sure that it can't find it (hence // the deletion). let root = if cross { - p.root().join("target").join(cross_compile::alternate()).join("debug").join("deps") + p.root() + .join("target") + .join(cross_compile::alternate()) + .join("debug") + .join("deps") } else { p.root().join("target").join("debug").join("deps") }; @@ -3328,7 +3570,7 @@ panic!("failed to rename: {}", error); } println!("assuming {} is spurious, waiting to try again", error); - thread::sleep(Duration::from_millis(100)); + thread::sleep(slow_cpu_multiplier(100)); } p2.cargo(&format!("run{}", target_arg)) @@ -3338,7 +3580,8 @@ [FINISHED] [..] [RUNNING] [..] ", - ).run(); + ) + .run(); } #[test] @@ -3358,7 +3601,8 @@ [build-dependencies] bar = { path = "bar", optional = true } "#, - ).file( + ) + .file( "build.rs", r#" #[cfg(feature = "bar")] @@ -3372,7 +3616,8 @@ println!("cargo:rustc-env=FOO=0"); } "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(feature = "bar")] @@ -3382,7 +3627,8 @@ println!("{}", env!("FOO")); } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("bar/src/lib.rs", "pub fn bar() -> u32 { 1 }"); let p = p.build(); @@ -3407,7 +3653,8 @@ [build-dependencies] bar = { path = "./bar" } "#, - ).file("build.rs", "extern crate bar; fn main() { bar::bar(); }") + ) + .file("build.rs", "extern crate bar; fn main() { bar::bar(); }") .file( "src/main.rs", r#" @@ -3423,7 +3670,8 @@ } } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("bar/src/lib.rs", "pub fn bar() -> u32 { 1 }"); let p = p.build(); @@ -3435,7 +3683,8 @@ [COMPILING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]foo[EXE]`", - ).run(); + ) + .run(); p.cargo("run --all-features") .with_stdout("1") @@ -3444,5 +3693,6 @@ [COMPILING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]foo[EXE]`", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/cargo_alias_config.rs cargo-0.35.0/tests/testsuite/cargo_alias_config.rs --- cargo-0.33.0/tests/testsuite/cargo_alias_config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cargo_alias_config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_bin_manifest, project}; +use crate::support::{basic_bin_manifest, project}; #[test] fn alias_incorrect_config_type() { @@ -11,7 +11,8 @@ [alias] b-cargo-test = 5 "#, - ).build(); + ) + .build(); p.cargo("b-cargo-test -v") .with_status(101) @@ -19,7 +20,8 @@ "\ [ERROR] invalid configuration for key `alias.b-cargo-test` expected a list, but found a integer for [..]", - ).run(); + ) + .run(); } #[test] @@ -33,14 +35,16 @@ [alias] b-cargo-test = "build" "#, - ).build(); + ) + .build(); p.cargo("b-cargo-test -v") .with_stderr_contains( "\ [COMPILING] foo v0.5.0 [..] [RUNNING] `rustc --crate-name foo [..]", - ).run(); + ) + .run(); } #[test] @@ -55,14 +59,16 @@ b-cargo-test = "build" a-cargo-test = ["b-cargo-test", "-v"] "#, - ).build(); + ) + .build(); p.cargo("a-cargo-test") .with_stderr_contains( "\ [COMPILING] foo v0.5.0 [..] [RUNNING] `rustc --crate-name foo [..]", - ).run(); + ) + .run(); } #[test] @@ -76,7 +82,8 @@ [alias] b-cargo-test = ["build", "--release"] "#, - ).build(); + ) + .build(); p.cargo("b-cargo-test -v") .with_stderr_contains("[COMPILING] foo v0.5.0 [..]") @@ -95,7 +102,8 @@ [alias] b-cargo-test = "build --release" "#, - ).build(); + ) + .build(); p.cargo("b-cargo-test -v") .with_stderr_contains("[COMPILING] foo v0.5.0 [..]") @@ -114,7 +122,8 @@ [alias] build = "fetch" "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -123,7 +132,8 @@ [COMPILING] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -137,7 +147,8 @@ [alias] b = "run" "#, - ).build(); + ) + .build(); p.cargo("b") .with_stderr( @@ -146,7 +157,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo[EXE]` ", - ).run(); + ) + .run(); } #[test] diff -Nru cargo-0.33.0/tests/testsuite/cargo_command.rs cargo-0.35.0/tests/testsuite/cargo_command.rs --- cargo-0.33.0/tests/testsuite/cargo_command.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cargo_command.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,11 +4,11 @@ use std::path::{Path, PathBuf}; use std::str; +use crate::support::cargo_process; +use crate::support::paths::{self, CargoPathExt}; +use crate::support::registry::Package; +use crate::support::{basic_bin_manifest, basic_manifest, cargo_exe, project, Project}; use cargo; -use support::cargo_process; -use support::paths::{self, CargoPathExt}; -use support::registry::Package; -use support::{basic_bin_manifest, basic_manifest, cargo_exe, project, Project}; #[cfg_attr(windows, allow(dead_code))] enum FakeKind<'a> { @@ -16,9 +16,10 @@ Symlink { target: &'a Path }, } -/// Add an empty file with executable flags (and platform-dependent suffix). -/// TODO: move this to `Project` if other cases using this emerge. -fn fake_file(proj: Project, dir: &Path, name: &str, kind: &FakeKind) -> Project { +/// Adds an empty file with executable flags (and platform-dependent suffix). +// +// TODO: move this to `Project` if other cases using this emerge. +fn fake_file(proj: Project, dir: &Path, name: &str, kind: &FakeKind<'_>) -> Project { let path = proj .root() .join(dir) @@ -64,9 +65,14 @@ fn list_commands_with_descriptions() { let p = project().build(); p.cargo("--list") - .with_stdout_contains(" build Compile a local package and all of its dependencies") - // assert read-manifest prints the right one-line description followed by another command, indented. - .with_stdout_contains(" read-manifest Print a JSON representation of a Cargo.toml manifest.") + .with_stdout_contains( + " build Compile a local package and all of its dependencies", + ) + // Assert that `read-manifest` prints the right one-line description followed by another + // command, indented. + .with_stdout_contains( + " read-manifest Print a JSON representation of a Cargo.toml manifest.", + ) .run(); } @@ -83,7 +89,10 @@ let mut path = path(); path.push(proj.root().join("path-test")); let path = env::join_paths(path.iter()).unwrap(); - let output = cargo_process("-v --list").env("PATH", &path).exec_with_output().unwrap(); + let output = cargo_process("-v --list") + .env("PATH", &path) + .exec_with_output() + .unwrap(); let output = str::from_utf8(&output.stdout).unwrap(); assert!( output.contains("\n 1 "), @@ -92,7 +101,7 @@ ); } -// windows and symlinks don't currently agree that well +// Windows and symlinks don't currently mix well. #[cfg(unix)] #[test] fn list_command_resolves_symlinks() { @@ -109,7 +118,10 @@ let mut path = path(); path.push(proj.root().join("path-test")); let path = env::join_paths(path.iter()).unwrap(); - let output = cargo_process("-v --list").env("PATH", &path).exec_with_output().unwrap(); + let output = cargo_process("-v --list") + .env("PATH", &path) + .exec_with_output() + .unwrap(); let output = str::from_utf8(&output.stdout).unwrap(); assert!( output.contains("\n 2 "), @@ -128,7 +140,8 @@ Did you mean `build`? ", - ).run(); + ) + .run(); // But, if we actually have `biuld`, it must work! // https://github.com/rust-lang/cargo/issues/5201 @@ -140,7 +153,8 @@ println!("Similar, but not identical to, build"); } "#, - ).publish(); + ) + .publish(); cargo_process("install cargo-biuld").run(); cargo_process("biuld") @@ -149,11 +163,12 @@ cargo_process("--list") .with_stdout_contains( " build Compile a local package and all of its dependencies\n", - ).with_stdout_contains(" biuld\n") + ) + .with_stdout_contains(" biuld\n") .run(); } -// if a subcommand is more than 3 edit distance away, we don't make a suggestion +// If a subcommand is more than an edit distance of 3 away, we don't make a suggestion. #[test] fn find_closest_dont_correct_nonsense() { cargo_process("there-is-no-way-that-there-is-a-command-close-to-this") @@ -163,7 +178,8 @@ "[ERROR] no such subcommand: \ `there-is-no-way-that-there-is-a-command-close-to-this` ", - ).run(); + ) + .run(); } #[test] @@ -188,7 +204,8 @@ email = "bar" git = false "#, - ).unwrap(); + ) + .unwrap(); cargo_process("new foo") .env("USER", "foo") @@ -252,7 +269,8 @@ println!("{:?}", args); } "#, - ).build(); + ) + .build(); p.cargo("build").run(); let cargo_foo_bin = p.bin("cargo-foo"); @@ -291,7 +309,8 @@ println!("fancy help output"); } }"#, - ).publish(); + ) + .publish(); cargo_process("install cargo-fake-help").run(); cargo_process("help fake-help") .with_stdout("fancy help output\n") @@ -303,15 +322,17 @@ cargo_process("--explain E0001") .with_stdout_contains( "This error suggests that the expression arm corresponding to the noted pattern", - ).run(); + ) + .run(); } -// Test that the output of 'cargo -Z help' shows a different help screen with -// all the -Z flags. +// Test that the output of `cargo -Z help` shows a different help screen with +// all the `-Z` flags. #[test] fn z_flags_help() { cargo_process("-Z help") .with_stdout_contains( " -Z unstable-options -- Allow the usage of unstable options such as --registry", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/cargo_features.rs cargo-0.35.0/tests/testsuite/cargo_features.rs --- cargo-0.33.0/tests/testsuite/cargo_features.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cargo_features.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{project, publish}; +use crate::support::{project, registry}; #[test] fn feature_required() { @@ -12,7 +12,8 @@ authors = [] im-a-teapot = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .masquerade_as_nightly_cargo() @@ -29,7 +30,8 @@ consider adding `cargo-features = [\"test-dummy-unstable\"]` to the manifest ", - ).run(); + ) + .run(); p.cargo("build") .with_status(101) @@ -47,7 +49,8 @@ switch to nightly channel you can add `cargo-features = [\"test-dummy-unstable\"]` to enable this feature ", - ).run(); + ) + .run(); } #[test] @@ -63,7 +66,8 @@ version = "0.0.1" authors = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .with_status(101) @@ -74,7 +78,8 @@ Caused by: unknown cargo feature `foo` ", - ).run(); + ) + .run(); } #[test] @@ -90,7 +95,8 @@ version = "0.0.1" authors = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .with_stderr( @@ -100,7 +106,8 @@ [COMPILING] a [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -117,7 +124,8 @@ authors = [] im-a-teapot = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .masquerade_as_nightly_cargo() @@ -126,7 +134,8 @@ [COMPILING] a [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .with_status(101) @@ -138,7 +147,8 @@ the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \ but this is the `stable` channel ", - ).run(); + ) + .run(); } #[test] @@ -155,7 +165,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -167,7 +178,8 @@ authors = [] im-a-teapot = true "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build") .masquerade_as_nightly_cargo() @@ -177,7 +189,8 @@ [COMPILING] b [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .with_status(101) @@ -195,7 +208,8 @@ the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \ but this is the `stable` channel ", - ).run(); + ) + .run(); } #[test] @@ -212,7 +226,8 @@ authors = [] im-a-teapot = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") .masquerade_as_nightly_cargo() @@ -221,7 +236,8 @@ [COMPILING] a [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build") .with_status(101) @@ -233,7 +249,8 @@ the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \ but this is the `stable` channel ", - ).run(); + ) + .run(); } #[test] @@ -250,7 +267,8 @@ authors = [] im-a-teapot = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -Zprint-im-a-teapot") .with_status(101) @@ -271,12 +289,13 @@ [COMPILING] a [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] fn publish_allowed() { - publish::setup(); + registry::init(); let p = project() .file( @@ -289,10 +308,11 @@ version = "0.0.1" authors = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry::registry_url().to_string()) .masquerade_as_nightly_cargo() .run(); } diff -Nru cargo-0.33.0/tests/testsuite/cfg.rs cargo-0.35.0/tests/testsuite/cfg.rs --- cargo-0.33.0/tests/testsuite/cfg.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cfg.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ use std::fmt; use std::str::FromStr; +use crate::support::registry::Package; +use crate::support::rustc_host; +use crate::support::{basic_manifest, project}; use cargo::util::{Cfg, CfgExpr}; -use support::registry::Package; -use support::rustc_host; -use support::{basic_manifest, project}; macro_rules! c { ($a:ident) => { @@ -156,7 +156,8 @@ [target."cfg(windows)".dependencies] b = { path = 'b' } "#, - ).file("src/lib.rs", "extern crate b;") + ) + .file("src/lib.rs", "extern crate b;") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -181,7 +182,8 @@ "#, other_family ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -191,7 +193,8 @@ [COMPILING] a v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -214,10 +217,12 @@ [dependencies] bar = "0.1.0" "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate bar;", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -231,7 +236,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -259,10 +265,12 @@ "#, this_family, other_family ), - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate bar;", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -274,7 +282,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -291,7 +300,8 @@ [target.'cfg(4)'.dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -306,7 +316,8 @@ Caused by: unexpected character in cfg `4`, [..] ", - ).run(); + ) + .run(); } #[test] @@ -323,7 +334,8 @@ [target.'cfg(bar =)'.dependencies] baz = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -338,7 +350,8 @@ Caused by: expected a string, found nothing ", - ).run(); + ) + .run(); } #[test] @@ -369,7 +382,8 @@ "#, rustc_host() ), - ).file("src/lib.rs", "extern crate b;") + ) + .file("src/lib.rs", "extern crate b;") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -390,7 +404,8 @@ [target."cfg(any(windows, unix))".dependencies] b = { path = 'b' } "#, - ).file("src/lib.rs", "extern crate b;") + ) + .file("src/lib.rs", "extern crate b;") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -399,11 +414,7 @@ // https://github.com/rust-lang/cargo/issues/5313 #[test] -#[cfg(all( - target_arch = "x86_64", - target_os = "linux", - target_env = "gnu" -))] +#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] fn cfg_looks_at_rustflags_for_target() { let p = project() .file( @@ -417,7 +428,8 @@ [target.'cfg(with_b)'.dependencies] b = { path = 'b' } "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(with_b)] @@ -425,7 +437,8 @@ fn main() { b::foo(); } "#, - ).file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) + ) + .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "pub fn foo() {}") .build(); diff -Nru cargo-0.33.0/tests/testsuite/check.rs cargo-0.35.0/tests/testsuite/check.rs --- cargo-0.33.0/tests/testsuite/check.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/check.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ use std::fmt::{self, Write}; +use crate::support::install::exe; +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; use glob::glob; -use support::install::exe; -use support::paths::CargoPathExt; -use support::registry::Package; -use support::{basic_manifest, project}; #[test] fn check_success() { @@ -20,10 +20,12 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::baz(); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) @@ -47,17 +49,22 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::baz(42); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("src/lib.rs", "pub fn baz() {}") .build(); - foo.cargo("check").with_status(101).run(); + foo.cargo("check") + .with_status(101) + .with_stderr_contains("[..]this function takes 0 parameters but 1 parameter was supplied") + .run(); } #[test] @@ -74,7 +81,8 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", r#" #[macro_use] @@ -92,7 +100,8 @@ a.b(); } "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file( @@ -105,7 +114,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate proc_macro; @@ -117,7 +127,8 @@ format!("impl B for A {{ fn b(&self) {{}} }}").parse().unwrap() } "#, - ).build(); + ) + .build(); foo.cargo("check").run(); } @@ -136,10 +147,12 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::baz(); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") @@ -165,10 +178,12 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::baz(); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") @@ -210,7 +225,8 @@ [dependencies] rustc-serialize = "*" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate rustc_serialize; @@ -219,7 +235,8 @@ pub fn take() {} "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate rustc_serialize; @@ -233,7 +250,8 @@ foo::take::(); } "#, - ).build(); + ) + .build(); Package::new("rustc-serialize", "1.0.0") .file( @@ -247,7 +265,8 @@ -> Result where F: FnOnce(&mut Self) -> Result; } "#, - ).publish(); + ) + .publish(); p.cargo("check").run(); } @@ -269,7 +288,8 @@ [dependencies] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -278,7 +298,8 @@ [..]Compiling foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("check").run(); @@ -302,10 +323,12 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::baz(); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) @@ -329,10 +352,12 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", "extern crate bar; fn main() { ::bar::qux(); }", - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) @@ -341,6 +366,9 @@ foo.cargo("rustc --profile check -- --emit=metadata") .with_status(101) + .with_stderr_contains("[CHECKING] bar [..]") + .with_stderr_contains("[CHECKING] foo [..]") + .with_stderr_contains("[..]cannot find function `qux` in module `bar`") .run(); } @@ -359,7 +387,8 @@ [dependencies] b = { path = "b" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("examples/a.rs", "fn main() {}") .file("tests/a.rs", "") .file("src/lib.rs", "") @@ -385,7 +414,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -398,6 +428,20 @@ } #[test] +fn exclude_warns_on_non_existing_package() { + let p = project().file("src/lib.rs", "").build(); + p.cargo("check --all --exclude bar") + .with_stdout("") + .with_stderr( + r#"[WARNING] excluded package(s) bar not found in workspace `[CWD]` +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +"#, + ) + .run(); +} + +#[test] fn targets_selected_default() { let foo = project() .file("src/main.rs", "fn main() {}") @@ -449,7 +493,8 @@ } } "#, - ).build(); + ) + .build(); foo.cargo("check").run(); foo.cargo("check --profile test") @@ -471,7 +516,8 @@ fn unused_unit_lib() {} } "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() {} @@ -481,7 +527,8 @@ fn unused_unit_bin() {} } "#, - ).file( + ) + .file( "tests/t1.rs", r#" fn unused_normal_t1() {} @@ -490,7 +537,8 @@ fn unused_unit_t1() {} } "#, - ).file( + ) + .file( "examples/ex1.rs", r#" fn main() {} @@ -500,7 +548,8 @@ fn unused_unit_ex1() {} } "#, - ).file( + ) + .file( "benches/b1.rs", r#" fn unused_normal_b1() {} @@ -509,7 +558,8 @@ fn unused_unit_b1() {} } "#, - ).build(); + ) + .build(); p.cargo("check") .with_stderr_contains("[..]unused_normal_lib[..]") @@ -615,12 +665,11 @@ p.cargo("check --example ex1").run(); assert!(!p.root().join("target/debug/libfoo.rmeta").is_file()); assert!(!p.root().join("target/debug/libfoo.rlib").is_file()); - assert!( - !p.root() - .join("target/debug/examples") - .join(exe("ex1")) - .is_file() - ); + assert!(!p + .root() + .join("target/debug/examples") + .join(exe("ex1")) + .is_file()); assert_glob("target/debug/deps/libfoo-*.rmeta", 1); assert_glob("target/debug/examples/libex1-*.rmeta", 1); @@ -647,7 +696,8 @@ error: aborting due to previous error error: Could not compile `foo`. ", - ).run(); + ) + .run(); } #[test] @@ -663,7 +713,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate proc_macro; @@ -675,7 +726,8 @@ "".parse().unwrap() } "#, - ).file( + ) + .file( "src/main.rs", r#" #[macro_use] @@ -686,7 +738,8 @@ fn main() {} "#, - ).build(); + ) + .build(); p.cargo("check -v").env("RUST_LOG", "cargo=trace").run(); } diff -Nru cargo-0.33.0/tests/testsuite/clean.rs cargo-0.35.0/tests/testsuite/clean.rs --- cargo-0.33.0/tests/testsuite/clean.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/clean.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ use std::env; -use support::registry::Package; -use support::{basic_bin_manifest, basic_manifest, git, main_file, project}; +use crate::support::registry::Package; +use crate::support::{basic_bin_manifest, basic_manifest, git, main_file, project}; #[test] fn cargo_clean_simple() { @@ -54,7 +54,8 @@ [[bin]] name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""i am foo""#, &[])) + ) + .file("src/foo.rs", &main_file(r#""i am foo""#, &[])) .file("d1/Cargo.toml", &basic_bin_manifest("d1")) .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }") .file("d2/Cargo.toml", &basic_bin_manifest("d2")) @@ -99,7 +100,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -116,7 +118,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").run(); @@ -140,7 +143,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -169,7 +173,8 @@ authors = [] build = "build.rs" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "build.rs", r#" @@ -185,7 +190,8 @@ } } "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build").env("FIRST", "1").run(); @@ -199,7 +205,8 @@ [RUNNING] `rustc [..] src/main.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -208,7 +215,8 @@ project .file("Cargo.toml", &basic_manifest("dep", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -225,7 +233,8 @@ "#, git.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -247,7 +256,8 @@ [dependencies] bar = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.1.0").publish(); @@ -270,7 +280,8 @@ [dependencies] bar = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.1.0").publish(); @@ -282,6 +293,7 @@ [REMOVING] [..] [REMOVING] [..] ", - ).run(); + ) + .run(); p.cargo("build").run(); } diff -Nru cargo-0.33.0/tests/testsuite/collisions.rs cargo-0.35.0/tests/testsuite/collisions.rs --- cargo-0.33.0/tests/testsuite/collisions.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/collisions.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ +use crate::support::{basic_manifest, project}; use std::env; -use support::{basic_manifest, project}; #[test] fn collision_dylib() { @@ -39,8 +39,8 @@ .file("b/src/lib.rs", "") .build(); - // j=1 is required because on windows you'll get an error because - // two processes will be writing to the file at the same time. + // `j=1` is required because on Windows you'll get an error due to + // two processes writing to the file at the same time. p.cargo("build -j=1") .with_stderr_contains(&format!("\ [WARNING] output filename collision. @@ -48,7 +48,7 @@ Colliding filename is: [..]/foo/target/debug/deps/{}a{} The targets should have unique names. Consider changing their names to be unique or compiling them separately. -This may become a hard error in the future, see https://github.com/rust-lang/cargo/issues/6313 +This may become a hard error in the future; see . ", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX)) .run(); } @@ -77,14 +77,14 @@ Colliding filename is: [..]/foo/target/debug/examples/ex1[EXE] The targets should have unique names. Consider changing their names to be unique or compiling them separately. -This may become a hard error in the future, see https://github.com/rust-lang/cargo/issues/6313 +This may become a hard error in the future; see . ") .run(); } #[test] fn collision_export() { - // --out-dir combines some things which can cause conflicts. + // `--out-dir` combines some things which can cause conflicts. let p = project() .file("Cargo.toml", &basic_manifest("foo", "1.0.0")) .file("examples/foo.rs", "fn main() {}") @@ -99,7 +99,7 @@ Colliding filename is: [..]/foo/out/foo[EXE] The exported filenames should be unique. Consider changing their names to be unique or compiling them separately. -This may become a hard error in the future, see https://github.com/rust-lang/cargo/issues/6313 +This may become a hard error in the future; see . ") .run(); } diff -Nru cargo-0.33.0/tests/testsuite/concurrent.rs cargo-0.35.0/tests/testsuite/concurrent.rs --- cargo-0.33.0/tests/testsuite/concurrent.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/concurrent.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,15 +4,14 @@ use std::process::Stdio; use std::sync::mpsc::channel; use std::thread; -use std::time::Duration; use std::{env, str}; +use crate::support::cargo_process; +use crate::support::git; +use crate::support::install::{assert_has_installed_exe, cargo_home}; +use crate::support::registry::Package; +use crate::support::{basic_manifest, execs, project, slow_cpu_multiplier}; use git2; -use support::cargo_process; -use support::git; -use support::install::{cargo_home, assert_has_installed_exe}; -use support::registry::Package; -use support::{basic_manifest, execs, project}; fn pkg(name: &str, vers: &str) { Package::new(name, vers) @@ -109,7 +108,8 @@ .with_status(101) .with_stderr_contains( "[ERROR] binary `foo[..]` already exists in destination as part of `[..]`", - ).run_output(&bad); + ) + .run_output(&bad); execs() .with_stderr_contains("warning: be sure to add `[..]` to your PATH [..]") .run_output(&good); @@ -140,7 +140,8 @@ [dependencies] bar = "*" "#, - ).file("a/src/main.rs", "fn main() {}") + ) + .file("a/src/main.rs", "fn main() {}") .file( "b/Cargo.toml", r#" @@ -152,7 +153,8 @@ [dependencies] bar = "*" "#, - ).file("b/src/main.rs", "fn main() {}"); + ) + .file("b/src/main.rs", "fn main() {}"); let p = p.build(); let mut a = p.cargo("build").cwd(p.root().join("a")).build_command(); @@ -171,18 +173,16 @@ execs().run_output(&b); let suffix = env::consts::EXE_SUFFIX; - assert!( - p.root() - .join("a/target/debug") - .join(format!("foo{}", suffix)) - .is_file() - ); - assert!( - p.root() - .join("b/target/debug") - .join(format!("bar{}", suffix)) - .is_file() - ); + assert!(p + .root() + .join("a/target/debug") + .join(format!("foo{}", suffix)) + .is_file()); + assert!(p + .root() + .join("b/target/debug") + .join(format!("bar{}", suffix)) + .is_file()); } #[test] @@ -191,7 +191,8 @@ project .file("Cargo.toml", &basic_manifest("dep", "0.5.0")) .file("src/lib.rs", "pub fn tag1() {}") - }).unwrap(); + }) + .unwrap(); let repo = git2::Repository::open(&a.root()).unwrap(); git::tag(&repo, "tag1"); @@ -220,10 +221,12 @@ "#, a.url() ), - ).file( + ) + .file( "a/src/main.rs", "extern crate dep; fn main() { dep::tag1(); }", - ).file( + ) + .file( "b/Cargo.toml", &format!( r#" @@ -237,7 +240,8 @@ "#, a.url() ), - ).file( + ) + .file( "b/src/main.rs", "extern crate dep; fn main() { dep::tag2(); }", ); @@ -265,7 +269,8 @@ project .file("Cargo.toml", &basic_manifest("dep", "0.5.0")) .file("src/lib.rs", "pub fn f1() {}") - }).unwrap(); + }) + .unwrap(); let p = project() .no_manifest() @@ -283,10 +288,12 @@ "#, a.url() ), - ).file( + ) + .file( "a/src/main.rs", "extern crate dep; fn main() { dep::f1(); }", - ).file( + ) + .file( "b/Cargo.toml", &format!( r#" @@ -300,7 +307,8 @@ "#, a.url() ), - ).file( + ) + .file( "b/src/main.rs", "extern crate dep; fn main() { dep::f2(); }", ); @@ -377,7 +385,8 @@ version = "0.0.0" build = "build.rs" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "build.rs", r#" @@ -449,14 +458,16 @@ [COMPILING] foo v0.0.1 [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run_output(&a); + ) + .run_output(&a); execs() .with_stderr( "\ [COMPILING] foo v0.0.1 [..] [FINISHED] release [optimized] target(s) in [..] ", - ).run_output(&b); + ) + .run_output(&b); } #[test] @@ -465,13 +476,15 @@ project .file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let dep2 = git::new("dep2", |project| { project .file("Cargo.toml", &basic_manifest("dep2", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -490,7 +503,8 @@ dep1.url(), dep2.url() ), - ).file("src/main.rs", "fn main() { }"); + ) + .file("src/main.rs", "fn main() { }"); let p = p.build(); let n_concurrent_builds = 5; @@ -511,7 +525,7 @@ } for _ in 0..n_concurrent_builds { - let result = rx.recv_timeout(Duration::from_secs(30)).expect("Deadlock!"); + let result = rx.recv_timeout(slow_cpu_multiplier(30)).expect("Deadlock!"); execs().run_output(&result); } } diff -Nru cargo-0.33.0/tests/testsuite/config.rs cargo-0.35.0/tests/testsuite/config.rs --- cargo-0.33.0/tests/testsuite/config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,12 @@ -use cargo::core::{enable_nightly_features, Shell}; -use cargo::util::config::{self, Config}; -use cargo::util::toml::{self, VecStringOrBool as VSOB}; -use cargo::CargoError; use std::borrow::Borrow; use std::collections; use std::fs; -use support::{lines_match, paths, project}; + +use crate::support::{lines_match, paths, project}; +use cargo::core::{enable_nightly_features, Shell}; +use cargo::util::config::{self, Config}; +use cargo::util::toml::{self, VecStringOrBool as VSOB}; +use serde::Deserialize; #[test] fn read_env_vars_for_config() { @@ -19,7 +20,8 @@ version = "0.0.0" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -28,7 +30,8 @@ assert_eq!(env::var("NUM_JOBS").unwrap(), "100"); } "#, - ).build(); + ) + .build(); p.cargo("build").env("CARGO_BUILD_JOBS", "100").run(); } @@ -60,11 +63,12 @@ false, &None, &["advanced-env".into()], - ).unwrap(); + ) + .unwrap(); config } -fn assert_error>(error: E, msgs: &str) { +fn assert_error>(error: E, msgs: &str) { let causes = error .borrow() .iter_chain() @@ -169,7 +173,7 @@ ("CARGO_PROFILE_DEV_OVERRIDES_bar_OPT_LEVEL", "2"), ]); - // TODO: don't use actual tomlprofile + // TODO: don't use actual `tomlprofile`. let p: toml::TomlProfile = config.get("profile.dev").unwrap(); let mut overrides = collections::BTreeMap::new(); let key = toml::ProfilePackageSpec::Spec(::cargo::core::PackageIdSpec::parse("bar").unwrap()); diff -Nru cargo-0.33.0/tests/testsuite/corrupt_git.rs cargo-0.35.0/tests/testsuite/corrupt_git.rs --- cargo-0.33.0/tests/testsuite/corrupt_git.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/corrupt_git.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ use std::fs; use std::path::{Path, PathBuf}; +use crate::support::paths; +use crate::support::{basic_manifest, git, project}; use cargo::util::paths as cargopaths; -use support::paths; -use support::{basic_manifest, git, project}; #[test] fn deleting_database_files() { @@ -12,7 +12,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let project = project .file( @@ -29,7 +30,8 @@ "#, git_project.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); project.cargo("build").run(); @@ -69,7 +71,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let project = project .file( @@ -86,7 +89,8 @@ "#, git_project.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); project.cargo("build").run(); diff -Nru cargo-0.33.0/tests/testsuite/cross_compile.rs cargo-0.35.0/tests/testsuite/cross_compile.rs --- cargo-0.33.0/tests/testsuite/cross_compile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cross_compile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::{basic_bin_manifest, basic_manifest, cross_compile, project}; -use support::{is_nightly, rustc_host}; +use crate::support::{basic_bin_manifest, basic_manifest, cross_compile, project}; +use crate::support::{is_nightly, rustc_host}; #[test] fn simple_cross() { @@ -17,7 +17,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", &format!( r#" @@ -27,7 +28,8 @@ "#, cross_compile::alternate() ), - ).file( + ) + .file( "src/main.rs", &format!( r#" @@ -38,7 +40,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("build -v --target").arg(&target).run(); @@ -63,7 +66,8 @@ "#, cross_compile::alternate() ), - ).file( + ) + .file( "Cargo.toml", r#" [package] @@ -72,7 +76,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", &format!( r#" @@ -82,7 +87,8 @@ "#, cross_compile::alternate() ), - ).file( + ) + .file( "src/main.rs", &format!( r#" @@ -93,7 +99,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("build -v").run(); @@ -120,7 +127,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }") .build(); let _p2 = project() .at("bar") @@ -159,7 +167,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "src/main.rs", r#" #![feature(plugin)] @@ -169,7 +178,8 @@ assert_eq!(bar!(), baz::baz()); } "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file( @@ -184,7 +194,8 @@ name = "bar" plugin = true "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -209,7 +220,8 @@ MacEager::expr(cx.expr_lit(sp, LitKind::Int(1, LitIntType::Unsuffixed))) } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") .file("Cargo.toml", &basic_manifest("baz", "0.0.1")) @@ -247,7 +259,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "src/main.rs", r#" #![feature(plugin)] @@ -257,7 +270,8 @@ assert_eq!(bar!(), baz::baz()); } "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file( @@ -275,7 +289,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -304,7 +319,8 @@ MacEager::expr(cx.expr_call(sp, cx.expr_path(path), vec![])) } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") .file("Cargo.toml", &basic_manifest("baz", "0.0.1")) @@ -338,7 +354,8 @@ "#, target ), - ).file("Cargo.toml", &basic_bin_manifest("foo")) + ) + .file("Cargo.toml", &basic_bin_manifest("foo")) .file( "src/foo.rs", &format!( @@ -350,7 +367,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); p.cargo("build -v --target") .arg(&target) @@ -368,7 +386,8 @@ -L dependency=[CWD]/target/debug/deps` ", target = target, - )).run(); + )) + .run(); } #[test] @@ -392,7 +411,8 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", r#" #![feature(plugin)] @@ -400,7 +420,8 @@ fn main() {} "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file( @@ -418,7 +439,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -433,7 +455,8 @@ println!("{}", baz::baz()); } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") .file( @@ -448,7 +471,8 @@ name = "baz" crate_type = ["dylib"] "#, - ).file("src/lib.rs", "pub fn baz() -> i32 { 1 }") + ) + .file("src/lib.rs", "pub fn baz() -> i32 { 1 }") .build(); let target = cross_compile::alternate(); @@ -473,7 +497,8 @@ [[bin]] name = "bar" "#, - ).file( + ) + .file( "src/bin/bar.rs", &format!( r#" @@ -487,7 +512,8 @@ "#, cross_compile::alternate_arch() ), - ).file( + ) + .file( "src/lib.rs", &format!( r#" @@ -497,7 +523,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("test --target") @@ -509,7 +536,8 @@ [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] [RUNNING] target/{triple}/debug/deps/bar-[..][EXE]", triple = target - )).with_stdout_contains("test test_foo ... ok") + )) + .with_stdout_contains("test test_foo ... ok") .with_stdout_contains("test test ... ok") .run(); } @@ -529,10 +557,10 @@ //! assert!(true); //! ``` "#, - ).build(); + ) + .build(); - let host_output = - "\ + let host_output = "\ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] @@ -554,7 +582,8 @@ [DOCTEST] foo ", triple = target - )).run(); + )) + .run(); println!("c"); let target = cross_compile::alternate(); @@ -567,7 +596,8 @@ [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] ", triple = target - )).run(); + )) + .run(); } #[test] @@ -588,7 +618,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("run --target").arg(&target).run(); @@ -611,7 +642,8 @@ authors = [] build = 'build.rs' "#, - ).file( + ) + .file( "build.rs", &format!( r#" @@ -636,7 +668,8 @@ "#, target ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v --target") @@ -650,7 +683,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", target = target, - )).run(); + )) + .run(); } #[test] @@ -676,21 +710,24 @@ [build-dependencies.d2] path = "d2" "#, - ).file( + ) + .file( "build.rs", r#" #[allow(unused_extern_crates)] extern crate d2; fn main() { d2::d2(); } "#, - ).file( + ) + .file( "src/main.rs", " #[allow(unused_extern_crates)] extern crate d1; fn main() { d1::d1(); } ", - ).file( + ) + .file( "d1/Cargo.toml", r#" [package] @@ -699,7 +736,8 @@ authors = [] build = 'build.rs' "#, - ).file("d1/src/lib.rs", "pub fn d1() {}") + ) + .file("d1/src/lib.rs", "pub fn d1() {}") .file( "d1/build.rs", r#" @@ -709,7 +747,8 @@ println!("cargo:rustc-flags=-L /path/to/{}", target); } "#, - ).file( + ) + .file( "d2/Cargo.toml", r#" [package] @@ -720,14 +759,16 @@ [dependencies.d1] path = "../d1" "#, - ).file( + ) + .file( "d2/src/lib.rs", " #[allow(unused_extern_crates)] extern crate d1; pub fn d2() { d1::d1(); } ", - ).build(); + ) + .build(); p.cargo("build -v --target") .arg(&target) @@ -741,17 +782,20 @@ .with_stderr_contains(&format!( "[RUNNING] `rustc [..] d2/src/lib.rs [..] -L /path/to/{host}`", host = host - )).with_stderr_contains("[COMPILING] foo v0.0.0 ([CWD])") + )) + .with_stderr_contains("[COMPILING] foo v0.0.0 ([CWD])") .with_stderr_contains(&format!( "[RUNNING] `rustc [..] build.rs [..] --out-dir [CWD]/target/debug/build/foo-[..] \ -L /path/to/{host}`", host = host - )).with_stderr_contains(&format!( + )) + .with_stderr_contains(&format!( "\ [RUNNING] `rustc [..] src/main.rs [..] --target {target} [..] \ -L /path/to/{target}`", target = target - )).run(); + )) + .run(); } #[test] @@ -772,7 +816,8 @@ [dependencies.d2] path = "d2" "#, - ).file("src/main.rs", "extern crate d2; fn main() {}") + ) + .file("src/main.rs", "extern crate d2; fn main() {}") .file("d1/Cargo.toml", &basic_manifest("d1", "0.0.0")) .file("d1/src/lib.rs", "pub fn d1() {}") .file( @@ -787,7 +832,8 @@ [build-dependencies.d1] path = "../d1" "#, - ).file("d2/build.rs", "extern crate d1; fn main() {}") + ) + .file("d2/build.rs", "extern crate d1; fn main() {}") .file("d2/src/lib.rs", "") .build(); @@ -814,7 +860,8 @@ [build-dependencies.d1] path = "d1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("build.rs", "extern crate d1; fn main() {}") .file( "d1/Cargo.toml", @@ -825,7 +872,8 @@ authors = [] build = "build.rs" "#, - ).file("d1/src/lib.rs", "pub fn d1() {}") + ) + .file("d1/src/lib.rs", "pub fn d1() {}") .file( "d1/build.rs", r#" @@ -837,7 +885,8 @@ "bad: {:?}", env::var("OUT_DIR")); } "#, - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("build -v --target").arg(&target).run(); @@ -862,7 +911,8 @@ name = "foo" plugin = true "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "") .build(); @@ -876,7 +926,8 @@ [RUNNING] `rustc [..] src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -900,14 +951,16 @@ [build-dependencies.d1] path = "d1" "#, - ).file( + ) + .file( "build.rs", " #[allow(unused_extern_crates)] extern crate d1; fn main() {} ", - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "d1/Cargo.toml", &format!( @@ -922,10 +975,12 @@ "#, host ), - ).file( + ) + .file( "d1/src/lib.rs", "#[allow(unused_extern_crates)] extern crate d2;", - ).file("d2/Cargo.toml", &basic_manifest("d2", "0.0.0")) + ) + .file("d2/Cargo.toml", &basic_manifest("d2", "0.0.0")) .file("d2/src/lib.rs", "") .build(); @@ -944,7 +999,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", target = target - )).run(); + )) + .run(); } #[test] @@ -971,7 +1027,8 @@ [build-dependencies.d1] path = "d1" "#, - ).file("build.rs", "extern crate d1; fn main() {}") + ) + .file("build.rs", "extern crate d1; fn main() {}") .file("src/lib.rs", "") .file( "d1/Cargo.toml", @@ -987,7 +1044,8 @@ "#, host ), - ).file("d1/src/lib.rs", "extern crate d2;") + ) + .file("d1/src/lib.rs", "extern crate d2;") .file("d1/Cargo.toml", &basic_manifest("d1", "0.0.0")) .file("d2/src/lib.rs", "") .build(); @@ -1027,7 +1085,8 @@ host = host, target = target ), - ).file( + ) + .file( "build.rs", &format!( r#" @@ -1050,7 +1109,8 @@ host = host, target = target ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "d1/Cargo.toml", r#" @@ -1061,7 +1121,8 @@ links = "d1" build = "build.rs" "#, - ).file("d1/build.rs", r#"fn main() { println!("cargo:val=1") }"#) + ) + .file("d1/build.rs", r#"fn main() { println!("cargo:val=1") }"#) .file("d1/src/lib.rs", "") .file( "d2/Cargo.toml", @@ -1073,7 +1134,8 @@ links = "d2" build = "build.rs" "#, - ).file("d2/build.rs", r#"fn main() { println!("cargo:val=1") }"#) + ) + .file("d2/build.rs", r#"fn main() { println!("cargo:val=1") }"#) .file("d2/src/lib.rs", "") .build(); @@ -1105,7 +1167,8 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar as the_bar; @@ -1115,7 +1178,8 @@ #[test] fn foo() { bar(); } "#, - ).file( + ) + .file( "tests/test.rs", r#" extern crate foo as the_foo; @@ -1123,7 +1187,8 @@ #[test] fn foo() { the_foo::bar(); } "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -1135,7 +1200,8 @@ name = "bar" crate_type = ["dylib"] "#, - ).file( + ) + .file( "bar/src/lib.rs", &format!( r#" @@ -1146,7 +1212,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); p.cargo("test --target") .arg(&target) @@ -1158,6 +1225,7 @@ [RUNNING] target/{arch}/debug/deps/foo-[..][EXE] [RUNNING] target/{arch}/debug/deps/test-[..][EXE]", arch = cross_compile::alternate() - )).with_stdout_contains_n("test foo ... ok", 2) + )) + .with_stdout_contains_n("test foo ... ok", 2) .run(); } diff -Nru cargo-0.33.0/tests/testsuite/cross_publish.rs cargo-0.35.0/tests/testsuite/cross_publish.rs --- cargo-0.33.0/tests/testsuite/cross_publish.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/cross_publish.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,6 @@ use std::fs::File; -use std::io::prelude::*; -use std::path::PathBuf; -use flate2::read::GzDecoder; -use support::{cross_compile, project, publish}; -use tar::Archive; +use crate::support::{cross_compile, project, publish, registry}; #[test] fn simple_cross_package() { @@ -24,7 +20,8 @@ description = "foo" repository = "bar" "#, - ).file( + ) + .file( "src/main.rs", &format!( r#" @@ -35,7 +32,8 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); @@ -47,21 +45,17 @@ Compiling foo v0.0.0 ([CWD]/target/package/foo-0.0.0) Finished dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // Check that the tarball contains the files let f = File::open(&p.root().join("target/package/foo-0.0.0.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - let entries = ar.entries().unwrap(); - let entry_paths = entries - .map(|entry| entry.unwrap().path().unwrap().into_owned()) - .collect::>(); - assert!(entry_paths.contains(&PathBuf::from("foo-0.0.0/Cargo.toml"))); - assert!(entry_paths.contains(&PathBuf::from("foo-0.0.0/Cargo.toml.orig"))); - assert!(entry_paths.contains(&PathBuf::from("foo-0.0.0/src/main.rs"))); + publish::validate_crate_contents( + f, + "foo-0.0.0.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[], + ); } #[test] @@ -70,7 +64,7 @@ return; } - publish::setup(); + registry::init(); let p = project() .file( @@ -84,7 +78,8 @@ description = "foo" repository = "bar" "#, - ).file( + ) + .file( "src/main.rs", &format!( r#" @@ -95,12 +90,13 @@ "#, cross_compile::alternate_arch() ), - ).build(); + ) + .build(); let target = cross_compile::alternate(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry::registry_url().to_string()) .arg("--target") .arg(&target) .with_stderr(&format!( @@ -111,6 +107,7 @@ Finished dev [unoptimized + debuginfo] target(s) in [..] Uploading foo v0.0.0 ([CWD]) ", - registry = publish::registry_path().to_str().unwrap() - )).run(); + registry = registry::registry_path().to_str().unwrap() + )) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/custom_target.rs cargo-0.35.0/tests/testsuite/custom_target.rs --- cargo-0.33.0/tests/testsuite/custom_target.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/custom_target.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::is_nightly; -use support::{basic_manifest, project}; +use crate::support::is_nightly; +use crate::support::{basic_manifest, project}; #[test] fn custom_target_minimal() { @@ -27,7 +27,8 @@ // Empty. } "#, - ).file( + ) + .file( "custom-target.json", r#" { @@ -41,7 +42,8 @@ "linker-flavor": "ld.lld" } "#, - ).build(); + ) + .build(); p.cargo("build --lib --target custom-target.json -v").run(); p.cargo("build --lib --target src/../custom-target.json -v") @@ -66,7 +68,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(no_core)] @@ -83,7 +86,8 @@ #[lang = "freeze"] unsafe auto trait Freeze {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file( "bar/src/lib.rs", r#" @@ -104,7 +108,8 @@ // Empty. } "#, - ).file( + ) + .file( "custom-target.json", r#" { @@ -118,7 +123,8 @@ "linker-flavor": "ld.lld" } "#, - ).build(); + ) + .build(); p.cargo("build --lib --target custom-target.json -v").run(); } diff -Nru cargo-0.33.0/tests/testsuite/death.rs cargo-0.35.0/tests/testsuite/death.rs --- cargo-0.33.0/tests/testsuite/death.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/death.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,9 +3,8 @@ use std::net::TcpListener; use std::process::{Child, Stdio}; use std::thread; -use std::time::Duration; -use support::project; +use crate::{support::project, support::slow_cpu_multiplier}; #[cfg(unix)] fn enabled() -> bool { @@ -66,7 +65,8 @@ authors = [] build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", &format!( @@ -82,7 +82,8 @@ "#, addr ), - ).build(); + ) + .build(); let mut cargo = p.cargo("build").build_command(); cargo @@ -119,7 +120,7 @@ Ok(()) => return, Err(e) => println!("attempt {}: {}", i, e), } - thread::sleep(Duration::from_millis(100)); + thread::sleep(slow_cpu_multiplier(100)); } panic!( @@ -130,8 +131,6 @@ #[cfg(unix)] fn ctrl_c(child: &mut Child) { - use libc; - let r = unsafe { libc::kill(-(child.id() as i32), libc::SIGINT) }; if r < 0 { panic!("failed to kill: {}", io::Error::last_os_error()); diff -Nru cargo-0.33.0/tests/testsuite/dep_info.rs cargo-0.35.0/tests/testsuite/dep_info.rs --- cargo-0.33.0/tests/testsuite/dep_info.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/dep_info.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ +use crate::support::{basic_bin_manifest, main_file, project}; use filetime::FileTime; -use support::{basic_bin_manifest, main_file, project}; #[test] fn build_dep_info() { @@ -30,7 +30,8 @@ name = "ex" crate-type = ["lib"] "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); @@ -54,7 +55,8 @@ name = "ex" crate-type = ["rlib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); @@ -77,7 +79,8 @@ name = "ex" crate-type = ["dylib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/ex.rs", "") .build(); diff -Nru cargo-0.33.0/tests/testsuite/directory.rs cargo-0.35.0/tests/testsuite/directory.rs --- cargo-0.33.0/tests/testsuite/directory.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/directory.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,14 +1,15 @@ -use serde_json; use std::collections::HashMap; use std::fs::{self, File}; use std::io::prelude::*; use std::str; -use support::cargo_process; -use support::git; -use support::paths; -use support::registry::{cksum, Package}; -use support::{basic_manifest, project, ProjectBuilder}; +use serde::Serialize; + +use crate::support::cargo_process; +use crate::support::git; +use crate::support::paths; +use crate::support::registry::{cksum, Package}; +use crate::support::{basic_manifest, project, ProjectBuilder}; fn setup() { let root = paths::root(); @@ -93,10 +94,12 @@ [dependencies] bar = "0.1.0" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -105,7 +108,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -128,10 +132,12 @@ [dependencies] foo = "0.0.1" "#, - ).file( + ) + .file( "src/main.rs", "extern crate foo; pub fn main() { foo::foo(); }", - ).build(); + ) + .build(); cargo_process("install bar") .with_stderr( @@ -142,7 +148,8 @@ Installing [..]bar[..] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); } #[test] @@ -166,10 +173,12 @@ foo = "0.1.0" baz = "9.8.7" "#, - ).file( + ) + .file( "src/main.rs", "extern crate foo; pub fn main() { foo::foo(); }", - ).build(); + ) + .build(); cargo_process("install bar") .with_status(101) @@ -180,10 +189,11 @@ Caused by: no matching package named `baz` found location searched: registry `https://github.com/rust-lang/crates.io-index` -did you mean: bar, foo +perhaps you meant: bar or foo required by package `bar v0.1.0` ", - ).run(); + ) + .run(); } #[test] @@ -210,10 +220,12 @@ [features] wantbaz = ["baz"] "#, - ).file( + ) + .file( "src/main.rs", "extern crate foo; pub fn main() { foo::foo(); }", - ).build(); + ) + .build(); cargo_process("install bar") .with_stderr( @@ -224,7 +236,8 @@ Installing [..]bar[..] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); } #[test] @@ -245,10 +258,12 @@ [dependencies] bar = "0.1.0" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -258,7 +273,8 @@ location searched: [..] required by package `foo v0.1.0 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -289,10 +305,12 @@ [dependencies] bar = "0.1.0" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -301,7 +319,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -318,10 +337,12 @@ [dependencies] bar = "0.1.0" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); let cksum = Package::new("bar", "0.1.0") .file("src/lib.rs", "pub fn bar() -> u32 { 0 }") @@ -337,7 +358,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); setup(); @@ -354,7 +376,8 @@ [COMPILING] foo v0.1.0 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -371,7 +394,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); Package::new("bar", "0.1.0").publish(); @@ -393,13 +417,14 @@ this could be indicative of a few possible errors: * the lock file is corrupt - * a replacement source in use (e.g. a mirror) returned a different checksum + * a replacement source in use (e.g., a mirror) returned a different checksum * the source itself may be corrupt in one way or another unable to verify that `bar v0.1.0` is the same as when the lockfile was generated ", - ).run(); + ) + .run(); } #[test] @@ -426,7 +451,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -441,7 +467,8 @@ required then it is recommended that [replace] is used with a forked copy of \ the source ", - ).run(); + ) + .run(); } #[test] @@ -469,7 +496,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -501,7 +529,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -512,7 +541,8 @@ let git = git::new("git", |p| { p.file("Cargo.toml", &basic_manifest("git", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); VendorPackage::new("git") .file("Cargo.toml", &basic_manifest("git", "0.5.0")) @@ -535,7 +565,8 @@ "#, git.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -556,7 +587,8 @@ directory = 'index' "#, git.url() - ).as_bytes() + ) + .as_bytes() )); p.cargo("build") @@ -566,7 +598,8 @@ [COMPILING] [..] [FINISHED] [..] ", - ).run(); + ) + .run(); let mut lock2 = String::new(); t!(t!(File::open(p.root().join("Cargo.lock"))).read_to_string(&mut lock2)); @@ -593,7 +626,8 @@ [dependencies] git = { git = 'https://example.com/' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let root = paths::root(); @@ -626,7 +660,8 @@ restore the source replacement configuration to continue the build ", - ).run(); + ) + .run(); } #[test] @@ -643,7 +678,8 @@ [dependencies] baz = "*" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .file("foo/vendor/baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("foo/vendor/baz/src/lib.rs", "") .file("foo/vendor/baz/.cargo-checksum.json", "{\"files\":{}}") @@ -657,7 +693,8 @@ [dependencies] baz = "*" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file( ".cargo/config", r#" @@ -670,18 +707,19 @@ [source.my-awesome-local-registry] directory = 'foo/vendor' "#, - ).build(); + ) + .build(); p.cargo("build").cwd(p.root().join("foo")).run(); p.cargo("build") .cwd(p.root().join("bar")) - .with_status(0) .with_stderr( "\ [COMPILING] bar [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] diff -Nru cargo-0.33.0/tests/testsuite/doc.rs cargo-0.35.0/tests/testsuite/doc.rs --- cargo-0.33.0/tests/testsuite/doc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/doc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,13 +1,13 @@ use std::fs::{self, File}; use std::io::Read; use std::str; -use support; use glob::glob; -use support::paths::CargoPathExt; -use support::registry::Package; -use support::{basic_lib_manifest, basic_manifest, git, project}; -use support::{is_nightly, rustc_host}; + +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::{basic_lib_manifest, basic_manifest, git, project}; +use crate::support::{is_nightly, rustc_host}; #[test] fn simple() { @@ -21,7 +21,8 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "pub fn foo() {}") .build(); @@ -32,7 +33,8 @@ [..] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); assert!(p.root().join("target/doc/foo/index.html").is_file()); } @@ -52,7 +54,8 @@ name = "foo" doc = false "#, - ).file("src/main.rs", "bad code") + ) + .file("src/main.rs", "bad code") .build(); p.cargo("doc").run(); @@ -68,7 +71,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("doc").with_stdout("").run(); } @@ -87,7 +91,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "extern crate bar; pub fn foo() {}") + ) + .file("src/lib.rs", "extern crate bar; pub fn foo() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -100,7 +105,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); assert!(p.root().join("target/doc/foo/index.html").is_file()); @@ -119,7 +125,8 @@ .join("target/debug/deps/libbar-*.rmeta") .to_str() .unwrap() - ).unwrap() + ) + .unwrap() .count(), 1 ); @@ -148,7 +155,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "extern crate bar; pub fn foo() {}") + ) + .file("src/lib.rs", "extern crate bar; pub fn foo() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -160,7 +168,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); assert!(p.root().join("target/doc/foo/index.html").is_file()); @@ -181,7 +190,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "extern crate bar; pub fn foo() {}") + ) + .file("src/main.rs", "extern crate bar; pub fn foo() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -202,7 +212,8 @@ [workspace] members = ["foo", "bar"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -211,7 +222,8 @@ [lib] name = "foo_lib" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -221,7 +233,8 @@ [lib] name = "foo_lib" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("doc --all") @@ -241,7 +254,8 @@ [workspace] members = ["foo", "bar"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -251,7 +265,8 @@ name = "foo_lib" path = "src/foo_lib.rs" "#, - ).file("foo/src/foo_lib.rs", "") + ) + .file("foo/src/foo_lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -261,7 +276,8 @@ [lib] name = "foo_lib" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("doc --all") @@ -283,7 +299,8 @@ [workspace] members = ["foo", "bar"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -292,7 +309,8 @@ [[bin]] name = "foo-cli" "#, - ).file("foo/src/foo-cli.rs", "") + ) + .file("foo/src/foo-cli.rs", "") .file( "bar/Cargo.toml", r#" @@ -302,7 +320,8 @@ [[bin]] name = "foo-cli" "#, - ).file("bar/src/foo-cli.rs", "") + ) + .file("bar/src/foo-cli.rs", "") .build(); p.cargo("doc --all") @@ -322,7 +341,8 @@ [workspace] members = ["foo", "bar"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -331,7 +351,8 @@ [[bin]] name = "foo-cli" "#, - ).file("foo/src/foo-cli.rs", "") + ) + .file("foo/src/foo-cli.rs", "") .file( "bar/Cargo.toml", r#" @@ -342,7 +363,8 @@ name = "foo-cli" doc = false "#, - ).file("bar/src/foo-cli.rs", "") + ) + .file("bar/src/foo-cli.rs", "") .build(); p.cargo("doc --all").run(); @@ -360,13 +382,15 @@ foo::foo(); } "#, - ).file( + ) + .file( "src/lib.rs", r#" //! Library documentation pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("doc") .with_stderr( @@ -374,7 +398,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); let doc_file = p.root().join("target/doc/foo/index.html"); assert!(doc_file.is_file()); @@ -399,13 +424,15 @@ foo::foo(); } "#, - ).file( + ) + .file( "src/lib.rs", r#" //! Library documentation pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("doc --lib") .with_stderr( @@ -413,7 +440,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); let doc_file = p.root().join("target/doc/foo/index.html"); assert!(doc_file.is_file()); @@ -438,13 +466,15 @@ foo::foo(); } "#, - ).file( + ) + .file( "src/lib.rs", r#" //! Library documentation pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("doc --bin foo") .with_stderr( @@ -453,7 +483,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); let doc_file = p.root().join("target/doc/foo/index.html"); assert!(doc_file.is_file()); @@ -478,13 +509,15 @@ foo::foo(); } "#, - ).file( + ) + .file( "src/lib.rs", r#" //! Library documentation pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("doc --bins") .with_stderr( @@ -493,7 +526,8 @@ [DOCUMENTING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/doc").is_dir()); let doc_file = p.root().join("target/doc/foo/index.html"); assert!(doc_file.is_file()); @@ -520,7 +554,8 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "extern crate a;") + ) + .file("src/lib.rs", "extern crate a;") .file( "a/Cargo.toml", r#" @@ -532,7 +567,8 @@ [dependencies.b] path = "../b" "#, - ).file("a/src/lib.rs", "extern crate b;") + ) + .file("a/src/lib.rs", "extern crate b;") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -545,7 +581,8 @@ [DOCUMENTING] a v0.0.1 ([CWD]/a) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -578,15 +615,15 @@ pub static A: u32; } "#, - ).build(); + ) + .build(); p.cargo("doc --verbose --target").arg(TARGET).run(); assert!(p.root().join(&format!("target/{}/doc", TARGET)).is_dir()); - assert!( - p.root() - .join(&format!("target/{}/doc/foo/index.html", TARGET)) - .is_file() - ); + assert!(p + .root() + .join(&format!("target/{}/doc/foo/index.html", TARGET)) + .is_file()); } #[test] @@ -603,7 +640,8 @@ [target.foo.dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "not rust") .build(); @@ -625,7 +663,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file( "a/src/lib.rs", @@ -635,12 +674,13 @@ /// ``` pub fn foo() {} ", - ).build(); + ) + .build(); p.cargo("doc") .without_status() - .with_stderr_contains("1 | ☃") - .with_stderr_contains(r"error: unknown start of token: \u{2603}") + .with_stderr_contains("[..]☃") + .with_stderr_contains(r"[..]unknown start of token: \u{2603}") .run(); } @@ -663,7 +703,8 @@ "#, rustc_host() ), - ).file( + ) + .file( "src/lib.rs", " extern crate a; @@ -671,14 +712,16 @@ /// test pub fn foo() {} ", - ).file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file( "a/src/lib.rs", " /// test pub fn foo() {} ", - ).build(); + ) + .build(); p.cargo("doc").run(); } @@ -697,7 +740,8 @@ [build-dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file( "a/src/lib.rs", @@ -707,7 +751,8 @@ /// ``` pub fn foo() {} ", - ).build(); + ) + .build(); p.cargo("doc").run(); } @@ -724,7 +769,8 @@ [RUNNING] `rustdoc [..] src/lib.rs [..]` [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -744,7 +790,8 @@ [dependencies.baz] path = "baz" "#, - ).file("src/lib.rs", "extern crate bar; pub fn foo() {}") + ) + .file("src/lib.rs", "extern crate bar; pub fn foo() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) @@ -775,7 +822,8 @@ [features] foo = ["bar/bar"] "#, - ).file("src/lib.rs", r#"#[cfg(feature = "foo")] pub fn foo() {}"#) + ) + .file("src/lib.rs", r#"#[cfg(feature = "foo")] pub fn foo() {}"#) .file( "bar/Cargo.toml", r#" @@ -787,17 +835,20 @@ [features] bar = [] "#, - ).file( + ) + .file( "bar/build.rs", r#" fn main() { println!("cargo:rustc-cfg=bar"); } "#, - ).file( + ) + .file( "bar/src/lib.rs", r#"#[cfg(feature = "bar")] pub fn bar() {}"#, - ).build(); + ) + .build(); p.cargo("doc --features foo").run(); assert!(p.root().join("target/doc").is_dir()); assert!(p.root().join("target/doc/foo/fn.foo.html").is_file()); @@ -813,7 +864,8 @@ /// dox pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("doc").run(); assert!(p.root().join("target/doc/foo/index.html").is_file()); @@ -833,7 +885,8 @@ /// dox pub fn foo() {} "#, - ).file( + ) + .file( "src/bin/bar.rs", r#" /// ``` @@ -842,14 +895,15 @@ pub fn foo() {} fn main() { foo(); } "#, - ).build(); + ) + .build(); p.cargo("doc --lib").run(); assert!(p.root().join("target/doc/foo/index.html").is_file()); } #[test] fn plugins_no_use_target() { - if !support::is_nightly() { + if !is_nightly() { return; } let p = project() @@ -864,7 +918,8 @@ [lib] proc-macro = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("doc --target=x86_64-unknown-openbsd -v").run(); } @@ -884,7 +939,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -906,7 +962,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -928,7 +985,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -943,10 +1001,6 @@ #[test] fn doc_all_member_dependency_same_name() { - if !is_nightly() { - // This can be removed once 1.29 is stable (rustdoc --cap-lints). - return; - } let p = project() .file( "Cargo.toml", @@ -954,7 +1008,8 @@ [workspace] members = ["bar"] "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [project] @@ -964,7 +1019,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("bar/src/lib.rs", "pub fn bar() {}") + ) + .file("bar/src/lib.rs", "pub fn bar() {}") .build(); Package::new("bar", "0.1.0").publish(); @@ -984,7 +1040,8 @@ [workspace] members = ["foo", "bar"] "#, - ).file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) + ) + .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") @@ -998,10 +1055,12 @@ .with_stderr_contains( "error: Passing multiple packages and `open` \ is not supported.", - ).with_stderr_contains( + ) + .with_stderr_contains( "Please re-run this command with `-p ` \ where `` is one of the following:", - ).with_stderr_contains(" foo") + ) + .with_stderr_contains(" foo") .with_stderr_contains(" bar") .run(); } @@ -1016,7 +1075,8 @@ [workspace] members = ["foo"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -1025,7 +1085,8 @@ [lib] name = "foolib" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("doc --open") @@ -1045,7 +1106,8 @@ [workspace] members = ["foo"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -1055,7 +1117,8 @@ name = "foobin" path = "src/main.rs" "#, - ).file("foo/src/main.rs", "") + ) + .file("foo/src/main.rs", "") .build(); p.cargo("doc --open") @@ -1075,7 +1138,8 @@ [workspace] members = ["foo"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -1087,7 +1151,8 @@ name = "foobin" path = "src/main.rs" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .file("foo/src/main.rs", "") .build(); @@ -1100,8 +1165,8 @@ #[test] fn doc_edition() { - if !support::is_nightly() { - // Stable rustdoc won't have the edition option. Remove this once it + if !is_nightly() { + // Stable rustdoc won't have the edition option. Remove this once it // is stabilized. return; } @@ -1116,7 +1181,8 @@ authors = [] edition = "2018" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("doc -v") @@ -1132,7 +1198,7 @@ #[test] fn doc_target_edition() { - if !support::is_nightly() { + if !is_nightly() { return; } let p = project() @@ -1148,7 +1214,8 @@ [lib] edition = "2018" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("doc -v") @@ -1166,10 +1233,6 @@ // caused `cargo doc` to fail. #[test] fn issue_5345() { - if !is_nightly() { - // This can be removed once 1.29 is stable (rustdoc --cap-lints). - return; - } let foo = project() .file( "Cargo.toml", @@ -1185,7 +1248,8 @@ [target.'cfg(not(all(windows, target_arch = "x86")))'.dependencies] bar = "0.2" "#, - ).file("src/lib.rs", "extern crate bar;") + ) + .file("src/lib.rs", "extern crate bar;") .build(); Package::new("bar", "0.1.0").publish(); Package::new("bar", "0.2.0").publish(); @@ -1202,11 +1266,10 @@ foo.cargo("doc --document-private-items").run(); assert!(foo.root().join("target/doc").is_dir()); - assert!( - foo.root() - .join("target/doc/foo/private/index.html") - .is_file() - ); + assert!(foo + .root() + .join("target/doc/foo/private/index.html") + .is_file()); } #[test] @@ -1218,7 +1281,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "fn p() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "fn p2() {}") @@ -1227,11 +1291,14 @@ p.cargo("doc --all --bins --lib --document-private-items -v") .with_stderr_contains( "[RUNNING] `rustdoc [..] a/src/lib.rs [..]--document-private-items[..]", - ).with_stderr_contains( + ) + .with_stderr_contains( "[RUNNING] `rustdoc [..] b/src/lib.rs [..]--document-private-items[..]", - ).with_stderr_contains( + ) + .with_stderr_contains( "[RUNNING] `rustdoc [..] b/src/main.rs [..]--document-private-items[..]", - ).run(); + ) + .run(); } const BAD_INTRA_LINK_LIB: &str = r#" @@ -1244,13 +1311,14 @@ #[test] fn doc_cap_lints() { if !is_nightly() { - // This can be removed once 1.29 is stable (rustdoc --cap-lints). + // This can be removed once intra_doc_link_resolution_failure fails on stable. return; } let a = git::new("a", |p| { p.file("Cargo.toml", &basic_lib_manifest("a")) .file("src/lib.rs", BAD_INTRA_LINK_LIB) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1267,7 +1335,8 @@ "#, a.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("doc") @@ -1279,7 +1348,8 @@ [DOCUMENTING] foo v0.0.1 ([..]) [FINISHED] dev [..] ", - ).run(); + ) + .run(); p.root().join("target").rm_rf(); @@ -1288,20 +1358,21 @@ "\ [WARNING] `[bad_link]` cannot be resolved, ignoring it... ", - ).run(); + ) + .run(); } #[test] fn doc_message_format() { if !is_nightly() { - // This can be removed once 1.30 is stable (rustdoc --error-format stabilized). + // This can be removed once intra_doc_link_resolution_failure fails on stable. return; } let p = project().file("src/lib.rs", BAD_INTRA_LINK_LIB).build(); p.cargo("doc --message-format=json") .with_status(101) - .with_json( + .with_json_contains_unordered( r#" { "message": { @@ -1317,22 +1388,21 @@ "target": "{...}" } "#, - ).run(); + ) + .run(); } #[test] fn short_message_format() { if !is_nightly() { - // This can be removed once 1.30 is stable (rustdoc --error-format stabilized). + // This can be removed once intra_doc_link_resolution_failure fails on stable. return; } let p = project().file("src/lib.rs", BAD_INTRA_LINK_LIB).build(); p.cargo("doc --message-format=short") .with_status(101) .with_stderr_contains( - "\ -src/lib.rs:4:6: error: `[bad_link]` cannot be resolved, ignoring it... -error: Could not document `foo`. -", - ).run(); + "src/lib.rs:4:6: error: `[bad_link]` cannot be resolved, ignoring it...", + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/edition.rs cargo-0.35.0/tests/testsuite/edition.rs --- cargo-0.33.0/tests/testsuite/edition.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/edition.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_lib_manifest, is_nightly, project}; +use crate::support::{basic_lib_manifest, is_nightly, project}; #[test] fn edition_works_for_build_script() { @@ -18,7 +18,8 @@ [build-dependencies] a = { path = 'a' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -26,12 +27,10 @@ a::foo(); } "#, - ).file("a/Cargo.toml", &basic_lib_manifest("a")) + ) + .file("a/Cargo.toml", &basic_lib_manifest("a")) .file("a/src/lib.rs", "pub fn foo() {}") .build(); - p.cargo("build -v") - .masquerade_as_nightly_cargo() - .with_status(0) - .run(); + p.cargo("build -v").masquerade_as_nightly_cargo().run(); } diff -Nru cargo-0.33.0/tests/testsuite/features.rs cargo-0.35.0/tests/testsuite/features.rs --- cargo-0.33.0/tests/testsuite/features.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/features.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ use std::fs::File; use std::io::prelude::*; -use support::paths::CargoPathExt; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; #[test] fn invalid1() { @@ -19,7 +19,8 @@ [features] bar = ["baz"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -31,7 +32,8 @@ Caused by: Feature `bar` includes `baz` which is neither a dependency nor another feature ", - ).run(); + ) + .run(); } #[test] @@ -51,7 +53,8 @@ [dependencies.bar] path = "foo" "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -63,7 +66,8 @@ Caused by: Features and dependencies cannot have the same name: `bar` ", - ).run(); + ) + .run(); } #[test] @@ -83,7 +87,8 @@ [dependencies.baz] path = "foo" "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -96,7 +101,8 @@ Feature `bar` depends on `baz` which is not an optional dependency. Consider adding `optional = true` to the dependency ", - ).run(); + ) + .run(); } #[test] @@ -114,7 +120,8 @@ path = "bar" features = ["bar"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -131,7 +138,8 @@ failed to select a version for `bar` which could resolve this conflict", - ).run(); + ) + .run(); p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1")); @@ -156,7 +164,8 @@ path = "bar" optional = true "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -168,7 +177,8 @@ Caused by: Dev-dependencies are not allowed to be optional: `bar` ", - ).run(); + ) + .run(); } #[test] @@ -185,7 +195,8 @@ [features] foo = ["bar/baz"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build --features foo") @@ -197,7 +208,8 @@ Caused by: Feature `foo` requires a feature of `bar` which is not a dependency ", - ).run(); + ) + .run(); } #[test] @@ -215,7 +227,8 @@ foo = ["bar/baz"] bar = [] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build --features foo") @@ -227,7 +240,8 @@ Caused by: Feature `foo` requires a feature of `bar` which is not a dependency ", - ).run(); + ) + .run(); } #[test] @@ -245,7 +259,8 @@ path = "bar" features = ["foo/bar"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -270,7 +285,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); @@ -299,7 +315,8 @@ path = "bar" features = ["baz"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -311,7 +328,8 @@ [dependencies.baz] path = "baz" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("bar/baz/src/lib.rs", "") .build(); @@ -343,13 +361,15 @@ [features] default = ["derived/bar/qux"] "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate derived; fn main() { derived::test(); } "#, - ).file( + ) + .file( "derived/Cargo.toml", r#" [package] @@ -360,7 +380,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") + ) + .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") .file( "bar/Cargo.toml", r#" @@ -372,13 +393,15 @@ [features] qux = [] "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #[cfg(feature = "qux")] pub fn test() { print!("test"); } "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) .with_stderr("[ERROR] feature names may not contain slashes: `bar/qux`") @@ -400,7 +423,8 @@ path = "bar" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(feature = "bar")] @@ -410,7 +434,8 @@ #[cfg(not(feature = "bar"))] fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -420,7 +445,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.process(&p.bin("foo")).with_stdout("").run(); p.cargo("build --features bar") @@ -430,7 +456,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.process(&p.bin("foo")).with_stdout("bar\n").run(); } @@ -452,7 +479,8 @@ path = "bar" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(feature = "bar")] @@ -462,7 +490,8 @@ #[cfg(not(feature = "bar"))] fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -473,7 +502,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.process(&p.bin("foo")).with_stdout("bar\n").run(); p.cargo("build --no-default-features") @@ -482,7 +512,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.process(&p.bin("foo")).with_stdout("").run(); } @@ -500,12 +531,13 @@ [features] default = ["default"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") .with_status(101) - .with_stderr("[ERROR] Cyclic feature dependency: feature `default` depends on itself") + .with_stderr("[ERROR] cyclic feature dependency: feature `default` depends on itself") .run(); } @@ -524,7 +556,8 @@ foo = ["bar"] bar = ["foo"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").with_stdout("").run(); @@ -559,7 +592,8 @@ path = "baz" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -568,7 +602,8 @@ extern crate baz; fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -582,7 +617,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -604,7 +640,8 @@ path = "baz" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -613,7 +650,8 @@ extern crate baz; fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -628,7 +666,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -649,7 +688,8 @@ path = "d2" features = ["f2"] "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -660,7 +700,8 @@ d2::f2(); } "#, - ).file( + ) + .file( "d1/Cargo.toml", r#" [package] @@ -676,7 +717,8 @@ features = ["f1"] optional = true "#, - ).file("d1/src/lib.rs", "") + ) + .file("d1/src/lib.rs", "") .file( "d2/Cargo.toml", r#" @@ -689,13 +731,15 @@ f1 = [] f2 = [] "#, - ).file( + ) + .file( "d2/src/lib.rs", r#" #[cfg(feature = "f1")] pub fn f1() {} #[cfg(feature = "f2")] pub fn f2() {} "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -705,7 +749,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -723,7 +768,8 @@ path = "a" features = ["fall"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "a/Cargo.toml", r#" @@ -737,7 +783,8 @@ ftest2 = [] fall = ["ftest", "ftest2"] "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build") @@ -747,7 +794,8 @@ [COMPILING] b v0.1.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.root().move_into_the_past(); p.cargo("build -v") @@ -757,7 +805,8 @@ [FRESH] b v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } // Tests that all cmd lines work with `--features ""` @@ -786,7 +835,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::baz(); }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::baz(); }") .file( "bar/Cargo.toml", r#" @@ -798,10 +848,12 @@ [features] baz = [] "#, - ).file( + ) + .file( "bar/src/lib.rs", r#"#[cfg(feature = "baz")] pub fn baz() {}"#, - ).build(); + ) + .build(); p.cargo("build --features foo").run(); } @@ -830,7 +882,8 @@ path = "d3" optional = true "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "d1/Cargo.toml", r#" @@ -842,7 +895,8 @@ [features] f1 = [] "#, - ).file("d1/src/lib.rs", "") + ) + .file("d1/src/lib.rs", "") .file("d2/Cargo.toml", &basic_manifest("d2", "0.0.2")) .file("d2/src/lib.rs", "") .file( @@ -856,7 +910,8 @@ [features] f3 = [] "#, - ).file("d3/src/lib.rs", "") + ) + .file("d3/src/lib.rs", "") .build(); p.cargo("fetch").run(); @@ -895,7 +950,8 @@ a = { path = "a" } b = { path = "b" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "b/Cargo.toml", r#" @@ -907,7 +963,8 @@ [dependencies] a = { path = "../a", features = ["f1"], default-features = false } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -920,7 +977,8 @@ default = ["f1"] f1 = [] "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -943,7 +1001,8 @@ a = { path = "a" } b = { path = "b" } "#, - ).file("src/lib.rs", "extern crate a; pub fn foo() { a::a(); }") + ) + .file("src/lib.rs", "extern crate a; pub fn foo() { a::a(); }") .file( "b/Cargo.toml", r#" @@ -955,7 +1014,8 @@ [dependencies] a = { path = "../a", features = [], default-features = false } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -968,7 +1028,8 @@ default = ["f1"] f1 = [] "#, - ).file("a/src/lib.rs", r#"#[cfg(feature = "f1")] pub fn a() {}"#) + ) + .file("a/src/lib.rs", r#"#[cfg(feature = "f1")] pub fn a() {}"#) .build(); p.cargo("build").run(); @@ -992,7 +1053,8 @@ [dev-dependencies] foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "") .build(); @@ -1003,7 +1065,8 @@ [COMPILING] test v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1023,10 +1086,12 @@ [features] a = ["foo/a"] "#, - ).file( + ) + .file( "src/lib.rs", "extern crate foo; pub fn bar() { foo::bar(); }", - ).file( + ) + .file( "foo/Cargo.toml", r#" [package] @@ -1037,7 +1102,8 @@ [features] a = [] "#, - ).file("foo/src/lib.rs", r#"#[cfg(feature = "a")] pub fn bar() {}"#) + ) + .file("foo/src/lib.rs", r#"#[cfg(feature = "a")] pub fn bar() {}"#) .build(); p.cargo("build --features a -v").run(); @@ -1057,13 +1123,15 @@ [dependencies.derived] path = "derived" "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate derived; fn main() { derived::test(); } "#, - ).file( + ) + .file( "derived/Cargo.toml", r#" [package] @@ -1078,7 +1146,8 @@ default = [] derived-feat = ["bar/some-feat"] "#, - ).file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") + ) + .file("derived/src/lib.rs", "extern crate bar; pub use bar::test;") .file( "bar/Cargo.toml", r#" @@ -1090,17 +1159,22 @@ [features] some-feat = [] "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #[cfg(feature = "some-feat")] pub fn test() { print!("test"); } "#, - ).build(); + ) + .build(); // The foo project requires that feature "some-feat" in "bar" is enabled. // Building without any features enabled should fail: - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]unresolved import `bar::test`") + .run(); // We should be able to enable the feature "derived-feat", which enables "some-feat", // on the command line. The feature is enabled, thus building should be successful: @@ -1138,7 +1212,8 @@ path = "baz" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(feature = "foo")] @@ -1155,7 +1230,8 @@ bar(); } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "pub fn baz() {}") .build(); @@ -1181,7 +1257,8 @@ path = "baz" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -1190,7 +1267,8 @@ extern crate baz; fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -1204,7 +1282,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1234,7 +1313,8 @@ path = "bap" optional = true "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -1247,7 +1327,8 @@ extern crate bap; fn main() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "pub fn baz() {}") @@ -1268,7 +1349,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1290,7 +1372,8 @@ [dependencies] dep = "1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -1301,13 +1384,15 @@ [features] main = [] "#, - ).file( + ) + .file( "bar/src/main.rs", r#" #[cfg(feature = "main")] fn main() {} "#, - ).build(); + ) + .build(); p.cargo("build -Z package-features --all --features main") .masquerade_as_nightly_cargo() @@ -1315,7 +1400,8 @@ .with_stderr_contains( "\ [ERROR] cannot specify features for more than one package", - ).run(); + ) + .run(); p.cargo("build -Z package-features --package dep --features main") .masquerade_as_nightly_cargo() @@ -1323,21 +1409,24 @@ .with_stderr_contains( "\ [ERROR] cannot specify features for packages outside of workspace", - ).run(); + ) + .run(); p.cargo("build -Z package-features --package dep --all-features") .masquerade_as_nightly_cargo() .with_status(101) .with_stderr_contains( "\ [ERROR] cannot specify features for packages outside of workspace", - ).run(); + ) + .run(); p.cargo("build -Z package-features --package dep --no-default-features") .masquerade_as_nightly_cargo() .with_status(101) .with_stderr_contains( "\ [ERROR] cannot specify features for packages outside of workspace", - ).run(); + ) + .run(); p.cargo("build -Z package-features --all --all-features") .masquerade_as_nightly_cargo() @@ -1364,7 +1453,8 @@ [features] bar = ["baz"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -1377,7 +1467,8 @@ Caused by: Feature `bar` includes `baz` which is not defined as a feature ", - ).run(); + ) + .run(); } #[test] @@ -1397,7 +1488,8 @@ [features] bar = ["crate:baz"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -1410,7 +1502,8 @@ Caused by: Feature `bar` includes `crate:baz` which is not a known dependency ", - ).run(); + ) + .run(); } #[test] @@ -1433,7 +1526,8 @@ [dependencies] baz = "0.1" "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build") @@ -1447,7 +1541,8 @@ Feature `bar` includes `crate:baz` which is not an optional dependency. Consider adding `optional = true` to the dependency ", - ).run(); + ) + .run(); } #[test] @@ -1470,7 +1565,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").masquerade_as_nightly_cargo().run(); @@ -1496,7 +1592,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").masquerade_as_nightly_cargo().with_status(101).with_stderr( @@ -1531,7 +1628,8 @@ [dependencies] baz = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").masquerade_as_nightly_cargo().with_status(101).with_stderr( @@ -1567,7 +1665,8 @@ [dependencies] baz = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").masquerade_as_nightly_cargo().with_status(101).with_stderr( @@ -1602,7 +1701,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").masquerade_as_nightly_cargo().run(); @@ -1630,7 +1730,8 @@ [dev-dependencies] bar = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -1652,7 +1753,8 @@ [workspace] members = ['bar'] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -1664,7 +1766,8 @@ [features] foo = [] "#, - ).file("bar/src/main.rs", "#[cfg(feature = \"foo\")] fn main() {}") + ) + .file("bar/src/main.rs", "#[cfg(feature = \"foo\")] fn main() {}") .build(); p.cargo("build --all-features --all").run(); @@ -1730,3 +1833,37 @@ // Check that building without `f1` uses a dylib without `f1`. p.cargo("run -p bar").run(); } + +#[test] +fn warn_if_default_features() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + path = "bar" + optional = true + + [features] + default-features = ["bar"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file("bar/src/lib.rs", "pub fn bar() {}") + .build(); + + p.cargo("build") + .with_stderr( + r#" +[WARNING] `default-features = [".."]` was found in [features]. Did you mean to use `default = [".."]`? +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] + "#.trim(), + ).run(); +} diff -Nru cargo-0.33.0/tests/testsuite/fetch.rs cargo-0.35.0/tests/testsuite/fetch.rs --- cargo-0.33.0/tests/testsuite/fetch.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/fetch.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ -use support::registry::Package; -use support::rustc_host; -use support::{basic_manifest, cross_compile, project}; +use crate::support::registry::Package; +use crate::support::rustc_host; +use crate::support::{basic_manifest, cross_compile, project}; #[test] fn no_deps() { @@ -49,7 +49,8 @@ host = host, target = target ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("fetch") @@ -95,7 +96,8 @@ host = host, target = target ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("fetch --target") diff -Nru cargo-0.33.0/tests/testsuite/fix.rs cargo-0.35.0/tests/testsuite/fix.rs --- cargo-0.33.0/tests/testsuite/fix.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/fix.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,9 +2,9 @@ use git2; -use support::git; -use support::is_nightly; -use support::{basic_manifest, project}; +use crate::support::git; +use crate::support::is_nightly; +use crate::support::{basic_manifest, project}; use std::io::Write; @@ -23,11 +23,13 @@ let _x: u32 = "a"; } "#, - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") .with_status(101) + .with_stderr_contains("[ERROR] Could not compile `foo`.") .run(); assert!(p.read_file("src/lib.rs").contains("let mut x = 3;")); } @@ -43,7 +45,8 @@ foo(1); } "#, - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs --broken-code") .env("__CARGO_FIX_YOLO", "1") @@ -52,6 +55,19 @@ #[test] fn broken_fixes_backed_out() { + // This works as follows: + // - Create a `rustc` shim (the "foo" project) which will pretend that the + // verification step fails. + // - There is an empty build script so `foo` has `OUT_DIR` to track the steps. + // - The first "check", `foo` creates a file in OUT_DIR, and it completes + // successfully with a warning diagnostic to remove unused `mut`. + // - rustfix removes the `mut`. + // - The second "check" to verify the changes, `foo` swaps out the content + // with something that fails to compile. It creates a second file so it + // won't do anything in the third check. + // - cargo fix discovers that the fix failed, and it backs out the changes. + // - The third "check" is done to display the original diagnostics of the + // original code. let p = project() .file( "foo/Cargo.toml", @@ -61,7 +77,8 @@ version = '0.1.0' [workspace] "#, - ).file( + ) + .file( "foo/src/main.rs", r##" use std::env; @@ -71,19 +88,19 @@ use std::process::{self, Command}; fn main() { + // Ignore calls to things like --print=file-names and compiling build.rs. let is_lib_rs = env::args_os() .map(PathBuf::from) .any(|l| l == Path::new("src/lib.rs")); if is_lib_rs { let path = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let path = path.join("foo"); - if path.exists() { - fs::File::create("src/lib.rs") - .unwrap() - .write_all(b"not rust code") - .unwrap(); + let first = path.join("first"); + let second = path.join("second"); + if first.exists() && !second.exists() { + fs::write("src/lib.rs", b"not rust code").unwrap(); + fs::File::create(&second).unwrap(); } else { - fs::File::create(&path).unwrap(); + fs::File::create(&first).unwrap(); } } @@ -94,7 +111,8 @@ process::exit(status.code().unwrap_or(2)); } "##, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -102,7 +120,8 @@ version = '0.1.0' [workspace] "#, - ).file("bar/build.rs", "fn main() {}") + ) + .file("bar/build.rs", "fn main() {}") .file( "bar/src/lib.rs", r#" @@ -111,18 +130,17 @@ drop(x); } "#, - ).build(); + ) + .build(); // Build our rustc shim p.cargo("build").cwd(p.root().join("foo")).run(); // Attempt to fix code, but our shim will always fail the second compile - p.cargo("fix --allow-no-vcs") + p.cargo("fix --allow-no-vcs --lib") .cwd(p.root().join("bar")) .env("__CARGO_FIX_YOLO", "1") .env("RUSTC", p.root().join("foo/target/debug/foo")) - .with_status(101) - .with_stderr_contains("[..]not rust code[..]") .with_stderr_contains( "\ warning: failed to automatically apply fixes suggested by rustc \ @@ -137,11 +155,22 @@ and we would appreciate a bug report! You're likely to see \n\ a number of compiler warnings after this message which cargo\n\ attempted to fix but failed. If you could open an issue at\n\ - https://github.com/rust-lang/cargo/issues\n\ - quoting the full output of this command we'd be very appreciative!\ + [..]\n\ + quoting the full output of this command we'd be very appreciative!\n\ + Note that you may be able to make some more progress in the near-term\n\ + fixing code with the `--broken-code` flag\n\ + \n\ + The following errors were reported:\n\ + error: expected one of `!` or `::`, found `rust`\n\ ", - ).with_stderr_does_not_contain("[..][FIXING][..]") + ) + .with_stderr_contains("Original diagnostics will follow.") + .with_stderr_contains("[WARNING] variable does not need to be mutable") + .with_stderr_does_not_contain("[..][FIXING][..]") .run(); + + // Make sure the fix which should have been applied was backed out + assert!(p.read_file("bar/src/lib.rs").contains("let mut x = 3;")); } #[test] @@ -159,7 +188,8 @@ [workspace] "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -169,7 +199,8 @@ x } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file( "bar/src/lib.rs", r#" @@ -178,7 +209,8 @@ x } "#, - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs -p foo -p bar") .env("__CARGO_FIX_YOLO", "1") @@ -191,7 +223,8 @@ [FIXING] src/lib.rs (1 fix) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -210,7 +243,8 @@ [workspace] "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file( "bar/src/lib.rs", @@ -220,7 +254,8 @@ x } "#, - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") @@ -254,7 +289,8 @@ let x = ::foo::FOO; } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -268,10 +304,9 @@ println!("{}", p.read_file("src/lib.rs")); assert!(p.read_file("src/lib.rs").contains("use crate::foo::FOO;")); - assert!( - p.read_file("src/lib.rs") - .contains("let x = crate::foo::FOO;") - ); + assert!(p + .read_file("src/lib.rs") + .contains("let x = crate::foo::FOO;")); } #[test] @@ -295,7 +330,8 @@ foo(); } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -331,7 +367,8 @@ [dependencies] bar = { path = 'bar' } "#, - ).file( + ) + .file( "src/lib.rs", r#" #![warn(rust_2018_idioms)] @@ -344,7 +381,8 @@ bar(); } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -383,7 +421,8 @@ let x = ::foo::FOO; } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -422,7 +461,8 @@ x } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -448,7 +488,8 @@ x + y } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -473,7 +514,8 @@ x + y } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo v0.0.1 ([..]) @@ -496,7 +538,8 @@ fn add(a: &u32) -> u32 { a + 1 }\r\n\ pub fn foo() -> u32 { let mut x = 3; add(&x) }\r\n\ ", - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") @@ -513,7 +556,8 @@ #![deny(warnings)] pub fn foo() { let mut x = 3; drop(x); } ", - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") @@ -535,7 +579,8 @@ fn bar() {} ", - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") @@ -557,7 +602,8 @@ x } ", - ).file( + ) + .file( "src/bar.rs", " pub fn foo() -> u32 { @@ -566,7 +612,8 @@ } ", - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") @@ -589,31 +636,34 @@ #[test] pub fn foo2() { let mut x = 3; drop(x); } "#, - ).file( + ) + .file( "tests/a.rs", r#" #[test] pub fn foo() { let mut x = 3; drop(x); } "#, - ).file("examples/foo.rs", "fn main() { let mut x = 3; drop(x); }") + ) + .file("examples/foo.rs", "fn main() { let mut x = 3; drop(x); }") .file("build.rs", "fn main() { let mut x = 3; drop(x); }") .build(); p.cargo("fix --all-targets --allow-no-vcs") - .env("__CARGO_FIX_YOLO", "1") - .with_stdout("") - .with_stderr_contains("[COMPILING] foo v0.0.1 ([..])") - .with_stderr_contains("[FIXING] build.rs (1 fix)") - // Don't assert number of fixes for this one, as we don't know if we're - // fixing it once or twice! We run this all concurrently, and if we - // compile (and fix) in `--test` mode first, we get two fixes. Otherwise - // we'll fix one non-test thing, and then fix another one later in - // test mode. - .with_stderr_contains("[FIXING] src/lib.rs[..]") - .with_stderr_contains("[FIXING] src/main.rs (1 fix)") - .with_stderr_contains("[FIXING] examples/foo.rs (1 fix)") - .with_stderr_contains("[FIXING] tests/a.rs (1 fix)") - .with_stderr_contains("[FINISHED] [..]").run(); + .env("__CARGO_FIX_YOLO", "1") + .with_stdout("") + .with_stderr_contains("[COMPILING] foo v0.0.1 ([..])") + .with_stderr_contains("[FIXING] build.rs (1 fix)") + // Don't assert number of fixes for this one, as we don't know if we're + // fixing it once or twice! We run this all concurrently, and if we + // compile (and fix) in `--test` mode first, we get two fixes. Otherwise + // we'll fix one non-test thing, and then fix another one later in + // test mode. + .with_stderr_contains("[FIXING] src/lib.rs[..]") + .with_stderr_contains("[FIXING] src/main.rs (1 fix)") + .with_stderr_contains("[FIXING] examples/foo.rs (1 fix)") + .with_stderr_contains("[FIXING] tests/a.rs (1 fix)") + .with_stderr_contains("[FINISHED] [..]") + .run(); p.cargo("build").run(); p.cargo("test").run(); } @@ -633,13 +683,15 @@ [workspace] "#, - ).file( + ) + .file( "src/lib.rs", r#" #[cfg(feature = "bar")] pub fn foo() -> u32 { let mut x = 3; x } "#, - ).build(); + ) + .build(); p.cargo("fix --allow-no-vcs").run(); p.cargo("build").run(); @@ -650,11 +702,11 @@ #[test] fn shows_warnings() { let p = project() - .file("src/lib.rs", "use std::default::Default; pub fn foo() {}") + .file("src/lib.rs", "#[deprecated] fn bar() {} pub fn foo() { let _ = bar(); }") .build(); p.cargo("fix --allow-no-vcs") - .with_stderr_contains("[..]warning: unused import[..]") + .with_stderr_contains("[..]warning: use of deprecated item[..]") .run(); } @@ -669,7 +721,8 @@ error: no VCS found for this package and `cargo fix` can potentially perform \ destructive changes; if you'd like to suppress this error pass `--allow-no-vcs`\ ", - ).run(); + ) + .run(); p.cargo("fix --allow-no-vcs").run(); } @@ -699,7 +752,8 @@ ", - ).run(); + ) + .run(); p.cargo("fix --allow-dirty").run(); } @@ -733,7 +787,8 @@ ", - ).run(); + ) + .run(); p.cargo("fix --allow-staged").run(); } @@ -795,7 +850,8 @@ version = '0.1.0' edition = '2018' "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let stderr = "\ @@ -836,7 +892,8 @@ } } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo [..] @@ -867,7 +924,8 @@ version = '0.1.0' edition = '2018' "#, - ).file( + ) + .file( "src/lib.rs", r#" use std::any::Any; @@ -875,7 +933,8 @@ let _x: Box = Box::new(3); } "#, - ).build(); + ) + .build(); let stderr = "\ [CHECKING] foo [..] @@ -884,7 +943,6 @@ "; p.cargo("fix --edition-idioms --allow-no-vcs") .with_stderr(stderr) - .with_status(0) .run(); assert!(p.read_file("src/lib.rs").contains("Box")); @@ -896,7 +954,6 @@ p.cargo("fix --edition-idioms --allow-no-vcs") .masquerade_as_nightly_cargo() - .with_status(0) .run(); } @@ -925,20 +982,22 @@ .file( "src/lib.rs", r#" - use std::default::Default; + #[deprecated] + fn bar() {} pub fn foo() { + let _ = bar(); } "#, ) .build(); p.cargo("fix --allow-no-vcs") - .with_stderr_contains("[..]warning: unused import[..]") + .with_stderr_contains("[..]warning: use of deprecated item[..]") .run(); p.cargo("fix --allow-no-vcs") - .with_stderr_contains("[..]warning: unused import[..]") + .with_stderr_contains("[..]warning: use of deprecated item[..]") .run(); } @@ -948,65 +1007,76 @@ .file( "src/lib.rs", r#" - use std::default::Default; + #[deprecated] + fn bar() {} - pub fn a() -> u32 { 3 } + pub fn foo() { + let _ = bar(); + } "#, ) .file( "src/main.rs", r#" - use std::default::Default; - fn main() { println!("3"); } + #[deprecated] + fn bar() {} + + fn main() { + let _ = bar(); + } "#, ) .file( "tests/foo.rs", r#" - use std::default::Default; + #[deprecated] + fn bar() {} + #[test] fn foo_test() { - println!("3"); + let _ = bar(); } "#, ) .file( "tests/bar.rs", r#" - use std::default::Default; + #[deprecated] + fn bar() {} #[test] fn foo_test() { - println!("3"); + let _ = bar(); } "#, ) .file( "examples/fooxample.rs", r#" - use std::default::Default; + #[deprecated] + fn bar() {} fn main() { - println!("3"); + let _ = bar(); } "#, ) .build(); p.cargo("fix --allow-no-vcs --all-targets") - .with_stderr_contains(" --> examples/fooxample.rs:2:21") - .with_stderr_contains(" --> src/lib.rs:2:21") - .with_stderr_contains(" --> src/main.rs:2:21") - .with_stderr_contains(" --> tests/bar.rs:2:21") - .with_stderr_contains(" --> tests/foo.rs:2:21") + .with_stderr_contains(" --> examples/fooxample.rs:6:29") + .with_stderr_contains(" --> src/lib.rs:6:29") + .with_stderr_contains(" --> src/main.rs:6:29") + .with_stderr_contains(" --> tests/bar.rs:7:29") + .with_stderr_contains(" --> tests/foo.rs:7:29") .run(); p.cargo("fix --allow-no-vcs --all-targets") - .with_stderr_contains(" --> examples/fooxample.rs:2:21") - .with_stderr_contains(" --> src/lib.rs:2:21") - .with_stderr_contains(" --> src/main.rs:2:21") - .with_stderr_contains(" --> tests/bar.rs:2:21") - .with_stderr_contains(" --> tests/foo.rs:2:21") + .with_stderr_contains(" --> examples/fooxample.rs:6:29") + .with_stderr_contains(" --> src/lib.rs:6:29") + .with_stderr_contains(" --> src/main.rs:6:29") + .with_stderr_contains(" --> tests/bar.rs:7:29") + .with_stderr_contains(" --> tests/foo.rs:7:29") .run(); } @@ -1025,7 +1095,8 @@ [workspace] "#, - ).file("src/lib.rs", "extern crate bar;") + ) + .file("src/lib.rs", "extern crate bar;") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .build(); @@ -1033,20 +1104,24 @@ p.cargo("fix --allow-no-vcs -p foo") .env("__CARGO_FIX_YOLO", "1") .with_stdout("") - .with_stderr("\ + .with_stderr( + "\ [CHECKING] bar v0.1.0 ([..]) [CHECKING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -") +", + ) .run(); p.cargo("fix --allow-no-vcs -p foo") .env("__CARGO_FIX_YOLO", "1") .with_stdout("") - .with_stderr("\ + .with_stderr( + "\ [CHECKING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -") +", + ) .run(); } @@ -1109,11 +1184,13 @@ .build(); p.cargo("fix --allow-no-vcs --edition") - .with_stderr("\ + .with_stderr( + "\ [CHECKING] a v0.1.0 ([..]) [CHECKING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -") +", + ) .run(); } @@ -1131,7 +1208,8 @@ version = '0.1.0' [workspace] "#, - ).file( + ) + .file( "foo/src/main.rs", r##" use std::env; @@ -1161,7 +1239,8 @@ process::exit(status.code().unwrap_or(2)); } "##, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -1169,11 +1248,10 @@ version = '0.1.0' [workspace] "#, - ).file("bar/build.rs", "fn main() {}") - .file( - "bar/src/lib.rs", - "pub fn foo() { let mut x = 3; drop(x); }", - ).build(); + ) + .file("bar/build.rs", "fn main() {}") + .file("bar/src/lib.rs", "pub fn foo() { let mut x = 3; drop(x); }") + .build(); // Build our rustc shim p.cargo("build").cwd(p.root().join("foo")).run(); @@ -1183,7 +1261,31 @@ .cwd(p.root().join("bar")) .env("RUSTC", p.root().join("foo/target/debug/foo")) .with_status(101) + .with_stderr_contains("[WARNING] failed to automatically apply fixes [..]") .run(); - assert_eq!(p.read_file("bar/src/lib.rs"), "pub fn foo() { let x = 3; drop(x); }"); + assert_eq!( + p.read_file("bar/src/lib.rs"), + "pub fn foo() { let x = 3; drop(x); }" + ); +} + +#[test] +fn fix_with_common() { + let p = project() + .file("src/lib.rs", "") + .file( + "tests/t1.rs", + "mod common; #[test] fn t1() { common::try(); }", + ) + .file( + "tests/t2.rs", + "mod common; #[test] fn t2() { common::try(); }", + ) + .file("tests/common/mod.rs", "pub fn try() {}") + .build(); + + p.cargo("fix --edition --allow-no-vcs").run(); + + assert_eq!(p.read_file("tests/common/mod.rs"), "pub fn r#try() {}"); } diff -Nru cargo-0.33.0/tests/testsuite/freshness.rs cargo-0.35.0/tests/testsuite/freshness.rs --- cargo-0.33.0/tests/testsuite/freshness.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/freshness.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,14 @@ -use std::fs::{self, File}; +use std::fs::{self, File, OpenOptions}; use std::io::prelude::*; - -use support::paths::CargoPathExt; -use support::registry::Package; -use support::sleep_ms; -use support::{basic_manifest, is_coarse_mtime, project}; +use std::net::TcpListener; +use std::path::PathBuf; +use std::thread; +use std::time::SystemTime; + +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::sleep_ms; +use crate::support::{basic_manifest, is_coarse_mtime, project}; #[test] fn modifying_and_moving() { @@ -19,7 +23,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); p.root().move_into_the_past(); @@ -35,10 +40,14 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]file not found[..]") + .run(); } #[test] @@ -57,7 +66,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("test").run(); sleep_ms(1000); @@ -83,7 +93,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.bin("foo").is_file()); } @@ -103,7 +114,8 @@ [dependencies.b] path = "b" "#, - ).file("src/lib.rs", "extern crate a; extern crate b;") + ) + .file("src/lib.rs", "extern crate a; extern crate b;") .file( "a/Cargo.toml", r#" @@ -114,7 +126,8 @@ [dependencies.b] path = "../b" "#, - ).file("a/src/lib.rs", "extern crate b;") + ) + .file("a/src/lib.rs", "extern crate b;") .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -150,7 +163,8 @@ [features] foo = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -159,7 +173,8 @@ [..]Compiling foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build --features foo") .with_stderr( @@ -167,7 +182,8 @@ [..]Compiling foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); /* Targets should be cached from the first build */ @@ -196,7 +212,8 @@ [profile.dev] panic = "abort" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -205,7 +222,8 @@ [..]Compiling foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("test") .with_stderr( @@ -215,7 +233,8 @@ [RUNNING] target[..]debug[..]deps[..]foo-[..][EXE] [DOCTEST] foo ", - ).run(); + ) + .run(); /* Targets should be cached from the first build */ @@ -230,7 +249,8 @@ [RUNNING] target[..]debug[..]deps[..]foo-[..][EXE] [DOCTEST] foo ", - ).run(); + ) + .run(); } #[test] @@ -244,7 +264,8 @@ [build] target-dir = "./target" "#, - ).file( + ) + .file( "dep_crate/Cargo.toml", r#" [package] @@ -255,7 +276,8 @@ [features] ftest = [] "#, - ).file( + ) + .file( "dep_crate/src/lib.rs", r#" #[cfg(feature = "ftest")] @@ -267,7 +289,8 @@ println!("ftest off") } "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [package] @@ -278,7 +301,8 @@ [dependencies] dep_crate = {path = "../dep_crate", features = []} "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "a/src/main.rs", r#" @@ -288,7 +312,8 @@ yo(); } "#, - ).file( + ) + .file( "b/Cargo.toml", r#" [package] @@ -299,7 +324,8 @@ [dependencies] dep_crate = {path = "../dep_crate", features = ["ftest"]} "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "b/src/main.rs", r#" @@ -309,7 +335,8 @@ yo(); } "#, - ).build(); + ) + .build(); /* Build and rebuild a/. Ensure dep_crate only builds once */ p.cargo("run") @@ -322,7 +349,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/a[EXE]` ", - ).run(); + ) + .run(); p.cargo("clean -p a").cwd(p.root().join("a")).run(); p.cargo("run") .cwd(p.root().join("a")) @@ -333,7 +361,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/a[EXE]` ", - ).run(); + ) + .run(); /* Build and rebuild b/. Ensure dep_crate only builds once */ p.cargo("run") @@ -346,7 +375,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/b[EXE]` ", - ).run(); + ) + .run(); p.cargo("clean -p b").cwd(p.root().join("b")).run(); p.cargo("run") .cwd(p.root().join("b")) @@ -357,7 +387,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/b[EXE]` ", - ).run(); + ) + .run(); /* Build a/ package again. If we cache different feature dep builds correctly, * this should not cause a rebuild of dep_crate */ @@ -371,7 +402,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/a[EXE]` ", - ).run(); + ) + .run(); /* Build b/ package again. If we cache different feature dep builds correctly, * this should not cause a rebuild */ @@ -385,7 +417,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/b[EXE]` ", - ).run(); + ) + .run(); } #[test] @@ -402,7 +435,8 @@ [features] foo = [] "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() { @@ -410,18 +444,8 @@ println!("{}", msg); } "#, - ).build(); - - // Windows has a problem with replacing a binary that was just executed. - // Unlinking it will succeed, but then attempting to immediately replace - // it will sometimes fail with "Already Exists". - // See https://github.com/rust-lang/cargo/issues/5481 - let foo_proc = |name: &str| { - let src = p.bin("foo"); - let dst = p.bin(name); - fs::rename(&src, &dst).expect("Failed to rename foo"); - p.process(dst) - }; + ) + .build(); p.cargo("build") .with_stderr( @@ -429,8 +453,9 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - foo_proc("off1").with_stdout("feature off").run(); + ) + .run(); + p.rename_run("foo", "off1").with_stdout("feature off").run(); p.cargo("build --features foo") .with_stderr( @@ -438,8 +463,9 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - foo_proc("on1").with_stdout("feature on").run(); + ) + .run(); + p.rename_run("foo", "on1").with_stdout("feature on").run(); /* Targets should be cached from the first build */ @@ -448,16 +474,18 @@ "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - foo_proc("off2").with_stdout("feature off").run(); + ) + .run(); + p.rename_run("foo", "off2").with_stdout("feature off").run(); p.cargo("build --features foo") .with_stderr( "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - foo_proc("on2").with_stdout("feature on").run(); + ) + .run(); + p.rename_run("foo", "on2").with_stdout("feature on").run(); } #[test] @@ -471,7 +499,8 @@ #[test] fn test() { foo::foo(); } "#, - ).build(); + ) + .build(); p.cargo("build").run(); p.cargo("test").run(); @@ -480,7 +509,10 @@ File::create(&p.root().join("src/lib.rs")).unwrap(); p.cargo("build -v").run(); - p.cargo("test -v").with_status(101).run(); + p.cargo("test -v") + .with_status(101) + .with_stderr_contains("[..]cannot find function `foo`[..]") + .run(); } #[test] @@ -499,7 +531,8 @@ [dev-dependencies] b = { path = "b" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("tests/foo.rs", "") .file( "a/Cargo.toml", @@ -512,7 +545,8 @@ [target.foo.dependencies] c = { path = "../c" } "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .file( "b/Cargo.toml", r#" @@ -524,7 +558,8 @@ [dependencies] c = { path = "../c" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file("c/Cargo.toml", &basic_manifest("c", "0.0.1")) .file("c/src/lib.rs", "") .build(); @@ -538,7 +573,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -555,7 +591,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -565,14 +602,16 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "a/build.rs", r#" fn main() { println!("cargo:rerun-if-changed=build.rs"); } "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -593,7 +632,8 @@ [dependencies] b = { path = "../b" } "#, - ).file("a1/src/lib.rs", "") + ) + .file("a1/src/lib.rs", "") .file( "a2/Cargo.toml", r#" @@ -604,7 +644,8 @@ [dependencies] b = { path = "../b" } "#, - ).file("a2/src/lib.rs", "") + ) + .file("a2/src/lib.rs", "") .file( "b/Cargo.toml", r#" @@ -615,7 +656,8 @@ [dependencies] c = { path = "../c" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file( "c/Cargo.toml", r#" @@ -626,7 +668,8 @@ [dependencies] d = { path = "../d" } "#, - ).file("c/src/lib.rs", "") + ) + .file("c/src/lib.rs", "") .file("d/Cargo.toml", &basic_manifest("d", "0.0.1")) .file("d/src/lib.rs", "") .file( @@ -635,7 +678,8 @@ [build] target-dir = "./target" "#, - ).build(); + ) + .build(); p.cargo("build") .cwd(p.root().join("a1")) @@ -648,7 +692,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", dir = p.url().to_file_path().unwrap().to_str().unwrap() - )).run(); + )) + .run(); p.cargo("build") .cwd(p.root().join("a2")) .with_stderr( @@ -656,7 +701,8 @@ [COMPILING] a2 v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -673,7 +719,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -702,7 +749,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -720,7 +768,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -735,14 +784,16 @@ version = "0.0.1" authors = [] "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() { println!("{}", env!("CARGO_PKG_DESCRIPTION")); } "#, - ).build(); + ) + .build(); p.cargo("run") .with_stdout("old desc") @@ -752,7 +803,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo[EXE]` ", - ).run(); + ) + .run(); File::create(&p.root().join("Cargo.toml")) .unwrap() @@ -764,7 +816,8 @@ version = "0.0.1" authors = [] "#, - ).unwrap(); + ) + .unwrap(); p.cargo("run") .with_stdout("new desc") @@ -774,7 +827,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo[EXE]` ", - ).run(); + ) + .run(); } #[test] @@ -791,7 +845,8 @@ [dependencies] foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.0.1")) .file("foo/src/lib.rs", "") .build(); @@ -828,7 +883,8 @@ baz = { path = "baz" } registry1 = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -840,7 +896,8 @@ [dev-dependencies] registry2 = "*" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file( "baz/Cargo.toml", r#" @@ -852,7 +909,8 @@ [dependencies] registry3 = { version = "*", optional = true } "#, - ).file("baz/src/lib.rs", "") + ) + .file("baz/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -876,7 +934,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -891,7 +950,8 @@ [dev-dependencies] baz = { path = "../baz"} "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file( "baz/Cargo.toml", r#" @@ -903,7 +963,8 @@ [dependencies] registry2 = "*" "#, - ).file("baz/src/lib.rs", "") + ) + .file("baz/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -921,7 +982,8 @@ [profile.dev] panic = 'abort' "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) .file("bar/src/lib.rs", "") .file( @@ -938,7 +1000,8 @@ [dependencies] bar = { path = '../bar' } "#, - ).file("baz/src/lib.rs", "extern crate bar;") + ) + .file("baz/src/lib.rs", "extern crate bar;") .build(); p.cargo("build -p bar").run(); @@ -961,7 +1024,8 @@ [dependencies] proc-macro-thing = { path = 'proc-macro-thing' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "proc-macro-thing/Cargo.toml", r#" @@ -975,7 +1039,8 @@ [dependencies] qux = { path = '../qux' } "#, - ).file("proc-macro-thing/src/lib.rs", "") + ) + .file("proc-macro-thing/src/lib.rs", "") .file( "baz/Cargo.toml", r#" @@ -986,7 +1051,8 @@ [dependencies] qux = { path = '../qux' } "#, - ).file("baz/src/main.rs", "fn main() {}") + ) + .file("baz/src/main.rs", "fn main() {}") .file("qux/Cargo.toml", &basic_manifest("qux", "0.1.1")) .file("qux/src/lib.rs", "") .build(); @@ -1014,7 +1080,8 @@ [dependencies] baz = { path = 'baz' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.1")) .file("baz/src/lib.rs", "") .build(); @@ -1027,7 +1094,8 @@ [RUNNING] `rustc[..] --test [..]` [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1079,6 +1147,211 @@ } #[test] +fn changing_rustflags_is_cached() { + let p = project().file("src/lib.rs", "").build(); + + p.cargo("build").run(); + p.cargo("build") + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr( + "\ +[COMPILING] foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); + // This should not recompile! + p.cargo("build") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); + p.cargo("build") + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); +} + +fn simple_deps_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) { + // Cargo is experimenting with letting outside projects develop some + // limited forms of GC for target_dir. This is one of the forms. + // Specifically, Cargo is updating the mtime of files in + // target/profile/deps each time it uses the file. + // So a cleaner can remove files older then a time stamp without + // effecting any builds that happened since that time stamp. + let mut cleand = false; + dir.push("deps"); + for dep in fs::read_dir(&dir).unwrap() { + let dep = dep.unwrap(); + if filetime::FileTime::from_last_modification_time(&dep.metadata().unwrap()) <= timestamp { + fs::remove_file(dep.path()).unwrap(); + println!("remove: {:?}", dep.path()); + cleand = true; + } + } + assert!( + cleand, + "called simple_deps_cleaner, but there was nothing to remove" + ); +} + +#[test] +fn simple_deps_cleaner_does_not_rebuild() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file("bar/src/lib.rs", "") + .build(); + + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .run(); + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr( + "\ +[COMPILING] bar v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); + if is_coarse_mtime() { + sleep_ms(1000); + } + let timestamp = filetime::FileTime::from_system_time(SystemTime::now()); + if is_coarse_mtime() { + sleep_ms(1000); + } + // This does not make new files, but it does update the mtime. + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); + simple_deps_cleaner(p.target_debug_dir(), timestamp); + // This should not recompile! + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); + // But this should be cleaned and so need a rebuild + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .with_stderr( + "\ +[COMPILING] bar v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); +} + +fn fingerprint_cleaner(mut dir: PathBuf, timestamp: filetime::FileTime) { + // Cargo is experimenting with letting outside projects develop some + // limited forms of GC for target_dir. This is one of the forms. + // Specifically, Cargo is updating the mtime of a file in + // target/profile/.fingerprint each time it uses the fingerprint. + // So a cleaner can remove files associated with a fingerprint + // if all the files in the fingerprint's folder are older then a time stamp without + // effecting any builds that happened since that time stamp. + let mut cleand = false; + dir.push(".fingerprint"); + for fing in fs::read_dir(&dir).unwrap() { + let fing = fing.unwrap(); + + if fs::read_dir(fing.path()).unwrap().all(|f| { + filetime::FileTime::from_last_modification_time(&f.unwrap().metadata().unwrap()) + <= timestamp + }) { + fs::remove_dir_all(fing.path()).unwrap(); + println!("remove: {:?}", fing.path()); + // a real cleaner would remove the big files in deps and build as well + // but fingerprint is sufficient for our tests + cleand = true; + } else { + } + } + assert!( + cleand, + "called fingerprint_cleaner, but there was nothing to remove" + ); +} + +#[test] +fn fingerprint_cleaner_does_not_rebuild() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = { path = "bar" } + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + .file("bar/src/lib.rs", "") + .build(); + + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .run(); + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr( + "\ +[COMPILING] bar v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); + if is_coarse_mtime() { + sleep_ms(1000); + } + let timestamp = filetime::FileTime::from_system_time(SystemTime::now()); + if is_coarse_mtime() { + sleep_ms(1000); + } + // This does not make new files, but it does update the mtime. + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); + fingerprint_cleaner(p.target_debug_dir(), timestamp); + // This should not recompile! + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .env("RUSTFLAGS", "-C target-cpu=native") + .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .run(); + // But this should be cleaned and so need a rebuild + p.cargo("build -Z mtime-on-use") + .masquerade_as_nightly_cargo() + .with_stderr( + "\ +[COMPILING] bar v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); +} + +#[test] fn reuse_panic_build_dep_test() { let p = project() .file( @@ -1206,6 +1479,9 @@ .build(); p.cargo("build").run(); + if is_coarse_mtime() { + sleep_ms(1000); + } File::create(&p.root().join("reg1new/src/lib.rs")).unwrap(); if is_coarse_mtime() { @@ -1234,3 +1510,110 @@ ) .run(); } + +#[test] +fn rebuild_on_mid_build_file_modification() { + let server = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = server.local_addr().unwrap(); + + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["root", "proc_macro_dep"] + "#, + ) + .file( + "root/Cargo.toml", + r#" + [project] + name = "root" + version = "0.1.0" + authors = [] + + [dependencies] + proc_macro_dep = { path = "../proc_macro_dep" } + "#, + ) + .file( + "root/src/lib.rs", + r#" + #[macro_use] + extern crate proc_macro_dep; + + #[derive(Noop)] + pub struct X; + "#, + ) + .file( + "proc_macro_dep/Cargo.toml", + r#" + [project] + name = "proc_macro_dep" + version = "0.1.0" + authors = [] + + [lib] + proc-macro = true + "#, + ) + .file( + "proc_macro_dep/src/lib.rs", + &format!( + r#" + extern crate proc_macro; + + use std::io::Read; + use std::net::TcpStream; + use proc_macro::TokenStream; + + #[proc_macro_derive(Noop)] + pub fn noop(_input: TokenStream) -> TokenStream {{ + let mut stream = TcpStream::connect("{}").unwrap(); + let mut v = Vec::new(); + stream.read_to_end(&mut v).unwrap(); + "".parse().unwrap() + }} + "#, + addr + ), + ) + .build(); + let root = p.root(); + + let t = thread::spawn(move || { + let socket = server.accept().unwrap().0; + sleep_ms(1000); + let mut file = OpenOptions::new() + .write(true) + .append(true) + .open(root.join("root/src/lib.rs")) + .unwrap(); + writeln!(file, "// modified").expect("Failed to append to root sources"); + drop(file); + drop(socket); + drop(server.accept().unwrap()); + }); + + p.cargo("build") + .with_stderr( + "\ +[COMPILING] proc_macro_dep v0.1.0 ([..]/proc_macro_dep) +[COMPILING] root v0.1.0 ([..]/root) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + p.cargo("build") + .with_stderr( + "\ +[COMPILING] root v0.1.0 ([..]/root) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + t.join().ok().unwrap(); +} diff -Nru cargo-0.33.0/tests/testsuite/generate_lockfile.rs cargo-0.35.0/tests/testsuite/generate_lockfile.rs --- cargo-0.33.0/tests/testsuite/generate_lockfile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/generate_lockfile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,8 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::registry::Package; -use support::{basic_manifest, paths, project, ProjectBuilder}; +use crate::support::registry::Package; +use crate::support::{basic_manifest, paths, project, ProjectBuilder}; #[test] fn adding_and_removing_packages() { @@ -30,7 +30,8 @@ [dependencies.bar] path = "bar" "#, - ).unwrap(); + ) + .unwrap(); p.cargo("generate-lockfile").run(); let lock2 = p.read_lockfile(); assert_ne!(lock1, lock2); @@ -56,7 +57,8 @@ authors = [] version = "0.0.1" "#, - ).unwrap(); + ) + .unwrap(); p.cargo("generate-lockfile").run(); let lock4 = p.read_lockfile(); assert_eq!(lock1, lock4); @@ -78,7 +80,8 @@ [dependencies] serde = "1.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("generate-lockfile") @@ -141,7 +144,7 @@ let lock0 = p.read_lockfile(); - assert!(lock0.starts_with("[[package]]\n")); + assert!(lock0.starts_with("# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\n")); let lock1 = lock0.replace("\n", "\r\n"); { @@ -155,7 +158,7 @@ let lock2 = p.read_lockfile(); - assert!(lock2.starts_with("[[package]]\r\n")); + assert!(lock2.starts_with("# This file is automatically @generated by Cargo.\r\n# It is not intended for manual editing.\r\n")); assert_eq!(lock1, lock2); } @@ -189,7 +192,8 @@ [dependencies] common = {path="common"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let common_toml = &basic_manifest("common", "0.0.1"); @@ -212,7 +216,8 @@ common = {path="common"} a = {path="../a"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let _common_in_b = ProjectBuilder::new(paths::root().join("b/common")) @@ -220,12 +225,13 @@ .file("src/lib.rs", "") .build(); - // should fail due to a duplicate package `common` in the lockfile + // should fail due to a duplicate package `common` in the lock file b.cargo("build") .with_status(101) .with_stderr_contains( "[..]package collision in the lockfile: packages common [..] and \ common [..] are different, but only one can be written to \ lockfile unambiguously", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/git.rs cargo-0.35.0/tests/testsuite/git.rs --- cargo-0.33.0/tests/testsuite/git.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/git.rs 2019-04-01 21:32:07.000000000 +0000 @@ -8,10 +8,10 @@ use std::sync::Arc; use std::thread; -use support::paths::{self, CargoPathExt}; -use support::sleep_ms; -use support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}; -use support::Project; +use crate::support::paths::{self, CargoPathExt}; +use crate::support::sleep_ms; +use crate::support::Project; +use crate::support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}; #[test] fn cargo_compile_simple_git_dep() { @@ -27,7 +27,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); let project = project .file( @@ -46,10 +47,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); let git_root = git_project.root(); @@ -62,7 +65,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", path2url(&git_root), path2url(&git_root), - )).run(); + )) + .run(); assert!(project.bin("foo").is_file()); @@ -87,7 +91,8 @@ [dependencies.dep1] git = 'https://github.com/some_user/dep1.git' "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build -Zoffline").masquerade_as_nightly_cargo().with_status(101). @@ -112,7 +117,8 @@ pub static COOL_STR:&str = "cached git repo rev1"; "#, ) - }).unwrap(); + }) + .unwrap(); let repo = git2::Repository::open(&git_project.root()).unwrap(); let rev1 = repo.revparse_single("HEAD").unwrap().id(); @@ -144,7 +150,8 @@ git_project.url(), rev1 ), - ).file("src/main.rs", "fn main(){}") + ) + .file("src/main.rs", "fn main(){}") .build(); prj.cargo("build").run(); @@ -163,8 +170,10 @@ "#, git_project.url(), rev2 - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); prj.cargo("build").run(); } @@ -182,10 +191,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", &main_file(r#""hello from {}", dep1::COOL_STR"#, &["dep1"]), - ).build(); + ) + .build(); let git_root = git_project.root(); @@ -197,7 +208,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", path2url(git_root), - )).run(); + )) + .run(); assert!(p.bin("foo").is_file()); @@ -220,10 +232,14 @@ "#, git_project.url(), rev1 - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); - p.cargo("build -Zoffline").masquerade_as_nightly_cargo().run(); + p.cargo("build -Zoffline") + .masquerade_as_nightly_cargo() + .run(); p.process(&p.bin("foo")) .with_stdout("hello from cached git repo rev1\n") .run(); @@ -243,7 +259,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); // Make a new branch based on the current HEAD commit let repo = git2::Repository::open(&git_project.root()).unwrap(); @@ -270,10 +287,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); let git_root = git_project.root(); @@ -286,7 +305,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", path2url(&git_root), path2url(&git_root), - )).run(); + )) + .run(); assert!(project.bin("foo").is_file()); @@ -310,7 +330,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); // Make a tag corresponding to the current HEAD let repo = git2::Repository::open(&git_project.root()).unwrap(); @@ -321,7 +342,8 @@ &repo.signature().unwrap(), "make a new tag", false, - ).unwrap(); + ) + .unwrap(); let project = project .file( @@ -341,10 +363,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); let git_root = git_project.root(); @@ -357,7 +381,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", path2url(&git_root), path2url(&git_root), - )).run(); + )) + .run(); assert!(project.bin("foo").is_file()); @@ -391,7 +416,8 @@ name = "dep1" "#, - ).file( + ) + .file( "src/dep1.rs", r#" extern crate dep2; @@ -400,7 +426,8 @@ dep2::hello() } "#, - ).file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2")) + ) + .file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2")) .file( "vendor/dep2/src/dep2.rs", r#" @@ -409,7 +436,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -433,10 +461,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); p.cargo("build").run(); @@ -457,8 +487,10 @@ "hello world" } "#, - ).file("vendor/dep2/Cargo.toml", "!INVALID!") - }).unwrap(); + ) + .file("vendor/dep2/Cargo.toml", "!INVALID!") + }) + .unwrap(); let p = project() .file( @@ -482,10 +514,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); p.cargo("build").run(); @@ -506,7 +540,8 @@ "this is dep1" } "#, - ).file("dep2/Cargo.toml", &basic_lib_manifest("dep2")) + ) + .file("dep2/Cargo.toml", &basic_lib_manifest("dep2")) .file( "dep2/src/dep2.rs", r#" @@ -515,7 +550,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -545,13 +581,15 @@ git_project.url(), git_project.url() ), - ).file( + ) + .file( "src/foo.rs", &main_file( r#""{} {}", dep1::hello(), dep2::hello()"#, &["dep1", "dep2"], ), - ).build(); + ) + .build(); p.cargo("build").run(); @@ -587,10 +625,12 @@ "#, url ), - ).file( + ) + .file( "src/foo.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -603,7 +643,8 @@ invalid url `{}`: relative URL without a base ", url - )).run(); + )) + .run(); } #[test] @@ -612,7 +653,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.0.0")) .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") - }).unwrap(); + }) + .unwrap(); let repo = git2::Repository::open(&bar.root()).unwrap(); let rev1 = repo.revparse_single("HEAD").unwrap().id(); @@ -645,7 +687,8 @@ bar.url(), rev1 ), - ).file( + ) + .file( "src/main.rs", r#" extern crate bar; @@ -656,7 +699,8 @@ assert_eq!(baz::baz(), 2); } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") @@ -676,13 +720,15 @@ bar.url(), rev2 ), - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; pub fn baz() -> i32 { bar::bar() } "#, - ).build(); + ) + .build(); foo.cargo("build -v").run(); assert!(foo.bin("foo").is_file()); @@ -695,7 +741,8 @@ project .file("Cargo.toml", &basic_lib_manifest("bar")) .file("src/bar.rs", "pub fn bar() {}") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -715,7 +762,8 @@ "#, git_project.url() ), - ).file("src/main.rs", &main_file(r#""{:?}", bar::bar()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{:?}", bar::bar()"#, &["bar"])) .build(); // First time around we should compile both foo and bar @@ -728,7 +776,8 @@ in [..]\n", git_project.url(), git_project.url(), - )).run(); + )) + .run(); // Don't recompile the second time p.cargo("build").with_stdout("").run(); @@ -745,12 +794,13 @@ .with_stderr(&format!( "[UPDATING] git repository `{}`", git_project.url() - )).run(); + )) + .run(); p.cargo("build").with_stdout("").run(); // Commit the changes and make sure we don't trigger a recompile because the - // lockfile says not to change + // lock file says not to change let repo = git2::Repository::open(&git_project.root()).unwrap(); git::add(&repo); git::commit(&repo); @@ -766,7 +816,8 @@ [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\ ", git_project.url() - )).run(); + )) + .run(); println!("going for the last compile"); p.cargo("build") .with_stderr(&format!( @@ -775,7 +826,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", git_project.url(), - )).run(); + )) + .run(); // Make sure clean only cleans one dep p.cargo("clean -p foo").with_stdout("").run(); @@ -783,8 +835,9 @@ .with_stderr( "[COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ - in [..]" - ).run(); + in [..]", + ) + .run(); } #[test] @@ -793,7 +846,8 @@ project .file("Cargo.toml", &basic_lib_manifest("bar")) .file("src/bar.rs", "pub fn bar() {}") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -809,7 +863,8 @@ [dependencies.dep2] path = "dep2" "#, - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -818,7 +873,8 @@ extern crate dep2; fn main() {} "#, - ).file( + ) + .file( "dep1/Cargo.toml", &format!( r#" @@ -833,7 +889,8 @@ "#, git_project.url() ), - ).file("dep1/src/lib.rs", "") + ) + .file("dep1/src/lib.rs", "") .file( "dep2/Cargo.toml", &format!( @@ -849,7 +906,8 @@ "#, git_project.url() ), - ).file("dep2/src/lib.rs", "") + ) + .file("dep2/src/lib.rs", "") .build(); // First time around we should compile both foo and bar @@ -863,7 +921,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", git = git_project.url(), - )).run(); + )) + .run(); // Modify a file manually, and commit it File::create(&git_project.root().join("src/bar.rs")) @@ -893,7 +952,8 @@ Caused by: revspec '0.1.2' not found; [..] ", - ).run(); + ) + .run(); // Specifying a precise rev to the old rev shouldn't actually update // anything because we already have the rev in the db. @@ -911,7 +971,8 @@ [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\ ", git_project.url() - )).run(); + )) + .run(); // Make sure we still only compile one version of the git repo println!("build"); @@ -924,14 +985,16 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", git = git_project.url(), - )).run(); + )) + .run(); // We should be able to update transitive deps p.cargo("update -p bar") .with_stderr(&format!( "[UPDATING] git repository `{}`", git_project.url() - )).run(); + )) + .run(); } #[test] @@ -939,7 +1002,8 @@ let project = project(); let git_project = git::new("dep1", |project| { project.file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) - }).unwrap(); + }) + .unwrap(); let git_project2 = git::new("dep2", |project| project.file("lib.rs", "pub fn dep() {}")).unwrap(); @@ -965,10 +1029,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate dep1; pub fn foo() { dep1::dep() }", - ).build(); + ) + .build(); project .cargo("build") @@ -978,7 +1044,8 @@ [COMPILING] dep1 [..] [COMPILING] foo [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -986,7 +1053,8 @@ let project = project(); let git_project = git::new("dep1", |project| { project.file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) - }).unwrap(); + }) + .unwrap(); let git_project2 = git::new("dep2", |project| project.file("lib.rs", "pub fn dep() {}")).unwrap(); @@ -1008,7 +1076,8 @@ None, Some("something something"), None, - ).unwrap(); + ) + .unwrap(); let p = project .file( @@ -1027,10 +1096,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate dep1; pub fn foo() { dep1::dep() }", - ).build(); + ) + .build(); let expected = format!( "\ @@ -1062,12 +1133,14 @@ project .file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let git2 = git::new("dep2", |project| { project .file("Cargo.toml", &basic_manifest("dep2", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project .file( @@ -1088,7 +1161,8 @@ git1.url(), git2.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); fn oid_to_short_sha(oid: git2::Oid) -> String { @@ -1111,7 +1185,8 @@ [COMPILING] [..] v0.5.0 ([..])\n\ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", - ).run(); + ) + .run(); File::create(&git1.root().join("src/lib.rs")) .unwrap() @@ -1128,7 +1203,8 @@ [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\ ", git1.url() - )).run(); + )) + .run(); } #[test] @@ -1137,7 +1213,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.0.0")) .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") - }).unwrap(); + }) + .unwrap(); // Update the git database in the cache with the current state of the git // repo @@ -1156,19 +1233,21 @@ "#, bar.url() ), - ).file( + ) + .file( "src/main.rs", r#" extern crate bar; fn main() { assert_eq!(bar::bar(), 1) } "#, - ).build(); + ) + .build(); foo.cargo("build").run(); foo.process(&foo.bin("foo")).run(); - // Update the repo, and simulate someone else updating the lockfile and then + // Update the repo, and simulate someone else updating the lock file and then // us pulling it down. File::create(&bar.root().join("src/lib.rs")) .unwrap() @@ -1201,8 +1280,10 @@ "#, url = bar.url(), hash = rev - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); // Now build! foo.cargo("build") @@ -1214,7 +1295,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", bar = bar.url(), - )).run(); + )) + .run(); foo.process(&foo.bin("foo")).run(); } @@ -1223,15 +1305,18 @@ let project = project(); let git_project = git::new("dep1", |project| { project.file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) - }).unwrap(); + }) + .unwrap(); let git_project2 = git::new("dep2", |project| { project.file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }") - }).unwrap(); + }) + .unwrap(); let git_project3 = git::new("dep3", |project| { project.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }") - }).unwrap(); + }) + .unwrap(); let repo = git2::Repository::open(&git_project.root()).unwrap(); let mut sub = git::add_submodule(&repo, &git_project2.url().to_string(), Path::new("src")); @@ -1251,13 +1336,15 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", " extern crate dep1; pub fn main() { println!(\"{}\", dep1::dep()) } ", - ).build(); + ) + .build(); println!("first run"); p.cargo("run") @@ -1268,7 +1355,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in \ [..]\n\ [RUNNING] `target/debug/foo[EXE]`\n", - ).with_stdout("project2\n") + ) + .with_stdout("project2\n") .run(); File::create(&git_project.root().join(".gitmodules")) @@ -1277,8 +1365,10 @@ format!( "[submodule \"src\"]\n\tpath = src\n\turl={}", git_project3.url() - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); // Sync the submodule and reset it to the new remote. sub.sync().unwrap(); @@ -1310,7 +1400,8 @@ [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\ ", git_project.url() - )).run(); + )) + .run(); println!("last run"); p.cargo("run") @@ -1320,7 +1411,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in \ [..]\n\ [RUNNING] `target/debug/foo[EXE]`\n", - ).with_stdout("project3\n") + ) + .with_stdout("project3\n") .run(); } @@ -1335,7 +1427,8 @@ pub fn gimme() -> &'static str { "zoidberg" } "#, ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1354,7 +1447,8 @@ "#, p2.url() ), - ).file( + ) + .file( "src/main.rs", r#" fn main() {} @@ -1365,10 +1459,11 @@ #[test] fn foo() { bar::gimme(); } } "#, - ).build(); + ) + .build(); - // Generate a lockfile which did not use `bar` to compile, but had to update - // `bar` to generate the lockfile + // Generate a lock file which did not use `bar` to compile, but had to update + // `bar` to generate the lock file p.cargo("build") .with_stderr(&format!( "\ @@ -1377,7 +1472,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", bar = p2.url() - )).run(); + )) + .run(); // Make sure we use the previous resolution of `bar` instead of updating it // a second time. @@ -1388,7 +1484,8 @@ [COMPILING] [..] v0.5.0 ([..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test tests::foo ... ok") + ) + .with_stdout_contains("test tests::foo ... ok") .run(); } @@ -1405,10 +1502,12 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") .file(".gitignore", "src/bar.rs") - }).unwrap(); + }) + .unwrap(); foo.root().move_into_the_past(); sleep_ms(1000); @@ -1419,7 +1518,8 @@ [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // Smoke test to make sure it doesn't compile again println!("first pass"); @@ -1442,7 +1542,8 @@ pub fn gimme() -> &'static str { "zoidberg" } "#, ) - }).unwrap(); + }) + .unwrap(); let repo = git2::Repository::open(&p2.root()).unwrap(); let mut cfg = repo.config().unwrap(); @@ -1464,11 +1565,12 @@ "#, p2.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - // Generate a lockfile which did not use `bar` to compile, but had to update - // `bar` to generate the lockfile + // Generate a lock file which did not use `bar` to compile, but had to update + // `bar` to generate the lock file p.cargo("build") .with_stderr(&format!( "\ @@ -1477,7 +1579,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", bar = p2.url() - )).run(); + )) + .run(); } #[test] @@ -1486,7 +1589,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") - }).unwrap(); + }) + .unwrap(); // Lock p1 to the first rev in the git repo let p1 = project() @@ -1505,7 +1609,8 @@ "#, bar.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("build.rs", "fn main() {}") .build(); p1.root().move_into_the_past(); @@ -1518,7 +1623,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", bar = bar.url() - )).run(); + )) + .run(); // Make a commit to lock p2 to a different rev File::create(&bar.root().join("src/lib.rs")) @@ -1545,7 +1651,8 @@ "#, bar.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p2.cargo("build") .with_stderr(&format!( @@ -1556,7 +1663,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", bar = bar.url() - )).run(); + )) + .run(); // And now for the real test! Make sure that p1 doesn't get rebuilt // even though the git repo has changed. @@ -1585,7 +1693,8 @@ name = "foo" "#, - ).file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -1600,12 +1709,14 @@ name = "bar" path = "src/bar.rs" "#, - ).file( + ) + .file( "bar/src/bar.rs.in", r#" pub fn gimme() -> i32 { 0 } "#, - ).file( + ) + .file( "bar/build.rs", r#" use std::fs; @@ -1614,7 +1725,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); p.root().join("bar").move_into_the_past(); @@ -1639,7 +1751,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "pub fn bar() -> i32 { 1 }") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1655,13 +1768,15 @@ "#, bar.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("fetch") .with_stderr(&format!( "[UPDATING] git repository `{url}`", url = bar.url() - )).run(); + )) + .run(); p.cargo("fetch").with_stdout("").run(); } @@ -1672,7 +1787,8 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "fn unused() {}") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1688,7 +1804,8 @@ "#, bar.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build") @@ -1699,7 +1816,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n", bar.url(), bar.url(), - )).run(); + )) + .run(); } #[test] @@ -1708,12 +1826,14 @@ project .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let bar2 = git::new("bar2", |project| { project .file("Cargo.toml", &basic_manifest("bar", "0.6.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let baz = git::new("baz", |project| { project .file( @@ -1730,8 +1850,10 @@ "#, bar2.url() ), - ).file("src/lib.rs", "") - }).unwrap(); + ) + .file("src/lib.rs", "") + }) + .unwrap(); let p = project() .file( @@ -1750,7 +1872,8 @@ bar1.url(), baz.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("generate-lockfile").run(); @@ -1765,7 +1888,8 @@ bar:0.[..].0 bar:0.[..].0 ", - ).run(); + ) + .run(); } #[test] @@ -1776,7 +1900,8 @@ .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) .file("a/src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1795,7 +1920,8 @@ bar.url(), bar.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("generate-lockfile").run(); @@ -1810,7 +1936,8 @@ project .file("Cargo.toml", &basic_manifest("transitive", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let dep1 = git::new("dep1", |project| { project .file( @@ -1827,8 +1954,10 @@ "#, transitive.url() ), - ).file("src/lib.rs", "") - }).unwrap(); + ) + .file("src/lib.rs", "") + }) + .unwrap(); let dep2 = git::new("dep2", |project| { project .file( @@ -1845,8 +1974,10 @@ "#, transitive.url() ), - ).file("src/lib.rs", "") - }).unwrap(); + ) + .file("src/lib.rs", "") + }) + .unwrap(); let p = project() .file( @@ -1862,7 +1993,8 @@ "#, dep1.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build") @@ -1877,7 +2009,8 @@ ", dep1.url(), transitive.url() - )).run(); + )) + .run(); // Update the dependency to point to the second repository, but this // shouldn't update the transitive dependency which is the same. @@ -1894,8 +2027,10 @@ git = '{}' "#, dep2.url() - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build") .with_stderr(&format!( @@ -1906,7 +2041,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", dep2.url() - )).run(); + )) + .run(); } #[test] @@ -1924,10 +2060,12 @@ [dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) .file("a/src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1943,7 +2081,8 @@ "#, dep.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -1979,12 +2118,14 @@ project .file("Cargo.toml", &basic_manifest("a", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let a2 = git::new("a2", |project| { project .file("Cargo.toml", &basic_manifest("a", "0.5.1")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -1997,7 +2138,8 @@ [dependencies.b] path = "b" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "b/Cargo.toml", &format!( @@ -2011,7 +2153,8 @@ "#, a1.url() ), - ).file("b/src/lib.rs", "pub fn main() {}") + ) + .file("b/src/lib.rs", "pub fn main() {}") .build(); p.cargo("build") @@ -2023,7 +2166,8 @@ [COMPILING] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); File::create(&p.root().join("b/Cargo.toml")) .unwrap() @@ -2038,8 +2182,10 @@ git = '{}' "#, a2.url() - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build") .with_stderr( @@ -2050,7 +2196,8 @@ [COMPILING] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2066,10 +2213,12 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "") .file("a/foo", "") - }).unwrap(); + }) + .unwrap(); let git2 = git::new("dep2", |p| p).unwrap(); let repo = git2::Repository::open(&git1.root()).unwrap(); @@ -2090,7 +2239,8 @@ let a2 = git::new("a2", |p| { p.file("Cargo.toml", &basic_manifest("a", "0.5.0")) .file("src/lib.rs", "pub fn a2() {}") - }).unwrap(); + }) + .unwrap(); let a1 = git::new("a1", |p| { p.file( @@ -2106,8 +2256,10 @@ "#, a2.url() ), - ).file("src/lib.rs", "extern crate a; pub fn a1() {}") - }).unwrap(); + ) + .file("src/lib.rs", "extern crate a; pub fn a1() {}") + }) + .unwrap(); let p = project() .file( @@ -2124,13 +2276,15 @@ "#, a1.url() ), - ).file( + ) + .file( "src/lib.rs", r#" #[macro_use] extern crate a; "#, - ).build(); + ) + .build(); p.cargo("test -v").run(); } @@ -2144,7 +2298,8 @@ use std::option; ", ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -2161,7 +2316,8 @@ "#, a.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -2172,7 +2328,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2185,7 +2342,8 @@ use std::option; ", ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -2202,7 +2360,8 @@ "#, a.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -2213,7 +2372,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2221,7 +2381,8 @@ let git = git::new("git", |p| { p.file("Cargo.toml", &basic_manifest("git", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -2239,7 +2400,8 @@ "#, git.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -2260,8 +2422,10 @@ git = {{ git = '{}' }} "#, git.url() - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build").run(); } @@ -2273,7 +2437,8 @@ .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("git2", "0.5.0")) .file("a/src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); // Make a tag corresponding to the current HEAD let repo = git2::Repository::open(&git.root()).unwrap(); @@ -2284,7 +2449,8 @@ &repo.signature().unwrap(), "make a new tag", false, - ).unwrap(); + ) + .unwrap(); let p = project() .file( @@ -2302,7 +2468,8 @@ "#, git.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("generate-lockfile").run(); @@ -2326,7 +2493,8 @@ [build-dependencies] filetime = "0.1" "#, - ).file( + ) + .file( ".gitignore", r#" target @@ -2335,7 +2503,8 @@ src/incl.rs src/not_incl.rs "#, - ).file( + ) + .file( "tango-build.rs", r#" extern crate filetime; @@ -2359,14 +2528,16 @@ } } "#, - ).file("src/lib.rs", "mod not_incl; mod incl;") + ) + .file("src/lib.rs", "mod not_incl; mod incl;") .file( "src/mod.md", r#" (The content of this file does not matter since we are not doing real codegen.) "#, ) - }).unwrap(); + }) + .unwrap(); println!("build 1: all is new"); p.cargo("build -v") @@ -2385,7 +2556,8 @@ [RUNNING] `rustc --crate-name reduction src/lib.rs --crate-type lib [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); println!("build 2: nothing changed; file timestamps reset by build script"); p.cargo("build -v") @@ -2396,9 +2568,10 @@ [FRESH] reduction [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); - println!("build 3: touch `src/not_incl.rs`; expect build script *not* re-run"); + println!("build 3: touch `src/not_incl.rs`; expect build script **not** re-run"); sleep_ms(1000); File::create(p.root().join("src").join("not_incl.rs")).unwrap(); @@ -2411,7 +2584,8 @@ [RUNNING] `rustc --crate-name reduction src/lib.rs --crate-type lib [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // This final case models the bug from rust-lang/cargo#4135: an // explicitly included file should cause a build-script re-run, @@ -2430,7 +2604,8 @@ [RUNNING] `rustc --crate-name reduction src/lib.rs --crate-type lib [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2453,7 +2628,8 @@ name = "dep1" "#, - ).file( + ) + .file( "src/dep1.rs", r#" pub fn hello() -> &'static str { @@ -2461,7 +2637,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); let project = project .file( @@ -2480,10 +2657,12 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/main.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]), - ).build(); + ) + .build(); let git_root = git_project.root(); @@ -2507,7 +2686,8 @@ duplicate key: `categories` for key `project`", path2url(&git_root), path2url(&git_root), - )).run(); + )) + .run(); } #[test] @@ -2515,7 +2695,8 @@ let project = project(); let git_project = git::new("dep1", |project| { project.file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) - }).unwrap(); + }) + .unwrap(); let git_project2 = git::new("dep2", |project| project.file("lib.rs", "")).unwrap(); @@ -2567,7 +2748,8 @@ "#, git_project.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); project @@ -2601,7 +2783,8 @@ project .file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let project = project .file( @@ -2618,14 +2801,16 @@ "#, git_project.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", " [net] git-fetch-with-cli = true ", - ).build(); + ) + .build(); let stderr = "\ [UPDATING] git repository `[..]` @@ -2646,16 +2831,19 @@ project .file("Cargo.toml", &basic_manifest("dep2", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let git_project = git::new("dep1", |project| { project .file("Cargo.toml", &basic_manifest("dep1", "0.5.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( "Cargo.toml", - &format!(r#" + &format!( + r#" [project] name = "fo" version = "0.5.0" @@ -2663,24 +2851,32 @@ [dependencies] dep1 = {{ git = '{}' }} - "#, git_project.url()), - ).file("src/main.rs", "fn main() {}") + "#, + git_project.url() + ), + ) + .file("src/main.rs", "fn main() {}") .build(); File::create(paths::home().join(".gitconfig")) .unwrap() .write_all( - &format!(r#" + &format!( + r#" [init] templatedir = {} - "#, git_project2.url() - .to_file_path() - .unwrap() - .to_str() - .unwrap() - .replace("\\", "/") - ).as_bytes(), - ).unwrap(); + "#, + git_project2 + .url() + .to_file_path() + .unwrap() + .to_str() + .unwrap() + .replace("\\", "/") + ) + .as_bytes(), + ) + .unwrap(); p.cargo("build").run(); } diff -Nru cargo-0.33.0/tests/testsuite/init.rs cargo-0.35.0/tests/testsuite/init.rs --- cargo-0.33.0/tests/testsuite/init.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/init.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ +use crate::support; use std::env; use std::fs::{self, File}; use std::io::prelude::*; -use support; -use support::{paths, Execs}; +use crate::support::{paths, Execs}; fn cargo_process(s: &str) -> Execs { let mut execs = support::cargo_process(s); @@ -39,11 +39,50 @@ assert!(paths::root().join("foo/src/main.rs").is_file()); cargo_process("build").cwd(&path).run(); - assert!( - paths::root() - .join(&format!("foo/target/debug/foo{}", env::consts::EXE_SUFFIX)) - .is_file() + assert!(paths::root() + .join(&format!("foo/target/debug/foo{}", env::consts::EXE_SUFFIX)) + .is_file()); +} + +#[test] +fn simple_git_ignore_exists() { + // write a .gitignore file with one entry + fs::create_dir_all(paths::root().join("foo")).unwrap(); + let mut ignore_file = File::create(paths::root().join("foo/.gitignore")).unwrap(); + ignore_file + .write("/target\n**/some.file".as_bytes()) + .unwrap(); + + cargo_process("init --lib foo --edition 2015") + .env("USER", "foo") + .run(); + + assert!(paths::root().is_dir()); + assert!(paths::root().join("foo/Cargo.toml").is_file()); + assert!(paths::root().join("foo/src/lib.rs").is_file()); + assert!(paths::root().join("foo/.git").is_dir()); + assert!(paths::root().join("foo/.gitignore").is_file()); + + let fp = paths::root().join("foo/.gitignore"); + let mut contents = String::new(); + File::open(&fp) + .unwrap() + .read_to_string(&mut contents) + .unwrap(); + assert_eq!( + contents, + "/target\n\ + **/some.file\n\n\ + #Added by cargo\n\ + #\n\ + #already existing elements are commented out\n\ + \n\ + #/target\n\ + **/*.rs.bk\n\ + Cargo.lock", ); + + cargo_process("build").cwd(&paths::root().join("foo")).run(); } #[test] @@ -183,7 +222,8 @@ foo.rs cannot automatically generate Cargo.toml as the main target would be ambiguous ", - ).run(); + ) + .run(); assert!(!paths::root().join("foo/Cargo.toml").is_file()); } @@ -265,7 +305,8 @@ [ERROR] Invalid character `.` in crate name: `foo.bar` use --name to override crate name ", - ).run(); + ) + .run(); assert!(!foo.join("Cargo.toml").is_file()); } @@ -283,7 +324,8 @@ [ERROR] The name `test` cannot be used as a crate name\n\ use --name to override crate name ", - ).run(); + ) + .run(); assert!(!test.join("Cargo.toml").is_file()); } @@ -502,7 +544,8 @@ .with_status(1) .with_stderr_contains( "error: Found argument '--flag' which wasn't expected, or isn't valid in this context", - ).run(); + ) + .run(); } #[cfg(not(windows))] @@ -513,5 +556,6 @@ .with_stderr( "[ERROR] cannot auto-detect package name from path \"/\" ; use --name to override" .to_string(), - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/install.rs cargo-0.35.0/tests/testsuite/install.rs --- cargo-0.33.0/tests/testsuite/install.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/install.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,14 +1,15 @@ use std::fs::{self, File, OpenOptions}; use std::io::prelude::*; -use support; use git2; -use support::cross_compile; -use support::git; -use support::install::{assert_has_installed_exe, assert_has_not_installed_exe, cargo_home}; -use support::paths; -use support::registry::Package; -use support::{basic_manifest, cargo_process, project}; + +use crate::support; +use crate::support::cross_compile; +use crate::support::git; +use crate::support::install::{assert_has_installed_exe, assert_has_not_installed_exe, cargo_home}; +use crate::support::paths; +use crate::support::registry::Package; +use crate::support::{basic_manifest, cargo_process, project}; fn pkg(name: &str, vers: &str) { Package::new(name, vers) @@ -16,7 +17,8 @@ .file( "src/main.rs", &format!("extern crate {}; fn main() {{}}", name), - ).publish(); + ) + .publish(); } #[test] @@ -35,7 +37,8 @@ [INSTALLING] [CWD]/home/.cargo/bin/foo[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); assert_has_installed_exe(cargo_home(), "foo"); cargo_process("uninstall foo") @@ -71,7 +74,8 @@ warning: be sure to add `[..]` to your PATH to be able to run the installed binaries error: some crates failed to install ", - ).run(); + ) + .run(); assert_has_installed_exe(cargo_home(), "foo"); assert_has_installed_exe(cargo_home(), "bar"); @@ -82,7 +86,8 @@ [REMOVING] [CWD]/home/.cargo/bin/bar[EXE] [SUMMARY] Successfully uninstalled foo, bar! ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); assert_has_not_installed_exe(cargo_home(), "bar"); @@ -108,7 +113,8 @@ [INSTALLING] [CWD]/home/.cargo/bin/foo[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); assert_has_installed_exe(cargo_home(), "foo"); } @@ -136,7 +142,8 @@ [UPDATING] [..] index [ERROR] could not find `bar` in registry `[..]` ", - ).run(); + ) + .run(); } #[test] @@ -149,24 +156,33 @@ [UPDATING] [..] index [ERROR] could not find `foo` in registry `[..]` with version `=0.2.0` ", - ).run(); + ) + .run(); } #[test] -fn no_crate() { +fn bad_paths() { cargo_process("install") .with_status(101) - .with_stderr( - "\ -[ERROR] `[..]` is not a crate root; specify a crate to install [..] + .with_stderr("[ERROR] `[CWD]` is not a crate root; specify a crate to install [..]") + .run(); -Caused by: - failed to read `[..]Cargo.toml` + cargo_process("install --path .") + .with_status(101) + .with_stderr("[ERROR] `[CWD]` does not contain a Cargo.toml file[..]") + .run(); -Caused by: - [..] (os error [..]) -", - ).run(); + let toml = paths::root().join("Cargo.toml"); + fs::write(toml, "").unwrap(); + cargo_process("install --path Cargo.toml") + .with_status(101) + .with_stderr("[ERROR] `[CWD]/Cargo.toml` is not a directory[..]") + .run(); + + cargo_process("install --path .") + .with_status(101) + .with_stderr_contains("[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`") + .run(); } #[test] @@ -189,8 +205,10 @@ root = '{}' ", t3.display() - ).as_bytes(), - ).unwrap(); + ) + .as_bytes(), + ) + .unwrap(); println!("install --root"); @@ -237,7 +255,8 @@ [ERROR] binary `foo[..]` already exists in destination as part of `foo v0.0.1 [..]` Add --force to overwrite ", - ).run(); + ) + .run(); } #[test] @@ -257,7 +276,8 @@ [UPDATING] git repository [..] [ERROR] multiple packages with binaries found: bar, foo ", - ).run(); + ) + .run(); } #[test] @@ -286,14 +306,23 @@ #[test] fn multiple_crates_git_all() { let p = git::repo(&paths::root().join("foo")) - .file("Cargo.toml", r#"\ + .file( + "Cargo.toml", + r#"\ [workspace] members = ["bin1", "bin2"] -"#) +"#, + ) .file("bin1/Cargo.toml", &basic_manifest("bin1", "0.1.0")) .file("bin2/Cargo.toml", &basic_manifest("bin2", "0.1.0")) - .file("bin1/src/main.rs", r#"fn main() { println!("Hello, world!"); }"#) - .file("bin2/src/main.rs", r#"fn main() { println!("Hello, world!"); }"#) + .file( + "bin1/src/main.rs", + r#"fn main() { println!("Hello, world!"); }"#, + ) + .file( + "bin2/src/main.rs", + r#"fn main() { println!("Hello, world!"); }"#, + ) .build(); cargo_process(&format!("install --git {} bin1 bin2", p.url().to_string())).run(); @@ -313,7 +342,8 @@ [dependencies] bar = { path = "a" } "#, - ).file("src/main.rs", "extern crate bar; fn main() {}") + ) + .file("src/main.rs", "extern crate bar; fn main() {}") .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("a/src/lib.rs", "") .build(); @@ -336,7 +366,8 @@ [dependencies] bar = { path = "a" } "#, - ).file("src/lib.rs", "extern crate bar;") + ) + .file("src/lib.rs", "extern crate bar;") .file( "examples/foo.rs", " @@ -344,7 +375,8 @@ extern crate foo; fn main() {} ", - ).file("a/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("a/src/lib.rs", "") .build(); @@ -369,7 +401,8 @@ [dependencies] bar = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("a/src/lib.rs", "") .build(); @@ -397,7 +430,8 @@ [INSTALLING] foo [..] [ERROR] specified package has no binaries ", - ).run(); + ) + .run(); } #[test] @@ -432,7 +466,8 @@ binary `foo-bin2[..]` already exists in destination as part of `foo v0.0.1 ([..])` Add --force to overwrite ", - ).run(); + ) + .run(); } #[test] @@ -457,7 +492,8 @@ [REPLACING] [CWD]/home/.cargo/bin/foo[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); cargo_process("install --list") .with_stdout( @@ -465,7 +501,8 @@ foo v0.2.0 ([..]): foo[..] ", - ).run(); + ) + .run(); } #[test] @@ -495,7 +532,8 @@ [REPLACING] [CWD]/home/.cargo/bin/foo-bin2[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); cargo_process("install --list") .with_stdout( @@ -506,7 +544,8 @@ foo-bin2[..] foo-bin3[..] ", - ).run(); + ) + .run(); } #[test] @@ -535,7 +574,8 @@ [REPLACING] [CWD]/home/.cargo/bin/foo-bin2[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); cargo_process("install --list") .with_stdout( @@ -545,7 +585,8 @@ foo v0.2.0 ([..]): foo-bin2[..] ", - ).run(); + ) + .run(); } #[test] @@ -565,7 +606,8 @@ To learn more, run the command again with --verbose. ", - ).run(); + ) + .run(); } #[test] @@ -575,7 +617,7 @@ .file("src/main.rs", "fn main() {}") .build(); - // use `--locked` to test that we don't even try to write a lockfile + // Use `--locked` to test that we don't even try to write a lock file. cargo_process("install --locked --git") .arg(p.url().to_string()) .with_stderr( @@ -587,7 +629,8 @@ [INSTALLING] [CWD]/home/.cargo/bin/foo[EXE] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); assert_has_installed_exe(cargo_home(), "foo"); assert_has_installed_exe(cargo_home(), "foo"); } @@ -610,7 +653,8 @@ foo v0.0.1: foo[..] ", - ).run(); + ) + .run(); } #[test] @@ -623,7 +667,8 @@ foo v0.0.1: foo[..] ", - ).run(); + ) + .run(); let mut worldfile_path = cargo_home(); worldfile_path.push(".crates.toml"); let mut worldfile = OpenOptions::new() @@ -644,14 +689,15 @@ Caused by: unexpected character[..] ", - ).run(); + ) + .run(); } #[test] fn uninstall_pkg_does_not_exist() { cargo_process("uninstall foo") .with_status(101) - .with_stderr("[ERROR] package id specification `foo` matched no packages") + .with_stderr("[ERROR] package ID specification `foo` matched no packages") .run(); } @@ -691,7 +737,7 @@ cargo_process("uninstall foo") .with_status(101) - .with_stderr("[ERROR] package id specification `foo` matched no packages") + .with_stderr("[ERROR] package ID specification `foo` matched no packages") .run(); } @@ -717,14 +763,15 @@ package in current working directory is deprecated, \ use `cargo install --path .` instead. \ Use `cargo build` if you want to simply build the package.", - ).run(); + ) + .run(); assert_has_installed_exe(cargo_home(), "foo"); } #[test] fn installs_from_cwd_with_2018_warnings() { if !support::is_nightly() { - // Stable rust won't have the edition option. Remove this once it + // Stable rust won't have the edition option. Remove this once it // is stabilized. return; } @@ -740,7 +787,8 @@ authors = [] edition = "2018" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("install") @@ -751,7 +799,8 @@ package in current working directory is no longer supported, \ use `cargo install --path .` instead. \ Use `cargo build` if you want to simply build the package.", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); } @@ -767,7 +816,8 @@ [INSTALLING] {home}/bin/foo[EXE] warning: be sure to add `{home}/bin` to your PATH to be able to run the installed binaries", home = cargo_home().display(), - )).run(); + )) + .run(); assert_has_installed_exe(cargo_home(), "foo"); p.cargo("uninstall") @@ -776,7 +826,8 @@ "\ [REMOVING] {home}/bin/foo[EXE]", home = cargo_home().display() - )).run(); + )) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); } @@ -789,7 +840,8 @@ .with_stderr( "\ error: package `foo v0.0.1 ([CWD])` is not installed", - ).run(); + ) + .run(); } #[test] @@ -809,7 +861,8 @@ Caused by: {err_msg} (os error 2)", err_msg = err_msg, - )).run(); + )) + .run(); } #[test] @@ -825,7 +878,8 @@ [INSTALLING] [..] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); assert!(p.build_dir().exists()); assert!(p.release_bin("foo").exists()); @@ -861,7 +915,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "fn main() {}") .file( @@ -876,7 +931,8 @@ name = "bar" version = "0.1.0" "#, - ).build(); + ) + .build(); cargo_process("install --git") .arg(p.url().to_string()) @@ -923,7 +979,8 @@ [workspace] members = ["baz"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "baz/Cargo.toml", r#" @@ -935,7 +992,8 @@ [dependencies] foo = "1" "#, - ).file("baz/src/lib.rs", "") + ) + .file("baz/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -960,10 +1018,14 @@ [dev-dependencies] baz = "1.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..] no matching package named `baz` found") + .run(); p.cargo("install").run(); } @@ -982,7 +1044,8 @@ [dev-dependencies] bar = { path = "a" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("a/src/lib.rs", "") .build(); @@ -1050,7 +1113,8 @@ error: The argument '--version ' was provided more than once, \ but cannot be used multiple times ", - ).run(); + ) + .run(); } #[test] @@ -1065,7 +1129,8 @@ historically Cargo treated this as a semver version requirement accidentally and will continue to do so, but this behavior will be removed eventually ", - ).run(); + ) + .run(); } #[test] @@ -1089,11 +1154,12 @@ .with_stderr( "\ [REMOVING] [CWD]/home/.cargo/bin/foo[EXE] -error: package id specification `bar` matched no packages +error: package ID specification `bar` matched no packages [SUMMARY] Successfully uninstalled foo! Failed to uninstall bar (see error(s) above). error: some packages failed to uninstall ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); assert_has_not_installed_exe(cargo_home(), "bar"); @@ -1130,7 +1196,8 @@ .file( "src/main.rs", "extern crate foo; extern crate bar; fn main() {}", - ).file( + ) + .file( "Cargo.lock", r#" [[package]] @@ -1145,7 +1212,8 @@ "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] "#, - ).publish(); + ) + .publish(); cargo_process("install foo").run(); } @@ -1160,7 +1228,8 @@ .file( "src/main.rs", "extern crate foo; extern crate bar; fn main() {}", - ).file( + ) + .file( "Cargo.lock", r#" [[package]] @@ -1174,7 +1243,8 @@ "bar 0.1.0", ] "#, - ).publish(); + ) + .publish(); cargo_process("install foo").run(); } @@ -1187,7 +1257,8 @@ .with_status(1) .with_stderr_contains( "[ERROR] The argument '...' requires a value but none was supplied", - ).run(); + ) + .run(); } #[test] @@ -1207,19 +1278,15 @@ path.push(".cargo/.crates.toml"); assert_ne!(old_rev, new_rev); - assert!( - fs::read_to_string(path.clone()) - .unwrap() - .contains(&format!("{}", old_rev)) - ); + assert!(fs::read_to_string(path.clone()) + .unwrap() + .contains(&format!("{}", old_rev))); cargo_process("install --force --git") .arg(p.url().to_string()) .run(); - assert!( - fs::read_to_string(path) - .unwrap() - .contains(&format!("{}", new_rev)) - ); + assert!(fs::read_to_string(path) + .unwrap() + .contains(&format!("{}", new_rev))); } #[test] @@ -1238,7 +1305,8 @@ [dependencies] bar = { path = 'bar' } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}") .build(); @@ -1252,7 +1320,8 @@ [INSTALLING] [..] warning: be sure to add `[..]` to your PATH to be able to run the installed binaries ", - ).run(); + ) + .run(); } #[test] @@ -1281,10 +1350,12 @@ let config = cargo_home().join("config"); let mut toml = fs::read_to_string(&config).unwrap_or(String::new()); - toml.push_str(r#" + toml.push_str( + r#" [build] target = 'nonexistent' - "#); + "#, + ); fs::write(&config, toml).unwrap(); cargo_process("install bar") diff -Nru cargo-0.33.0/tests/testsuite/jobserver.rs cargo-0.35.0/tests/testsuite/jobserver.rs --- cargo-0.33.0/tests/testsuite/jobserver.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/jobserver.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,7 +2,7 @@ use std::process::Command; use std::thread; -use support::{cargo_exe, project}; +use crate::support::{cargo_exe, project}; #[test] fn jobserver_exists() { @@ -45,7 +45,8 @@ // a little too complicated for a test... } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -76,7 +77,8 @@ d2 = { path = "d2" } d3 = { path = "d3" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "d1/Cargo.toml", r#" @@ -86,7 +88,8 @@ authors = [] build = "../dbuild.rs" "#, - ).file("d1/src/lib.rs", "") + ) + .file("d1/src/lib.rs", "") .file( "d2/Cargo.toml", r#" @@ -96,7 +99,8 @@ authors = [] build = "../dbuild.rs" "#, - ).file("d2/src/lib.rs", "") + ) + .file("d2/src/lib.rs", "") .file( "d3/Cargo.toml", r#" @@ -106,7 +110,8 @@ authors = [] build = "../dbuild.rs" "#, - ).file("d3/src/lib.rs", "") + ) + .file("d3/src/lib.rs", "") .file( "dbuild.rs", r#" @@ -121,13 +126,15 @@ stream.read_to_end(&mut v).unwrap(); } "#, - ).file( + ) + .file( "Makefile", "\ all: \t+$(CARGO) build ", - ).build(); + ) + .build(); let l = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = l.local_addr().unwrap(); @@ -176,7 +183,8 @@ all: \t+$(CARGO) build -j2 ", - ).build(); + ) + .build(); p.process(make) .env("CARGO", cargo_exe()) @@ -188,5 +196,6 @@ [COMPILING] [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/list_targets.rs cargo-0.35.0/tests/testsuite/list_targets.rs --- cargo-0.33.0/tests/testsuite/list_targets.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/list_targets.rs 2019-04-01 21:32:07.000000000 +0000 @@ -0,0 +1,189 @@ +use crate::support::project; + +const EXAMPLE: u8 = 0x1; +const BIN: u8 = 0x2; +const TEST: u8 = 0x4; +const BENCH: u8 = 0x8; + +fn list_targets_test(command: &str, targets: u8) { + let full_project = project() + .file("examples/a.rs", "fn main() { }") + .file("examples/b.rs", "fn main() { }") + .file("benches/bench1.rs", "") + .file("benches/bench2.rs", "") + .file("tests/test1.rs", "") + .file("tests/test2.rs", "") + .file("src/main.rs", "fn main() { }") + .build(); + + if targets & EXAMPLE != 0 { + full_project + .cargo(&format!("{} --example", command)) + .with_stderr( + "\ +error: \"--example\" takes one argument. +Available examples: + a + b + +", + ) + .with_status(101) + .run(); + } + + if targets & BIN != 0 { + full_project + .cargo(&format!("{} --bin", command)) + .with_stderr( + "\ +error: \"--bin\" takes one argument. +Available binaries: + foo + +", + ) + .with_status(101) + .run(); + } + + if targets & BENCH != 0 { + full_project + .cargo(&format!("{} --bench", command)) + .with_stderr( + "\ +error: \"--bench\" takes one argument. +Available benches: + bench1 + bench2 + +", + ) + .with_status(101) + .run(); + } + + if targets & TEST != 0 { + full_project + .cargo(&format!("{} --test", command)) + .with_stderr( + "\ +error: \"--test\" takes one argument. +Available tests: + test1 + test2 + +", + ) + .with_status(101) + .run(); + } + + let empty_project = project().file("src/lib.rs", "").build(); + + if targets & EXAMPLE != 0 { + empty_project + .cargo(&format!("{} --example", command)) + .with_stderr( + "\ +error: \"--example\" takes one argument. +No examples available. + +", + ) + .with_status(101) + .run(); + } + + if targets & BIN != 0 { + empty_project + .cargo(&format!("{} --bin", command)) + .with_stderr( + "\ +error: \"--bin\" takes one argument. +No binaries available. + +", + ) + .with_status(101) + .run(); + } + + if targets & BENCH != 0 { + empty_project + .cargo(&format!("{} --bench", command)) + .with_stderr( + "\ +error: \"--bench\" takes one argument. +No benches available. + +", + ) + .with_status(101) + .run(); + } + + if targets & TEST != 0 { + empty_project + .cargo(&format!("{} --test", command)) + .with_stderr( + "\ +error: \"--test\" takes one argument. +No tests available. + +", + ) + .with_status(101) + .run(); + } +} + +#[test] +fn build_list_targets() { + list_targets_test("build", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn check_list_targets() { + list_targets_test("check", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn doc_list_targets() { + list_targets_test("doc", BIN); +} + +#[test] +fn fix_list_targets() { + list_targets_test("fix", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn run_list_targets() { + list_targets_test("run", EXAMPLE | BIN); +} + +#[test] +fn test_list_targets() { + list_targets_test("test", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn bench_list_targets() { + list_targets_test("bench", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn install_list_targets() { + list_targets_test("install", EXAMPLE | BIN); +} + +#[test] +fn rustdoc_list_targets() { + list_targets_test("rustdoc", EXAMPLE | BIN | TEST | BENCH); +} + +#[test] +fn rustc_list_targets() { + list_targets_test("rustc", EXAMPLE | BIN | TEST | BENCH); +} diff -Nru cargo-0.33.0/tests/testsuite/local_registry.rs cargo-0.35.0/tests/testsuite/local_registry.rs --- cargo-0.33.0/tests/testsuite/local_registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/local_registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::paths::{self, CargoPathExt}; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::paths::{self, CargoPathExt}; +use crate::support::registry::{registry_path, Package}; +use crate::support::{basic_manifest, project}; fn setup() { let root = paths::root(); @@ -40,10 +40,12 @@ [dependencies] bar = "0.0.1" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -53,12 +55,52 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); p.cargo("test").run(); } #[test] +fn depend_on_yanked() { + setup(); + Package::new("bar", "0.0.1").local(true).publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.0.1" + "#, + ) + .file("src/lib.rs", "") + .build(); + + // Run cargo to create lock file. + p.cargo("check").run(); + + registry_path().join("index").join("3").rm_rf(); + Package::new("bar", "0.0.1") + .local(true) + .yanked(true) + .publish(); + + p.cargo("check") + .with_stderr( + "\ +[FINISHED] [..] +", + ) + .run(); +} + +#[test] fn multiple_versions() { setup(); Package::new("bar", "0.0.1").local(true).publish(); @@ -79,10 +121,12 @@ [dependencies] bar = "*" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -92,7 +136,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); Package::new("bar", "0.2.0") .local(true) @@ -129,7 +174,8 @@ bar = "*" baz = "*" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -139,7 +185,8 @@ baz::baz(); } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -151,7 +198,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -180,7 +228,8 @@ bar = "*" baz = "*" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -190,7 +239,8 @@ baz::baz(); } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -202,7 +252,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -226,7 +277,8 @@ [dependencies] bar = { path = "bar", version = "*" } "#, - ).file("src/lib.rs", "extern crate bar; pub fn baz() {}") + ) + .file("src/lib.rs", "extern crate bar; pub fn baz() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .publish(); @@ -244,7 +296,8 @@ bar = "*" baz = "*" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -254,7 +307,8 @@ baz::baz(); } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -266,7 +320,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -284,7 +339,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -295,7 +351,8 @@ [source.my-awesome-local-directory] local-registry = '/path/to/nowhere' "#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) @@ -312,7 +369,8 @@ Caused by: local registry path is not a directory: [..]path[..]to[..]nowhere ", - ).run(); + ) + .run(); } #[test] @@ -337,7 +395,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); // Generate a lock file against the crates.io registry @@ -363,13 +422,14 @@ this could be indicative of a few possible errors: * the lock file is corrupt - * a replacement source in use (e.g. a mirror) returned a different checksum + * a replacement source in use (e.g., a mirror) returned a different checksum * the source itself may be corrupt in one way or another unable to verify that `bar v0.0.1` is the same as when the lockfile was generated ", - ).run(); + ) + .run(); } #[test] @@ -403,10 +463,12 @@ [dependencies] bar = "0.0.1" "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -416,7 +478,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); p.cargo("test").run(); } diff -Nru cargo-0.33.0/tests/testsuite/lockfile_compat.rs cargo-0.35.0/tests/testsuite/lockfile_compat.rs --- cargo-0.33.0/tests/testsuite/lockfile_compat.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/lockfile_compat.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ -use support::git; -use support::registry::Package; -use support::{basic_manifest, lines_match, project}; +use crate::support::git; +use crate::support::registry::Package; +use crate::support::{basic_manifest, lines_match, project}; #[test] fn oldest_lockfile_still_works() { @@ -13,7 +13,9 @@ fn oldest_lockfile_still_works_with_command(cargo_command: &str) { Package::new("bar", "0.1.0").publish(); - let expected_lockfile = r#"[[package]] + let expected_lockfile = r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] name = "bar" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -29,7 +31,8 @@ "checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "[..]" "#; - let old_lockfile = r#"[root] + let old_lockfile = r#" +[root] name = "foo" version = "0.0.1" dependencies = [ @@ -54,7 +57,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("Cargo.lock", old_lockfile) .build(); @@ -103,7 +107,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("Cargo.lock", &old_lockfile) .build(); @@ -133,7 +138,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", r#" @@ -160,9 +166,10 @@ p.cargo("build").run(); let lock = p.read_lockfile(); - assert!( - lock.starts_with( - r#" + assert!(lock.starts_with( + r#" +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "bar" version = "0.1.0" @@ -176,9 +183,9 @@ ] [metadata] -"#.trim() - ) - ); +"# + .trim() + )); } #[test] @@ -197,7 +204,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", r#" @@ -230,17 +238,18 @@ this could be indicative of a few possible errors: * the lock file is corrupt - * a replacement source in use (e.g. a mirror) returned a different checksum + * a replacement source in use (e.g., a mirror) returned a different checksum * the source itself may be corrupt in one way or another unable to verify that `bar v0.1.0` is the same as when the lockfile was generated ", - ).run(); + ) + .run(); } -// If the checksum is unlisted in the lockfile (e.g. ) yet we can -// calculate it (e.g. it's a registry dep), then we should in theory just fill +// If the checksum is unlisted in the lock file (e.g., ) yet we can +// calculate it (e.g., it's a registry dep), then we should in theory just fill // it in. #[test] fn unlisted_checksum_is_bad_if_we_calculate() { @@ -258,7 +267,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", r#" @@ -297,17 +307,19 @@ * the lock file is corrupt ", - ).run(); + ) + .run(); } -// If the checksum is listed in the lockfile yet we cannot calculate it (e.g. -// git dependencies as of today), then make sure we choke. +// If the checksum is listed in the lock file yet we cannot calculate it (e.g., +// Git dependencies as of today), then make sure we choke. #[test] fn listed_checksum_bad_if_we_cannot_compute() { let git = git::new("bar", |p| { p.file("Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( @@ -324,7 +336,8 @@ "#, git.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "Cargo.lock", &format!( @@ -367,7 +380,8 @@ unable to verify that `bar v0.1.0 ([..])` is the same as when the lockfile was generated ", - ).run(); + ) + .run(); } #[test] @@ -386,7 +400,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", ""); + ) + .file("src/lib.rs", ""); let p = p.build(); p.cargo("build").run(); @@ -394,6 +409,7 @@ let actual = p.read_lockfile(); let expected = "\ +# This file is automatically @generated by Cargo.\n# It is not intended for manual editing. [[package]] name = \"bar\" version = \"0.1.0\" @@ -420,7 +436,10 @@ fn lockfile_without_root() { Package::new("bar", "0.1.0").publish(); - let lockfile = r#"[[package]] + let lockfile = r#" +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] name = "bar" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -445,7 +464,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("Cargo.lock", lockfile); let p = p.build(); @@ -472,7 +492,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", ""); + ) + .file("src/lib.rs", ""); let p = p.build(); p.cargo("build --locked") @@ -482,5 +503,6 @@ [UPDATING] `[..]` index error: the lock file [CWD]/Cargo.lock needs to be updated but --locked was passed to prevent this ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/login.rs cargo-0.35.0/tests/testsuite/login.rs --- cargo-0.33.0/tests/testsuite/login.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/login.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,28 +1,15 @@ use std::fs::{self, File}; use std::io::prelude::*; +use crate::support::cargo_process; +use crate::support::install::cargo_home; +use crate::support::registry::{self, registry_url}; use cargo::core::Shell; use cargo::util::config::Config; -use support::cargo_process; -use support::install::cargo_home; -use support::registry::registry; use toml; const TOKEN: &str = "test-token"; const ORIGINAL_TOKEN: &str = "api-token"; -const CONFIG_FILE: &str = r#" - [registry] - token = "api-token" - - [registries.test-reg] - index = "http://dummy_index/" -"#; - -fn setup_old_credentials() { - let config = cargo_home().join("config"); - t!(fs::create_dir_all(config.parent().unwrap())); - t!(t!(File::create(&config)).write_all(CONFIG_FILE.as_bytes())); -} fn setup_new_credentials() { let config = cargo_home().join("credentials"); @@ -72,39 +59,27 @@ #[test] fn login_with_old_credentials() { - setup_old_credentials(); + registry::init(); cargo_process("login --host") - .arg(registry().to_string()) + .arg(registry_url().to_string()) .arg(TOKEN) .run(); - let config = cargo_home().join("config"); - assert!(config.is_file()); - - let mut contents = String::new(); - File::open(&config) - .unwrap() - .read_to_string(&mut contents) - .unwrap(); - assert_eq!(CONFIG_FILE, contents); - // Ensure that we get the new token for the registry assert!(check_token(TOKEN, None)); } #[test] fn login_with_new_credentials() { + registry::init(); setup_new_credentials(); cargo_process("login --host") - .arg(registry().to_string()) + .arg(registry_url().to_string()) .arg(TOKEN) .run(); - let config = cargo_home().join("config"); - assert!(!config.is_file()); - // Ensure that we get the new token for the registry assert!(check_token(TOKEN, None)); } @@ -117,25 +92,23 @@ #[test] fn login_without_credentials() { + registry::init(); cargo_process("login --host") - .arg(registry().to_string()) + .arg(registry_url().to_string()) .arg(TOKEN) .run(); - let config = cargo_home().join("config"); - assert!(!config.is_file()); - // Ensure that we get the new token for the registry assert!(check_token(TOKEN, None)); } #[test] fn new_credentials_is_used_instead_old() { - setup_old_credentials(); + registry::init(); setup_new_credentials(); cargo_process("login --host") - .arg(registry().to_string()) + .arg(registry_url().to_string()) .arg(TOKEN) .run(); @@ -147,10 +120,10 @@ #[test] fn registry_credentials() { - setup_old_credentials(); + registry::init(); setup_new_credentials(); - let reg = "test-reg"; + let reg = "alternative"; cargo_process("login --registry") .arg(reg) diff -Nru cargo-0.33.0/tests/testsuite/main.rs cargo-0.35.0/tests/testsuite/main.rs --- cargo-0.33.0/tests/testsuite/main.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/main.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,28 +1,7 @@ -#![deny(warnings)] -#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))] -#![cfg_attr(feature = "cargo-clippy", allow(explicit_iter_loop))] - -extern crate bufstream; -extern crate cargo; -extern crate filetime; -extern crate flate2; -extern crate git2; -extern crate glob; -extern crate hex; -#[macro_use] -extern crate lazy_static; -extern crate libc; -#[macro_use] -extern crate proptest; -#[macro_use] -extern crate serde_derive; -#[macro_use] -extern crate serde_json; -extern crate tar; -extern crate toml; -extern crate url; -#[cfg(windows)] -extern crate winapi; +#![warn(rust_2018_idioms)] // while we're getting used to 2018 +#![cfg_attr(feature = "deny-warnings", deny(warnings))] +#![allow(clippy::blacklisted_name)] +#![allow(clippy::explicit_iter_loop)] #[macro_use] mod support; @@ -64,6 +43,7 @@ mod init; mod install; mod jobserver; +mod list_targets; mod local_registry; mod lockfile_compat; mod login; diff -Nru cargo-0.33.0/tests/testsuite/member_errors.rs cargo-0.35.0/tests/testsuite/member_errors.rs --- cargo-0.33.0/tests/testsuite/member_errors.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/member_errors.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,7 +3,7 @@ use cargo::ops::{self, CompileOptions}; use cargo::util::{config::Config, errors::ManifestError}; -use support::project; +use crate::support::project; /// Tests inclusion of a `ManifestError` pointing to a member manifest /// when that manifest fails to deserialize. @@ -105,7 +105,7 @@ assert_eq!(causes[1].manifest_path(), &missing_manifest_path); } -/// Test dependency version errors provide which package failed via a `ResolveError`. +/// Tests dependency version errors provide which package failed via a `ResolveError`. #[test] fn member_manifest_version_error() { let p = project() diff -Nru cargo-0.33.0/tests/testsuite/metabuild.rs cargo-0.35.0/tests/testsuite/metabuild.rs --- cargo-0.33.0/tests/testsuite/metabuild.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/metabuild.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ -use glob::glob; -use serde_json; -use std::str; -use support::{ +use crate::support::{ basic_lib_manifest, basic_manifest, is_coarse_mtime, project, registry::Package, rustc_host, Project, }; +use glob::glob; +use serde_json; +use std::str; #[test] fn metabuild_gated() { @@ -17,7 +17,8 @@ version = "0.0.1" metabuild = ["mb"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -32,7 +33,8 @@ consider adding `cargo-features = [\"metabuild\"]` to the manifest ", - ).run(); + ) + .run(); } fn basic_project() -> Project { @@ -50,22 +52,26 @@ mb = {path="mb"} mb-other = {path="mb-other"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).file( + ) + .file( "mb-other/Cargo.toml", r#" [package] name = "mb-other" version = "0.0.1" "#, - ).file( + ) + .file( "mb-other/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb-other"); }"#, - ).build() + ) + .build() } #[test] @@ -93,13 +99,15 @@ [build-dependencies] mb = {path="mb"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", r#"fn main() {}"#) .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).build(); + ) + .build(); p.cargo("build -vv") .masquerade_as_nightly_cargo() @@ -111,7 +119,8 @@ Caused by: cannot specify both `metabuild` and `build` ", - ).run(); + ) + .run(); } #[test] @@ -126,7 +135,8 @@ version = "0.0.1" metabuild = "mb" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -vv") @@ -138,7 +148,8 @@ Caused by: metabuild package `mb` must be specified in `build-dependencies`", - ).run(); + ) + .run(); } #[test] @@ -156,12 +167,14 @@ [build-dependencies] mb = {path="mb", optional=true} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).build(); + ) + .build(); p.cargo("build -vv") .masquerade_as_nightly_cargo() @@ -190,7 +203,8 @@ [build-dependencies] mb = {path="mb"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "mb/Cargo.toml", r#" @@ -200,10 +214,12 @@ [lib] name = "other" "#, - ).file( + ) + .file( "mb/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).build(); + ) + .build(); p.cargo("build -vv") .masquerade_as_nightly_cargo() @@ -235,12 +251,14 @@ [build-dependencies] mb = {path="mb"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).build(); + ) + .build(); p.cargo("build -vv") .masquerade_as_nightly_cargo() @@ -256,7 +274,8 @@ [FRESH] foo [..] [FINISHED] dev [..] ", - ).run(); + ) + .run(); } #[test] @@ -275,7 +294,8 @@ [build-dependencies] mb = {path="mb"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", @@ -284,7 +304,8 @@ Ok("cat".to_string())); println!("Hello mb"); }"#, - ).build(); + ) + .build(); p.cargo("build -vv") .masquerade_as_nightly_cargo() @@ -308,12 +329,14 @@ [build-dependencies] mb = {path="mb"} "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("mb/Cargo.toml", &basic_lib_manifest("mb")) .file( "mb/src/lib.rs", r#"pub fn metabuild() { panic!("should not run"); }"#, - ).file( + ) + .file( ".cargo/config", &format!( r#" @@ -322,7 +345,8 @@ "#, rustc_host() ), - ).build(); + ) + .build(); p.cargo("build -vv").masquerade_as_nightly_cargo().run(); } @@ -336,7 +360,8 @@ [workspace] members = ["member1", "member2"] "#, - ).file( + ) + .file( "member1/Cargo.toml", r#" cargo-features = ["metabuild"] @@ -349,7 +374,8 @@ mb1 = {path="../../mb1"} mb2 = {path="../../mb2"} "#, - ).file("member1/src/lib.rs", "") + ) + .file("member1/src/lib.rs", "") .file( "member2/Cargo.toml", r#" @@ -362,7 +388,8 @@ [build-dependencies] mb1 = {path="../../mb1"} "#, - ).file("member2/src/lib.rs", "") + ) + .file("member2/src/lib.rs", "") .build(); project() @@ -507,7 +534,8 @@ ] } "#, - ).run(); + ) + .run(); assert_eq!( glob( @@ -515,7 +543,8 @@ .join("target/.metabuild/metabuild-foo-*.rs") .to_str() .unwrap() - ).unwrap() + ) + .unwrap() .count(), 1 ); @@ -532,7 +561,8 @@ [workspace] members = ["member1", "member2"] "#, - ).file( + ) + .file( "member1/Cargo.toml", r#" cargo-features = ["metabuild"] @@ -544,7 +574,8 @@ [build-dependencies] mb = {path="../../mb1"} "#, - ).file("member1/src/lib.rs", "") + ) + .file("member1/src/lib.rs", "") .file( "member2/Cargo.toml", r#" @@ -557,7 +588,8 @@ [build-dependencies] mb = {path="../../mb2"} "#, - ).file("member2/src/lib.rs", "") + ) + .file("member2/src/lib.rs", "") .build(); project().at("mb1") @@ -596,7 +628,8 @@ .join("target/.metabuild/metabuild-member?-*.rs") .to_str() .unwrap() - ).unwrap() + ) + .unwrap() .count(), 2 ); @@ -609,7 +642,8 @@ .file( "src/lib.rs", r#"pub fn metabuild() { println!("Hello mb"); }"#, - ).publish(); + ) + .publish(); Package::new("dep", "1.0.0") .file( "Cargo.toml", @@ -623,7 +657,8 @@ [build-dependencies] mb = "1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build_dep("mb", "1.0.0") .publish(); @@ -637,7 +672,8 @@ [dependencies] dep = "1.0" "#, - ).file("src/lib.rs", "extern crate dep;") + ) + .file("src/lib.rs", "extern crate dep;") .build(); p.cargo("build -vv") @@ -651,7 +687,8 @@ .join("target/.metabuild/metabuild-dep-*.rs") .to_str() .unwrap() - ).unwrap() + ) + .unwrap() .count(), 1 ); @@ -662,5 +699,78 @@ let p = basic_project(); p.cargo("build --message-format=json") .masquerade_as_nightly_cargo() + .with_json_contains_unordered( + r#" +{ + "executable": null, + "features": [], + "filenames": [ + "[..]/foo/target/debug/build/foo-[..]/metabuild-foo[EXE]" + ], + "fresh": false, + "package_id": "foo [..]", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ + "bin" + ], + "edition": "2018", + "kind": [ + "custom-build" + ], + "name": "metabuild-foo", + "src_path": "[..]/foo/target/.metabuild/metabuild-foo-[..].rs" + } +} + +{ + "cfgs": [], + "env": [], + "linked_libs": [], + "linked_paths": [], + "package_id": "foo [..]", + "reason": "build-script-executed" +} +"#, + ) + .run(); +} + +#[test] +fn metabuild_failed_build_json() { + let p = basic_project(); + // Modify the metabuild dep so that it fails to compile. + p.change_file("mb/src/lib.rs", ""); + p.cargo("build --message-format=json") + .masquerade_as_nightly_cargo() + .with_status(101) + .with_json_contains_unordered( + r#" +{ + "message": { + "children": "{...}", + "code": "{...}", + "level": "error", + "message": "cannot find function `metabuild` in module `mb`", + "rendered": "[..]", + "spans": "{...}" + }, + "package_id": "foo [..]", + "reason": "compiler-message", + "target": { + "crate_types": [ + "bin" + ], + "edition": "2018", + "kind": [ + "custom-build" + ], + "name": "metabuild-foo", + "src_path": null + } +} +"#, + ) .run(); } diff -Nru cargo-0.33.0/tests/testsuite/metadata.rs cargo-0.35.0/tests/testsuite/metadata.rs --- cargo-0.33.0/tests/testsuite/metadata.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/metadata.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::registry::Package; -use support::{basic_bin_manifest, basic_lib_manifest, main_file, project}; +use crate::support::registry::Package; +use crate::support::{basic_bin_manifest, basic_lib_manifest, main_file, project}; #[test] fn cargo_metadata_simple() { @@ -27,6 +27,7 @@ "edition": "2015", "license": null, "license_file": null, + "links": null, "description": null, "readme": null, "repository": null, @@ -64,7 +65,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -93,7 +95,8 @@ [lib] crate-type = ["lib", "staticlib"] "#, - ).build(); + ) + .build(); p.cargo("metadata") .with_json( @@ -114,6 +117,7 @@ "edition": "2015", "license": null, "license_file": null, + "links": null, "description": null, "targets": [ { @@ -151,7 +155,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -170,7 +175,8 @@ default_feat = [] optional_feat = [] "#, - ).build(); + ) + .build(); p.cargo("metadata") .with_json( @@ -191,6 +197,7 @@ "edition": "2015", "license": null, "license_file": null, + "links": null, "description": null, "targets": [ { @@ -235,7 +242,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -257,9 +265,13 @@ [dependencies] bar = "*" + [dev-dependencies] + foobar = "*" "#, - ).build(); + ) + .build(); Package::new("baz", "0.0.1").publish(); + Package::new("foobar", "0.0.1").publish(); Package::new("bar", "0.0.1").dep("baz", "0.0.1").publish(); p.cargo("metadata -q --format-version 1") @@ -272,33 +284,33 @@ "categories": [], "dependencies": [], "description": null, + "edition": "2015", "features": {}, - "id": "baz 0.0.1 (registry+[..])", + "id": "baz 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keywords": [], + "license": null, + "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", + "metadata": null, "name": "baz", "readme": null, "repository": null, - "source": "registry+[..]", - "license": null, - "license_file": null, - "description": null, - "edition": "2015", + "source": "registry+https://github.com/rust-lang/crates.io-index", "targets": [ { - "kind": [ - "lib" - ], "crate_types": [ "lib" ], "edition": "2015", + "kind": [ + "lib" + ], "name": "baz", - "src_path": "[..]lib.rs" + "src_path": "[..]src/lib.rs" } ], - "version": "0.0.1", - "metadata": null + "version": "0.0.1" }, { "authors": [], @@ -307,42 +319,89 @@ { "features": [], "kind": null, - "name": "baz", + "name": "bar", "optional": false, - "req": "^0.0.1", - "source": "registry+[..]", + "registry": null, + "rename": null, + "req": "*", + "source": "registry+https://github.com/rust-lang/crates.io-index", "target": null, - "uses_default_features": true, - "rename": null + "uses_default_features": true + }, + { + "features": [], + "kind": "dev", + "name": "foobar", + "optional": false, + "registry": null, + "rename": null, + "req": "*", + "source": "registry+https://github.com/rust-lang/crates.io-index", + "target": null, + "uses_default_features": true } ], + "description": "foo", + "edition": "2015", "features": {}, - "id": "bar 0.0.1 (registry+[..])", + "id": "foo 0.5.0 (path+file:[..]foo)", "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", - "name": "bar", + "metadata": null, + "name": "foo", "readme": null, "repository": null, - "source": "registry+[..]", - "license": null, - "license_file": null, - "description": null, - "edition": "2015", + "source": null, "targets": [ { + "crate_types": [ + "bin" + ], + "edition": "2015", "kind": [ - "lib" + "bin" ], + "name": "foo", + "src_path": "[..]src/foo.rs" + } + ], + "version": "0.5.0" + }, + { + "authors": [], + "categories": [], + "dependencies": [], + "description": null, + "edition": "2015", + "features": {}, + "id": "foobar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keywords": [], + "license": null, + "license_file": null, + "links": null, + "manifest_path": "[..]Cargo.toml", + "metadata": null, + "name": "foobar", + "readme": null, + "repository": null, + "source": "registry+https://github.com/rust-lang/crates.io-index", + "targets": [ + { "crate_types": [ "lib" ], "edition": "2015", - "name": "bar", - "src_path": "[..]lib.rs" + "kind": [ + "lib" + ], + "name": "foobar", + "src_path": "[..]src/lib.rs" } ], - "version": "0.0.1", - "metadata": null + "version": "0.0.1" }, { "authors": [], @@ -351,81 +410,103 @@ { "features": [], "kind": null, - "name": "bar", + "name": "baz", "optional": false, - "req": "*", - "source": "registry+[..]", + "registry": null, + "rename": null, + "req": "^0.0.1", + "source": "registry+https://github.com/rust-lang/crates.io-index", "target": null, - "uses_default_features": true, - "rename": null + "uses_default_features": true } ], + "description": null, + "edition": "2015", "features": {}, - "id": "foo 0.5.0 (path+file:[..]foo)", + "id": "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "keywords": [], + "license": null, + "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", - "name": "foo", + "metadata": null, + "name": "bar", "readme": null, "repository": null, - "source": null, - "license": "MIT", - "license_file": null, - "description": "foo", - "edition": "2015", + "source": "registry+https://github.com/rust-lang/crates.io-index", "targets": [ { - "kind": [ - "bin" - ], "crate_types": [ - "bin" + "lib" ], "edition": "2015", - "name": "foo", - "src_path": "[..]foo.rs" + "kind": [ + "lib" + ], + "name": "bar", + "src_path": "[..]src/lib.rs" } ], - "version": "0.5.0", - "metadata": null + "version": "0.0.1" } ], - "workspace_members": ["foo 0.5.0 (path+file:[..]foo)"], "resolve": { "nodes": [ { + "dependencies": [], + "deps": [], + "features": [], + "id": "baz 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" + }, + { + "dependencies": [], + "deps": [], + "features": [], + "id": "foobar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" + }, + { "dependencies": [ - "bar 0.0.1 (registry+[..])" + "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foobar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" ], "deps": [ - { "name": "bar", "pkg": "bar 0.0.1 (registry+[..])" } + { + "name": "bar", + "pkg": "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" + }, + { + "name": "foobar", + "pkg": "foobar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" + } ], "features": [], "id": "foo 0.5.0 (path+file:[..]foo)" }, { "dependencies": [ - "baz 0.0.1 (registry+[..])" + "baz 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" ], "deps": [ - { "name": "baz", "pkg": "baz 0.0.1 (registry+[..])" } + { + "name": "baz", + "pkg": "baz 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" + } ], "features": [], - "id": "bar 0.0.1 (registry+[..])" - }, - { - "dependencies": [], - "deps": [], - "features": [], - "id": "baz 0.0.1 (registry+[..])" + "id": "bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" } ], "root": "foo 0.5.0 (path+file:[..]foo)" }, "target_directory": "[..]foo/target", "version": 1, + "workspace_members": [ + "foo 0.5.0 (path+file:[..]foo)" + ], "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -443,7 +524,8 @@ [[example]] name = "ex" "#, - ).build(); + ) + .build(); p.cargo("metadata") .with_json( @@ -461,6 +543,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "source": null, @@ -504,7 +587,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -523,7 +607,8 @@ name = "ex" crate-type = ["rlib", "dylib"] "#, - ).build(); + ) + .build(); p.cargo("metadata") .with_json( @@ -541,6 +626,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "source": null, @@ -584,7 +670,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -596,7 +683,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_lib_manifest("bar")) + ) + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file("baz/src/lib.rs", "") @@ -622,6 +710,7 @@ "dependencies": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "targets": [ @@ -652,6 +741,7 @@ "dependencies": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "targets": [ @@ -690,7 +780,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -702,7 +793,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("bar/Cargo.toml", &basic_lib_manifest("bar")) + ) + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file("baz/src/lib.rs", "") @@ -728,6 +820,7 @@ "dependencies": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "targets": [ @@ -758,6 +851,7 @@ "dependencies": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "targets": [ @@ -780,7 +874,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -795,7 +890,8 @@ Caused by: virtual manifests must be configured with [workspace]", - ).run(); + ) + .run(); } const MANIFEST_OUTPUT: &str = r#" @@ -813,6 +909,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "targets":[{ @@ -875,7 +972,8 @@ .with_stderr( "[ERROR] the manifest-path must be \ a path to a Cargo.toml file", - ).run(); + ) + .run(); } #[test] @@ -892,7 +990,8 @@ .with_stderr( "[ERROR] the manifest-path must be \ a path to a Cargo.toml file", - ).run(); + ) + .run(); } #[test] @@ -921,7 +1020,8 @@ error: '2' isn't a valid value for '--format-version ' [possible values: 1] ", - ).run(); + ) + .run(); } #[test] @@ -939,7 +1039,8 @@ a = [] b = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("metadata --features").arg("a b").run(); @@ -963,7 +1064,8 @@ [package.metadata.bar] baz = "quux" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("metadata --no-deps") @@ -985,6 +1087,7 @@ "edition": "2015", "license": null, "license_file": null, + "links": null, "description": null, "targets": [ { @@ -1010,7 +1113,8 @@ "version": 1, "workspace_root": "[..]/foo" }"#, - ).run(); + ) + .run(); } #[test] @@ -1022,7 +1126,8 @@ [workspace] members = ["bar"] "#, - ).file("bar/Cargo.toml", &basic_lib_manifest("bar")) + ) + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -1050,6 +1155,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", "metadata": null, "name": "bar", @@ -1091,7 +1197,8 @@ "workspace_root": "[..]" } "#, - ).run(); + ) + .run(); } #[test] @@ -1109,7 +1216,8 @@ authors = ["wycats@example.com"] edition = "2018" "#, - ).build(); + ) + .build(); p.cargo("metadata") .masquerade_as_nightly_cargo() .with_json( @@ -1129,6 +1237,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", "metadata": null, "name": "foo", @@ -1170,7 +1279,8 @@ "workspace_root": "[..]" } "#, - ).run(); + ) + .run(); } #[test] @@ -1192,7 +1302,8 @@ [lib] edition = "2018" "#, - ).build(); + ) + .build(); p.cargo("metadata") .masquerade_as_nightly_cargo() .with_json( @@ -1212,6 +1323,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]Cargo.toml", "metadata": null, "name": "foo", @@ -1264,7 +1376,8 @@ "workspace_root": "[..]" } "#, - ).run(); + ) + .run(); } #[test] @@ -1287,7 +1400,8 @@ bar = { version = "0.1.0" } baz = { version = "0.2.0", package = "bar" } "#, - ).file("src/lib.rs", "extern crate bar; extern crate baz;") + ) + .file("src/lib.rs", "extern crate bar; extern crate baz;") .build(); p.cargo("metadata") @@ -1306,6 +1420,7 @@ "name": "bar", "optional": false, "rename": null, + "registry": null, "req": "^0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "target": null, @@ -1317,6 +1432,7 @@ "name": "bar", "optional": false, "rename": "baz", + "registry": null, "req": "^0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "target": null, @@ -1330,6 +1446,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]", "metadata": null, "name": "foo", @@ -1362,6 +1479,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]", "metadata": null, "name": "bar", @@ -1394,6 +1512,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "manifest_path": "[..]", "metadata": null, "name": "bar", @@ -1458,5 +1577,95 @@ ], "workspace_root": "[..]" }"#, - ).run(); + ) + .run(); +} + +#[test] +fn metadata_links() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.5.0" + links = "a" + "#, + ) + .file("src/lib.rs", "") + .file("build.rs", "fn main() {}") + .build(); + + p.cargo("metadata") + .with_json( + r#" +{ + "packages": [ + { + "authors": [], + "categories": [], + "dependencies": [], + "description": null, + "edition": "2015", + "features": {}, + "id": "foo 0.5.0 [..]", + "keywords": [], + "license": null, + "license_file": null, + "links": "a", + "manifest_path": "[..]/foo/Cargo.toml", + "metadata": null, + "name": "foo", + "readme": null, + "repository": null, + "source": null, + "targets": [ + { + "crate_types": [ + "lib" + ], + "edition": "2015", + "kind": [ + "lib" + ], + "name": "foo", + "src_path": "[..]/foo/src/lib.rs" + }, + { + "crate_types": [ + "bin" + ], + "edition": "2015", + "kind": [ + "custom-build" + ], + "name": "build-script-build", + "src_path": "[..]/foo/build.rs" + } + ], + "version": "0.5.0" + } + ], + "resolve": { + "nodes": [ + { + "dependencies": [], + "deps": [], + "features": [], + "id": "foo 0.5.0 [..]" + } + ], + "root": "foo 0.5.0 [..]" + }, + "target_directory": "[..]/foo/target", + "version": 1, + "workspace_members": [ + "foo 0.5.0 [..]" + ], + "workspace_root": "[..]/foo" +} +"#, + ) + .run() } diff -Nru cargo-0.33.0/tests/testsuite/net_config.rs cargo-0.35.0/tests/testsuite/net_config.rs --- cargo-0.33.0/tests/testsuite/net_config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/net_config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::project; +use crate::support::project; #[test] fn net_retry_loads_from_config() { @@ -14,7 +14,8 @@ [dependencies.bar] git = "https://127.0.0.1:11/foo/bar" "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file( ".cargo/config", r#" @@ -23,14 +24,16 @@ [http] timeout=1 "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_status(101) .with_stderr_contains( "[WARNING] spurious network error \ (1 tries remaining): [..]", - ).run(); + ) + .run(); } #[test] @@ -47,13 +50,15 @@ [dependencies.bar] git = "https://127.0.0.1:11/foo/bar" "#, - ).file( + ) + .file( ".cargo/config", r#" [http] timeout=1 "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("build -v -j 1") @@ -61,6 +66,7 @@ .with_stderr_contains( "[WARNING] spurious network error \ (2 tries remaining): [..]", - ).with_stderr_contains("[WARNING] spurious network error (1 tries remaining): [..]") + ) + .with_stderr_contains("[WARNING] spurious network error (1 tries remaining): [..]") .run(); } diff -Nru cargo-0.33.0/tests/testsuite/new.rs cargo-0.35.0/tests/testsuite/new.rs --- cargo-0.33.0/tests/testsuite/new.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/new.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,8 +2,8 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::paths; -use support::{cargo_process, git_process}; +use crate::support::paths; +use crate::support::{cargo_process, git_process}; fn create_empty_gitconfig() { // This helps on Windows where libgit2 is very aggressive in attempting to @@ -57,11 +57,9 @@ assert!(paths::root().join("foo/src/main.rs").is_file()); cargo_process("build").cwd(&paths::root().join("foo")).run(); - assert!( - paths::root() - .join(&format!("foo/target/debug/foo{}", env::consts::EXE_SUFFIX)) - .is_file() - ); + assert!(paths::root() + .join(&format!("foo/target/debug/foo{}", env::consts::EXE_SUFFIX)) + .is_file()); } #[test] @@ -75,7 +73,9 @@ #[test] fn simple_git() { - cargo_process("new --lib foo --edition 2015").env("USER", "foo").run(); + cargo_process("new --lib foo --edition 2015") + .env("USER", "foo") + .run(); assert!(paths::root().is_dir()); assert!(paths::root().join("foo/Cargo.toml").is_file()); @@ -83,6 +83,14 @@ assert!(paths::root().join("foo/.git").is_dir()); assert!(paths::root().join("foo/.gitignore").is_file()); + let fp = paths::root().join("foo/.gitignore"); + let mut contents = String::new(); + File::open(&fp) + .unwrap() + .read_to_string(&mut contents) + .unwrap(); + assert_eq!(contents, "/target\n**/*.rs.bk\nCargo.lock",); + cargo_process("build").cwd(&paths::root().join("foo")).run(); } @@ -95,7 +103,8 @@ error: The following required arguments were not provided: ", - ).run(); + ) + .run(); } #[test] @@ -107,7 +116,8 @@ .with_stderr( "[ERROR] destination `[CWD]/foo` already exists\n\n\ Use `cargo init` to initialize the directory", - ).run(); + ) + .run(); } #[test] @@ -118,7 +128,8 @@ "\ [ERROR] Invalid character `.` in crate name: `foo.rs` use --name to override crate name", - ).run(); + ) + .run(); } #[test] @@ -129,7 +140,8 @@ "\ [ERROR] The name `test` cannot be used as a crate name\n\ use --name to override crate name", - ).run(); + ) + .run(); } #[test] @@ -140,7 +152,8 @@ "\ [ERROR] The name `incremental` cannot be used as a crate name\n\ use --name to override crate name", - ).run(); + ) + .run(); } #[test] @@ -151,7 +164,8 @@ "\ [ERROR] The name `pub` cannot be used as a crate name\n\ use --name to override crate name", - ).run(); + ) + .run(); } #[test] @@ -323,7 +337,8 @@ email = "new-bar" vcs = "none" "#, - ).unwrap(); + ) + .unwrap(); cargo_process("new foo").env("USER", "foo").run(); @@ -367,7 +382,8 @@ name = "foo" email = "bar" "#, - ).unwrap(); + ) + .unwrap(); cargo_process("new foo --vcs git").env("USER", "foo").run(); assert!(paths::root().join("foo/.gitignore").exists()); @@ -386,16 +402,12 @@ .env("USER", "foo") .run(); - assert!( - !paths::root() - .join("foo/components/subcomponent/.git") - .is_file() - ); - assert!( - !paths::root() - .join("foo/components/subcomponent/.gitignore") - .is_file() - ); + assert!(!paths::root() + .join("foo/components/subcomponent/.git") + .is_file()); + assert!(!paths::root() + .join("foo/components/subcomponent/.gitignore") + .is_file()); } #[test] @@ -414,16 +426,12 @@ .env("USER", "foo") .run(); - assert!( - paths::root() - .join("foo/components/subcomponent/.git") - .is_dir() - ); - assert!( - paths::root() - .join("foo/components/subcomponent/.gitignore") - .is_file() - ); + assert!(paths::root() + .join("foo/components/subcomponent/.git") + .is_dir()); + assert!(paths::root() + .join("foo/components/subcomponent/.gitignore") + .is_file()); } #[test] @@ -436,16 +444,12 @@ .env("USER", "foo") .run(); - assert!( - paths::root() - .join("foo/components/subcomponent/.git") - .is_dir() - ); - assert!( - paths::root() - .join("foo/components/subcomponent/.gitignore") - .is_file() - ); + assert!(paths::root() + .join("foo/components/subcomponent/.git") + .is_dir()); + assert!(paths::root() + .join("foo/components/subcomponent/.gitignore") + .is_file()); } #[test] @@ -454,7 +458,8 @@ .with_status(1) .with_stderr_contains( "error: Found argument '--flag' which wasn't expected, or isn't valid in this context", - ).run(); + ) + .run(); } #[test] @@ -493,9 +498,7 @@ #[test] fn new_default_edition() { - cargo_process("new foo") - .env("USER", "foo") - .run(); + cargo_process("new foo").env("USER", "foo").run(); let manifest = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap(); assert!(manifest.contains("edition = \"2018\"")); } diff -Nru cargo-0.33.0/tests/testsuite/out_dir.rs cargo-0.35.0/tests/testsuite/out_dir.rs --- cargo-0.33.0/tests/testsuite/out_dir.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/out_dir.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,8 +2,8 @@ use std::fs::{self, File}; use std::path::Path; -use support::sleep_ms; -use support::{basic_manifest, project}; +use crate::support::sleep_ms; +use crate::support::{basic_manifest, project}; #[test] fn binary_with_debug() { @@ -36,13 +36,15 @@ [lib] crate-type = ["staticlib"] "#, - ).file( + ) + .file( "src/lib.rs", r#" #[no_mangle] pub extern "C" fn foo() { println!("Hello, World!") } "#, - ).build(); + ) + .build(); p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() @@ -69,13 +71,15 @@ [lib] crate-type = ["cdylib"] "#, - ).file( + ) + .file( "src/lib.rs", r#" #[no_mangle] pub extern "C" fn foo() { println!("Hello, World!") } "#, - ).build(); + ) + .build(); p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() @@ -102,12 +106,14 @@ [lib] crate-type = ["rlib"] "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn foo() { println!("Hello, World!") } "#, - ).build(); + ) + .build(); p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() @@ -136,7 +142,8 @@ [dependencies] utils = { path = "./utils" } "#, - ).file("src/lib.rs", "extern crate utils;") + ) + .file("src/lib.rs", "extern crate utils;") .file( "src/main.rs", r#" @@ -146,7 +153,8 @@ println!("Hello, World!") } "#, - ).file("utils/Cargo.toml", &basic_manifest("utils", "0.0.1")) + ) + .file("utils/Cargo.toml", &basic_manifest("utils", "0.0.1")) .file("utils/src/lib.rs", "") .build(); @@ -187,7 +195,8 @@ p.process( &p.root() .join(&format!("out/foo{}", env::consts::EXE_SUFFIX)), - ).with_stdout("foo") + ) + .with_stdout("foo") .run(); sleep_ms(1000); @@ -199,7 +208,8 @@ p.process( &p.root() .join(&format!("out/foo{}", env::consts::EXE_SUFFIX)), - ).with_stdout("bar") + ) + .with_stdout("bar") .run(); } diff -Nru cargo-0.33.0/tests/testsuite/overrides.rs cargo-0.35.0/tests/testsuite/overrides.rs --- cargo-0.33.0/tests/testsuite/overrides.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/overrides.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ -use support::git; -use support::paths; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::git; +use crate::support::paths; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; #[test] fn override_simple() { @@ -30,10 +30,12 @@ "#, bar.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -44,7 +46,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -64,7 +67,8 @@ [replace] bar = { git = 'https://example.com' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -76,7 +80,8 @@ Caused by: replacements must specify a version to replace, but `[..]bar` does not ", - ).run(); + ) + .run(); } #[test] @@ -96,7 +101,8 @@ [replace] "bar:*" = { git = 'https://example.com' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -108,7 +114,8 @@ Caused by: replacements must specify a valid semver version to replace, but `bar:*` does not ", - ).run(); + ) + .run(); } #[test] @@ -131,7 +138,8 @@ [replace] "bar:0.1.0" = "0.2.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -143,7 +151,8 @@ Caused by: replacements cannot specify a version requirement, but found one for [..] ", - ).run(); + ) + .run(); } #[test] @@ -177,7 +186,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -192,7 +202,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); } @@ -224,10 +235,12 @@ "#, foo.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -238,7 +251,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); } @@ -268,10 +282,12 @@ [replace] "bar:0.1.0" = { path = "../bar" } "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -281,7 +297,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -295,7 +312,8 @@ .file( "src/lib.rs", "extern crate baz; pub fn bar() { baz::baz3(); }", - ).publish(); + ) + .publish(); let foo = git::repo(&paths::root().join("override")) .file("Cargo.toml", &basic_manifest("baz", "0.2.0")) @@ -321,7 +339,8 @@ "#, foo.url() ), - ).file( + ) + .file( "src/lib.rs", " extern crate bar; @@ -332,7 +351,8 @@ bar::bar(); } ", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -348,7 +368,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -368,7 +389,8 @@ [dependencies] baz = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let p = project() @@ -389,7 +411,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -404,7 +427,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); @@ -416,13 +440,15 @@ [UPDATING] git repository `file://[..]` [UPDATING] `[ROOT][..]` index ", - ).run(); + ) + .run(); p.cargo("update -p https://github.com/rust-lang/crates.io-index#bar") .with_stderr( "\ [UPDATING] `[ROOT][..]` index ", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); } @@ -446,7 +472,8 @@ [dependencies] baz = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let p = project() @@ -468,7 +495,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -504,7 +532,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -517,7 +546,8 @@ location searched: file://[..] version required: = 0.1.0 ", - ).run(); + ) + .run(); } #[test] @@ -546,7 +576,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -563,7 +594,8 @@ Caused by: Could not find Cargo.toml in `[..]` ", - ).run(); + ) + .run(); } #[test] @@ -580,7 +612,8 @@ [replace] "bar:0.1.0" = { git = 'https://example.com', version = '0.2.0' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -592,7 +625,8 @@ Caused by: replacements cannot specify a version requirement, but found one for `[..]bar:0.1.0` ", - ).run(); + ) + .run(); } #[test] @@ -625,7 +659,8 @@ "#, bar.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -641,7 +676,8 @@ both specifications match: bar v0.1.0 ", - ).run(); + ) + .run(); } #[test] @@ -671,7 +707,8 @@ "#, bar.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("test -p bar") @@ -683,7 +720,8 @@ [..]#bar:0.1.0 [..]#bar:0.1.0 ", - ).run(); + ) + .run(); } #[test] @@ -713,7 +751,8 @@ "#, bar.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("generate-lockfile").run(); @@ -723,7 +762,8 @@ [UPDATING] `[..]` index [UPDATING] git repository `[..]` ", - ).run(); + ) + .run(); } // foo -> near -> far @@ -744,7 +784,8 @@ [dependencies] far = { path = "../far" } "#, - ).file("near/src/lib.rs", "#![no_std] pub extern crate far;") + ) + .file("near/src/lib.rs", "#![no_std] pub extern crate far;") .build(); let p = project() @@ -765,7 +806,8 @@ "#, deps.url() ), - ).file("src/lib.rs", "#![no_std] pub extern crate near;") + ) + .file("src/lib.rs", "#![no_std] pub extern crate near;") .build(); p.cargo("build --verbose").run(); @@ -788,7 +830,8 @@ [dependencies] a = { path = "a1" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a1/Cargo.toml", r#" @@ -800,7 +843,8 @@ [dependencies] bar = "0.1" "#, - ).file("a1/src/lib.rs", "") + ) + .file("a1/src/lib.rs", "") .file( "a2/Cargo.toml", r#" @@ -812,7 +856,8 @@ [dependencies] bar = "0.2" "#, - ).file("a2/src/lib.rs", "") + ) + .file("a2/src/lib.rs", "") .file(".cargo/config", r#"paths = ["a2"]"#) .build(); @@ -842,7 +887,8 @@ [COMPILING] [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -874,7 +920,8 @@ "chrono:0.2.0" = { path = "chrono" } "serde:0.8.0" = { path = "serde" } "#, - ).file( + ) + .file( "Cargo.lock", r#" [[package]] @@ -913,7 +960,8 @@ name = "serde" version = "0.8.0" "#, - ).file( + ) + .file( "src/lib.rs", " extern crate chrono; @@ -924,7 +972,8 @@ serde::serde08_override(); } ", - ).file( + ) + .file( "chrono/Cargo.toml", r#" [package] @@ -935,7 +984,8 @@ [dependencies] serde = "< 0.9" "#, - ).file( + ) + .file( "chrono/src/lib.rs", " extern crate serde; @@ -943,7 +993,8 @@ serde::serde07(); } ", - ).file("serde/Cargo.toml", &basic_manifest("serde", "0.8.0")) + ) + .file("serde/Cargo.toml", &basic_manifest("serde", "0.8.0")) .file("serde/src/lib.rs", "pub fn serde08_override() {}") .build(); @@ -967,7 +1018,8 @@ [dependencies] baz = { path = "baz" } "#, - ).file("src/lib.rs", "pub fn bar() {}") + ) + .file("src/lib.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/lib.rs", "pub fn baz() {}") .build(); @@ -991,7 +1043,8 @@ "#, url = bar.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -1001,7 +1054,8 @@ [WARNING] package replacement is not used: [..]baz:0.1.0 [FINISHED] [..] ", - ).with_stdout("") + ) + .with_stdout("") .run(); } @@ -1019,7 +1073,8 @@ [replace] "bar:0.1.0" = { path = "local_bar" }"#, - ).file( + ) + .file( "first_crate/Cargo.toml", r#" [package] @@ -1029,11 +1084,13 @@ [dependencies] bar = "0.1.0" "#, - ).file("first_crate/src/lib.rs", "") + ) + .file("first_crate/src/lib.rs", "") .file( "second_crate/Cargo.toml", &basic_manifest("second_crate", "0.1.0"), - ).file("second_crate/src/lib.rs", "") + ) + .file("second_crate/src/lib.rs", "") .file("local_bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("local_bar/src/lib.rs", "") .build(); @@ -1047,7 +1104,8 @@ [COMPILING] bar v0.1.0 ([..]) [COMPILING] first_crate v0.1.0 ([..]) [FINISHED] [..]", - ).run(); + ) + .run(); p.cargo("build") .cwd(p.root().join("second_crate")) @@ -1056,7 +1114,8 @@ "\ [COMPILING] second_crate v0.1.0 ([..]) [FINISHED] [..]", - ).run(); + ) + .run(); } #[test] @@ -1076,7 +1135,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -1088,7 +1148,8 @@ [dependencies] baz = { path = "baz" } "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("bar/baz/src/lib.rs", "") .file(".cargo/config", r#"paths = ["bar"]"#) @@ -1117,7 +1178,8 @@ [replace] "bar:0.1.0" = { path = "bar" } "#, - ).file("src/lib.rs", "extern crate bar;") + ) + .file("src/lib.rs", "extern crate bar;") .file( "bar/Cargo.toml", r#" @@ -1129,10 +1191,12 @@ [dependencies] baz = { path = "baz" } "#, - ).file( + ) + .file( "bar/src/lib.rs", "extern crate baz; pub fn bar() { baz::baz(); }", - ).file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) + ) + .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("bar/baz/src/lib.rs", "pub fn baz() {}") .build(); @@ -1155,7 +1219,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -1167,7 +1232,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file( "bar2/Cargo.toml", r#" @@ -1179,7 +1245,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("bar2/src/lib.rs", "") + ) + .file("bar2/src/lib.rs", "") .file(".cargo/config", r#"paths = ["bar2"]"#) .build(); @@ -1190,7 +1257,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1209,7 +1277,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .file( @@ -1223,7 +1292,8 @@ [dependencies] baz = { version = "0.1", optional = true } "#, - ).file("bar2/src/lib.rs", "") + ) + .file("bar2/src/lib.rs", "") .file(".cargo/config", r#"paths = ["bar2"]"#) .build(); @@ -1233,7 +1303,8 @@ warning: path override for crate `bar` has altered the original list of dependencies; the dependency on `baz` was either added or\ ", - ).run(); + ) + .run(); } #[test] @@ -1259,7 +1330,8 @@ [replace] 'bar:0.1.0' = { path = "bar" } "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }") .file( "bar/Cargo.toml", r#" @@ -1271,13 +1343,15 @@ [features] default = [] "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #[cfg(feature = "default")] pub fn bar() {} "#, - ).file( + ) + .file( "another2/Cargo.toml", r#" [package] @@ -1288,7 +1362,8 @@ [dependencies] bar = { version = "0.1", default-features = false } "#, - ).file("another2/src/lib.rs", "") + ) + .file("another2/src/lib.rs", "") .build(); p.cargo("run").run(); @@ -1313,7 +1388,8 @@ [replace] 'bar:0.1.0' = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -1325,7 +1401,8 @@ [dependencies] foo = { path = ".." } "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("build") diff -Nru cargo-0.33.0/tests/testsuite/package.rs cargo-0.35.0/tests/testsuite/package.rs --- cargo-0.33.0/tests/testsuite/package.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/package.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,19 +1,22 @@ use std; use std::fs::File; use std::io::prelude::*; -use std::path::{Path, PathBuf}; +use std::path::Path; -use flate2::read::GzDecoder; +use crate::support::registry::Package; +use crate::support::{ + basic_manifest, git, is_nightly, path2url, paths, project, publish::validate_crate_contents, + registry, +}; +use crate::support::{cargo_process, sleep_ms}; use git2; -use support::registry::Package; -use support::{basic_manifest, git, is_nightly, path2url, paths, project, registry}; -use support::{cargo_process, sleep_ms}; -use tar::Archive; #[test] fn simple() { let p = project() - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" @@ -21,7 +24,8 @@ exclude = ["*.txt"] license = "MIT" description = "foo" - "#) + "#, + ) .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .file("src/bar.txt", "") // should be ignored when packaging .build(); @@ -36,7 +40,8 @@ [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); p.cargo("package -l") .with_stdout( @@ -44,26 +49,17 @@ Cargo.toml src/main.rs ", - ).run(); + ) + .run(); p.cargo("package").with_stdout("").run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for f in ar.entries().unwrap() { - let f = f.unwrap(); - let fname = f.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - f.header().path() - ) - } + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[], + ); } #[test] @@ -74,13 +70,14 @@ "\ warning: manifest has no description, license, license-file, documentation, \ homepage or repository. -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([CWD]) [VERIFYING] foo v0.0.1 ([CWD]) [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p = project() .file( @@ -92,19 +89,21 @@ authors = [] license = "MIT" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("package") .with_stderr( "\ warning: manifest has no description, documentation, homepage or repository. -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([CWD]) [VERIFYING] foo v0.0.1 ([CWD]) [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p = project() .file( @@ -118,7 +117,8 @@ description = "foo" repository = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("package") .with_stderr( @@ -128,7 +128,8 @@ [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -148,38 +149,35 @@ .with_stderr( "\ [WARNING] manifest has no description[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([..]) [ARCHIVING] [..] [ARCHIVING] [..] [ARCHIVING] .cargo_vcs_info.json ", - ).run(); + ) + .run(); let f = File::open(&repo.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - let mut entry = ar - .entries() - .unwrap() - .map(|f| f.unwrap()) - .find(|e| e.path().unwrap().ends_with(".cargo_vcs_info.json")) - .unwrap(); - let mut contents = String::new(); - entry.read_to_string(&mut contents).unwrap(); - assert_eq!( - &contents[..], - &*format!( - r#"{{ + let vcs_contents = format!( + r#"{{ "git": {{ "sha1": "{}" }} }} "#, - repo.revparse_head() - ) + repo.revparse_head() + ); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &[ + "Cargo.toml", + "Cargo.toml.orig", + "src/main.rs", + ".cargo_vcs_info.json", + ], + &[(".cargo_vcs_info.json", &vcs_contents)], ); println!("package sub-repo"); @@ -188,13 +186,14 @@ .with_stderr( "\ [WARNING] manifest has no description[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] a v0.0.1 ([..]) [ARCHIVING] Cargo.toml [ARCHIVING] src/lib.rs [ARCHIVING] .cargo_vcs_info.json ", - ).run(); + ) + .run(); } #[test] @@ -205,13 +204,14 @@ .with_stderr( "\ [WARNING] manifest has no description[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([CWD]) [VERIFYING] foo v0.0.1 ([CWD]) [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -232,12 +232,14 @@ repository = "foo" exclude = ["*.no-existe"] "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() {} "#, - ).file(".cargo_vcs_info.json", "foo") + ) + .file(".cargo_vcs_info.json", "foo") .build(); p.cargo("package") .arg("--no-verify") @@ -247,7 +249,8 @@ [ERROR] Invalid inclusion of reserved file name .cargo_vcs_info.json \ in package source ", - ).run(); + ) + .run(); } #[test] @@ -266,7 +269,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .build(); @@ -276,18 +280,21 @@ .with_stderr( "\ [WARNING] manifest has no documentation, homepage or repository. -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [ERROR] all path dependencies must have a version specified when packaging. dependency `bar` does not specify a version. ", - ).run(); + ) + .run(); } #[test] fn exclude() { let root = paths::root().join("exclude"); let repo = git::repo(&root) - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" @@ -319,29 +326,30 @@ "dir_deep_4/*", # CHANGING (packaged -> ignored) "dir_deep_5/**", # CHANGING (packaged -> ignored) ] - "#) + "#, + ) .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .file("bar.txt", "") .file("src/bar.txt", "") - // file in root + // File in root. .file("file_root_1", "") .file("file_root_2", "") .file("file_root_3", "") .file("file_root_4", "") .file("file_root_5", "") - // file in sub-dir + // File in sub-dir. .file("some_dir/file_deep_1", "") .file("some_dir/file_deep_2", "") .file("some_dir/file_deep_3", "") .file("some_dir/file_deep_4", "") .file("some_dir/file_deep_5", "") - // dir in root + // Dir in root. .file("dir_root_1/some_dir/file", "") .file("dir_root_2/some_dir/file", "") .file("dir_root_3/some_dir/file", "") .file("dir_root_4/some_dir/file", "") .file("dir_root_5/some_dir/file", "") - // dir in sub-dir + // Dir in sub-dir. .file("some_dir/dir_deep_1/some_dir/file", "") .file("some_dir/dir_deep_2/some_dir/file", "") .file("some_dir/dir_deep_3/some_dir/file", "") @@ -355,7 +363,7 @@ .with_stderr( "\ [WARNING] manifest has no description[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [WARNING] [..] file `dir_root_1/some_dir/file` WILL be excluded [..] See [..] [WARNING] [..] file `dir_root_2/some_dir/file` WILL be excluded [..] @@ -389,7 +397,8 @@ [ARCHIVING] [..] [ARCHIVING] .cargo_vcs_info.json ", - ).run(); + ) + .run(); assert!(repo.root().join("target/package/foo-0.0.1.crate").is_file()); @@ -417,24 +426,29 @@ some_dir/file_deep_5 src/main.rs ", - ).run(); + ) + .run(); } #[test] fn include() { let root = paths::root().join("include"); let repo = git::repo(&root) - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" authors = [] exclude = ["*.txt"] include = ["foo.txt", "**/*.rs", "Cargo.toml"] - "#) + "#, + ) .file("foo.txt", "") .file("src/main.rs", r#"fn main() { println!("hello"); }"#) - .file("src/bar.txt", "") // should be ignored when packaging + // Should be ignored when packaging. + .file("src/bar.txt", "") .build(); cargo_process("package --no-verify -v") @@ -442,14 +456,15 @@ .with_stderr( "\ [WARNING] manifest has no description[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([..]) [ARCHIVING] [..] [ARCHIVING] [..] [ARCHIVING] [..] [ARCHIVING] .cargo_vcs_info.json ", - ).run(); + ) + .run(); } #[test] @@ -477,11 +492,14 @@ description = "foo" repository = "foo" "#, - ).file("src/lib.rs", "pub fn foo() {}") - }).unwrap(); + ) + .file("src/lib.rs", "pub fn foo() {}") + }) + .unwrap(); let library = git::new("bar", |library| { library.no_manifest().file("Makefile", "all:") - }).unwrap(); + }) + .unwrap(); let repository = git2::Repository::open(&project.root()).unwrap(); let url = path2url(library.root()).to_string(); @@ -494,9 +512,11 @@ &repository.revparse_single("HEAD").unwrap(), git2::ResetType::Hard, None, - ).unwrap(); + ) + .unwrap(); - project.cargo("package --no-verify -v") + project + .cargo("package --no-verify -v") .with_stderr_contains("[ARCHIVING] bar/Makefile") .run(); } @@ -520,7 +540,8 @@ Cargo.toml src/main.rs ", - ).run(); + ) + .run(); } #[test] @@ -549,13 +570,14 @@ .with_stderr( "\ [WARNING] manifest has no documentation[..] -See http://doc.crates.io/manifest.html#package-metadata for more info. +See for more info. [PACKAGING] foo v0.0.1 ([CWD]) [VERIFYING] foo v0.0.1 ([CWD]) [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); p.cargo("package -l") .with_stdout( @@ -563,29 +585,21 @@ Cargo.toml src[..]main.rs ", - ).run(); + ) + .run(); p.cargo("package").with_stdout("").run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for f in ar.entries().unwrap() { - let f = f.unwrap(); - let fname = f.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - f.header().path() - ) - } + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[], + ); } -#[cfg(unix)] // windows doesn't allow these characters in filenames +// Windows doesn't allow these characters in filenames. +#[cfg(unix)] #[test] fn package_weird_characters() { let p = project() @@ -605,7 +619,8 @@ Caused by: cannot package a filename with a special character `:`: src/:foo ", - ).run(); + ) + .run(); } #[test] @@ -640,19 +655,17 @@ [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); // Check that the tarball contains the added file let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - let entries = ar.entries().unwrap(); - let entry_paths = entries - .map(|entry| entry.unwrap().path().unwrap().into_owned()) - .collect::>(); - assert!(entry_paths.contains(&PathBuf::from("foo-0.0.1/src/foo.rs"))); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "src/foo.rs"], + &[], + ); } #[test] @@ -674,7 +687,8 @@ homepage = 'foo' repository = 'foo' "#, - ).file("src/main.rs", r#"fn main() { println!("hello"); }"#) + ) + .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .build(); t!(fs::symlink("nowhere", &p.root().join("src/foo.rs"))); @@ -690,7 +704,8 @@ Caused by: [..] ", - ).run(); + ) + .run(); } #[test] @@ -711,7 +726,8 @@ homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); // Modify Cargo.toml without committing the change. @@ -741,7 +757,8 @@ to proceed despite this, pass the `--allow-dirty` flag ", - ).run(); + ) + .run(); } #[test] @@ -775,7 +792,8 @@ ghi = "1.0" abc = "1.0" "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .build(); @@ -785,29 +803,13 @@ .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - let mut entry = ar - .entries() - .unwrap() - .map(|f| f.unwrap()) - .find(|e| e.path().unwrap().ends_with("Cargo.toml")) - .unwrap(); - let mut contents = String::new(); - entry.read_to_string(&mut contents).unwrap(); - // BTreeMap makes the order of dependencies in the generated file deterministic - // by sorting alphabetically - assert_eq!( - &contents[..], - &*format!( - r#"# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO + let rewritten_toml = format!( + r#"# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -839,8 +841,14 @@ [dependencies.ghi] version = "1.0" "#, - registry::alt_registry() - ) + registry::alt_registry_url() + ); + + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[("Cargo.toml", &rewritten_toml)], ); } @@ -861,7 +869,8 @@ [dependencies] bar = { path = "bar", version = "0.1" } "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file( "bar/Cargo.toml", r#" @@ -871,7 +880,8 @@ authors = [] workspace = ".." "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("package --no-verify") @@ -879,26 +889,12 @@ .run(); let f = File::open(&p.root().join("target/package/bar-0.1.0.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - let mut entry = ar - .entries() - .unwrap() - .map(|f| f.unwrap()) - .find(|e| e.path().unwrap().ends_with("Cargo.toml")) - .unwrap(); - let mut contents = String::new(); - entry.read_to_string(&mut contents).unwrap(); - assert_eq!( - &contents[..], - r#"# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO + let rewritten_toml = r#"# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -909,7 +905,12 @@ name = "bar" version = "0.1.0" authors = [] -"# +"#; + validate_crate_contents( + f, + "bar-0.1.0.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], + &[("Cargo.toml", &rewritten_toml)], ); } @@ -930,7 +931,8 @@ other = "1.0" other1 = { version = "1.0" } "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .build(); p.cargo("package --no-verify").run(); @@ -949,18 +951,23 @@ authors = [] edition = "2018" "#, - ).file("src/lib.rs", r#" "#) + ) + .file("src/lib.rs", r#" "#) .build(); - p.cargo("build -v").masquerade_as_nightly_cargo() + p.cargo("build -v") + .masquerade_as_nightly_cargo() .without_status() // passes on nightly, fails on stable, b/c --edition is nightly-only // --edition is still in flux and we're not passing -Zunstable-options // from Cargo so it will probably error. Only partially match the output // until stuff stabilizes - .with_stderr_contains("\ + .with_stderr_contains( + "\ [COMPILING] foo v0.0.1 ([..]) [RUNNING] `rustc [..]--edition=2018 [..] -").run(); +", + ) + .run(); } #[test] @@ -983,7 +990,8 @@ [package.metadata.docs.rs] features = ["foobar"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("package").run(); @@ -1001,7 +1009,8 @@ authors = [] edition = "chicken" "#, - ).file("src/lib.rs", r#" "#) + ) + .file("src/lib.rs", r#" "#) .build(); p.cargo("build -v") @@ -1015,8 +1024,10 @@ Caused by: supported edition values are `2015` or `2018`, but `chicken` is unknown -".to_string(), - ).run(); +" + .to_string(), + ) + .run(); } #[test] @@ -1035,7 +1046,8 @@ description = "foo" publish-lockfile = true "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("package") @@ -1049,7 +1061,8 @@ [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); p.cargo("package -l") .masquerade_as_nightly_cargo() @@ -1059,30 +1072,20 @@ Cargo.toml src/main.rs ", - ).run(); + ) + .run(); p.cargo("package") .masquerade_as_nightly_cargo() .with_stdout("") .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for f in ar.entries().unwrap() { - let f = f.unwrap(); - let fname = f.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/Cargo.lock" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - f.header().path() - ) - } + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "Cargo.lock", "src/main.rs"], + &[], + ); } #[test] @@ -1106,7 +1109,8 @@ repository = "foo" publish-lockfile = true "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("package -l") .masquerade_as_nightly_cargo() @@ -1117,7 +1121,8 @@ Cargo.toml src/main.rs ", - ).run(); + ) + .run(); } #[test] @@ -1136,21 +1141,19 @@ description = "foo" publish-lockfile = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("package").masquerade_as_nightly_cargo().run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for f in ar.entries().unwrap() { - let f = f.unwrap(); - let fname = f.header().path().unwrap(); - assert!(!fname.ends_with("Cargo.lock")); - } + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], + &[], + ); } #[test] @@ -1162,7 +1165,8 @@ [workspace] members = ["foo"] "#, - ).file( + ) + .file( "foo/Cargo.toml", r#" cargo-features = ["publish-lockfile"] @@ -1175,7 +1179,8 @@ description = "foo" publish-lockfile = true "#, - ).file("foo/src/main.rs", "fn main() {}") + ) + .file("foo/src/main.rs", "fn main() {}") .build(); p.cargo("package") @@ -1184,15 +1189,12 @@ .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - let mut rdr = GzDecoder::new(f); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - assert!(ar.entries().unwrap().into_iter().any(|f| { - let f = f.unwrap(); - let fname = f.header().path().unwrap(); - fname.ends_with("Cargo.lock") - })); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "Cargo.lock"], + &[], + ); } #[test] @@ -1210,7 +1212,8 @@ file.write_all(b"Hello, world of generated files.").expect("failed to write"); } "#, - ).build(); + ) + .build(); if cfg!(target_os = "macos") { // MacOS has 1s resolution filesystem. @@ -1230,7 +1233,99 @@ Build scripts should not modify anything outside of OUT_DIR. Modified file: [..]src/generated.txt To proceed despite this, pass the `--no-verify` flag.", - ).run(); + ) + .run(); p.cargo("package --no-verify").run(); } + +#[test] +fn package_with_select_features() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + required = [] + optional = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("package --features required").masquerade_as_nightly_cargo().run(); +} + +#[test] +fn package_with_all_features() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + required = [] + optional = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("package --all-features").masquerade_as_nightly_cargo().run(); +} + +#[test] +fn package_no_default_features() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + default = ["required"] + required = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("package --no-default-features") + .masquerade_as_nightly_cargo() + .with_stderr_contains("error: This crate requires `required` feature!") + .with_status(101) + .run(); +} diff -Nru cargo-0.33.0/tests/testsuite/patch.rs cargo-0.35.0/tests/testsuite/patch.rs --- cargo-0.33.0/tests/testsuite/patch.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/patch.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,10 +1,10 @@ use std::fs::{self, File}; use std::io::{Read, Write}; -use support::git; -use support::paths; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::git; +use crate::support::paths; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; use toml; #[test] @@ -14,7 +14,8 @@ .file( "src/lib.rs", "extern crate bar; pub fn baz() { bar::bar(); }", - ).dep("bar", "0.1.0") + ) + .dep("bar", "0.1.0") .publish(); let p = project() @@ -33,7 +34,8 @@ [patch.crates-io] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", " extern crate bar; @@ -43,7 +45,8 @@ baz::baz(); } ", - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -58,7 +61,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); } @@ -82,10 +86,12 @@ [patch.crates-io] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -97,7 +103,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); } @@ -126,10 +133,12 @@ "#, bar.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -141,7 +150,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); } @@ -172,10 +182,12 @@ "#, bar.url() ), - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::bar(); }", - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -186,7 +198,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); } @@ -209,7 +222,8 @@ [patch.crates-io] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) .file("bar/src/lib.rs", "not rust code") .build(); @@ -218,14 +232,31 @@ .with_stderr( "\ [UPDATING] `[ROOT][..]` index +[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] [DOWNLOADING] crates ... [DOWNLOADED] bar v0.1.0 [..] [COMPILING] bar v0.1.0 [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); + ) + .run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..] +", + ) + .run(); // unused patch should be in the lock file let mut lock = String::new(); @@ -269,7 +300,8 @@ "#, foo.url() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -277,14 +309,31 @@ "\ [UPDATING] git repository `file://[..]` [UPDATING] `[ROOT][..]` index +[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. +[..] +[..] +[..] +[..] [DOWNLOADING] crates ... [DOWNLOADED] bar v0.1.0 [..] [COMPILING] bar v0.1.0 [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); + ) + .run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..] +", + ) + .run(); } #[test] @@ -303,7 +352,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", r#""#) .build(); @@ -318,7 +368,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); t!(t!(File::create(p.root().join("Cargo.toml"))).write_all( @@ -343,7 +394,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); } @@ -363,7 +415,8 @@ [dependencies] bar = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) .file("bar/src/lib.rs", r#""#) .build(); @@ -378,7 +431,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build").with_stderr("[FINISHED] [..]").run(); t!(t!(File::create(p.root().join("Cargo.toml"))).write_all( @@ -397,9 +451,82 @@ )); p.cargo("build") - .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") + .with_stderr( + "\ +[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", + ) + .run(); + p.cargo("build") + .with_stderr( + "\ +[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. +[..] +[..] +[..] +[..] +[FINISHED] [..]", + ) + .run(); + + p.cargo("update").run(); + p.cargo("build") + .with_stderr( + "\ +[COMPILING] bar v0.1.1 ([CWD]/bar) +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [..] +", + ) + .run(); +} + +#[test] +fn no_warn_ws_patch() { + Package::new("c", "0.1.0").publish(); + + // Don't issue an unused patch warning when the patch isn't used when + // partially building a workspace. + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["a", "b", "c"] + + [patch.crates-io] + c = { path = "c" } + "#, + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + .file("a/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.1.0" + [dependencies] + c = "0.1.0" + "#, + ) + .file("b/src/lib.rs", "") + .file("c/Cargo.toml", &basic_manifest("c", "0.1.0")) + .file("c/src/lib.rs", "") + .build(); + + p.cargo("build -p a") + .with_stderr( + "\ +[UPDATING] [..] +[COMPILING] a [..] +[FINISHED] [..]", + ) .run(); - p.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[test] @@ -421,7 +548,8 @@ [patch.crates-io] bar = { path = 'bar' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) .file("bar/src/lib.rs", r#""#) .build(); @@ -434,7 +562,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -456,7 +585,8 @@ [patch.crates-io] baz = { path = 'baz' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -468,7 +598,8 @@ [dependencies] baz = '0.1.0' "#, - ).file("bar/src/lib.rs", r#""#) + ) + .file("bar/src/lib.rs", r#""#) .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.1")) .file("baz/src/lib.rs", r#""#) .build(); @@ -482,7 +613,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -504,7 +636,8 @@ [patch.crates-io] bar = { path = 'bar' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) .file("bar/src/lib.rs", r#""#) .build(); @@ -517,7 +650,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); Package::new("bar", "0.2.0").publish(); p.cargo("update").run(); @@ -546,7 +680,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -568,7 +703,8 @@ [patch.crates-io] baz = { path = 'baz' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -580,7 +716,8 @@ [dependencies] baz = '0.2.0' "#, - ).file("bar/src/lib.rs", r#""#) + ) + .file("bar/src/lib.rs", r#""#) .file("baz/Cargo.toml", &basic_manifest("baz", "0.2.0")) .file("baz/src/lib.rs", r#""#) .build(); @@ -594,7 +731,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -618,7 +756,8 @@ foo = { path = 'foo' } bar = { path = 'bar' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", r#""#) .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) @@ -649,7 +788,8 @@ [patch.crates-io] bar = { path = 'bar' } "#, - ).unwrap(); + ) + .unwrap(); p.cargo("build").run(); let mut lock_file2 = String::new(); File::open(p.root().join("Cargo.lock")) @@ -687,7 +827,8 @@ [patch.some-other-source] bar = { path = 'bar' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", r#""#) .build(); @@ -699,9 +840,13 @@ error: failed to parse manifest at `[..]` Caused by: + [patch] entry `some-other-source` should be a URL or registry name + +Caused by: invalid url `some-other-source`: relative URL without a base ", - ).run(); + ) + .run(); } #[test] @@ -720,7 +865,8 @@ [patch.crates-io] bar = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", r#""#) .build(); @@ -736,7 +882,8 @@ patch for `bar` in `[..]` points to the same source, but patches must point \ to different sources ", - ).run(); + ) + .run(); } #[test] @@ -753,7 +900,8 @@ [patch.crates-io] bar = { path = "bar" } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", r#""#) .file( "foo/Cargo.toml", @@ -766,7 +914,8 @@ [dependencies] bar = "0.1" "#, - ).file("foo/src/lib.rs", r#""#) + ) + .file("foo/src/lib.rs", r#""#) .build(); p.cargo("build").run(); @@ -801,7 +950,8 @@ bar = { path = "bar" } baz = { path = "baz" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) .file("bar/src/lib.rs", r#""#) .file( @@ -815,7 +965,8 @@ [dependencies] bar = "0.1" "#, - ).file("baz/src/lib.rs", r#""#) + ) + .file("baz/src/lib.rs", r#""#) .build(); p.cargo("build").run(); @@ -837,7 +988,8 @@ [patch.crates-io] baz = { path = "./baz" } "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [project] @@ -848,10 +1000,12 @@ [dependencies] baz = "1.1.0-pre.1" "#, - ).file( + ) + .file( "bar/src/main.rs", "extern crate baz; fn main() { baz::baz() }", - ).file( + ) + .file( "baz/Cargo.toml", r#" [project] @@ -860,7 +1014,8 @@ authors = [] [workspace] "#, - ).file("baz/src/lib.rs", "pub fn baz() {}") + ) + .file("baz/src/lib.rs", "pub fn baz() {}") .build(); p.cargo("build").run(); diff -Nru cargo-0.33.0/tests/testsuite/path.rs cargo-0.35.0/tests/testsuite/path.rs --- cargo-0.33.0/tests/testsuite/path.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/path.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,14 +1,15 @@ use std::fs::{self, File}; use std::io::prelude::*; -use support::paths::{self, CargoPathExt}; -use support::registry::Package; -use support::sleep_ms; -use support::{basic_lib_manifest, basic_manifest, main_file, project}; +use crate::support::paths::{self, CargoPathExt}; +use crate::support::registry::Package; +use crate::support::sleep_ms; +use crate::support::{basic_lib_manifest, basic_manifest, main_file, project}; #[test] -#[cfg(not(windows))] // I have no idea why this is failing spuriously on - // Windows, for more info see #3466. +// I have no idea why this is failing spuriously on Windows; +// for more info, see #3466. +#[cfg(not(windows))] fn cargo_compile_with_nested_deps_shorthand() { let p = project() .file( @@ -25,7 +26,8 @@ version = "0.5.0" path = "bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -44,7 +46,8 @@ name = "bar" "#, - ).file( + ) + .file( "bar/src/bar.rs", r#" extern crate baz; @@ -53,7 +56,8 @@ baz::gimme() } "#, - ).file("bar/baz/Cargo.toml", &basic_lib_manifest("baz")) + ) + .file("bar/baz/Cargo.toml", &basic_lib_manifest("baz")) .file( "bar/baz/src/baz.rs", r#" @@ -61,7 +65,8 @@ "test passed".to_string() } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -70,7 +75,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); assert!(p.bin("foo").is_file()); @@ -84,7 +90,8 @@ "[COMPILING] baz v0.5.0 ([CWD]/bar/baz)\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); println!("building foo"); p.cargo("build -p foo") .with_stderr( @@ -92,7 +99,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -115,7 +123,8 @@ [[bin]] name = "foo" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .build(); let _p2 = project() .at("bar") @@ -127,9 +136,13 @@ "zoidberg" } "#, - ).build(); + ) + .build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]can't find crate for `bar`") + .run(); } #[test] @@ -152,7 +165,8 @@ [[bin]] name = "foo" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .build(); let _p2 = project() .at("bar") @@ -164,7 +178,8 @@ "zoidberg" } "#, - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -173,7 +188,8 @@ [COMPILING] [..] v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); } @@ -194,7 +210,8 @@ version = "0.5.0" path = "bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -212,14 +229,16 @@ name = "bar" "#, - ).file( + ) + .file( "bar/src/bar.rs", r#" pub fn gimme() -> &'static str { "zoidberg" } "#, - ).build(); + ) + .build(); p.cargo("build") .with_stderr( @@ -227,7 +246,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in \ [..]\n", - ).run(); + ) + .run(); assert!(p.bin("foo").is_file()); @@ -249,7 +269,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/bar.rs", "pub fn bar() {}") .build(); @@ -260,7 +281,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); sleep_ms(1000); p.change_file( @@ -277,7 +299,8 @@ [COMPILING] foo v0.5.0 ([..])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -295,7 +318,8 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") .file( "bar/Cargo.toml", r#" @@ -310,10 +334,12 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "bar/src/bar.rs", "extern crate baz; pub fn bar() { baz::baz() }", - ).file("baz/Cargo.toml", &basic_lib_manifest("baz")) + ) + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file("baz/src/baz.rs", "pub fn baz() {}") .build(); p.cargo("build") @@ -323,13 +349,15 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); p.cargo("build").with_stdout("").run(); // Make sure an update to baz triggers a rebuild of bar // // We base recompilation off mtime, so sleep for at least a second to ensure // that this write will change the mtime. + sleep_ms(1000); File::create(&p.root().join("baz/src/baz.rs")) .unwrap() .write_all(br#"pub fn baz() { println!("hello!"); }"#) @@ -342,9 +370,11 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); // Make sure an update to bar doesn't trigger baz + sleep_ms(1000); File::create(&p.root().join("bar/src/bar.rs")) .unwrap() .write_all( @@ -352,7 +382,8 @@ extern crate baz; pub fn bar() { println!("hello!"); baz::baz(); } "#, - ).unwrap(); + ) + .unwrap(); sleep_ms(1000); p.cargo("build") .with_stderr( @@ -360,7 +391,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -380,7 +412,8 @@ [dependencies.baz] path = "baz" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") .file( "bar/Cargo.toml", r#" @@ -395,7 +428,8 @@ [dependencies.baz] path = "../baz" "#, - ).file("bar/src/bar.rs", "pub fn bar() {}") + ) + .file("bar/src/bar.rs", "pub fn bar() {}") .file("baz/Cargo.toml", &basic_lib_manifest("baz")) .file("baz/src/baz.rs", "pub fn baz() {}") .build(); @@ -406,7 +440,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); assert!(p.bin("foo").is_file()); p.cargo("build").with_stdout("").run(); assert!(p.bin("foo").is_file()); @@ -429,7 +464,8 @@ version = "0.5.0" path = "src/bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file("src/bar/Cargo.toml", &basic_lib_manifest("bar")) .file("src/bar/src/bar.rs", "pub fn gimme() -> i32 { 92 }") .build(); @@ -440,7 +476,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); sleep_ms(1000); File::create(&p.root().join("src/main.rs")) @@ -454,7 +491,8 @@ "[COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); } #[test] @@ -473,7 +511,8 @@ path = "src/bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/bar/not-a-manifest", "") .build(); @@ -492,7 +531,8 @@ Caused by: [..] (os error [..]) ", - ).run(); + ) + .run(); } #[test] @@ -525,7 +565,8 @@ "#, bar.root().display() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v").run(); } @@ -558,7 +599,8 @@ "#, bar.root().display() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "fn main() {}") .build(); @@ -580,7 +622,8 @@ [dependencies.p2] path = "../p2" "#, - ).file("p1/src/lib.rs", "") + ) + .file("p1/src/lib.rs", "") .file("p2/Cargo.toml", &basic_manifest("p2", "0.5.0")) .file("p2/src/lib.rs", "") .build(); @@ -593,7 +636,8 @@ bar.root().join("p1").display(), bar.root().join("p2").display() ), - ).file( + ) + .file( "Cargo.toml", &format!( r#" @@ -609,7 +653,8 @@ "#, bar.root().join("p2").display() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v").run(); @@ -632,7 +677,8 @@ version = "0.5.0" path = "bar" "#, - ).file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) .file( "bar/Cargo.toml", r#" @@ -647,7 +693,8 @@ name = "bar" path = "src/bar.rs" "#, - ).file( + ) + .file( "bar/build.rs", r#" use std::fs; @@ -655,7 +702,8 @@ fs::copy("src/bar.rs.in", "src/bar.rs").unwrap(); } "#, - ).file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 0 }") + ) + .file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 0 }") .build(); p.root().join("bar").move_into_the_past(); @@ -665,7 +713,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in \ [..]\n", - ).run(); + ) + .run(); assert!(p.bin("foo").is_file()); @@ -685,7 +734,8 @@ [COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) in \ [..]\n", - ).run(); + ) + .run(); p.process(&p.bin("foo")).with_stdout("1\n").run(); } @@ -708,13 +758,15 @@ name = "foo" doctest = false "#, - ).file( + ) + .file( "src/lib.rs", r#" #[cfg(test)] #[allow(unused_extern_crates)] extern crate bar; #[cfg(not(test))] pub fn foo() { env!("FOO"); } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); p.cargo("build") @@ -723,7 +775,8 @@ "[COMPILING] foo v0.5.0 ([CWD])\n\ [FINISHED] dev [unoptimized + debuginfo] target(s) \ in [..]\n", - ).run(); + ) + .run(); p.cargo("test") .with_stderr( @@ -732,7 +785,8 @@ [COMPILING] [..] v0.5.0 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); } @@ -751,7 +805,8 @@ [workspace] members = ["a", "b"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) .file("a/src/lib.rs", "") .file( @@ -764,7 +819,8 @@ [dependencies] a = { path = "../a" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .build(); p.cargo("build") .with_stderr( @@ -773,7 +829,8 @@ [COMPILING] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); t!(fs::rename( p.root().join("target"), @@ -786,7 +843,8 @@ [COMPILING] b v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -803,7 +861,8 @@ [dependencies] a2 = { path = "../a2" } "#, - ).file("a/a1/src/lib.rs", "") + ) + .file("a/a1/src/lib.rs", "") .file("a/a2/Cargo.toml", &basic_manifest("a2", "0.5.0")) .file("a/a2/src/lib.rs", "") .file( @@ -817,7 +876,8 @@ a1 = { path = "../a/a1" } a2 = { path = "../a/a2" } "#, - ).file("b/src/lib.rs", "") + ) + .file("b/src/lib.rs", "") .file("b/.cargo/config", r#"paths = ["../a"]"#) .build(); p.cargo("build") @@ -829,7 +889,8 @@ [COMPILING] b v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -840,7 +901,8 @@ .file( ".cargo/config", r#"paths = ["../whoa-this-does-not-exist"]"#, - ).build(); + ) + .build(); p.cargo("build") .with_status(101) .with_stderr( @@ -854,7 +916,8 @@ Caused by: [..] (os error [..]) ", - ).run(); + ) + .run(); } #[test] @@ -875,7 +938,8 @@ [dependencies] foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -887,7 +951,8 @@ [dependencies] bar = "*" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); // Generate a lock file @@ -906,7 +971,8 @@ [dependencies] bar = { path = "" } "#, - ).unwrap(); + ) + .unwrap(); // Make sure we get a nice error. In the past this actually stack // overflowed! @@ -916,10 +982,11 @@ "\ error: no matching package named `bar` found location searched: [..] -did you mean: foo +perhaps you meant: foo required by package `foo v0.5.0 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -938,7 +1005,8 @@ [dependencies] foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.5.0")) .file("foo/src/lib.rs", "") .build(); @@ -963,7 +1031,8 @@ [profile.release] lto = 'thin' "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build --release -v") @@ -973,5 +1042,6 @@ [RUNNING] `rustc [..] -C lto=thin [..]` [FINISHED] [..] ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/plugins.rs cargo-0.35.0/tests/testsuite/plugins.rs --- cargo-0.33.0/tests/testsuite/plugins.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/plugins.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::{basic_manifest, project}; -use support::{is_nightly, rustc_host}; +use crate::support::{basic_manifest, project}; +use crate::support::{is_nightly, rustc_host}; #[test] fn plugin_to_the_max() { @@ -22,7 +22,8 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/main.rs", r#" #![feature(plugin)] @@ -31,7 +32,8 @@ fn main() { foo_lib::foo(); } "#, - ).file( + ) + .file( "src/foo_lib.rs", r#" #![feature(plugin)] @@ -39,7 +41,8 @@ pub fn foo() {} "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file( @@ -57,7 +60,8 @@ [dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -72,7 +76,8 @@ println!("{}", baz::baz()); } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") .file( @@ -87,7 +92,8 @@ name = "baz" crate_type = ["dylib"] "#, - ).file("src/lib.rs", "pub fn baz() -> i32 { 1 }") + ) + .file("src/lib.rs", "pub fn baz() -> i32 { 1 }") .build(); foo.cargo("build").run(); @@ -114,7 +120,8 @@ name = "builder" crate-type = ["dylib"] "#, - ).file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") + ) + .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") .build(); let foo = project() @@ -129,7 +136,8 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/main.rs", r#" #![feature(plugin)] @@ -137,7 +145,8 @@ fn main() {} "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -150,7 +159,8 @@ name = "bar" plugin = true "#, - ).file( + ) + .file( "bar/build.rs", r#" use std::env; @@ -173,7 +183,8 @@ println!("cargo:rustc-flags=-L {}", out_dir.display()); } "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -190,7 +201,8 @@ unsafe { foo() } } "#, - ).build(); + ) + .build(); build.cargo("build").run(); @@ -215,7 +227,8 @@ plugin = true doctest = false "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "") .file("tests/it_works.rs", "") .build(); @@ -237,7 +250,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "#[macro_use] extern crate bar;") + ) + .file("src/lib.rs", "#[macro_use] extern crate bar;") .file( "bar/Cargo.toml", r#" @@ -250,7 +264,8 @@ name = "bar" plugin = true "#, - ).file("bar/src/lib.rs", "pub fn bar() {}") + ) + .file("bar/src/lib.rs", "pub fn bar() {}") .build(); p.cargo("test -v").run(); @@ -273,7 +288,8 @@ [lib] plugin = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let bar = project() @@ -289,7 +305,8 @@ [dependencies.foo] path = "../foo" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", &format!( @@ -300,7 +317,8 @@ "#, target ), - ).build(); + ) + .build(); bar.cargo("build --verbose") .with_status(101) @@ -310,7 +328,8 @@ [RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]` [ERROR] [..]linker[..] ", - ).run(); + ) + .run(); } #[test] @@ -334,7 +353,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -346,13 +366,15 @@ [lib] plugin = true "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #![feature(rustc_private)] extern crate syntax; "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -379,7 +401,8 @@ bar = { path = "bar" } baz = { path = "baz" } "#, - ).file("src/lib.rs", "extern crate baz;") + ) + .file("src/lib.rs", "extern crate baz;") .file( "bar/Cargo.toml", r#" @@ -394,14 +417,16 @@ [dependencies] baz = { path = "../baz" } "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #![feature(rustc_private)] extern crate syntax; extern crate baz; "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.0.1")) .file("baz/src/lib.rs", "") .build(); diff -Nru cargo-0.33.0/tests/testsuite/proc_macro.rs cargo-0.35.0/tests/testsuite/proc_macro.rs --- cargo-0.33.0/tests/testsuite/proc_macro.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/proc_macro.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::is_nightly; -use support::project; +use crate::support::is_nightly; +use crate::support::project; #[test] fn probe_cfg_before_crate_type_discovery() { @@ -15,7 +15,8 @@ [target.'cfg(not(stage300))'.dependencies.noop] path = "../noop" "#, - ).file( + ) + .file( "src/main.rs", r#" #[macro_use] @@ -26,7 +27,8 @@ fn main() {} "#, - ).build(); + ) + .build(); let _noop = project() .at("noop") .file( @@ -40,7 +42,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate proc_macro; @@ -51,7 +54,8 @@ "".parse().unwrap() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -70,7 +74,8 @@ [dependencies.noop] path = "../noop" "#, - ).file( + ) + .file( "src/main.rs", r#" #[macro_use] @@ -81,7 +86,8 @@ fn main() {} "#, - ).build(); + ) + .build(); let _noop = project() .at("noop") .file( @@ -95,7 +101,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate proc_macro; @@ -106,7 +113,8 @@ "".parse().unwrap() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); p.cargo("build").run(); @@ -126,7 +134,8 @@ [dependencies.transmogrify] path = "../transmogrify" "#, - ).file( + ) + .file( "src/main.rs", r#" #[macro_use] @@ -145,7 +154,8 @@ println!("{:?}", x); } "#, - ).build(); + ) + .build(); let _transmogrify = project() .at("transmogrify") .file( @@ -159,7 +169,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate proc_macro; @@ -183,7 +194,8 @@ ".parse().unwrap() } "#, - ).build(); + ) + .build(); p.cargo("build").run(); p.cargo("run").with_stdout("X { success: true }").run(); @@ -208,7 +220,8 @@ plugin = true proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" #![feature(plugin_registrar, rustc_private)] @@ -228,9 +241,10 @@ input } "#, - ).build(); + ) + .build(); - let msg = " lib.plugin and lib.proc-macro cannot both be true"; + let msg = " `lib.plugin` and `lib.proc-macro` cannot both be `true`"; p.cargo("build") .with_status(101) .with_stderr_contains(msg) @@ -250,7 +264,8 @@ [lib] proc-macro = true "#, - ).file( + ) + .file( "src/lib.rs", r#" #![crate_type = "proc-macro"] @@ -272,7 +287,8 @@ assert!(true); } "#, - ).build(); + ) + .build(); foo.cargo("test") .with_stdout_contains("test a ... ok") diff -Nru cargo-0.33.0/tests/testsuite/profile_config.rs cargo-0.35.0/tests/testsuite/profile_config.rs --- cargo-0.33.0/tests/testsuite/profile_config.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/profile_config.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_lib_manifest, paths, project}; +use crate::support::{basic_lib_manifest, is_nightly, paths, project}; #[test] fn profile_config_gated() { @@ -11,14 +11,16 @@ [profile.dev] debug = 1 "#, - ).build(); + ) + .build(); p.cargo("build -v") .with_stderr_contains( "\ [WARNING] profiles in config files require `-Z config-profile` command-line option ", - ).with_stderr_contains("[..]-C debuginfo=2[..]") + ) + .with_stderr_contains("[..]-C debuginfo=2[..]") .run(); } @@ -34,7 +36,8 @@ name = "foo" version = "0.0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" @@ -53,7 +56,8 @@ [profile.dev.overrides.bar] bad-key-bar = true "#, - ).build(); + ) + .build(); p.cargo("build -Z config-profile") .masquerade_as_nightly_cargo() @@ -67,7 +71,8 @@ [COMPILING] foo [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -81,13 +86,15 @@ [profile.dev] opt-level = 3 "#, - ).file( + ) + .file( paths::home().join(".cargo/config"), r#" [profile.dev] rpath = "foo" "#, - ).build(); + ) + .build(); p.cargo("build -Z config-profile") .masquerade_as_nightly_cargo() @@ -99,7 +106,8 @@ Caused by: error in [..].cargo/config: `profile.dev.rpath` expected true/false, but found a string ", - ).run(); + ) + .run(); } #[test] @@ -114,29 +122,29 @@ name = "foo" version = "0.0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" [profile.dev.overrides.foo] panic = "abort" "#, - ).build(); + ) + .build(); p.cargo("build -Z config-profile") .masquerade_as_nightly_cargo() .with_status(101) .with_stderr( "\ -[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` - -Caused by: - config profile `profile.dev` is not valid +[ERROR] config profile `profile.dev` is not valid Caused by: `panic` may not be specified in a profile override. ", - ).run(); + ) + .run(); } #[test] @@ -150,7 +158,8 @@ [profile.dev] codegen-units = "foo" "#, - ).build(); + ) + .build(); p.cargo("build -Z config-profile") .masquerade_as_nightly_cargo() @@ -162,7 +171,8 @@ Caused by: error in [..].cargo/config: `profile.dev.codegen-units` expected an integer, but found a string ", - ).run(); + ) + .run(); } #[test] @@ -180,7 +190,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file( + ) + .file( ".cargo/config", r#" [profile.dev.overrides.bar] @@ -189,7 +200,8 @@ [profile.dev.overrides."bar:0.5.0"] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -199,7 +211,8 @@ name = "bar" version = "0.5.0" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); // Unfortunately this doesn't tell you which file, hopefully it's not too @@ -211,15 +224,20 @@ "\ [ERROR] multiple profile overrides in profile `dev` match package `bar v0.5.0 ([..])` found profile override specs: bar, bar:0.5.0", - ).run(); + ) + .run(); } #[test] fn profile_config_all_options() { + if !is_nightly() { + // May be removed once 1.34 is stable (added support for incremental-LTO). + return; + } + // Ensure all profile options are supported. let p = project() - .file("Cargo.toml", &basic_lib_manifest("foo")) - .file("src/lib.rs", "") + .file("src/main.rs", "fn main() {}") .file( ".cargo/config", r#" @@ -234,24 +252,29 @@ panic = "abort" incremental = true "#, - ).build(); + ) + .build(); p.cargo("build --release -v -Z config-profile") .masquerade_as_nightly_cargo() + .env_remove("CARGO_INCREMENTAL") .with_stderr( "\ [COMPILING] foo [..] [RUNNING] `rustc --crate-name foo [..] \ -C opt-level=1 \ -C panic=abort \ + -C lto \ -C codegen-units=2 \ -C debuginfo=2 \ -C debug-assertions=on \ -C overflow-checks=off [..]\ - -C rpath [..] + -C rpath [..]\ + -C incremental=[..] [FINISHED] release [optimized + debuginfo] [..] ", - ).run(); + ) + .run(); } #[test] @@ -276,7 +299,8 @@ [profile.dev.overrides.bar] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "bar/Cargo.toml", r#" @@ -286,14 +310,16 @@ name = "bar" version = "0.0.1" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file( ".cargo/config", r#" [profile.dev.overrides.bar] opt-level = 2 "#, - ).build(); + ) + .build(); p.cargo("build -v -Z config-profile") .masquerade_as_nightly_cargo() @@ -304,7 +330,8 @@ [COMPILING] foo [..] [RUNNING] `rustc --crate-name foo [..]-C codegen-units=2 [..] [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -319,14 +346,16 @@ name = "foo" version = "0.0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( ".cargo/config", r#" [profile.dev.overrides.bar] codegen-units = 4 "#, - ).build(); + ) + .build(); p.cargo("build -Z config-profile") .masquerade_as_nightly_cargo() @@ -345,13 +374,15 @@ [profile.dev] opt-level = 3 "#, - ).file( + ) + .file( paths::home().join(".cargo/config"), r#" [profile.dev] opt-level = 's' "#, - ).build(); + ) + .build(); p.cargo("build -v -Z config-profile") .masquerade_as_nightly_cargo() diff -Nru cargo-0.33.0/tests/testsuite/profile_overrides.rs cargo-0.35.0/tests/testsuite/profile_overrides.rs --- cargo-0.33.0/tests/testsuite/profile_overrides.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/profile_overrides.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_lib_manifest, basic_manifest, project}; +use crate::support::{basic_lib_manifest, basic_manifest, project}; #[test] fn profile_override_gated() { @@ -14,7 +14,8 @@ [profile.dev.build-override] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -29,7 +30,8 @@ consider adding `cargo-features = [\"profile-overrides\"]` to the manifest ", - ).run(); + ) + .run(); let p = project() .file( @@ -43,7 +45,8 @@ [profile.dev.overrides."*"] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -58,7 +61,8 @@ consider adding `cargo-features = [\"profile-overrides\"]` to the manifest ", - ).run(); + ) + .run(); } #[test] @@ -83,7 +87,8 @@ [profile.dev.overrides.bar] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -96,7 +101,8 @@ [COMPILING] foo [..] [RUNNING] `rustc --crate-name foo [..] -C opt-level=1 [..]` [FINISHED] dev [optimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -123,7 +129,8 @@ [profile.dev.overrides."bar:1.2.3"] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -159,7 +166,8 @@ [profile.test.overrides.bar] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -172,7 +180,8 @@ Caused by: Profile overrides may only be specified for `dev` or `release` profile, not `test`. ", - ).run(); + ) + .run(); } #[test] @@ -212,7 +221,8 @@ "#, snippet ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -248,10 +258,11 @@ [profile.dev.build-override] codegen-units = 4 - "#) - + "#, + ) // m1 - .file("m1/Cargo.toml", + .file( + "m1/Cargo.toml", r#" [package] name = "m1" @@ -260,12 +271,13 @@ [dependencies] m2 = { path = "../m2" } dep = { path = "../../dep" } - "#) + "#, + ) .file("m1/src/lib.rs", "extern crate m2; extern crate dep;") .file("m1/build.rs", "fn main() {}") - // m2 - .file("m2/Cargo.toml", + .file( + "m2/Cargo.toml", r#" [package] name = "m2" @@ -277,10 +289,13 @@ [build-dependencies] m3 = { path = "../m3" } dep = { path = "../../dep" } - "#) + "#, + ) .file("m2/src/lib.rs", "extern crate m3;") - .file("m2/build.rs", "extern crate m3; extern crate dep; fn main() {}") - + .file( + "m2/build.rs", + "extern crate m3; extern crate dep; fn main() {}", + ) // m3 .file("m3/Cargo.toml", &basic_lib_manifest("m3")) .file("m3/src/lib.rs", "") @@ -343,7 +358,8 @@ [profile.dev.overrides."bar:0.5.0"] opt-level = 3 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file("bar/src/lib.rs", "") .build(); @@ -355,7 +371,8 @@ "\ [ERROR] multiple profile overrides in profile `dev` match package `bar v0.5.0 ([..])` found profile override specs: bar, bar:0.5.0", - ).run(); + ) + .run(); } #[test] @@ -374,10 +391,11 @@ [profile.dev.overrides."dep:2.0.0"] codegen-units = 2 - "#) - + "#, + ) // m1 - .file("m1/Cargo.toml", + .file( + "m1/Cargo.toml", r#" [package] name = "m1" @@ -385,11 +403,12 @@ [dependencies] dep = { path = "../../dep1" } - "#) + "#, + ) .file("m1/src/lib.rs", "extern crate dep;") - // m2 - .file("m2/Cargo.toml", + .file( + "m2/Cargo.toml", r#" [package] name = "m2" @@ -397,9 +416,9 @@ [dependencies] dep = {path = "../../dep2" } - "#) + "#, + ) .file("m2/src/lib.rs", "extern crate dep;") - .build(); project() diff -Nru cargo-0.33.0/tests/testsuite/profiles.rs cargo-0.35.0/tests/testsuite/profiles.rs --- cargo-0.33.0/tests/testsuite/profiles.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/profiles.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ use std::env; -use support::is_nightly; -use support::project; +use crate::support::is_nightly; +use crate::support::project; #[test] fn profile_overrides() { @@ -20,7 +20,8 @@ debug = false rpath = true "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_stderr( @@ -36,7 +37,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -54,7 +56,8 @@ [profile.dev] opt-level = 0 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_stderr( @@ -68,7 +71,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] [..] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -85,7 +89,8 @@ [profile.dev] debug = 1 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_stderr( @@ -99,7 +104,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] [..] target(s) in [..] ", - ).run(); + ) + .run(); } fn check_opt_level_override(profile_level: &str, rustc_level: &str) { @@ -119,7 +125,8 @@ "#, level = profile_level ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") .with_stderr(&format!( @@ -136,7 +143,8 @@ [FINISHED] [..] target(s) in [..] ", level = rustc_level - )).run(); + )) + .run(); } #[test] @@ -175,7 +183,8 @@ [dependencies.foo] path = "foo" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -193,7 +202,8 @@ name = "foo" crate_type = ["dylib", "rlib"] "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build -v --release") .with_stderr(&format!( @@ -223,7 +233,8 @@ ", prefix = env::consts::DLL_PREFIX, suffix = env::consts::DLL_SUFFIX - )).run(); + )) + .run(); } #[test] @@ -243,7 +254,8 @@ [profile.dev] debug = false "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -256,7 +268,8 @@ [profile.dev] opt-level = 1 "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -269,7 +282,8 @@ [COMPILING] bar v0.1.0 ([..]) [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -285,7 +299,8 @@ opt-level = 1 debug = false "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -295,7 +310,8 @@ authors = [] workspace = ".." "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .build(); p.cargo("build -v") @@ -305,7 +321,8 @@ [COMPILING] bar v0.1.0 ([..]) [RUNNING] `rustc [..]` [FINISHED] dev [optimized] target(s) in [..]", - ).run(); + ) + .run(); } #[test] @@ -324,7 +341,8 @@ [profile.bench] panic = "abort" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") @@ -333,7 +351,8 @@ [WARNING] `panic` setting is ignored for `test` profile [WARNING] `panic` setting is ignored for `bench` profile ", - ).run(); + ) + .run(); } #[test] @@ -349,7 +368,8 @@ [profile.doc] opt-level = 0 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build") diff -Nru cargo-0.33.0/tests/testsuite/profile_targets.rs cargo-0.35.0/tests/testsuite/profile_targets.rs --- cargo-0.33.0/tests/testsuite/profile_targets.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/profile_targets.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,6 @@ -use support::is_nightly; -use support::{basic_manifest, project, Project}; +use crate::support::{basic_manifest, project, Project}; -// These tests try to exercise exactly which profiles are selected for every -// target. +// These tests try to exercise exactly which profiles are selected for every target. fn all_target_project() -> Project { // This abuses the `codegen-units` setting so that we can verify exactly @@ -38,7 +36,9 @@ .file("examples/ex1.rs", "extern crate foo; fn main() {}") .file("tests/test1.rs", "extern crate foo;") .file("benches/bench1.rs", "extern crate foo;") - .file("build.rs", r#" + .file( + "build.rs", + r#" extern crate bdep; fn main() { eprintln!("foo custom build PROFILE={} DEBUG={} OPT_LEVEL={}", @@ -47,21 +47,23 @@ std::env::var("OPT_LEVEL").unwrap(), ); } - "#) - - // bar package + "#, + ) + // `bar` package. .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") - - // bdep package - .file("bdep/Cargo.toml", r#" + // `bdep` package. + .file( + "bdep/Cargo.toml", + r#" [package] name = "bdep" version = "0.0.1" [dependencies] bar = { path = "../bar" } - "#) + "#, + ) .file("bdep/src/lib.rs", "extern crate bar;") .build() } @@ -70,22 +72,22 @@ fn profile_selection_build() { let p = all_target_project(); - // Build default targets. + // `build` // NOTES: // - bdep `panic` is not set because it thinks `build.rs` is a plugin. // - build_script_build is built without panic because it thinks `build.rs` is a plugin. p.cargo("build -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); p.cargo("build -vv") @@ -96,26 +98,27 @@ [FRESH] foo [..] [FINISHED] dev [unoptimized + debuginfo] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_build_release() { let p = all_target_project(); - // Build default targets, release. + // `build --release` p.cargo("build --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] ").run(); p.cargo("build --release -vv") @@ -126,19 +129,20 @@ [FRESH] foo [..] [FINISHED] release [optimized] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_build_all_targets() { let p = all_target_project(); - // Build all explicit targets. - // NOTES + // `build` + // NOTES: // - bdep `panic` is not set because it thinks `build.rs` is a plugin. // - build_script_build is built without panic because it thinks // `build.rs` is a plugin. // - Benchmark dependencies are compiled in `dev` mode, which may be - // surprising. See https://github.com/rust-lang/cargo/issues/4929. + // surprising. See issue rust-lang/cargo#4929. // // - Dependency profiles: // Pkg Target Profile Reason @@ -148,7 +152,7 @@ // bdep lib dev-panic For foo build.rs // foo custom dev-panic // - // - foo target list is: + // - `foo` target list is: // Target Profile Mode // ------ ------- ---- // lib dev+panic build (a normal lib target) @@ -161,22 +165,22 @@ // example dev build p.cargo("build --all-targets -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..]` [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); p.cargo("build -vv") @@ -187,20 +191,21 @@ [FRESH] foo [..] [FINISHED] dev [unoptimized + debuginfo] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_build_all_targets_release() { let p = all_target_project(); - // Build all explicit targets, release. - // NOTES + // `build --all-targets --release` + // NOTES: // - bdep `panic` is not set because it thinks `build.rs` is a plugin. - // - bar compiled twice. It tries with and without panic, but the "is a + // - bar compiled twice. It tries with and without panic, but the "is a // plugin" logic is forcing it to be cleared. // - build_script_build is built without panic because it thinks // `build.rs` is a plugin. - // - build_script_build is being run two times. Once for the `dev` and + // - build_script_build is being run two times. Once for the `dev` and // `test` targets, once for the `bench` targets. // TODO: "PROFILE" says debug both times, though! // @@ -212,7 +217,7 @@ // bdep lib release-panic For foo build.rs // foo custom release-panic // - // - foo target list is: + // - `foo` target list is: // Target Profile Mode // ------ ------- ---- // lib release+panic build (a normal lib target) @@ -225,22 +230,22 @@ // example release build p.cargo("build --all-targets --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..]` -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..]` +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..]` [FINISHED] release [optimized] [..] ").run(); p.cargo("build --all-targets --release -vv") @@ -251,13 +256,14 @@ [FRESH] foo [..] [FINISHED] release [optimized] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_test() { let p = all_target_project(); - // Test default. + // `test` // NOTES: // - Dependency profiles: // Pkg Target Profile Reason @@ -267,7 +273,7 @@ // bdep lib dev-panic For foo build.rs // foo custom dev-panic // - // - foo target list is: + // - `foo` target list is: // Target Profile Mode // ------ ------- ---- // lib dev-panic build (for tests) @@ -280,21 +286,21 @@ // p.cargo("test -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C codegen-units=3 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] [RUNNING] `[..]/deps/foo-[..]` [RUNNING] `[..]/deps/foo-[..]` @@ -315,13 +321,14 @@ [DOCTEST] foo [RUNNING] `rustdoc --test [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_test_release() { let p = all_target_project(); - // Test default release. + // `test --release` // NOTES: // - Dependency profiles: // Pkg Target Profile Reason @@ -331,7 +338,7 @@ // bdep lib release-panic For foo build.rs // foo custom release-panic // - // - foo target list is: + // - `foo` target list is: // Target Profile Mode // ------ ------- ---- // lib release-panic build (for tests) @@ -344,21 +351,21 @@ // p.cargo("test --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]/target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] [RUNNING] `[..]/deps/foo-[..]` [RUNNING] `[..]/deps/foo-[..]` @@ -379,14 +386,15 @@ [DOCTEST] foo [RUNNING] `rustdoc --test [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_bench() { let p = all_target_project(); - // Bench default. + // `bench` // NOTES: // - Dependency profiles: // Pkg Target Profile Reason @@ -396,7 +404,7 @@ // bdep lib release-panic For foo build.rs // foo custom release-panic // - // - foo target list is: + // - `foo` target list is: // Target Profile Mode // ------ ------- ---- // lib release-panic build (for benches) @@ -408,20 +416,20 @@ // p.cargo("bench -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,link -C opt-level=3 -C codegen-units=4 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] [RUNNING] `[..]/deps/foo-[..] --bench` [RUNNING] `[..]/deps/foo-[..] --bench` @@ -438,18 +446,14 @@ [RUNNING] `[..]/deps/foo-[..] --bench` [RUNNING] `[..]/deps/bench1-[..] --bench` ", - ).run(); + ) + .run(); } #[test] fn profile_selection_check_all_targets() { - if !is_nightly() { - // This can be removed once 1.27 is stable, see below. - return; - } - let p = all_target_project(); - // check + // `check` // NOTES: // - Dependency profiles: // Pkg Target Profile Action Reason @@ -476,30 +480,29 @@ // p.cargo("check --all-targets -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep[..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); // Starting with Rust 1.27, rustc emits `rmeta` files for bins, so - // everything should be completely fresh. Previously, bins were being + // everything should be completely fresh. Previously, bins were being // rechecked. - // See https://github.com/rust-lang/rust/pull/49289 and - // https://github.com/rust-lang/cargo/issues/3624 + // See PR rust-lang/rust#49289 and issue rust-lang/cargo#3624. p.cargo("check --all-targets -vv") .with_stderr_unordered( "\ @@ -508,41 +511,37 @@ [FRESH] foo [..] [FINISHED] dev [unoptimized + debuginfo] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_check_all_targets_release() { - if !is_nightly() { - // See note in profile_selection_check_all_targets. - return; - } - let p = all_target_project(); - // check --release - // https://github.com/rust-lang/cargo/issues/5218 + // `check --release` + // See issue rust-lang/cargo#5218. // This is a pretty straightforward variant of // `profile_selection_check_all_targets` that uses `release` instead of // `dev` for all targets. p.cargo("check --all-targets --release -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [COMPILING] bdep[..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C opt-level=3 -C codegen-units=2 [..] [RUNNING] `[..]target/release/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=release DEBUG=false OPT_LEVEL=3 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C opt-level=3 -C codegen-units=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--crate-type bin --emit=dep-info,metadata -C opt-level=3 -C panic=abort -C codegen-units=2 [..] [FINISHED] release [optimized] [..] ").run(); @@ -554,21 +553,17 @@ [FRESH] foo [..] [FINISHED] release [optimized] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_check_all_targets_test() { - if !is_nightly() { - // See note in profile_selection_check_all_targets. - return; - } - let p = all_target_project(); - // check --profile=test + // `check --profile=test` // NOTES: - // - This doesn't actually use the "test" profile. Everything uses dev. - // It probably should use "test"??? Probably doesn't really matter. + // - This doesn't actually use the "test" profile. Everything uses "dev". + // It should probably use "test", although it probably doesn't really matter. // - Dependency profiles: // Pkg Target Profile Action Reason // --- ------ ------- ------ ------ @@ -591,20 +586,20 @@ // p.cargo("check --all-targets --profile=test -vv").with_stderr_unordered("\ [COMPILING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep[..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] -[RUNNING] `rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] -[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name test1 tests/test1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name foo src/main.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name bench1 benches/bench1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] +[RUNNING] `[..] rustc --crate-name ex1 examples/ex1.rs [..]--emit=dep-info,metadata -C codegen-units=1 -C debuginfo=2 --test [..] [FINISHED] dev [unoptimized + debuginfo] [..] ").run(); @@ -616,13 +611,14 @@ [FRESH] foo [..] [FINISHED] dev [unoptimized + debuginfo] [..] ", - ).run(); + ) + .run(); } #[test] fn profile_selection_doc() { let p = all_target_project(); - // doc + // `doc` // NOTES: // - Dependency profiles: // Pkg Target Profile Action Reason @@ -636,13 +632,13 @@ p.cargo("doc -vv").with_stderr_unordered("\ [COMPILING] bar [..] [DOCUMENTING] bar [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `rustdoc --crate-name bar bar/src/lib.rs [..] -[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=dep-info,metadata -C panic=abort -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] bdep [..] -[RUNNING] `rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [COMPILING] foo [..] -[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] +[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=dep-info,link -C codegen-units=1 -C debuginfo=2 [..] [RUNNING] `[..]target/debug/build/foo-[..]/build-script-build` [foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0 [DOCUMENTING] foo [..] diff -Nru cargo-0.33.0/tests/testsuite/publish.rs cargo-0.35.0/tests/testsuite/publish.rs --- cargo-0.33.0/tests/testsuite/publish.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/publish.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,16 +1,77 @@ use std::fs::{self, File}; use std::io::prelude::*; -use std::io::SeekFrom; -use flate2::read::GzDecoder; -use support::git::repo; -use support::paths; -use support::{basic_manifest, project, publish}; -use tar::Archive; +use crate::support::git::repo; +use crate::support::paths; +use crate::support::registry::{self, registry_path, registry_url, Package}; +use crate::support::{basic_manifest, project, publish}; + +const CLEAN_FOO_JSON: &str = r#" + { + "authors": [], + "badges": {}, + "categories": [], + "deps": [], + "description": "foo", + "documentation": "foo", + "features": {}, + "homepage": "foo", + "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": "foo", + "vers": "0.0.1" + } +"#; + +fn validate_upload_foo() { + publish::validate_upload( + r#" + { + "authors": [], + "badges": {}, + "categories": [], + "deps": [], + "description": "foo", + "documentation": null, + "features": {}, + "homepage": null, + "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.0.1" + } + "#, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + ); +} + +fn validate_upload_foo_clean() { + publish::validate_upload( + CLEAN_FOO_JSON, + "foo-0.0.1.crate", + &[ + "Cargo.toml", + "Cargo.toml.orig", + "src/main.rs", + ".cargo_vcs_info.json", + ], + ); +} #[test] fn simple() { - publish::setup(); + registry::init(); let p = project() .file( @@ -23,11 +84,12 @@ license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_stderr(&format!( "\ [UPDATING] `{reg}` index @@ -36,54 +98,18 @@ [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) ", - reg = publish::registry_path().to_str().unwrap() - )).run(); + reg = registry::registry_path().to_str().unwrap() + )) + .run(); - let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); - // Skip the metadata payload and the size of the tarball - let mut sz = [0; 4]; - assert_eq!(f.read(&mut sz).unwrap(), 4); - let sz = (u32::from(sz[0]) << 0) - | (u32::from(sz[1]) << 8) - | (u32::from(sz[2]) << 16) - | (u32::from(sz[3]) << 24); - f.seek(SeekFrom::Current(i64::from(sz) + 4)).unwrap(); - - // Verify the tarball - let mut rdr = GzDecoder::new(f); - assert_eq!( - rdr.header().unwrap().filename().unwrap(), - b"foo-0.0.1.crate" - ); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for file in ar.entries().unwrap() { - let file = file.unwrap(); - let fname = file.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - file.header().path() - ); - } + validate_upload_foo(); } #[test] fn old_token_location() { - publish::setup(); - - // publish::setup puts a token in this file. - fs::remove_file(paths::root().join(".cargo/config")).unwrap(); - - let credentials = paths::root().join("home/.cargo/credentials"); - File::create(credentials) - .unwrap() - .write_all(br#"token = "api-token""#) - .unwrap(); + // Check that the `token` key works at the root instead of under a + // `[registry]` table. + registry::init(); let p = project() .file( @@ -96,11 +122,27 @@ license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); + let credentials = paths::home().join(".cargo/credentials"); + fs::remove_file(&credentials).unwrap(); + + // Verify can't publish without a token. p.cargo("publish --no-verify --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) + .with_status(101) + .with_stderr_contains("[ERROR] no upload token found, please run `cargo login`") + .run(); + + File::create(&credentials) + .unwrap() + .write_all(br#"token = "api-token""#) + .unwrap(); + + p.cargo("publish --no-verify --index") + .arg(registry_url().to_string()) .with_stderr(&format!( "\ [UPDATING] `{reg}` index @@ -109,47 +151,18 @@ [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) ", - reg = publish::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); - let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); - // Skip the metadata payload and the size of the tarball - let mut sz = [0; 4]; - assert_eq!(f.read(&mut sz).unwrap(), 4); - let sz = (u32::from(sz[0]) << 0) - | (u32::from(sz[1]) << 8) - | (u32::from(sz[2]) << 16) - | (u32::from(sz[3]) << 24); - f.seek(SeekFrom::Current(i64::from(sz) + 4)).unwrap(); - - // Verify the tarball - let mut rdr = GzDecoder::new(f); - assert_eq!( - rdr.header().unwrap().filename().unwrap(), - b"foo-0.0.1.crate" - ); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for file in ar.entries().unwrap() { - let file = file.unwrap(); - let fname = file.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - file.header().path() - ); - } + validate_upload_foo(); } // TODO: Deprecated // remove once it has been decided --host can be removed #[test] fn simple_with_host() { - publish::setup(); + registry::init(); let p = project() .file( @@ -162,11 +175,12 @@ license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --host") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_stderr(&format!( "\ [WARNING] The flag '--host' is no longer valid. @@ -184,47 +198,18 @@ [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) ", - reg = publish::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); - let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); - // Skip the metadata payload and the size of the tarball - let mut sz = [0; 4]; - assert_eq!(f.read(&mut sz).unwrap(), 4); - let sz = (u32::from(sz[0]) << 0) - | (u32::from(sz[1]) << 8) - | (u32::from(sz[2]) << 16) - | (u32::from(sz[3]) << 24); - f.seek(SeekFrom::Current(i64::from(sz) + 4)).unwrap(); - - // Verify the tarball - let mut rdr = GzDecoder::new(f); - assert_eq!( - rdr.header().unwrap().filename().unwrap(), - b"foo-0.0.1.crate" - ); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for file in ar.entries().unwrap() { - let file = file.unwrap(); - let fname = file.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - file.header().path() - ); - } + validate_upload_foo(); } // TODO: Deprecated // remove once it has been decided --host can be removed #[test] fn simple_with_index_and_host() { - publish::setup(); + registry::init(); let p = project() .file( @@ -237,13 +222,14 @@ license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --no-verify --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .arg("--host") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_stderr(&format!( "\ [WARNING] The flag '--host' is no longer valid. @@ -261,45 +247,16 @@ [PACKAGING] foo v0.0.1 ([CWD]) [UPLOADING] foo v0.0.1 ([CWD]) ", - reg = publish::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); - let mut f = File::open(&publish::upload_path().join("api/v1/crates/new")).unwrap(); - // Skip the metadata payload and the size of the tarball - let mut sz = [0; 4]; - assert_eq!(f.read(&mut sz).unwrap(), 4); - let sz = (u32::from(sz[0]) << 0) - | (u32::from(sz[1]) << 8) - | (u32::from(sz[2]) << 16) - | (u32::from(sz[3]) << 24); - f.seek(SeekFrom::Current(i64::from(sz) + 4)).unwrap(); - - // Verify the tarball - let mut rdr = GzDecoder::new(f); - assert_eq!( - rdr.header().unwrap().filename().unwrap(), - b"foo-0.0.1.crate" - ); - let mut contents = Vec::new(); - rdr.read_to_end(&mut contents).unwrap(); - let mut ar = Archive::new(&contents[..]); - for file in ar.entries().unwrap() { - let file = file.unwrap(); - let fname = file.header().path_bytes(); - let fname = &*fname; - assert!( - fname == b"foo-0.0.1/Cargo.toml" - || fname == b"foo-0.0.1/Cargo.toml.orig" - || fname == b"foo-0.0.1/src/main.rs", - "unexpected filename: {:?}", - file.header().path() - ); - } + validate_upload_foo(); } #[test] fn git_deps() { - publish::setup(); + registry::init(); let p = project() .file( @@ -315,27 +272,29 @@ [dependencies.foo] git = "git://path/to/nowhere" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish -v --no-verify --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) .with_stderr( "\ [UPDATING] [..] index -[ERROR] crates cannot be published to crates.io with dependencies sourced from \ -a repository\neither publish `foo` as its own crate on crates.io and \ -specify a crates.io version as a dependency or pull it into this \ +[ERROR] crates cannot be published with dependencies sourced from \ +a repository\neither publish `foo` as its own crate and \ +specify a version as a dependency or pull it into this \ repository and specify it with a path and version\n\ (crate `foo` has repository path `git://path/to/nowhere`)\ ", - ).run(); + ) + .run(); } #[test] fn path_dependency_no_version() { - publish::setup(); + registry::init(); let p = project() .file( @@ -351,13 +310,14 @@ [dependencies.bar] path = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) .with_stderr( "\ @@ -365,12 +325,13 @@ [ERROR] all path dependencies must have a version specified when publishing. dependency `bar` does not specify a version ", - ).run(); + ) + .run(); } #[test] fn unpublishable_crate() { - publish::setup(); + registry::init(); let p = project() .file( @@ -384,23 +345,25 @@ description = "foo" publish = false "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) .with_stderr( "\ [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] fn dont_publish_dirty() { - publish::setup(); + registry::init(); let p = project().file("bar", "").build(); let _ = repo(&paths::root().join("foo")) @@ -417,11 +380,12 @@ homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) .with_stderr( "\ @@ -433,12 +397,13 @@ to proceed despite this, pass the `--allow-dirty` flag ", - ).run(); + ) + .run(); } #[test] fn publish_clean() { - publish::setup(); + registry::init(); let p = project().build(); @@ -456,17 +421,20 @@ homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .run(); + + validate_upload_foo_clean(); } #[test] fn publish_in_sub_repo() { - publish::setup(); + registry::init(); let p = project().no_manifest().file("baz", "").build(); @@ -484,19 +452,22 @@ homepage = "foo" repository = "foo" "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .build(); p.cargo("publish") .cwd(p.root().join("bar")) .arg("--index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .run(); + + validate_upload_foo_clean(); } #[test] fn publish_when_ignored() { - publish::setup(); + registry::init(); let p = project().file("baz", "").build(); @@ -514,18 +485,31 @@ homepage = "foo" repository = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file(".gitignore", "baz") .build(); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .run(); + + publish::validate_upload( + CLEAN_FOO_JSON, + "foo-0.0.1.crate", + &[ + "Cargo.toml", + "Cargo.toml.orig", + "src/main.rs", + ".gitignore", + ".cargo_vcs_info.json", + ], + ); } #[test] fn ignore_when_crate_ignored() { - publish::setup(); + registry::init(); let p = project().no_manifest().file("bar/baz", "").build(); @@ -544,17 +528,24 @@ homepage = "foo" repository = "foo" "#, - ).nocommit_file("bar/src/main.rs", "fn main() {}"); + ) + .nocommit_file("bar/src/main.rs", "fn main() {}"); p.cargo("publish") .cwd(p.root().join("bar")) .arg("--index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .run(); + + publish::validate_upload( + CLEAN_FOO_JSON, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "baz"], + ); } #[test] fn new_crate_rejected() { - publish::setup(); + registry::init(); let p = project().file("baz", "").build(); @@ -572,16 +563,21 @@ homepage = "foo" repository = "foo" "#, - ).nocommit_file("src/main.rs", "fn main() {}"); + ) + .nocommit_file("src/main.rs", "fn main() {}"); p.cargo("publish --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) + .with_stderr_contains( + "[ERROR] 3 files in the working directory contain \ + changes that were not yet committed into git:", + ) .run(); } #[test] fn dry_run() { - publish::setup(); + registry::init(); let p = project() .file( @@ -594,11 +590,12 @@ license = "MIT" description = "foo" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish --dry-run --index") - .arg(publish::registry().to_string()) + .arg(registry_url().to_string()) .with_stderr( "\ [UPDATING] `[..]` index @@ -611,15 +608,17 @@ [UPLOADING] foo v0.0.1 ([CWD]) [WARNING] aborting upload due to dry run ", - ).run(); + ) + .run(); // Ensure the API request wasn't actually made - assert!(!publish::upload_path().join("api/v1/crates/new").exists()); + assert!(registry::api_path().join("api/v1/crates").exists()); + assert!(!registry::api_path().join("api/v1/crates/new").exists()); } #[test] -fn block_publish_feature_not_enabled() { - publish::setup(); +fn registry_not_in_publish_list() { + registry::init(); let p = project() .file( @@ -635,74 +634,101 @@ "test" ] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + p.cargo("publish") + .arg("--registry") + .arg("alternative") .with_status(101) .with_stderr( "\ -error: failed to parse manifest at `[..]` - -Caused by: - the `publish` manifest key is unstable for anything other than a value of true or false - -Caused by: - feature `alternative-registries` is required - -consider adding `cargo-features = [\"alternative-registries\"]` to the manifest +[ERROR] some crates cannot be published. +`foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] -fn registry_not_in_publish_list() { - publish::setup(); +fn publish_empty_list() { + registry::init(); let p = project() .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] - [project] name = "foo" version = "0.0.1" authors = [] license = "MIT" description = "foo" - publish = [ - "test" - ] + publish = [] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("publish") - .masquerade_as_nightly_cargo() - .arg("--registry") - .arg("alternative") - .arg("-Zunstable-options") + p.cargo("publish --registry alternative") .with_status(101) .with_stderr( "\ [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] -fn publish_empty_list() { - publish::setup(); +fn publish_allowed_registry() { + registry::init(); - let p = project() + let p = project().build(); + + let _ = repo(&paths::root().join("foo")) .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + publish = ["alternative"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("publish --registry alternative").run(); + publish::validate_alt_upload( + CLEAN_FOO_JSON, + "foo-0.0.1.crate", + &[ + "Cargo.toml", + "Cargo.toml.orig", + "src/main.rs", + ".cargo_vcs_info.json", + ], + ); +} + +#[test] +fn block_publish_no_registry() { + registry::init(); + + let p = project() + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" @@ -711,78 +737,209 @@ description = "foo" publish = [] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + p.cargo("publish --registry alternative") .with_status(101) .with_stderr( "\ [ERROR] some crates cannot be published. `foo` is marked as unpublishable ", - ).run(); + ) + .run(); } #[test] -fn publish_allowed_registry() { - publish::setup(); +fn publish_with_select_features() { + registry::init(); - let p = project().build(); - - let _ = repo(&paths::root().join("foo")) + let p = project() .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [features] + required = [] + optional = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("publish --features required --index") + .arg(registry_url().to_string()) + .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])") + .run(); +} +#[test] +fn publish_with_all_features() { + registry::init(); + + let p = project() + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" authors = [] license = "MIT" description = "foo" - documentation = "foo" - homepage = "foo" - publish = ["alternative"] + + [features] + required = [] + optional = [] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) .build(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + p.cargo("publish --all-features --index") + .arg(registry_url().to_string()) + .with_stderr_contains("[UPLOADING] foo v0.0.1 ([CWD])") .run(); } #[test] -fn block_publish_no_registry() { - publish::setup(); +fn publish_with_no_default_features() { + registry::init(); let p = project() .file( "Cargo.toml", r#" - cargo-features = ["alternative-registries"] + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + [features] + default = ["required"] + required = [] + "#, + ) + .file( + "src/main.rs", + "#[cfg(not(feature = \"required\"))] + compile_error!(\"This crate requires `required` feature!\"); + fn main() {}", + ) + .build(); + + p.cargo("publish --no-default-features --index") + .arg(registry_url().to_string()) + .with_stderr_contains("error: This crate requires `required` feature!") + .with_status(101) + .run(); +} + +#[test] +fn publish_with_patch() { + Package::new("bar", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.0.1" authors = [] license = "MIT" description = "foo" - publish = [] + [dependencies] + bar = "1.0" + [patch.crates-io] + bar = { path = "bar" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file( + "src/main.rs", + "extern crate bar; + fn main() { + bar::newfunc(); + }", + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("bar/src/lib.rs", "pub fn newfunc() {}") .build(); - p.cargo("publish --registry alternative -Zunstable-options") - .masquerade_as_nightly_cargo() + // Check that it works with the patched crate. + p.cargo("build").run(); + + // Check that verify fails with patched crate which has new functionality. + p.cargo("publish --index") + .arg(registry_url().to_string()) + .with_stderr_contains("[..]newfunc[..]") .with_status(101) - .with_stderr( - "\ -[ERROR] some crates cannot be published. -`foo` is marked as unpublishable -", - ).run(); + .run(); + + // Remove the usage of new functionality and try again. + p.change_file("src/main.rs", "extern crate bar; pub fn main() {}"); + + p.cargo("publish --index") + .arg(registry_url().to_string()) + .run(); + + // Note, use of `registry` in the deps here is an artifact that this + // publishes to a fake, local registry that is pretending to be crates.io. + // Normal publishes would set it to null. + publish::validate_upload( + r#" + { + "authors": [], + "badges": {}, + "categories": [], + "deps": [ + { + "default_features": true, + "features": [], + "kind": "normal", + "name": "bar", + "optional": false, + "registry": "https://github.com/rust-lang/crates.io-index", + "target": null, + "version_req": "^1.0" + } + ], + "description": "foo", + "documentation": null, + "features": {}, + "homepage": null, + "keywords": [], + "license": "MIT", + "license_file": null, + "links": null, + "name": "foo", + "readme": null, + "readme_file": null, + "repository": null, + "vers": "0.0.1" + } + "#, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + ); } diff -Nru cargo-0.33.0/tests/testsuite/read_manifest.rs cargo-0.35.0/tests/testsuite/read_manifest.rs --- cargo-0.33.0/tests/testsuite/read_manifest.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/read_manifest.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_bin_manifest, main_file, project}; +use crate::support::{basic_bin_manifest, main_file, project}; static MANIFEST_OUTPUT: &'static str = r#" { @@ -14,6 +14,7 @@ "keywords": [], "license": null, "license_file": null, + "links": null, "description": null, "edition": "2015", "source":null, @@ -70,7 +71,8 @@ .with_stderr( "[ERROR] the manifest-path must be \ a path to a Cargo.toml file", - ).run(); + ) + .run(); } #[test] @@ -87,7 +89,8 @@ .with_stderr( "[ERROR] the manifest-path must be \ a path to a Cargo.toml file", - ).run(); + ) + .run(); } #[test] @@ -97,7 +100,5 @@ .file("src/foo.rs", &main_file(r#""i am foo""#, &[])) .build(); - p.cargo("read-manifest") - .with_json(MANIFEST_OUTPUT) - .run(); + p.cargo("read-manifest").with_json(MANIFEST_OUTPUT).run(); } diff -Nru cargo-0.33.0/tests/testsuite/registry.rs cargo-0.35.0/tests/testsuite/registry.rs --- cargo-0.33.0/tests/testsuite/registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,21 +1,12 @@ use std::fs::{self, File}; use std::io::prelude::*; -use std::path::PathBuf; +use crate::support::cargo_process; +use crate::support::git; +use crate::support::paths::{self, CargoPathExt}; +use crate::support::registry::{self, registry_path, registry_url, Dependency, Package}; +use crate::support::{basic_manifest, project}; use cargo::util::paths::remove_dir_all; -use support::cargo_process; -use support::git; -use support::paths::{self, CargoPathExt}; -use support::registry::{self, Package, Dependency}; -use support::{basic_manifest, project}; -use url::Url; - -fn registry_path() -> PathBuf { - paths::root().join("registry") -} -fn registry() -> Url { - Url::from_file_path(&*registry_path()).ok().unwrap() -} #[test] fn simple() { @@ -31,7 +22,8 @@ [dependencies] bar = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); @@ -46,8 +38,9 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - reg = registry::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); p.cargo("clean").run(); @@ -59,7 +52,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -76,7 +70,8 @@ [dependencies] bar = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); @@ -94,8 +89,9 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - reg = registry::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); } #[test] @@ -114,7 +110,8 @@ [dependencies] nonexistent = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build") @@ -126,7 +123,8 @@ location searched: registry [..] required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -145,7 +143,8 @@ [dependencies] Init = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); // #5678 to make this work @@ -156,10 +155,11 @@ [UPDATING] [..] index error: no matching package named `Init` found location searched: registry [..] -did you mean: init +perhaps you meant: init required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -178,7 +178,8 @@ [dependencies] mis_hyphenated = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); // #2775 to make this work @@ -189,10 +190,11 @@ [UPDATING] [..] index error: no matching package named `mis_hyphenated` found location searched: registry [..] -did you mean: mis-hyphenated +perhaps you meant: mis-hyphenated required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -209,7 +211,8 @@ [dependencies] foo = ">= 1.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foo", "0.0.1").publish(); @@ -224,7 +227,8 @@ location searched: `[..]` index (which is replacing registry `[..]`) required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); Package::new("foo", "0.0.3").publish(); Package::new("foo", "0.0.4").publish(); @@ -238,7 +242,8 @@ location searched: `[..]` index (which is replacing registry `[..]`) required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); } #[test] @@ -255,7 +260,8 @@ [dependencies] bad-cksum = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); let pkg = Package::new("bad-cksum", "0.0.1"); @@ -274,7 +280,8 @@ Caused by: failed to verify the checksum of `bad-cksum v0.0.1 (registry `[ROOT][..]`)` ", - ).run(); + ) + .run(); } #[test] @@ -293,7 +300,8 @@ [dependencies] notyet = ">= 0.0.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build") @@ -304,7 +312,8 @@ location searched: registry `[..]` required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); Package::new("notyet", "0.0.1").publish(); @@ -318,8 +327,9 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - reg = registry::registry_path().to_str().unwrap() - )).run(); + reg = registry_path().to_str().unwrap() + )) + .run(); } #[test] @@ -342,7 +352,8 @@ version = "0.0.1" path = "notyet" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("notyet/Cargo.toml", &basic_manifest("notyet", "0.0.1")) .file("notyet/src/lib.rs", "") .build(); @@ -358,7 +369,8 @@ location searched: registry [..] required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); Package::new("notyet", "0.0.1").publish(); @@ -374,7 +386,8 @@ [COMPILING] foo v0.0.1 ([CWD][..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -391,7 +404,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); @@ -406,7 +420,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); p.root().move_into_the_past(); Package::new("bar", "0.0.2").publish(); @@ -428,7 +443,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); @@ -446,7 +462,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); p.root().move_into_the_past(); Package::new("baz", "0.0.2").publish(); @@ -469,7 +486,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); @@ -492,7 +510,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -509,7 +528,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); @@ -526,7 +546,8 @@ required by package `bar v0.0.1` ... which is depended on by `foo [..]` ", - ).run(); + ) + .run(); } #[test] @@ -543,14 +564,15 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); p.cargo("build").run(); - registry::registry_path().join("3").rm_rf(); + registry_path().join("3").rm_rf(); Package::new("bar", "0.0.1").yanked(true).publish(); @@ -564,7 +586,105 @@ location searched: registry [..] required by package `foo v0.0.1 ([..])` ", - ).run(); + ) + .run(); +} + +#[test] +fn yanks_in_lockfiles_are_ok_for_other_update() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "*" + baz = "*" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("bar", "0.0.1").publish(); + Package::new("baz", "0.0.1").publish(); + + p.cargo("build").run(); + + registry_path().join("3").rm_rf(); + + Package::new("bar", "0.0.1").yanked(true).publish(); + Package::new("baz", "0.0.1").publish(); + + p.cargo("build").with_stdout("").run(); + + Package::new("baz", "0.0.2").publish(); + + p.cargo("update") + .with_status(101) + .with_stderr_contains( + "\ +error: no matching package named `bar` found +location searched: registry [..] +required by package `foo v0.0.1 ([..])` +", + ) + .run(); + + p.cargo("update -p baz") + .with_stderr_contains( + "\ +[UPDATING] `[..]` index +[UPDATING] baz v0.0.1 -> v0.0.2 +", + ) + .run(); +} + +#[test] +fn yanks_in_lockfiles_are_ok_with_new_dep() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "*" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("bar", "0.0.1").publish(); + + p.cargo("build").run(); + + registry_path().join("3").rm_rf(); + + Package::new("bar", "0.0.1").yanked(true).publish(); + Package::new("baz", "0.0.1").publish(); + + t!(t!(File::create(p.root().join("Cargo.toml"))).write_all( + br#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "*" + baz = "*" + "# + )); + + p.cargo("build").with_stdout("").run(); } #[test] @@ -581,7 +701,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.0.1").publish(); @@ -597,7 +718,8 @@ [DOWNLOADED] bar v0.0.1 (registry `[ROOT][..]`) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -614,7 +736,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); println!("0.0.1"); @@ -631,7 +754,8 @@ [UPDATING] `[..]` index [UPDATING] bar v0.0.1 -> v0.0.2 ", - ).run(); + ) + .run(); println!("0.0.2 build"); p.cargo("build") @@ -643,7 +767,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); println!("0.0.3 update"); p.cargo("update -p bar") @@ -652,7 +777,8 @@ [UPDATING] `[..]` index [UPDATING] bar v0.0.2 -> v0.0.3 ", - ).run(); + ) + .run(); println!("0.0.3 build"); p.cargo("build") @@ -664,7 +790,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); println!("new dependencies update"); Package::new("bar", "0.0.4").dep("spam", "0.2.5").publish(); @@ -676,7 +803,8 @@ [UPDATING] bar v0.0.3 -> v0.0.4 [ADDING] spam v0.2.5 ", - ).run(); + ) + .run(); println!("new dependencies update"); Package::new("bar", "0.0.5").publish(); @@ -687,7 +815,8 @@ [UPDATING] bar v0.0.4 -> v0.0.5 [REMOVING] spam v0.2.5 ", - ).run(); + ) + .run(); } #[test] @@ -704,7 +833,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("update -Zoffline") .masquerade_as_nightly_cargo() @@ -727,7 +857,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); @@ -743,24 +874,33 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] fn login_with_no_cargo_dir() { - let home = paths::home().join("new-home"); - t!(fs::create_dir(&home)); + // Create a config in the root directory because `login` requires the + // index to be updated, and we don't want to hit crates.io. + registry::init(); + fs::rename(paths::home().join(".cargo"), paths::root().join(".cargo")).unwrap(); + paths::home().rm_rf(); cargo_process("login foo -v").run(); + let credentials = fs::read_to_string(paths::home().join(".cargo/credentials")).unwrap(); + assert_eq!(credentials, "[registry]\ntoken = \"foo\"\n"); } #[test] fn login_with_differently_sized_token() { - // Verify that the configuration file gets properly trunchated. - let home = paths::home().join("new-home"); - t!(fs::create_dir(&home)); + // Verify that the configuration file gets properly truncated. + registry::init(); + let credentials = paths::home().join(".cargo/credentials"); + fs::remove_file(&credentials).unwrap(); cargo_process("login lmaolmaolmao -v").run(); cargo_process("login lmao -v").run(); cargo_process("login lmaolmaolmao -v").run(); + let credentials = fs::read_to_string(&credentials).unwrap(); + assert_eq!(credentials, "[registry]\ntoken = \"lmaolmaolmao\"\n"); } #[test] @@ -778,10 +918,11 @@ description = "bar" repository = "baz" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("publish -v --index") - .arg(registry().to_string()) + .arg(registry_url().to_string()) .with_status(101) .with_stderr_contains("[ERROR] the license file `foo` does not exist") .run(); @@ -801,7 +942,8 @@ [dependencies.a] path = "a" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "a/Cargo.toml", r#" @@ -813,7 +955,8 @@ [dependencies] bar = "*" "#, - ).file("a/src/lib.rs", "") + ) + .file("a/src/lib.rs", "") .build(); Package::new("bar", "0.0.1").publish(); @@ -829,7 +972,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); t!(t!(File::create(&p.root().join("a/Cargo.toml"))).write_all( br#" @@ -856,7 +1000,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -873,7 +1018,8 @@ [dependencies] a = "0.0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); let p = project() .file( @@ -893,7 +1039,8 @@ "#, b.url() ), - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("a", "0.0.1").publish(); @@ -911,7 +1058,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); p.root().move_into_the_past(); println!("second"); @@ -934,7 +1082,8 @@ [dependencies] a = "0.1.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("a", "0.1.0").publish(); p.cargo("build").run(); @@ -961,7 +1110,8 @@ [dependencies] a = "0.1.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p2.cargo("build").run(); registry.rm_rf(); @@ -984,7 +1134,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -1001,7 +1152,8 @@ [dependencies] a = "0.1.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("a", "0.1.0").publish(); @@ -1013,7 +1165,8 @@ [DOWNLOADING] crates ... [DOWNLOADED] a v0.1.0 (registry [..]) ", - ).run(); + ) + .run(); } #[test] @@ -1030,7 +1183,8 @@ [dependencies] a = "0.1.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("a", "0.1.0").dep("b", "*").publish(); @@ -1046,7 +1200,8 @@ [UPDATING] `[..]` index [UPDATING] b v0.1.0 -> v0.1.1 ", - ).run(); + ) + .run(); p.cargo("build") .with_stderr( @@ -1058,7 +1213,8 @@ [COMPILING] foo v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -1075,7 +1231,8 @@ [dependencies] webdriver = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("webdriver", "0.1.0") @@ -1105,7 +1262,8 @@ [UPDATING] hyper v0.6.5 -> v0.6.6 [UPDATING] openssl v0.1.0 -> v0.1.1 ", - ).run(); + ) + .run(); } #[test] @@ -1124,7 +1282,8 @@ b = "*" c = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("a", "0.1.0").publish(); @@ -1144,7 +1303,8 @@ [UPDATING] a v0.1.0 -> v0.1.1 [UPDATING] b v0.1.0 -> v0.1.1 ", - ).run(); + ) + .run(); p.cargo("update -pb -pc") .with_stderr( @@ -1152,7 +1312,8 @@ [UPDATING] `[..]` index [UPDATING] c v0.1.0 -> v0.1.1 ", - ).run(); + ) + .run(); p.cargo("build") .with_stderr_contains("[DOWNLOADED] a v0.1.1 (registry `[ROOT][..]`)") @@ -1180,7 +1341,8 @@ bar = "0.1" baz = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("bar", "0.1.0").publish(); @@ -1197,7 +1359,8 @@ [dependencies] bar = { path = "bar", version = "0.1.0" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "") .publish(); @@ -1219,7 +1382,8 @@ [dependencies] foo = "0.1" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foobar", "0.2.0").publish(); @@ -1245,7 +1409,8 @@ [dependencies] foo = "1.2.3-alpha.0" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foo", "1.2.3-alpha.0").publish(); @@ -1271,7 +1436,8 @@ [dependencies] baz = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foo", "0.1.0").publish(); @@ -1288,7 +1454,8 @@ [COMPILING] bar v0.5.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s ", - ).run(); + ) + .run(); } #[test] @@ -1305,7 +1472,8 @@ [dependencies] foo = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foo", "0.1.1") @@ -1330,7 +1498,8 @@ [dependencies] foo = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("foo", "0.1.0") @@ -1356,7 +1525,8 @@ [dependencies] foo = "*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build --frozen") @@ -1371,7 +1541,8 @@ Caused by: attempting to make an HTTP request, but --frozen was specified ", - ).run(); + ) + .run(); } #[test] @@ -1388,7 +1559,8 @@ [dependencies] baz = { path = "baz" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "baz/Cargo.toml", r#" @@ -1400,7 +1572,8 @@ [dependencies] remote = "0.3" "#, - ).file("baz/src/lib.rs", "") + ) + .file("baz/src/lib.rs", "") .build(); Package::new("remote", "0.3.4").publish(); @@ -1426,7 +1599,8 @@ [COMPILING] bar v0.5.0 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1443,7 +1617,8 @@ [dependencies] baz = { path = "baz" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "baz/Cargo.toml", r#" @@ -1455,7 +1630,8 @@ [dependencies] remote = "0.3" "#, - ).file("baz/src/lib.rs", "") + ) + .file("baz/src/lib.rs", "") .build(); Package::new("remote", "0.3.4").publish(); @@ -1480,7 +1656,8 @@ [COMPILING] bar v0.6.0 ([..]) [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1497,7 +1674,8 @@ [dependencies] remote = "0.2*" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("remote", "0.2.0").publish(); @@ -1532,7 +1710,8 @@ [COMPILING] [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1549,7 +1728,8 @@ [dependencies] remote = "0.3" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); Package::new("remote", "0.3.0") @@ -1564,7 +1744,8 @@ [dependencies] bar = "0.2*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .publish(); Package::new("bar", "0.2.0").publish(); @@ -1588,7 +1769,8 @@ [COMPILING] [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -1607,7 +1789,8 @@ [dependencies] foo = "0.1.0" "#, - ).file("src/lib.rs", "extern crate foo;") + ) + .file("src/lib.rs", "extern crate foo;") .publish(); let p = project() @@ -1622,7 +1805,8 @@ [dependencies] bar = "0.3" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -v").run(); @@ -1634,7 +1818,8 @@ .file( "src/lib.rs", "#![deny(warnings)] fn foo() {} // unused function", - ).publish(); + ) + .publish(); let p = project() .file( @@ -1648,7 +1833,8 @@ [dependencies] foo = "0.2" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -vv").run(); @@ -1672,7 +1858,8 @@ [dependencies] foo = "0.2" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build -vv") @@ -1690,7 +1877,8 @@ Caused by: [..] contains a file at \"foo-0.1.0/src/lib.rs\" which isn't under \"foo-0.2.0\" ", - ).run(); + ) + .run(); } #[test] @@ -1710,7 +1898,8 @@ [dependencies] foo = "0.2" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build").run(); @@ -1723,7 +1912,8 @@ [init] templatedir = nowhere "#, - ).unwrap(); + ) + .unwrap(); p.cargo("build").run(); p.cargo("build").run(); @@ -1738,7 +1928,11 @@ .file("src/lib.rs", "pub fn f2() {}") .publish(); Package::new("bar", "0.2.0") - .add_dep(Dependency::new("foo01", "0.1.0").package("foo").optional(true)) + .add_dep( + Dependency::new("foo01", "0.1.0") + .package("foo") + .optional(true), + ) .add_dep(Dependency::new("foo02", "0.2.0").package("foo")) .feature("another", &["foo01"]) .file( @@ -1769,7 +1963,8 @@ [dependencies] bar = "0.2" "#, - ).file( + ) + .file( "src/main.rs", " extern crate bar; diff -Nru cargo-0.33.0/tests/testsuite/rename_deps.rs cargo-0.35.0/tests/testsuite/rename_deps.rs --- cargo-0.33.0/tests/testsuite/rename_deps.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rename_deps.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,7 +1,7 @@ -use support::git; -use support::paths; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::git; +use crate::support::paths; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; #[test] fn rename_dependency() { @@ -21,7 +21,8 @@ bar = { version = "0.1.0" } baz = { version = "0.2.0", package = "bar" } "#, - ).file("src/lib.rs", "extern crate bar; extern crate baz;") + ) + .file("src/lib.rs", "extern crate bar; extern crate baz;") .build(); p.cargo("build").run(); @@ -41,7 +42,8 @@ [dependencies] baz = { path = "bar", package = "bar" } "#, - ).file("src/lib.rs", "extern crate baz;") + ) + .file("src/lib.rs", "extern crate baz;") .file( "bar/Cargo.toml", r#" @@ -53,7 +55,8 @@ [lib] name = "random_name" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -97,7 +100,8 @@ "#, g.url() ), - ).file( + ) + .file( "src/lib.rs", " extern crate foo; @@ -114,7 +118,8 @@ foo4::foo4(); } ", - ).file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) + ) + .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "pub fn foo4() {}") .build(); @@ -140,10 +145,12 @@ [patch.crates-io] foo = { path = "foo" } "#, - ).file( + ) + .file( "src/lib.rs", "extern crate bar; pub fn foo() { bar::foo(); }", - ).file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) + ) + .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "pub fn foo() {}") .build(); @@ -168,7 +175,8 @@ [build-dependencies] foo = { version = "0.1" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build -v") @@ -178,10 +186,10 @@ [UPDATING] `[..]` index [DOWNLOADING] crates ... [DOWNLOADED] foo v0.1.0 (registry [..]) -error: multiple dependencies listed for the same crate must all have the same \ -name, but the dependency on `foo v0.1.0` is listed as having different names +error: the crate `test v0.1.0 ([CWD])` depends on crate `foo v0.1.0` multiple times with different names ", - ).run(); + ) + .run(); } #[test] @@ -200,7 +208,8 @@ [dependencies] foo = { version = "0.1", package = "foo" } "#, - ).file("src/lib.rs", "extern crate foo;") + ) + .file("src/lib.rs", "extern crate foo;") .build(); p.cargo("build -v").run(); @@ -220,6 +229,7 @@ p.cargo("build -v") .with_status(101) + .with_stderr_contains("[..]can't find crate for `foo`") .run(); } @@ -240,13 +250,15 @@ bar = { version = "0.1.0" } baz = { version = "0.2.0", package = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", " extern crate bar; extern crate baz; ", - ).build(); + ) + .build(); foo.cargo("test -v") .with_stderr_contains( @@ -258,7 +270,8 @@ --extern baz=[CWD]/target/debug/deps/libbar-[..].rlib \ [..]` ", - ).run(); + ) + .run(); } #[test] @@ -279,7 +292,8 @@ p1 = { path = 'a', features = ['b'] } p2 = { path = 'b' } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "a/Cargo.toml", r#" @@ -291,7 +305,8 @@ [dependencies] b = { version = "0.1", package = "foo", optional = true } "#, - ).file("a/src/lib.rs", "extern crate b;") + ) + .file("a/src/lib.rs", "extern crate b;") .file( "b/Cargo.toml", r#" @@ -306,7 +321,8 @@ [features] default = ['b'] "#, - ).file("b/src/lib.rs", "extern crate b;") + ) + .file("b/src/lib.rs", "extern crate b;") .build(); p.cargo("build -v").run(); @@ -332,7 +348,8 @@ [features] default = ['p1'] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("p1", "0.1.0")) .build(); @@ -345,7 +362,8 @@ Caused by: Feature `default` includes `p1` which is neither a dependency nor another feature ", - ).run(); + ) + .run(); } #[test] @@ -367,6 +385,5 @@ .file("a/src/lib.rs", "") .build(); - p.cargo("build") - .run(); + p.cargo("build").run(); } diff -Nru cargo-0.33.0/tests/testsuite/required_features.rs cargo-0.35.0/tests/testsuite/required_features.rs --- cargo-0.33.0/tests/testsuite/required_features.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/required_features.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ -use support::install::{cargo_home, assert_has_installed_exe, assert_has_not_installed_exe}; -use support::is_nightly; -use support::project; +use crate::support::install::{assert_has_installed_exe, assert_has_not_installed_exe, cargo_home}; +use crate::support::is_nightly; +use crate::support::project; #[test] fn build_bin_default_features() { @@ -21,7 +21,8 @@ name = "foo" required-features = ["a"] "#, - ).file( + ) + .file( "src/main.rs", r#" extern crate foo; @@ -33,7 +34,8 @@ fn main() {} "#, - ).file("src/lib.rs", r#"#[cfg(feature = "a")] pub fn foo() {}"#) + ) + .file("src/lib.rs", r#"#[cfg(feature = "a")] pub fn foo() {}"#) .build(); p.cargo("build").run(); @@ -49,9 +51,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); } #[test] @@ -72,7 +75,8 @@ name = "foo" required-features = ["a"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("build --features a").run(); @@ -106,7 +110,8 @@ path = "src/foo_2.rs" required-features = ["a"] "#, - ).file("src/foo_1.rs", "fn main() {}") + ) + .file("src/foo_1.rs", "fn main() {}") .file("src/foo_2.rs", "fn main() {}") .build(); @@ -142,7 +147,8 @@ name = "foo" required-features = ["a"] "#, - ).file("examples/foo.rs", "fn main() {}") + ) + .file("examples/foo.rs", "fn main() {}") .build(); p.cargo("build --example=foo").run(); @@ -153,9 +159,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); } #[test] @@ -176,7 +183,8 @@ name = "foo" required-features = ["a"] "#, - ).file("examples/foo.rs", "fn main() {}") + ) + .file("examples/foo.rs", "fn main() {}") .build(); p.cargo("build --example=foo --features a").run(); @@ -208,7 +216,8 @@ name = "foo_2" required-features = ["a"] "#, - ).file("examples/foo_1.rs", "fn main() {}") + ) + .file("examples/foo_1.rs", "fn main() {}") .file("examples/foo_2.rs", "fn main() {}") .build(); @@ -217,9 +226,10 @@ .with_stderr( "\ error: target `foo_1` in package `foo` requires the features: `b`, `c` -Consider enabling them by passing e.g. `--features=\"b c\"` +Consider enabling them by passing, e.g., `--features=\"b c\"` ", - ).run(); + ) + .run(); p.cargo("build --example=foo_2").run(); assert!(!p.bin("examples/foo_1").is_file()); @@ -236,17 +246,19 @@ .with_stderr( "\ error: target `foo_1` in package `foo` requires the features: `b`, `c` -Consider enabling them by passing e.g. `--features=\"b c\"` +Consider enabling them by passing, e.g., `--features=\"b c\"` ", - ).run(); + ) + .run(); p.cargo("build --example=foo_2 --no-default-features") .with_status(101) .with_stderr( "\ error: target `foo_2` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); } #[test] @@ -268,7 +280,8 @@ name = "foo" required-features = ["a"] "#, - ).file("tests/foo.rs", "#[test]\nfn test() {}") + ) + .file("tests/foo.rs", "#[test]\nfn test() {}") .build(); p.cargo("test") @@ -277,7 +290,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); p.cargo("test --no-default-features") @@ -290,7 +304,8 @@ "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); p.cargo("test --test=foo --no-default-features") @@ -298,9 +313,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); } #[test] @@ -321,7 +337,8 @@ name = "foo" required-features = ["a"] "#, - ).file("tests/foo.rs", "#[test]\nfn test() {}") + ) + .file("tests/foo.rs", "#[test]\nfn test() {}") .build(); p.cargo("test --features a") @@ -330,7 +347,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); } @@ -359,7 +377,8 @@ name = "foo_2" required-features = ["a"] "#, - ).file("tests/foo_1.rs", "#[test]\nfn test() {}") + ) + .file("tests/foo_1.rs", "#[test]\nfn test() {}") .file("tests/foo_2.rs", "#[test]\nfn test() {}") .build(); @@ -369,7 +388,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo_2-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); p.cargo("test --features c") @@ -379,7 +399,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo_1-[..][EXE] [RUNNING] target/debug/deps/foo_2-[..][EXE]", - ).with_stdout_contains_n("test test ... ok", 2) + ) + .with_stdout_contains_n("test test ... ok", 2) .run(); p.cargo("test --no-default-features") @@ -411,7 +432,8 @@ name = "foo" required-features = ["a"] "#, - ).file( + ) + .file( "benches/foo.rs", r#" #![feature(test)] @@ -420,7 +442,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -428,7 +451,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); p.cargo("bench --no-default-features") @@ -441,7 +465,8 @@ "\ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); p.cargo("bench --bench=foo --no-default-features") @@ -449,9 +474,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); } #[test] @@ -476,7 +502,8 @@ name = "foo" required-features = ["a"] "#, - ).file( + ) + .file( "benches/foo.rs", r#" #![feature(test)] @@ -485,7 +512,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench --features a") .with_stderr( @@ -493,7 +521,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); } @@ -526,7 +555,8 @@ name = "foo_2" required-features = ["a"] "#, - ).file( + ) + .file( "benches/foo_1.rs", r#" #![feature(test)] @@ -535,7 +565,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).file( + ) + .file( "benches/foo_2.rs", r#" #![feature(test)] @@ -544,7 +575,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); p.cargo("bench") .with_stderr( @@ -552,7 +584,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo_2-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); p.cargo("bench --features c") @@ -562,7 +595,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo_1-[..][EXE] [RUNNING] target/release/deps/foo_2-[..][EXE]", - ).with_stdout_contains_n("test bench ... bench: [..]", 2) + ) + .with_stdout_contains_n("test bench ... bench: [..]", 2) .run(); p.cargo("bench --no-default-features") @@ -594,7 +628,8 @@ name = "foo" required-features = ["a"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("examples/foo.rs", "fn main() {}") .build(); @@ -610,7 +645,8 @@ [FINISHED] release [optimized] target(s) in [..] [ERROR] no binaries are available for install using the selected features ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); p.cargo("install --path . --bin=foo").run(); @@ -627,9 +663,10 @@ Caused by: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); p.cargo("install --path . --example=foo").run(); @@ -646,9 +683,10 @@ Caused by: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); } @@ -670,7 +708,8 @@ name = "foo" required-features = ["a"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); p.cargo("install --features a").run(); @@ -705,7 +744,8 @@ path = "src/foo_2.rs" required-features = ["a"] "#, - ).file("src/foo_1.rs", "fn main() {}") + ) + .file("src/foo_1.rs", "fn main() {}") .file("src/foo_2.rs", "fn main() {}") .build(); @@ -727,7 +767,8 @@ [FINISHED] release [optimized] target(s) in [..] [ERROR] no binaries are available for install using the selected features ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo_1"); assert_has_not_installed_exe(cargo_home(), "foo_2"); } @@ -762,7 +803,8 @@ name = "foo" required-features = ["bar/a"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("examples/foo.rs", "fn main() {}") .file("tests/foo.rs", "#[test]\nfn test() {}") .file( @@ -774,7 +816,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [project] @@ -785,7 +828,8 @@ [features] a = [] "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -805,7 +849,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); // bench @@ -817,7 +862,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); } @@ -857,7 +903,8 @@ name = "foo" required-features = ["bar/a"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("examples/foo.rs", "fn main() {}") .file("tests/foo.rs", "#[test]\nfn test() {}") .file( @@ -869,7 +916,8 @@ #[bench] fn bench(_: &mut test::Bencher) { }"#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [project] @@ -880,7 +928,8 @@ [features] a = [] "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -891,9 +940,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `bar/a` -Consider enabling them by passing e.g. `--features=\"bar/a\"` +Consider enabling them by passing, e.g., `--features=\"bar/a\"` ", - ).run(); + ) + .run(); p.cargo("build --bin=foo --features bar/a").run(); assert!(p.bin("foo").is_file()); @@ -904,9 +954,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `bar/a` -Consider enabling them by passing e.g. `--features=\"bar/a\"` +Consider enabling them by passing, e.g., `--features=\"bar/a\"` ", - ).run(); + ) + .run(); p.cargo("build --example=foo --features bar/a").run(); assert!(p.bin("examples/foo").is_file()); @@ -923,7 +974,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); // bench @@ -940,7 +992,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("test bench ... bench: [..]") + ) + .with_stdout_contains("test bench ... bench: [..]") .run(); } @@ -953,7 +1006,8 @@ [FINISHED] release [optimized] target(s) in [..] [ERROR] no binaries are available for install using the selected features ", - ).run(); + ) + .run(); assert_has_not_installed_exe(cargo_home(), "foo"); p.cargo("install --features bar/a").run(); @@ -980,7 +1034,8 @@ path = "src/bin/foo.rs" required-features = ["a"] "#, - ).file("src/bin/foo.rs", "extern crate bar; fn main() {}") + ) + .file("src/bin/foo.rs", "extern crate bar; fn main() {}") .file("tests/foo.rs", "") .file("benches/foo.rs", "") .build(); @@ -991,7 +1046,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); p.cargo("test --features a -j 1") @@ -1000,7 +1056,8 @@ "\ [COMPILING] foo v0.0.1 ([CWD]) error[E0463]: can't find crate for `bar`", - ).run(); + ) + .run(); if is_nightly() { p.cargo("bench") @@ -1009,7 +1066,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] release [optimized] target(s) in [..] [RUNNING] target/release/deps/foo-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); p.cargo("bench --features a -j 1") @@ -1018,7 +1076,8 @@ "\ [COMPILING] foo v0.0.1 ([CWD]) error[E0463]: can't find crate for `bar`", - ).run(); + ) + .run(); } } @@ -1041,7 +1100,8 @@ name = "foo" required-features = ["a"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/main.rs", "extern crate foo; fn main() {}") .build(); @@ -1050,9 +1110,10 @@ .with_stderr( "\ error: target `foo` in package `foo` requires the features: `a` -Consider enabling them by passing e.g. `--features=\"a\"` +Consider enabling them by passing, e.g., `--features=\"a\"` ", - ).run(); + ) + .run(); p.cargo("run --features a").run(); } @@ -1083,7 +1144,8 @@ path = "src/foo2.rs" required-features = ["b"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/foo1.rs", "extern crate foo; fn main() {}") .file("src/foo2.rs", "extern crate foo; fn main() {}") .build(); @@ -1094,5 +1156,6 @@ "\ error: `cargo run` requires that a package only have one executable; \ use the `--bin` option to specify which one to run\navailable binaries: foo1, foo2", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/resolve.rs cargo-0.35.0/tests/testsuite/resolve.rs --- cargo-0.33.0/tests/testsuite/resolve.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/resolve.rs 2019-04-01 21:32:07.000000000 +0000 @@ -4,40 +4,34 @@ use cargo::core::{enable_nightly_features, Dependency}; use cargo::util::Config; -use support::project; -use support::registry::Package; -use support::resolver::{ +use crate::support::project; +use crate::support::registry::Package; +use crate::support::resolver::{ assert_contains, assert_same, dep, dep_kind, dep_loc, dep_req, loc_names, names, pkg, pkg_dep, - pkg_id, pkg_loc, registry, registry_strategy, resolve, resolve_and_validated, + pkg_id, pkg_loc, registry, registry_strategy, remove_dep, resolve, resolve_and_validated, resolve_with_config, PrettyPrintRegistry, ToDep, ToPkgId, }; -use proptest::collection::vec; -use proptest::prelude::*; +use proptest::{prelude::*, *}; -/// NOTE: proptest is a form of fuzz testing. It generates random input and makes shore that -/// certain universal truths are upheld. Therefore, it can pass when there is a problem, -/// but if it fails then there really is something wrong. When testing something as -/// complicated as the resolver, the problems can be very subtle and hard to generate. -/// We have had a history of these tests only failing on PRs long after a bug is introduced. -/// If you have one of these test fail please report it on #6258, -/// and if you did not change the resolver then feel free to retry without concern. +// NOTE: proptest is a form of fuzz testing. It generates random input and makes sure that +// certain universal truths are upheld. Therefore, it can pass when there is a problem, +// but if it fails then there really is something wrong. When testing something as +// complicated as the resolver, the problems can be very subtle and hard to generate. +// We have had a history of these tests only failing on PRs long after a bug is introduced. +// If you have one of these test fail please report it on #6258, +// and if you did not change the resolver then feel free to retry without concern. proptest! { #![proptest_config(ProptestConfig { - // Note that this is a little low in terms of cases we'd like to test, - // but this number affects how long this function takes. It can be - // increased locally to execute more tests and try to find more bugs, - // but for now it's semi-low to run in a small-ish amount of time on CI - // and locally. - cases: 256, max_shrink_iters: - if env::var("CI").is_ok() { + if env::var("CI").is_ok() || !atty::is(atty::Stream::Stderr) { // This attempts to make sure that CI will fail fast, 0 } else { // but that local builds will give a small clear test case. - ProptestConfig::default().max_shrink_iters + std::u32::MAX }, + result_cache: prop::test_runner::basic_result_cache, .. ProptestConfig::default() })] @@ -47,7 +41,7 @@ PrettyPrintRegistry(input) in registry_strategy(50, 20, 60) ) { let reg = registry(input.clone()); - // there is only a small chance that eny one + // there is only a small chance that any one // crate will be interesting. // So we try some of the most complicated. for this in input.iter().rev().take(20) { @@ -80,7 +74,7 @@ .unwrap(); let reg = registry(input.clone()); - // there is only a small chance that eny one + // there is only a small chance that any one // crate will be interesting. // So we try some of the most complicated. for this in input.iter().rev().take(10) { @@ -111,12 +105,54 @@ /// NOTE: if you think this test has failed spuriously see the note at the top of this macro. #[test] + fn removing_a_dep_cant_break( + PrettyPrintRegistry(input) in registry_strategy(50, 20, 60), + indexes_to_remove in collection::vec((any::(), any::()), ..10) + ) { + let reg = registry(input.clone()); + let mut removed_input = input.clone(); + for (summery_idx, dep_idx) in indexes_to_remove { + if removed_input.len() > 0 { + let summery_idx = summery_idx.index(removed_input.len()); + let deps = removed_input[summery_idx].dependencies(); + if deps.len() > 0 { + let new = remove_dep(&removed_input[summery_idx], dep_idx.index(deps.len())); + removed_input[summery_idx] = new; + } + } + } + let removed_reg = registry(removed_input); + // there is only a small chance that any one + // crate will be interesting. + // So we try some of the most complicated. + for this in input.iter().rev().take(10) { + if resolve( + &pkg_id("root"), + vec![dep_req(&this.name(), &format!("={}", this.version()))], + ®, + ).is_ok() { + prop_assert!( + resolve( + &pkg_id("root"), + vec![dep_req(&this.name(), &format!("={}", this.version()))], + &removed_reg, + ).is_ok(), + "full index worked for `{} = \"={}\"` but removing some deps broke it!", + this.name(), + this.version(), + ) + } + } + } + + /// NOTE: if you think this test has failed spuriously see the note at the top of this macro. + #[test] fn limited_independence_of_irrelevant_alternatives( PrettyPrintRegistry(input) in registry_strategy(50, 20, 60), - indexs_to_unpublish in vec(any::(), 10) + indexes_to_unpublish in collection::vec(any::(), ..10) ) { let reg = registry(input.clone()); - // there is only a small chance that eny one + // there is only a small chance that any one // crate will be interesting. // So we try some of the most complicated. for this in input.iter().rev().take(10) { @@ -136,13 +172,13 @@ .filter(|x| !r.contains(&x.package_id())) .collect(); if !not_selected.is_empty() { - let indexs_to_unpublish: Vec<_> = indexs_to_unpublish.iter().map(|x| x.get(¬_selected)).collect(); + let indexes_to_unpublish: Vec<_> = indexes_to_unpublish.iter().map(|x| x.get(¬_selected)).collect(); let new_reg = registry( input .iter() .cloned() - .filter(|x| !indexs_to_unpublish.contains(&x)) + .filter(|x| !indexes_to_unpublish.contains(&x)) .collect(), ); @@ -160,7 +196,7 @@ prop_assert!( res.is_ok(), "unpublishing {:?} stopped `{} = \"={}\"` from working", - indexs_to_unpublish.iter().map(|x| x.package_id()).collect::>(), + indexes_to_unpublish.iter().map(|x| x.package_id()).collect::>(), this.name(), this.version() ) @@ -170,13 +206,13 @@ Err(_) => { // If resolution was unsuccessful, then it should stay unsuccessful // even if any version of a crate is unpublished. - let indexs_to_unpublish: Vec<_> = indexs_to_unpublish.iter().map(|x| x.get(&input)).collect(); + let indexes_to_unpublish: Vec<_> = indexes_to_unpublish.iter().map(|x| x.get(&input)).collect(); let new_reg = registry( input .iter() .cloned() - .filter(|x| !indexs_to_unpublish.contains(&x)) + .filter(|x| !indexes_to_unpublish.contains(&x)) .collect(), ); @@ -191,7 +227,7 @@ "full index did not work for `{} = \"={}\"` but unpublishing {:?} fixed it!", this.name(), this.version(), - indexs_to_unpublish.iter().map(|x| x.package_id()).collect::>(), + indexes_to_unpublish.iter().map(|x| x.package_id()).collect::>(), ) } } @@ -1088,23 +1124,23 @@ // minimized bug found in: // https://github.com/rust-lang/cargo/commit/003c29b0c71e5ea28fbe8e72c148c755c9f3f8d9 let input = vec![ - pkg!{("to_yank", "3.0.3")}, - pkg!{("to_yank", "3.3.0")}, - pkg!{("to_yank", "3.3.1")}, - pkg!{("a", "3.3.0") => [ + pkg! {("to_yank", "3.0.3")}, + pkg! {("to_yank", "3.3.0")}, + pkg! {("to_yank", "3.3.1")}, + pkg! {("a", "3.3.0") => [ dep_req("to_yank", "=3.0.3"), ] }, - pkg!{("a", "3.3.2") => [ + pkg! {("a", "3.3.2") => [ dep_req("to_yank", "<=3.3.0"), ] }, - pkg!{("b", "0.1.3") => [ + pkg! {("b", "0.1.3") => [ dep_req("a", "=3.3.0"), ] }, - pkg!{("b", "2.0.2") => [ + pkg! {("b", "2.0.2") => [ dep_req("to_yank", "3.3.0"), dep("a"), ] }, - pkg!{("b", "2.3.3") => [ + pkg! {("b", "2.3.3") => [ dep_req("to_yank", "3.3.0"), dep_req("a", "=3.3.0"), ] }, diff -Nru cargo-0.33.0/tests/testsuite/run.rs cargo-0.35.0/tests/testsuite/run.rs --- cargo-0.33.0/tests/testsuite/run.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/run.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ +use crate::support; +use crate::support::{basic_bin_manifest, basic_lib_manifest, project, Project}; use cargo::util::paths::dylib_path_envvar; -use support; -use support::{basic_bin_manifest, basic_lib_manifest, project, Project}; #[test] fn simple() { @@ -14,7 +14,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/foo[EXE]`", - ).with_stdout("hello") + ) + .with_stdout("hello") .run(); assert!(p.bin("foo").is_file()); } @@ -51,7 +52,8 @@ [term] verbose = true "#, - ).file("src/main.rs", r#"fn main() { println!("hello"); }"#) + ) + .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .build(); p.cargo("run -q").run(); @@ -68,7 +70,8 @@ assert_eq!(std::env::args().nth(2).unwrap(), "world"); } "#, - ).build(); + ) + .build(); p.cargo("run hello world").run(); } @@ -126,7 +129,8 @@ .with_stderr( "[ERROR] a bin target must be available \ for `cargo run`\n", - ).run(); + ) + .run(); } #[test] @@ -144,7 +148,8 @@ "[ERROR] `cargo run` requires that a package only \ have one executable; use the `--bin` option \ to specify which one to run\navailable binaries: [..]\n", - ).run(); + ) + .run(); // Using [..] here because the order is not stable p.cargo("run") @@ -155,7 +160,8 @@ Use the `--bin` option to specify a binary, or (on \ nightly) the `default-run` manifest key.\ \navailable binaries: [..]\n", - ).run(); + ) + .run(); } #[test] @@ -169,14 +175,16 @@ extern crate foo; fn main() { println!("hello a.rs"); } "#, - ).file( + ) + .file( "src/bin/b.rs", r#" #[allow(unused_extern_crates)] extern crate foo; fn main() { println!("hello b.rs"); } "#, - ).build(); + ) + .build(); p.cargo("run --bin a -v") .with_stderr( @@ -186,7 +194,8 @@ [RUNNING] `rustc [..] src/bin/a.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/a[EXE]`", - ).with_stdout("hello a.rs") + ) + .with_stdout("hello a.rs") .run(); p.cargo("run --bin b -v") @@ -196,7 +205,8 @@ [RUNNING] `rustc [..] src/bin/b.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/b[EXE]`", - ).with_stdout("hello b.rs") + ) + .with_stdout("hello b.rs") .run(); } @@ -214,7 +224,8 @@ authors = [] default-run = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#) .file("src/bin/b.rs", r#"fn main() { println!("hello B"); }"#) .build(); @@ -247,7 +258,8 @@ authors = [] default-run = "b" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#) .build(); @@ -270,7 +282,8 @@ authors = [] default-run = "a" "#, - ).file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#) + ) + .file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#) .build(); p.cargo("run") @@ -288,7 +301,8 @@ switch to nightly channel you can add `cargo-features = ["default-run"]` to enable this feature "#, - ).run(); + ) + .run(); p.cargo("run") .masquerade_as_nightly_cargo() @@ -304,7 +318,8 @@ consider adding `cargo-features = ["default-run"]` to the manifest "#, - ).run(); + ) + .run(); } #[test] @@ -321,7 +336,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/examples/a[EXE]`", - ).with_stdout("example") + ) + .with_stdout("example") .run(); } @@ -339,7 +355,8 @@ name = "bar" crate_type = ["lib"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/bar.rs", "fn foo() {}") .build(); @@ -405,13 +422,15 @@ rust_edition = rust_edition, autoexamples = autoexamples ), - ).file("examples/a.rs", r#"fn main() { println!("example"); }"#) + ) + .file("examples/a.rs", r#"fn main() { println!("example"); }"#) .file( "examples/do_magic.rs", r#" fn main() { println!("magic example"); } "#, - ).build() + ) + .build() } #[test] @@ -442,7 +461,8 @@ https://github.com/rust-lang/cargo/issues/5330 error: no example target named `a` ", - ).run(); + ) + .run(); } #[test] @@ -458,7 +478,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/examples/a[EXE]`", - ).with_stdout("example") + ) + .with_stdout("example") .run(); } @@ -488,7 +509,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/examples/a[EXE]`", - ).with_stdout("example") + ) + .with_stdout("example") .run(); } @@ -502,7 +524,7 @@ name = "foo" version = "0.0.1" autobins = false - "# + "#, ) .file("src/lib.rs", "pub mod bin;") .file("src/bin/mod.rs", "// empty") @@ -526,7 +548,8 @@ .with_status(1) .with_stderr_contains( "error: Found argument '--bins' which wasn't expected, or isn't valid in this context", - ).run(); + ) + .run(); } #[test] @@ -539,7 +562,8 @@ extern crate foo; fn main() { println!("hello a.rs"); } "#, - ).file("examples/a.rs", r#"fn main() { println!("example"); }"#) + ) + .file("examples/a.rs", r#"fn main() { println!("example"); }"#) .build(); p.cargo("run --bin bin.rs") @@ -554,7 +578,8 @@ [ERROR] no bin target named `a.rs` Did you mean `a`?", - ).run(); + ) + .run(); p.cargo("run --example example.rs") .with_status(101) @@ -568,7 +593,8 @@ [ERROR] no example target named `a.rs` Did you mean `a`?", - ).run(); + ) + .run(); } #[test] @@ -584,7 +610,8 @@ "[ERROR] `cargo run` can run at most one \ executable, but multiple were \ specified", - ).run(); + ) + .run(); } #[test] @@ -594,7 +621,8 @@ .file( "src/bin/main.rs", r#"fn main() { println!("hello main.rs"); }"#, - ).file("examples/a.rs", r#"fn main() { println!("hello a.rs"); }"#) + ) + .file("examples/a.rs", r#"fn main() { println!("hello a.rs"); }"#) .file("examples/b.rs", r#"fn main() { println!("hello b.rs"); }"#) .build(); @@ -604,7 +632,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/main[EXE]`", - ).with_stdout("hello main.rs") + ) + .with_stdout("hello main.rs") .run(); } @@ -623,7 +652,8 @@ version = "*" path = "bar" "#, - ).file( + ) + .file( "examples/a.rs", r#" extern crate bar; @@ -637,7 +667,8 @@ bar::baz(); } "#, - ).file("bar/Cargo.toml", &basic_lib_manifest("bar")) + ) + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) .file( "bar/src/bar.rs", r#" @@ -649,7 +680,8 @@ } } "#, - ).build(); + ) + .build(); p.cargo("run -v --release --example a") .with_stderr( @@ -672,11 +704,13 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `target/release/examples/a[EXE]` ", - ).with_stdout( + ) + .with_stdout( "\ fast1 fast2", - ).run(); + ) + .run(); p.cargo("run -v --example a") .with_stderr( @@ -699,11 +733,13 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target/debug/examples/a[EXE]` ", - ).with_stdout( + ) + .with_stdout( "\ slow1 slow2", - ).run(); + ) + .run(); } #[test] @@ -720,10 +756,12 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/main.rs", r#"extern crate bar; fn main() { bar::bar(); }"#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -735,7 +773,8 @@ name = "bar" crate-type = ["dylib"] "#, - ).file("bar/src/lib.rs", "pub fn bar() {}") + ) + .file("bar/src/lib.rs", "pub fn bar() {}") .build(); p.cargo("run hello world").run(); @@ -749,7 +788,8 @@ r#" fn main() { if cfg!(debug_assertions) { panic!() } } "#, - ).build(); + ) + .build(); p.cargo("run --release") .with_stderr( @@ -758,7 +798,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `target/release/foo[EXE]` ", - ).run(); + ) + .run(); assert!(p.release_bin("foo").is_file()); } @@ -776,7 +817,8 @@ [[bin]] name = "bar" "#, - ).file("src/bar.rs", "fn main() {}") + ) + .file("src/bar.rs", "fn main() {}") .build(); p.cargo("run").run(); @@ -796,7 +838,8 @@ assert_eq!(s[4], "b"); } "#, - ).build(); + ) + .build(); p.cargo("run -- -- a -- b").run(); } @@ -816,7 +859,8 @@ "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n\ [RUNNING] `./foo[EXE]`", - ).with_stdout("hello") + ) + .with_stdout("hello") .run(); } @@ -842,7 +886,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", &format!( r##" @@ -854,7 +899,8 @@ dir1.display(), dir2.display() ), - ).file( + ) + .file( "src/main.rs", &format!( r##" @@ -869,7 +915,8 @@ dir1.display(), dir2.display() ), - ).build(); + ) + .build(); p.cargo("run").run(); } @@ -897,7 +944,8 @@ authors = [] build = "build.rs" "#, - ).file( + ) + .file( "build.rs", &format!( r##" @@ -911,7 +959,8 @@ dir2.display(), dir3.display() ), - ).file( + ) + .file( "src/main.rs", &format!( r##" @@ -926,7 +975,8 @@ "##, dylib_path_envvar() ), - ).build(); + ) + .build(); p.cargo("run").run(); } @@ -966,7 +1016,8 @@ [[bin]] name = "foo" "#, - ).file("foo/src/foo.rs", "fn main() { println!(\"foo\"); }") + ) + .file("foo/src/foo.rs", "fn main() { println!(\"foo\"); }") .file("foo/d1/Cargo.toml", &basic_bin_manifest("d1")) .file("foo/d1/src/lib.rs", "") .file("foo/d1/src/main.rs", "fn main() { println!(\"d1\"); }") @@ -1017,7 +1068,8 @@ assert_eq!(std::env::args().nth(2).unwrap(), "world"); } "#, - ).build(); + ) + .build(); p.cargo("run --bin foo hello world").run(); } @@ -1031,7 +1083,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_bin_manifest("a")) + ) + .file("a/Cargo.toml", &basic_bin_manifest("a")) .file("a/src/main.rs", r#"fn main() {println!("run-a");}"#) .file("b/Cargo.toml", &basic_bin_manifest("b")) .file("b/src/main.rs", r#"fn main() {println!("run-b");}"#) @@ -1043,11 +1096,9 @@ "\ [ERROR] `cargo run` requires that a package only have one executable[..] available binaries: a, b", - ).run(); - p.cargo("run --bin a") - .with_status(0) - .with_stdout("run-a") + ) .run(); + p.cargo("run --bin a").with_stdout("run-a").run(); } #[test] @@ -1059,7 +1110,8 @@ [workspace] members = ["a", "b"] "#, - ).file( + ) + .file( "a/Cargo.toml", r#" cargo-features = ["default-run"] @@ -1069,14 +1121,96 @@ version = "0.0.1" default-run = "a" "#, - ).file("a/src/main.rs", r#"fn main() {println!("run-a");}"#) + ) + .file("a/src/main.rs", r#"fn main() {println!("run-a");}"#) .file("b/Cargo.toml", &basic_bin_manifest("b")) .file("b/src/main.rs", r#"fn main() {println!("run-b");}"#) .build(); - p.cargo("run") - .masquerade_as_nightly_cargo() - .with_status(0) - .with_stdout("run-a") - .run(); + p.cargo("run").masquerade_as_nightly_cargo().with_stdout("run-a").run(); +} + +#[test] +#[cfg(target_os = "macos")] +fn run_link_system_path_macos() { + use crate::support::paths::{self, CargoPathExt}; + use std::fs; + // Check that the default system library path is honored. + // First, build a shared library that will be accessed from + // DYLD_FALLBACK_LIBRARY_PATH. + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + [lib] + crate-type = ["cdylib"] + "#, + ) + .file( + "src/lib.rs", + "#[no_mangle] pub extern fn something_shared() {}", + ) + .build(); + p.cargo("build").run(); + + // This is convoluted. Since this test can't modify things in /usr, + // this needs to dance around to check that things work. + // + // The default DYLD_FALLBACK_LIBRARY_PATH is: + // $(HOME)/lib:/usr/local/lib:/lib:/usr/lib + // + // This will make use of ~/lib in the path, but the default cc link + // path is /usr/lib:/usr/local/lib. So first need to build in one + // location, and then move it to ~/lib. + // + // 1. Build with rustc-link-search pointing to libfoo so the initial + // binary can be linked. + // 2. Move the library to ~/lib + // 3. Run `cargo run` to make sure it can still find the library in + // ~/lib. + // + // This should be equivalent to having the library in /usr/local/lib. + let p2 = project() + .at("bar") + .file("Cargo.toml", &basic_bin_manifest("bar")) + .file( + "src/main.rs", + r#" + extern { + fn something_shared(); + } + fn main() { + unsafe { something_shared(); } + } + "#, + ) + .file( + "build.rs", + &format!( + r#" + fn main() {{ + println!("cargo:rustc-link-lib=foo"); + println!("cargo:rustc-link-search={}"); + }} + "#, + p.target_debug_dir().display() + ), + ) + .build(); + p2.cargo("build").run(); + p2.cargo("test").run(); + + let libdir = paths::home().join("lib"); + fs::create_dir(&libdir).unwrap(); + fs::rename( + p.target_debug_dir().join("libfoo.dylib"), + libdir.join("libfoo.dylib"), + ) + .unwrap(); + p.root().rm_rf(); + p2.cargo("run").run(); + p2.cargo("test").run(); } diff -Nru cargo-0.33.0/tests/testsuite/rustc_info_cache.rs cargo-0.35.0/tests/testsuite/rustc_info_cache.rs --- cargo-0.33.0/tests/testsuite/rustc_info_cache.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rustc_info_cache.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,6 +1,6 @@ +use crate::support::paths::CargoPathExt; +use crate::support::{basic_manifest, project}; use std::env; -use support::paths::CargoPathExt; -use support::{basic_manifest, project}; #[test] fn rustc_info_cache() { @@ -53,7 +53,8 @@ std::process::exit(cmd.status().unwrap().code().unwrap()); } "#, - ).build(); + ) + .build(); p.cargo("build").run(); p.root() diff -Nru cargo-0.33.0/tests/testsuite/rustc.rs cargo-0.35.0/tests/testsuite/rustc.rs --- cargo-0.33.0/tests/testsuite/rustc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rustc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,8 @@ -use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; +use crate::support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project}; const CARGO_RUSTC_ERROR: &str = "[ERROR] extra arguments to `rustc` can only be passed to one target, consider filtering -the package by passing e.g. `--lib` or `--bin NAME` to specify a single target"; +the package by passing, e.g., `--lib` or `--bin NAME` to specify a single target"; #[test] fn build_lib_for_foo() { @@ -22,7 +22,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -44,7 +45,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -74,7 +76,8 @@ ", name = "foo", version = "0.0.1" - )).run(); + )) + .run(); } #[test] @@ -148,7 +151,8 @@ -C debug-assertions [..]--test[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -165,7 +169,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") .build(); let _bar = project() .at("bar") @@ -182,7 +187,8 @@ [RUNNING] `[..] -C debuginfo=2 -C debug-assertions [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -199,7 +205,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") .build(); let _bar = project() .at("bar") @@ -214,7 +221,8 @@ [RUNNING] `rustc --crate-name bar [..] --color never --crate-type lib [..] -C debug-assertions [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -222,17 +230,24 @@ let p = project().file("src/main.rs", "fn main() {}").build(); p.cargo("rustc -v") // bin - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]") + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ + --emit=dep-info,link[..]", + ) // bench - .with_stderr_does_not_contain("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C opt-level=3 --test [..]") + .with_stderr_does_not_contain( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C opt-level=3 --test [..]", + ) // unit test - .with_stderr_does_not_contain("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C debuginfo=2 --test [..]").run(); + .with_stderr_does_not_contain( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C debuginfo=2 --test [..]", + ) + .run(); } #[test] @@ -240,13 +255,18 @@ let p = project().file("src/main.rs", "fn main() {}").build(); p.cargo("rustc -v --all-targets") // bin - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ - --emit=dep-info,link[..]") + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --crate-type bin \ + --emit=dep-info,link[..]", + ) // unit test - .with_stderr_contains("\ - [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ - -C debuginfo=2 --test [..]").run(); + .with_stderr_contains( + "\ + [RUNNING] `rustc --crate-name foo src/main.rs --color never --emit=dep-info,link \ + -C debuginfo=2 --test [..]", + ) + .run(); } #[test] @@ -266,7 +286,8 @@ [dependencies.baz] path = "../baz" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .build(); let _bar = project() @@ -279,7 +300,8 @@ if cfg!(flag = "1") { println!("Yeah from bar!"); } } "#, - ).build(); + ) + .build(); let _baz = project() .at("baz") @@ -291,7 +313,8 @@ if cfg!(flag = "1") { println!("Yeah from baz!"); } } "#, - ).build(); + ) + .build(); foo.cargo("rustc -v -p bar -p baz") .with_status(1) @@ -300,7 +323,8 @@ error: The argument '--package ' was provided more than once, \ but cannot be used multiple times ", - ).run(); + ) + .run(); } #[test] @@ -317,7 +341,8 @@ [dev-dependencies] a = { path = "a" } "#, - ).file( + ) + .file( "src/main.rs", r#" #[cfg(test)] extern crate a; @@ -325,7 +350,8 @@ #[test] fn foo() {} "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/lib.rs", "") .build(); @@ -347,7 +373,8 @@ [RUNNING] `rustc [..]-C debug-assertions [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("rustc -v -- -C debug-assertions") .with_stderr( @@ -355,7 +382,8 @@ [FRESH] foo [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("rustc -v") .with_stderr_does_not_contain("-C debug-assertions") @@ -365,7 +393,8 @@ [RUNNING] `rustc [..] [FINISHED] [..] ", - ).run(); + ) + .run(); p.cargo("rustc -v") .with_stderr( @@ -373,7 +402,8 @@ [FRESH] foo [..] [FINISHED] [..] ", - ).run(); + ) + .run(); } #[test] @@ -387,21 +417,25 @@ fn f() { compile_fail!("Foo shouldn't be set."); } fn main() {} "#, - ).file( + ) + .file( "tests/test1.rs", r#" #[cfg(not(foo))] fn f() { compile_fail!("Foo should be set."); } "#, - ).build(); + ) + .build(); p.cargo("rustc --test test1 -v -- --cfg foo") .with_stderr_contains( "\ [RUNNING] `rustc --crate-name test1 tests/test1.rs [..] --cfg foo [..] ", - ).with_stderr_contains( + ) + .with_stderr_contains( "\ [RUNNING] `rustc --crate-name foo src/main.rs [..] ", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/rustdocflags.rs cargo-0.35.0/tests/testsuite/rustdocflags.rs --- cargo-0.33.0/tests/testsuite/rustdocflags.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rustdocflags.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::project; +use crate::support::project; #[test] fn parses_env() { @@ -20,7 +20,8 @@ [build] rustdocflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); p.cargo("doc -v") .with_stderr_contains("[RUNNING] `rustdoc [..] --cfg foo[..]`") @@ -34,6 +35,7 @@ p.cargo("doc") .env("RUSTDOCFLAGS", "--bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); } @@ -53,7 +55,8 @@ [DOCUMENTING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -66,7 +69,8 @@ //! assert!(cfg!(do_not_choke)); //! ``` "#, - ).build(); + ) + .build(); p.cargo("test --doc") .env("RUSTDOCFLAGS", "--cfg do_not_choke") diff -Nru cargo-0.33.0/tests/testsuite/rustdoc.rs cargo-0.35.0/tests/testsuite/rustdoc.rs --- cargo-0.33.0/tests/testsuite/rustdoc.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rustdoc.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_manifest, project}; +use crate::support::{basic_manifest, project}; #[test] fn rustdoc_simple() { @@ -13,7 +13,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -30,7 +31,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -47,7 +49,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "extern crate bar; pub fn foo() {}") + ) + .file("src/lib.rs", "extern crate bar; pub fn foo() {}") .build(); let _bar = project() .at("bar") @@ -68,7 +71,8 @@ --extern [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -85,7 +89,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::baz() }") .build(); let _bar = project() .at("bar") @@ -103,7 +108,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -123,7 +129,8 @@ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -140,7 +147,8 @@ [features] quux = [] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("rustdoc --verbose --features quux") @@ -149,11 +157,7 @@ } #[test] -#[cfg(all( - target_arch = "x86_64", - target_os = "linux", - target_env = "gnu" -))] +#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))] fn rustdoc_target() { let p = project().file("src/lib.rs", "").build(); @@ -167,5 +171,6 @@ -L dependency=[CWD]/target/x86_64-unknown-linux-gnu/debug/deps \ -L dependency=[CWD]/target/debug/deps` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", - ).run(); + ) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/rustflags.rs cargo-0.35.0/tests/testsuite/rustflags.rs --- cargo-0.33.0/tests/testsuite/rustflags.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/rustflags.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,8 @@ use std::fs::{self, File}; use std::io::Write; -use support::rustc_host; -use support::{basic_lib_manifest, basic_manifest, paths, project, project_in_home}; +use crate::support::rustc_host; +use crate::support::{basic_lib_manifest, basic_manifest, paths, project, project_in_home}; #[test] fn env_rustflags_normal_source() { @@ -17,28 +17,34 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); // Use RUSTFLAGS to pass an argument that will generate an error p.cargo("build --lib") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --bin=a") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --example=b") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("test") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("bench") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); } @@ -56,7 +62,8 @@ version = "0.0.1" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -64,7 +71,8 @@ #[cfg(not(foo))] fn main() { } "#, - ).build(); + ) + .build(); p.cargo("build").env("RUSTFLAGS", "--cfg foo").run(); } @@ -86,7 +94,8 @@ [build-dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .build(); let _bar = project() @@ -99,7 +108,8 @@ #[cfg(not(foo))] fn bar() { } "#, - ).build(); + ) + .build(); foo.cargo("build").env("RUSTFLAGS", "--cfg foo").run(); } @@ -121,14 +131,16 @@ name = "foo" plugin = true "#, - ).file( + ) + .file( "src/lib.rs", r#" fn main() { } #[cfg(not(foo))] fn main() { } "#, - ).build(); + ) + .build(); p.cargo("build").env("RUSTFLAGS", "--cfg foo").run(); } @@ -153,7 +165,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "fn foo() {}") + ) + .file("src/lib.rs", "fn foo() {}") .build(); let _bar = project() .at("bar") @@ -165,7 +178,8 @@ #[cfg(not(foo))] fn bar() { } "#, - ).build(); + ) + .build(); foo.cargo("build").env("RUSTFLAGS", "--cfg foo").run(); } @@ -183,7 +197,8 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).build(); + ) + .build(); let host = &rustc_host(); @@ -192,26 +207,31 @@ .arg(host) .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --bin=a --target") .arg(host) .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --example=b --target") .arg(host) .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("test --target") .arg(host) .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("bench --target") .arg(host) .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); } @@ -229,7 +249,8 @@ version = "0.0.1" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -237,7 +258,8 @@ #[cfg(foo)] fn main() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); p.cargo("build --target") @@ -263,7 +285,8 @@ [build-dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .build(); let _bar = project() @@ -276,7 +299,8 @@ #[cfg(foo)] fn bar() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); foo.cargo("build --target") @@ -302,14 +326,16 @@ name = "foo" plugin = true "#, - ).file( + ) + .file( "src/lib.rs", r#" fn main() { } #[cfg(foo)] fn main() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); p.cargo("build --target") @@ -338,7 +364,8 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "fn foo() {}") + ) + .file("src/lib.rs", "fn foo() {}") .build(); let _bar = project() .at("bar") @@ -350,7 +377,8 @@ #[cfg(foo)] fn bar() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); foo.cargo("build --target") @@ -368,6 +396,7 @@ p.cargo("build") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); } @@ -380,6 +409,7 @@ p.cargo("build") .env("RUSTFLAGS", "-Z bogus") .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); } @@ -407,19 +437,36 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["-Z", "bogus"] "#, - ).build(); + ) + .build(); - p.cargo("build --lib").with_status(101).run(); - p.cargo("build --bin=a").with_status(101).run(); - p.cargo("build --example=b").with_status(101).run(); - p.cargo("test").with_status(101).run(); - p.cargo("bench").with_status(101).run(); + p.cargo("build --lib") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --bin=a") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --example=b") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("test") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("bench") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); } #[test] @@ -436,7 +483,8 @@ version = "0.0.1" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -444,13 +492,15 @@ #[cfg(not(foo))] fn main() { } "#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -472,7 +522,8 @@ [build-dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .file( ".cargo/config", @@ -480,7 +531,8 @@ [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.0.1")) @@ -491,7 +543,8 @@ #[cfg(not(foo))] fn bar() { } "#, - ).build(); + ) + .build(); foo.cargo("build").run(); } @@ -513,20 +566,23 @@ name = "foo" plugin = true "#, - ).file( + ) + .file( "src/lib.rs", r#" fn main() { } #[cfg(not(foo))] fn main() { } "#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -551,14 +607,16 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "fn foo() {}") + ) + .file("src/lib.rs", "fn foo() {}") .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_lib_manifest("bar")) @@ -569,7 +627,8 @@ #[cfg(not(foo))] fn bar() { } "#, - ).build(); + ) + .build(); foo.cargo("build").run(); } @@ -587,13 +646,15 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["-Z", "bogus"] "#, - ).build(); + ) + .build(); let host = &rustc_host(); @@ -601,17 +662,28 @@ p.cargo("build --lib --target") .arg(host) .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --bin=a --target") .arg(host) .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); p.cargo("build --example=b --target") .arg(host) .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("test --target") + .arg(host) + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("bench --target") + .arg(host) + .with_status(101) + .with_stderr_contains("[..]bogus[..]") .run(); - p.cargo("test --target").arg(host).with_status(101).run(); - p.cargo("bench --target").arg(host).with_status(101).run(); } #[test] @@ -628,7 +700,8 @@ version = "0.0.1" build = "build.rs" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "build.rs", r#" @@ -636,13 +709,15 @@ #[cfg(foo)] fn main() { } "#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let host = rustc_host(); p.cargo("build --target").arg(host).run(); @@ -665,7 +740,8 @@ [build-dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("build.rs", "fn main() {}") .file( ".cargo/config", @@ -673,7 +749,8 @@ [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.0.1")) @@ -684,7 +761,8 @@ #[cfg(foo)] fn bar() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); foo.cargo("build --target").arg(host).run(); @@ -707,20 +785,23 @@ name = "foo" plugin = true "#, - ).file( + ) + .file( "src/lib.rs", r#" fn main() { } #[cfg(foo)] fn main() { } "#, - ).file( + ) + .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let host = rustc_host(); p.cargo("build --target").arg(host).run(); @@ -746,14 +827,16 @@ [dependencies.bar] path = "../bar" "#, - ).file("src/lib.rs", "fn foo() {}") + ) + .file("src/lib.rs", "fn foo() {}") .file( ".cargo/config", r#" [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); let _bar = project() .at("bar") .file("Cargo.toml", &basic_lib_manifest("bar")) @@ -764,7 +847,8 @@ #[cfg(foo)] fn bar() { } "#, - ).build(); + ) + .build(); let host = rustc_host(); foo.cargo("build --target").arg(host).run(); @@ -786,7 +870,10 @@ let mut config_file = File::create(config_file).unwrap(); config_file.write_all(config.as_bytes()).unwrap(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); } #[test] @@ -805,7 +892,10 @@ let mut config_file = File::create(config_file).unwrap(); config_file.write_all(config.as_bytes()).unwrap(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); } #[test] @@ -818,7 +908,8 @@ [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); p.cargo("build").env("RUSTFLAGS", "--cfg foo").run(); p.cargo("build") @@ -840,7 +931,8 @@ [build] rustflags = ["-Cllvm-args=-x86-asm-syntax=intel"] "#, - ).unwrap(); + ) + .unwrap(); // And we need the project to be inside the home directory // so the walking process finds the home project twice. @@ -862,7 +954,8 @@ #![feature(test)] extern crate test; #[bench] fn run1(_ben: &mut test::Bencher) { }"#, - ).file( + ) + .file( ".cargo/config", &format!( " @@ -871,13 +964,29 @@ ", rustc_host() ), - ).build(); + ) + .build(); - p.cargo("build --lib").with_status(101).run(); - p.cargo("build --bin=a").with_status(101).run(); - p.cargo("build --example=b").with_status(101).run(); - p.cargo("test").with_status(101).run(); - p.cargo("bench").with_status(101).run(); + p.cargo("build --lib") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --bin=a") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --example=b") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("test") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("bench") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); } // target.{}.rustflags takes precedence over build.rustflags @@ -885,6 +994,9 @@ fn target_rustflags_precedence() { let p = project() .file("src/lib.rs", "") + .file("src/bin/a.rs", "fn main() {}") + .file("examples/b.rs", "fn main() {}") + .file("tests/c.rs", "#[test] fn f() { }") .file( ".cargo/config", &format!( @@ -897,13 +1009,29 @@ ", rustc_host() ), - ).build(); + ) + .build(); - p.cargo("build --lib").with_status(101).run(); - p.cargo("build --bin=a").with_status(101).run(); - p.cargo("build --example=b").with_status(101).run(); - p.cargo("test").with_status(101).run(); - p.cargo("bench").with_status(101).run(); + p.cargo("build --lib") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --bin=a") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("build --example=b") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("test") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); + p.cargo("bench") + .with_status(101) + .with_stderr_contains("[..]bogus[..]") + .run(); } #[test] @@ -926,7 +1054,8 @@ "not(windows)" } ), - ).build(); + ) + .build(); p.cargo("build --lib -v") .with_stderr( @@ -935,7 +1064,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build --bin=a -v") .with_stderr( @@ -944,7 +1074,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build --example=b -v") .with_stderr( @@ -953,7 +1084,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("test --no-run -v") .with_stderr( @@ -964,7 +1096,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("bench --no-run -v") .with_stderr( @@ -975,7 +1108,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } // target.'cfg(...)'.rustflags takes precedence over build.rustflags @@ -1002,7 +1136,8 @@ "not(windows)" } ), - ).build(); + ) + .build(); p.cargo("build --lib -v") .with_stderr( @@ -1011,7 +1146,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build --bin=a -v") .with_stderr( @@ -1020,7 +1156,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build --example=b -v") .with_stderr( @@ -1029,7 +1166,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("test --no-run -v") .with_stderr( @@ -1040,7 +1178,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("bench --no-run -v") .with_stderr( @@ -1051,7 +1190,8 @@ [RUNNING] `rustc [..] --cfg bar[..]` [FINISHED] release [optimized] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1064,7 +1204,8 @@ [build] rustflags = ["--cfg", "foo"] "#, - ).build(); + ) + .build(); p1.cargo("build -v") .with_stderr( @@ -1073,7 +1214,8 @@ [RUNNING] `rustc [..] --cfg foo[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p2 = project() .file("src/lib.rs", "") @@ -1083,7 +1225,8 @@ [build] rustflags = "--cfg foo" "#, - ).build(); + ) + .build(); p2.cargo("build -v") .with_stderr( @@ -1092,7 +1235,8 @@ [RUNNING] `rustc [..] --cfg foo[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1107,7 +1251,8 @@ "#, rustc_host() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p1.cargo("build -v") @@ -1117,7 +1262,8 @@ [RUNNING] `rustc [..] --cfg foo[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); let p2 = project() .file( @@ -1129,7 +1275,8 @@ "#, rustc_host() ), - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p2.cargo("build -v") @@ -1139,7 +1286,8 @@ [RUNNING] `rustc [..] --cfg foo[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1157,7 +1305,8 @@ [target.'cfg(target_pointer_width = "64")'] rustflags = ["--cfg", 'foo="b"'] "#, - ).file( + ) + .file( "src/main.rs", r#" fn main() { @@ -1170,7 +1319,8 @@ } } "#, - ).build(); + ) + .build(); p1.cargo("run").run(); p1.cargo("build").with_stderr("[FINISHED] [..]").run(); diff -Nru cargo-0.33.0/tests/testsuite/search.rs cargo-0.35.0/tests/testsuite/search.rs --- cargo-0.33.0/tests/testsuite/search.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/search.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,11 +1,12 @@ +use std::collections::HashSet; use std::fs::{self, File}; use std::io::prelude::*; use std::path::Path; -use support::cargo_process; -use support::git::repo; -use support::paths; -use support::registry::{api_path, registry as registry_url, registry_path}; +use crate::support::cargo_process; +use crate::support::git::repo; +use crate::support::paths; +use crate::support::registry::{api_path, registry_path, registry_url}; use url::Url; fn api() -> Url { @@ -107,7 +108,7 @@ let sid = SourceId::for_registry(®istry_url()).unwrap(); let cfg = Config::new(Shell::new(), paths::root(), paths::home().join(".cargo")); - let mut regsrc = RegistrySource::remote(sid, &cfg); + let mut regsrc = RegistrySource::remote(sid, &HashSet::new(), &cfg); regsrc.update().unwrap(); cargo_process("search postgres") diff -Nru cargo-0.33.0/tests/testsuite/shell_quoting.rs cargo-0.35.0/tests/testsuite/shell_quoting.rs --- cargo-0.33.0/tests/testsuite/shell_quoting.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/shell_quoting.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,7 +2,7 @@ //! in the output, their arguments are quoted properly //! so that the command can be run in a terminal -use support::project; +use crate::support::project; #[test] fn features_are_quoted() { @@ -19,7 +19,8 @@ some_feature = [] default = ["some_feature"] "#, - ).file("src/main.rs", "fn main() {error}") + ) + .file("src/main.rs", "fn main() {error}") .build(); p.cargo("check -v") diff -Nru cargo-0.33.0/tests/testsuite/small_fd_limits.rs cargo-0.35.0/tests/testsuite/small_fd_limits.rs --- cargo-0.33.0/tests/testsuite/small_fd_limits.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/small_fd_limits.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,11 +3,11 @@ use std::path::PathBuf; use std::process::Command; +use crate::support::git; +use crate::support::paths; +use crate::support::project; +use crate::support::registry::Package; use git2; -use support::git; -use support::paths; -use support::project; -use support::registry::Package; use url::Url; @@ -31,7 +31,8 @@ [dependencies] bar = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); Package::new("bar", "0.1.0").publish(); diff -Nru cargo-0.33.0/tests/testsuite/support/cross_compile.rs cargo-0.35.0/tests/testsuite/support/cross_compile.rs --- cargo-0.33.0/tests/testsuite/support/cross_compile.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/cross_compile.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,20 +1,20 @@ use std::env; use std::process::Command; -use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT}; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Once, ONCE_INIT}; -use support::{basic_bin_manifest, main_file, project}; +use crate::support::{basic_bin_manifest, main_file, project}; pub fn disabled() -> bool { - // First, disable if ./configure requested so + // First, disable if `./configure` requested so. match env::var("CFG_DISABLE_CROSS_TESTS") { Ok(ref s) if *s == "1" => return true, _ => {} } - // Right now the windows bots cannot cross compile due to the mingw setup, - // so we disable ourselves on all but macos/linux setups where the rustc - // install script ensures we have both architectures + // Right now, the Windows bots cannot cross compile due to the Mingw setup, + // so we disable ourselves on all but macOS/Linux setups where the rustc + // install script ensures we have both architectures. if !(cfg!(target_os = "macos") || cfg!(target_os = "linux") || cfg!(target_env = "msvc")) { return true; } @@ -22,7 +22,7 @@ // It's not particularly common to have a cross-compilation setup, so // try to detect that before we fail a bunch of tests through no fault // of the user. - static CAN_RUN_CROSS_TESTS: AtomicBool = ATOMIC_BOOL_INIT; + static CAN_RUN_CROSS_TESTS: AtomicBool = AtomicBool::new(false); static CHECK: Once = ONCE_INIT; let cross_target = alternate(); @@ -46,17 +46,17 @@ if CAN_RUN_CROSS_TESTS.load(Ordering::SeqCst) { // We were able to compile a simple project, so the user has the - // necessary std:: bits installed. Therefore, tests should not + // necessary `std::` bits installed. Therefore, tests should not // be disabled. return false; } - // We can't compile a simple cross project. We want to warn the user + // We can't compile a simple cross project. We want to warn the user // by failing a single test and having the remainder of the cross tests - // pass. We don't use std::sync::Once here because panicing inside its - // call_once method would poison the Once instance, which is not what + // pass. We don't use `std::sync::Once` here because panicking inside its + // `call_once` method would poison the `Once` instance, which is not what // we want. - static HAVE_WARNED: AtomicBool = ATOMIC_BOOL_INIT; + static HAVE_WARNED: AtomicBool = AtomicBool::new(false); if HAVE_WARNED.swap(true, Ordering::SeqCst) { // We are some other test and somebody else is handling the warning. @@ -64,7 +64,7 @@ return true; } - // We are responsible for warning the user, which we do by panicing. + // We are responsible for warning the user, which we do by panicking. let rustup_available = Command::new("rustup").output().is_ok(); let linux_help = if cfg!(target_os = "linux") { diff -Nru cargo-0.33.0/tests/testsuite/support/git.rs cargo-0.35.0/tests/testsuite/support/git.rs --- cargo-0.33.0/tests/testsuite/support/git.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/git.rs 2019-04-01 21:32:07.000000000 +0000 @@ -46,7 +46,7 @@ use git2; use url::Url; -use support::{path2url, project, Project, ProjectBuilder}; +use crate::support::{path2url, project, Project, ProjectBuilder}; #[must_use] pub struct RepoBuilder { @@ -153,8 +153,8 @@ /// Add all files in the working directory to the git index. pub fn add(repo: &git2::Repository) { - // FIXME(libgit2/libgit2#2514): apparently add_all will add all submodules - // as well, and then fail b/c they're a directory. As a stopgap, we just + // FIXME(libgit2/libgit2#2514): apparently, `add_all` will add all submodules + // as well, and then fail because they're directories. As a stop-gap, we just // ignore all submodules. let mut s = t!(repo.submodules()); for submodule in s.iter_mut() { diff -Nru cargo-0.33.0/tests/testsuite/support/install.rs cargo-0.35.0/tests/testsuite/support/install.rs --- cargo-0.33.0/tests/testsuite/support/install.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/install.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,9 +1,9 @@ use std::path::{Path, PathBuf}; -use support::paths; +use crate::support::paths; /// Used by `cargo install` tests to assert an executable binary -/// has been installed. Example usage: +/// has been installed. Example usage: /// /// assert_has_installed_exe(cargo_home(), "foo"); pub fn assert_has_installed_exe>(path: P, name: &'static str) { diff -Nru cargo-0.33.0/tests/testsuite/support/mod.rs cargo-0.35.0/tests/testsuite/support/mod.rs --- cargo-0.33.0/tests/testsuite/support/mod.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/mod.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,13 +1,13 @@ /* -# Introduction To `support` +# Introduction to `support`. Cargo has a wide variety of integration tests that execute the `cargo` binary -and verify its behavior. The `support` module contains many helpers to make +and verify its behavior. The `support` module contains many helpers to make this process easy. The general form of a test involves creating a "project", running cargo, and -checking the result. Projects are created with the `ProjectBuilder` where you -specify some files to create. The general form looks like this: +checking the result. Projects are created with the `ProjectBuilder` where you +specify some files to create. The general form looks like this: ``` let p = project() @@ -35,8 +35,8 @@ The project creates a mini sandbox under the "cargo integration test" directory with each test getting a separate directory such as -`/path/to/cargo/target/cit/t123/`. Each project appears as a separate -directory. There is also an empty `home` directory created that will be used +`/path/to/cargo/target/cit/t123/`. Each project appears as a separate +directory. There is also an empty `home` directory created that will be used as a home directory instead of your normal home directory. See `support::lines_match` for an explanation of the string pattern matching. @@ -69,8 +69,8 @@ When checking output, use `/` for paths even on Windows: the actual output of `\` on Windows will be replaced with `/`. -Be careful when executing binaries on Windows. You should not rename, delete, -or overwrite a binary immediately after running it. Under some conditions +Be careful when executing binaries on Windows. You should not rename, delete, +or overwrite a binary immediately after running it. Under some conditions Windows will fail with errors like "directory not empty" or "failed to remove" or "access is denied". @@ -242,7 +242,7 @@ self } - /// Add a file to the project. + /// Adds a file to the project. pub fn file>(mut self, path: B, body: &str) -> Self { self._file(path.as_ref(), body); self @@ -253,7 +253,7 @@ .push(FileBuilder::new(self.root.root().join(path), body)); } - /// Add a symlink to the project. + /// Adds a symlink to the project. pub fn symlink>(mut self, dst: T, src: T) -> Self { self.symlinks.push(SymlinkBuilder::new( self.root.root().join(dst), @@ -267,7 +267,7 @@ self } - /// Create the project. + /// Creates the project. pub fn build(mut self) -> Project { // First, clean the directory if it already exists self.rm_root(); @@ -370,24 +370,24 @@ )) } - /// Change the contents of an existing file. + /// Changes the contents of an existing file. pub fn change_file(&self, path: &str, body: &str) { FileBuilder::new(self.root().join(path), body).mk() } - /// Create a `ProcessBuilder` to run a program in the project + /// Creates a `ProcessBuilder` to run a program in the project /// and wrap it in an Execs to assert on the execution. /// Example: /// p.process(&p.bin("foo")) /// .with_stdout("bar\n") /// .run(); pub fn process>(&self, program: T) -> Execs { - let mut p = ::support::process(program); + let mut p = crate::support::process(program); p.cwd(self.root()); execs().with_process_builder(p) } - /// Create a `ProcessBuilder` to run cargo. + /// Creates a `ProcessBuilder` to run cargo. /// Arguments can be separated by spaces. /// Example: /// p.cargo("build --bin foo").run(); @@ -399,6 +399,27 @@ execs } + /// Safely run a process after `cargo build`. + /// + /// Windows has a problem where a process cannot be reliably + /// be replaced, removed, or renamed immediately after executing it. + /// The action may fail (with errors like Access is denied), or + /// it may succeed, but future attempts to use the same filename + /// will fail with "Already Exists". + /// + /// If you have a test that needs to do `cargo run` multiple + /// times, you should instead use `cargo build` and use this + /// method to run the executable. Each time you call this, + /// use a new name for `dst`. + /// See rust-lang/cargo#5481. + pub fn rename_run(&self, src: &str, dst: &str) -> Execs { + let src = self.bin(src); + let dst = self.bin(dst); + fs::rename(&src, &dst) + .unwrap_or_else(|e| panic!("Failed to rename `{:?}` to `{:?}`: {}", src, dst, e)); + self.process(dst) + } + /// Returns the contents of `Cargo.lock`. pub fn read_lockfile(&self) -> String { self.read_file("Cargo.lock") @@ -516,7 +537,8 @@ } path }) - }).unwrap_or_else(|| panic!("CARGO_BIN_PATH wasn't set. Cannot continue running test")) + }) + .unwrap_or_else(|| panic!("CARGO_BIN_PATH wasn't set. Cannot continue running test")) } pub fn cargo_exe() -> PathBuf { @@ -549,6 +571,7 @@ expect_stderr_unordered: Vec, expect_neither_contains: Vec, expect_json: Option>, + expect_json_contains_unordered: Vec, stream_output: bool, } @@ -558,21 +581,21 @@ self } - /// Verify that stdout is equal to the given lines. + /// Verifies that stdout is equal to the given lines. /// See `lines_match` for supported patterns. pub fn with_stdout(&mut self, expected: S) -> &mut Self { self.expect_stdout = Some(expected.to_string()); self } - /// Verify that stderr is equal to the given lines. + /// Verifies that stderr is equal to the given lines. /// See `lines_match` for supported patterns. pub fn with_stderr(&mut self, expected: S) -> &mut Self { self.expect_stderr = Some(expected.to_string()); self } - /// Verify the exit code from the process. + /// Verifies the exit code from the process. /// /// This is not necessary if the expected exit code is `0`. pub fn with_status(&mut self, expected: i32) -> &mut Self { @@ -580,7 +603,7 @@ self } - /// Remove exit code check for the process. + /// Removes exit code check for the process. /// /// By default, the expected exit code is `0`. pub fn without_status(&mut self) -> &mut Self { @@ -588,7 +611,7 @@ self } - /// Verify that stdout contains the given contiguous lines somewhere in + /// Verifies that stdout contains the given contiguous lines somewhere in /// its output. /// See `lines_match` for supported patterns. pub fn with_stdout_contains(&mut self, expected: S) -> &mut Self { @@ -596,7 +619,7 @@ self } - /// Verify that stderr contains the given contiguous lines somewhere in + /// Verifies that stderr contains the given contiguous lines somewhere in /// its output. /// See `lines_match` for supported patterns. pub fn with_stderr_contains(&mut self, expected: S) -> &mut Self { @@ -604,7 +627,7 @@ self } - /// Verify that either stdout or stderr contains the given contiguous + /// Verifies that either stdout or stderr contains the given contiguous /// lines somewhere in its output. /// See `lines_match` for supported patterns. pub fn with_either_contains(&mut self, expected: S) -> &mut Self { @@ -612,7 +635,7 @@ self } - /// Verify that stdout contains the given contiguous lines somewhere in + /// Verifies that stdout contains the given contiguous lines somewhere in /// its output, and should be repeated `number` times. /// See `lines_match` for supported patterns. pub fn with_stdout_contains_n(&mut self, expected: S, number: usize) -> &mut Self { @@ -621,7 +644,7 @@ self } - /// Verify that stdout does not contain the given contiguous lines. + /// Verifies that stdout does not contain the given contiguous lines. /// See `lines_match` for supported patterns. /// See note on `with_stderr_does_not_contain`. pub fn with_stdout_does_not_contain(&mut self, expected: S) -> &mut Self { @@ -629,11 +652,11 @@ self } - /// Verify that stderr does not contain the given contiguous lines. + /// Verifies that stderr does not contain the given contiguous lines. /// See `lines_match` for supported patterns. /// /// Care should be taken when using this method because there is a - /// limitless number of possible things that *won't* appear. A typo means + /// limitless number of possible things that *won't* appear. A typo means /// your test will pass without verifying the correct behavior. If /// possible, write the test first so that it fails, and then implement /// your fix/feature to make it pass. @@ -642,7 +665,7 @@ self } - /// Verify that all of the stderr output is equal to the given lines, + /// Verifies that all of the stderr output is equal to the given lines, /// ignoring the order of the lines. /// See `lines_match` for supported patterns. /// This is useful when checking the output of `cargo build -v` since @@ -652,9 +675,11 @@ /// /// Be careful when using patterns such as `[..]`, because you may end up /// with multiple lines that might match, and this is not smart enough to - /// do anything like longest-match. For example, avoid something like: + /// do anything like longest-match. For example, avoid something like: + /// /// [RUNNING] `rustc [..] /// [RUNNING] `rustc --crate-name foo [..] + /// /// This will randomly fail if the other crate name is `bar`, and the /// order changes. pub fn with_stderr_unordered(&mut self, expected: S) -> &mut Self { @@ -662,7 +687,7 @@ self } - /// Verify the JSON output matches the given JSON. + /// Verifies the JSON output matches the given JSON. /// Typically used when testing cargo commands that emit JSON. /// Each separate JSON object should be separated by a blank line. /// Example: @@ -688,6 +713,24 @@ self } + /// Verifies JSON output contains the given objects (in any order) somewhere + /// in its output. + /// + /// CAUTION: Be very careful when using this. Make sure every object is + /// unique (not a subset of one another). Also avoid using objects that + /// could possibly match multiple output lines unless you're very sure of + /// what you are doing. + /// + /// See `with_json` for more detail. + pub fn with_json_contains_unordered(&mut self, expected: &str) -> &mut Self { + self.expect_json_contains_unordered.extend( + expected + .split("\n\n") + .map(|line| line.parse().expect("line to be a valid JSON value")), + ); + self + } + /// Forward subordinate process stdout/stderr to the terminal. /// Useful for printf debugging of the tests. /// CAUTION: CI will fail if you leave this in your test! @@ -761,6 +804,32 @@ } } + fn verify_checks_output(&self, output: &Output) { + if self.expect_exit_code.unwrap_or(0) != 0 + && self.expect_stdout.is_none() + && self.expect_stdin.is_none() + && self.expect_stderr.is_none() + && self.expect_stdout_contains.is_empty() + && self.expect_stderr_contains.is_empty() + && self.expect_either_contains.is_empty() + && self.expect_stdout_contains_n.is_empty() + && self.expect_stdout_not_contains.is_empty() + && self.expect_stderr_not_contains.is_empty() + && self.expect_stderr_unordered.is_empty() + && self.expect_neither_contains.is_empty() + && self.expect_json.is_none() + && self.expect_json_contains_unordered.is_empty() + { + panic!( + "`with_status()` is used, but no output is checked.\n\ + The test must check the output to ensure the correct error is triggered.\n\ + --- stdout\n{}\n--- stderr\n{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr), + ); + } + } + fn match_process(&self, process: &ProcessBuilder) -> MatchResult { println!("running {}", process); let res = if self.stream_output { @@ -797,6 +866,7 @@ } fn match_output(&self, actual: &Output) -> MatchResult { + self.verify_checks_output(actual); self.match_status(actual) .and(self.match_stdout(actual)) .and(self.match_stderr(actual)) @@ -940,6 +1010,33 @@ self.match_json(obj, line)?; } } + + if !self.expect_json_contains_unordered.is_empty() { + let stdout = str::from_utf8(&actual.stdout) + .map_err(|_| "stdout was not utf8 encoded".to_owned())?; + let mut lines = stdout + .lines() + .filter(|line| line.starts_with('{')) + .collect::>(); + for obj in &self.expect_json_contains_unordered { + match lines + .iter() + .position(|line| self.match_json(obj, line).is_ok()) + { + Some(index) => lines.remove(index), + None => { + return Err(format!( + "Did not find expected JSON:\n\ + {}\n\ + Remaining available output:\n\ + {}\n", + serde_json::to_string_pretty(obj).unwrap(), + lines.join("\n") + )); + } + }; + } + } Ok(()) } @@ -968,20 +1065,17 @@ None => out.to_string(), Some(ref p) => match p.get_cwd() { None => out.to_string(), - Some(cwd) => out - .replace( "[CWD]", &cwd.display().to_string()) - , + Some(cwd) => out.replace("[CWD]", &cwd.display().to_string()), }, }; // On Windows, we need to use a wildcard for the drive, // because we don't actually know what it will be. - let replaced = replaced - .replace("[ROOT]", - if cfg!(windows) { r#"[..]:\"# } else { "/" }); + let replaced = + replaced.replace("[ROOT]", if cfg!(windows) { r#"[..]:\"# } else { "/" }); replaced - }, + } None => return Ok(()), }; @@ -989,7 +1083,7 @@ Err(..) => return Err(format!("{} was not utf8 encoded", description)), Ok(actual) => actual, }; - // Let's not deal with \r\n vs \n on windows... + // Let's not deal with `\r\n` vs `\n` on Windows. let actual = actual.replace("\r", ""); let actual = actual.replace("\t", ""); @@ -1098,7 +1192,7 @@ {}\n", e_line, a.join("\n") - )) + )); } }; } @@ -1121,16 +1215,7 @@ Ok(actual) => actual, }; - match find_mismatch(expected, &actual) { - Some((expected_part, actual_part)) => Err(format!( - "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", - serde_json::to_string_pretty(expected).unwrap(), - serde_json::to_string_pretty(&actual).unwrap(), - serde_json::to_string_pretty(expected_part).unwrap(), - serde_json::to_string_pretty(actual_part).unwrap(), - )), - None => Ok(()), - } + find_json_mismatch(expected, &actual) } fn diff_lines<'a>( @@ -1157,13 +1242,14 @@ (Some(a), None) => Some(format!("{:3} -\n + |{}|\n", i, a)), (None, Some(e)) => Some(format!("{:3} - |{}|\n +\n", i, e)), (None, None) => panic!("Cannot get here"), - }).collect() + }) + .collect() } } impl Drop for Execs { fn drop(&mut self) { - if !self.ran { + if !self.ran && !std::thread::panicking() { panic!("forgot to run this command"); } } @@ -1178,7 +1264,7 @@ Unordered, } -/// Compare a line with an expected pattern. +/// Compares a line with an expected pattern. /// - Use `[..]` as a wildcard to match 0 or more characters on the same line /// (similar to `.*` in a regex). /// - Use `[EXE]` to optionally add `.exe` on Windows (empty string on other @@ -1186,6 +1272,8 @@ /// - There is a wide range of macros (such as `[COMPILING]` or `[WARNING]`) /// to match cargo's "status" output and allows you to ignore the alignment. /// See `substitute_macros` for a complete list of macros. +/// - `[ROOT]` is `/` or `[..]:\` on Windows. +/// - `[CWD]` is the working directory of the process that was run. pub fn lines_match(expected: &str, actual: &str) -> bool { // Let's not deal with / vs \ (windows...) // First replace backslash-escaped backslashes with forward slashes @@ -1220,12 +1308,28 @@ assert!(!lines_match("b", "cb")); } -// Compares JSON object for approximate equality. -// You can use `[..]` wildcard in strings (useful for OS dependent things such -// as paths). You can use a `"{...}"` string literal as a wildcard for -// arbitrary nested JSON (useful for parts of object emitted by other programs -// (e.g. rustc) rather than Cargo itself). Arrays are sorted before comparison. -fn find_mismatch<'a>(expected: &'a Value, actual: &'a Value) -> Option<(&'a Value, &'a Value)> { +/// Compares JSON object for approximate equality. +/// You can use `[..]` wildcard in strings (useful for OS-dependent things such +/// as paths). You can use a `"{...}"` string literal as a wildcard for +/// arbitrary nested JSON (useful for parts of object emitted by other programs +/// (e.g., rustc) rather than Cargo itself). Arrays are sorted before comparison. +pub fn find_json_mismatch(expected: &Value, actual: &Value) -> Result<(), String> { + match find_json_mismatch_r(expected, &actual) { + Some((expected_part, actual_part)) => Err(format!( + "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", + serde_json::to_string_pretty(expected).unwrap(), + serde_json::to_string_pretty(&actual).unwrap(), + serde_json::to_string_pretty(expected_part).unwrap(), + serde_json::to_string_pretty(actual_part).unwrap(), + )), + None => Ok(()), + } +} + +fn find_json_mismatch_r<'a>( + expected: &'a Value, + actual: &'a Value, +) -> Option<(&'a Value, &'a Value)> { use serde_json::Value::*; match (expected, actual) { (&Number(ref l), &Number(ref r)) if l == r => None, @@ -1240,7 +1344,7 @@ let mut r = r.iter().collect::>(); l.retain( - |l| match r.iter().position(|r| find_mismatch(l, r).is_none()) { + |l| match r.iter().position(|r| find_json_mismatch_r(l, r).is_none()) { Some(i) => { r.remove(i); false @@ -1265,11 +1369,11 @@ l.values() .zip(r.values()) - .filter_map(|(l, r)| find_mismatch(l, r)) + .filter_map(|(l, r)| find_json_mismatch_r(l, r)) .nth(0) } (&Null, &Null) => None, - // magic string literal "{...}" acts as wildcard for any sub-JSON + // Magic string literal `"{...}"` acts as wildcard for any sub-JSON. (&String(ref l), _) if l == "{...}" => None, _ => Some((expected, actual)), } @@ -1301,7 +1405,7 @@ } impl fmt::Debug for Execs { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "execs") } } @@ -1323,6 +1427,7 @@ expect_stderr_unordered: Vec::new(), expect_neither_contains: Vec::new(), expect_json: None, + expect_json_contains_unordered: Vec::new(), stream_output: false, } } @@ -1450,43 +1555,39 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder { let mut p = cargo::util::process(t); p.cwd(&paths::root()) - .env_remove("CARGO_HOME") - .env("HOME", paths::home()) - .env("CARGO_HOME", paths::home().join(".cargo")) - .env("__CARGO_TEST_ROOT", paths::root()) - - // Force cargo to think it's on the stable channel for all tests, this - // should hopefully not surprise us as we add cargo features over time and - // cargo rides the trains. - .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable") - - // For now disable incremental by default as support hasn't ridden to the - // stable channel yet. Once incremental support hits the stable compiler we - // can switch this to one and then fix the tests. - .env("CARGO_INCREMENTAL", "0") - - // This env var can switch the git backend from libgit2 to git2-curl, which - // can tweak error messages and cause some tests to fail, so let's forcibly - // remove it. - .env_remove("CARGO_HTTP_CHECK_REVOKE") - - .env_remove("__CARGO_DEFAULT_LIB_METADATA") - .env_remove("RUSTC") - .env_remove("RUSTDOC") - .env_remove("RUSTC_WRAPPER") - .env_remove("RUSTFLAGS") - .env_remove("XDG_CONFIG_HOME") // see #2345 - .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves - .env_remove("EMAIL") - .env_remove("MFLAGS") - .env_remove("MAKEFLAGS") - .env_remove("CARGO_MAKEFLAGS") - .env_remove("GIT_AUTHOR_NAME") - .env_remove("GIT_AUTHOR_EMAIL") - .env_remove("GIT_COMMITTER_NAME") - .env_remove("GIT_COMMITTER_EMAIL") - .env_remove("CARGO_TARGET_DIR") // we assume 'target' - .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows + .env_remove("CARGO_HOME") + .env("HOME", paths::home()) + .env("CARGO_HOME", paths::home().join(".cargo")) + .env("__CARGO_TEST_ROOT", paths::root()) + // Force Cargo to think it's on the stable channel for all tests, this + // should hopefully not surprise us as we add cargo features over time and + // cargo rides the trains. + .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable") + // For now disable incremental by default as support hasn't ridden to the + // stable channel yet. Once incremental support hits the stable compiler we + // can switch this to one and then fix the tests. + .env("CARGO_INCREMENTAL", "0") + // This env var can switch the git backend from libgit2 to git2-curl, which + // can tweak error messages and cause some tests to fail, so let's forcibly + // remove it. + .env_remove("CARGO_HTTP_CHECK_REVOKE") + .env_remove("__CARGO_DEFAULT_LIB_METADATA") + .env_remove("RUSTC") + .env_remove("RUSTDOC") + .env_remove("RUSTC_WRAPPER") + .env_remove("RUSTFLAGS") + .env_remove("XDG_CONFIG_HOME") // see #2345 + .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves + .env_remove("EMAIL") + .env_remove("MFLAGS") + .env_remove("MAKEFLAGS") + .env_remove("CARGO_MAKEFLAGS") + .env_remove("GIT_AUTHOR_NAME") + .env_remove("GIT_AUTHOR_EMAIL") + .env_remove("GIT_COMMITTER_NAME") + .env_remove("GIT_COMMITTER_EMAIL") + .env_remove("CARGO_TARGET_DIR") // we assume 'target' + .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows p } @@ -1525,10 +1626,24 @@ ::std::thread::sleep(Duration::from_millis(ms)); } -/// Returns true if the local filesystem has low-resolution mtimes. +/// Returns `true` if the local filesystem has low-resolution mtimes. pub fn is_coarse_mtime() -> bool { - // This should actually be a test that $CARGO_TARGET_DIR is on an HFS + // If the filetime crate is being used to emulate HFS then + // return `true`, without looking at the actual hardware. + cfg!(emulate_second_only_system) || + // This should actually be a test that `$CARGO_TARGET_DIR` is on an HFS // filesystem, (or any filesystem with low-resolution mtimes). However, // that's tricky to detect, so for now just deal with CI. cfg!(target_os = "macos") && env::var("CI").is_ok() } + +/// Some CI setups are much slower then the equipment used by Cargo itself. +/// Architectures that do not have a modern processor, hardware emulation, ect. +/// This provides a way for those setups to increase the cut off for all the time based test. +pub fn slow_cpu_multiplier(main: u64) -> Duration { + lazy_static::lazy_static! { + static ref SLOW_CPU_MULTIPLIER: u64 = + env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER").ok().and_then(|m| m.parse().ok()).unwrap_or(1); + } + Duration::from_secs(*SLOW_CPU_MULTIPLIER * main) +} diff -Nru cargo-0.33.0/tests/testsuite/support/paths.rs cargo-0.35.0/tests/testsuite/support/paths.rs --- cargo-0.33.0/tests/testsuite/support/paths.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/paths.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,13 +3,13 @@ use std::fs; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; -use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Once, ONCE_INIT}; use filetime::{self, FileTime}; static CARGO_INTEGRATION_TEST_DIR: &'static str = "cit"; -static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; +static NEXT_ID: AtomicUsize = AtomicUsize::new(0); thread_local!(static TASK_ID: usize = NEXT_ID.fetch_add(1, Ordering::SeqCst)); diff -Nru cargo-0.33.0/tests/testsuite/support/publish.rs cargo-0.35.0/tests/testsuite/support/publish.rs --- cargo-0.33.0/tests/testsuite/support/publish.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/publish.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,61 +1,124 @@ -use std::fs::{self, File}; -use std::io::prelude::*; -use std::path::PathBuf; - -use support::git::{repo, Repository}; -use support::paths; - -use url::Url; - -pub fn setup() -> Repository { - let config = paths::root().join(".cargo/config"); - t!(fs::create_dir_all(config.parent().unwrap())); - t!(t!(File::create(&config)).write_all( - format!( - r#" - [registry] - token = "api-token" - - [registries.alternative] - index = "{registry}" - "#, - registry = registry().to_string() - ).as_bytes() - )); - - let credentials = paths::root().join("home/.cargo/credentials"); - t!(fs::create_dir_all(credentials.parent().unwrap())); - t!(t!(File::create(&credentials)).write_all( - br#" - [registries.alternative] - token = "api-token" - "# - )); - - t!(fs::create_dir_all(&upload_path().join("api/v1/crates"))); - - repo(®istry_path()) - .file( - "config.json", - &format!( - r#"{{ - "dl": "{0}", - "api": "{0}" - }}"#, - upload() - ), - ).build() +use std::collections::{HashMap, HashSet}; +use std::fs::File; +use std::io::{prelude::*, SeekFrom}; +use std::path::{Path, PathBuf}; + +use crate::support::find_json_mismatch; +use crate::support::registry::{self, alt_api_path}; + +use byteorder::{LittleEndian, ReadBytesExt}; +use flate2::read::GzDecoder; +use tar::Archive; + +/// Checks the result of a crate publish. +pub fn validate_upload(expected_json: &str, expected_crate_name: &str, expected_files: &[&str]) { + let new_path = registry::api_path().join("api/v1/crates/new"); + _validate_upload( + &new_path, + expected_json, + expected_crate_name, + expected_files, + ); } -pub fn registry_path() -> PathBuf { - paths::root().join("registry") +/// Checks the result of a crate publish to an alternative registry. +pub fn validate_alt_upload( + expected_json: &str, + expected_crate_name: &str, + expected_files: &[&str], +) { + let new_path = alt_api_path().join("api/v1/crates/new"); + _validate_upload( + &new_path, + expected_json, + expected_crate_name, + expected_files, + ); } -pub fn registry() -> Url { - Url::from_file_path(&*registry_path()).ok().unwrap() -} -pub fn upload_path() -> PathBuf { - paths::root().join("upload") + +fn _validate_upload( + new_path: &Path, + expected_json: &str, + expected_crate_name: &str, + expected_files: &[&str], +) { + let mut f = File::open(new_path).unwrap(); + // 32-bit little-endian integer of length of JSON data. + let json_sz = f.read_u32::().expect("read json length"); + let mut json_bytes = vec![0; json_sz as usize]; + f.read_exact(&mut json_bytes).expect("read JSON data"); + let actual_json = serde_json::from_slice(&json_bytes).expect("uploaded JSON should be valid"); + let expected_json = serde_json::from_str(expected_json).expect("expected JSON does not parse"); + find_json_mismatch(&expected_json, &actual_json) + .expect("uploaded JSON did not match expected JSON"); + + // 32-bit little-endian integer of length of crate file. + let crate_sz = f.read_u32::().expect("read crate length"); + let mut krate_bytes = vec![0; crate_sz as usize]; + f.read_exact(&mut krate_bytes).expect("read crate data"); + // Check at end. + let current = f.seek(SeekFrom::Current(0)).unwrap(); + assert_eq!(f.seek(SeekFrom::End(0)).unwrap(), current); + + // Verify the tarball. + validate_crate_contents(&krate_bytes[..], expected_crate_name, expected_files, &[]); } -fn upload() -> Url { - Url::from_file_path(&*upload_path()).ok().unwrap() + +/// Checks the contents of a `.crate` file. +/// +/// - `expected_crate_name` should be something like `foo-0.0.1.crate`. +/// - `expected_files` should be a complete list of files in the crate +/// (relative to expected_crate_name). +/// - `expected_contents` should be a list of `(file_name, contents)` tuples +/// to validate the contents of the given file. Only the listed files will +/// be checked (others will be ignored). +pub fn validate_crate_contents( + reader: impl Read, + expected_crate_name: &str, + expected_files: &[&str], + expected_contents: &[(&str, &str)], +) { + let mut rdr = GzDecoder::new(reader); + assert_eq!( + rdr.header().unwrap().filename().unwrap(), + expected_crate_name.as_bytes() + ); + let mut contents = Vec::new(); + rdr.read_to_end(&mut contents).unwrap(); + let mut ar = Archive::new(&contents[..]); + let files: HashMap = ar + .entries() + .unwrap() + .map(|entry| { + let mut entry = entry.unwrap(); + let name = entry.path().unwrap().into_owned(); + let mut contents = String::new(); + entry.read_to_string(&mut contents).unwrap(); + (name, contents) + }) + .collect(); + assert!(expected_crate_name.ends_with(".crate")); + let base_crate_name = Path::new(&expected_crate_name[..expected_crate_name.len() - 6]); + let actual_files: HashSet = files.keys().cloned().collect(); + let expected_files: HashSet = expected_files + .iter() + .map(|name| base_crate_name.join(name)) + .collect(); + let missing: Vec<&PathBuf> = expected_files.difference(&actual_files).collect(); + let extra: Vec<&PathBuf> = actual_files.difference(&expected_files).collect(); + if !missing.is_empty() || !extra.is_empty() { + panic!( + "uploaded archive does not match.\nMissing: {:?}\nExtra: {:?}\n", + missing, extra + ); + } + if !expected_contents.is_empty() { + for (e_file_name, e_file_contents) in expected_contents { + let full_e_name = base_crate_name.join(e_file_name); + let actual_contents = files + .get(&full_e_name) + .unwrap_or_else(|| panic!("file `{}` missing in archive", e_file_name)); + assert_eq!(actual_contents, e_file_contents); + } + } } diff -Nru cargo-0.33.0/tests/testsuite/support/registry.rs cargo-0.35.0/tests/testsuite/support/registry.rs --- cargo-0.33.0/tests/testsuite/support/registry.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/registry.rs 2019-04-01 21:32:07.000000000 +0000 @@ -3,6 +3,7 @@ use std::io::prelude::*; use std::path::{Path, PathBuf}; +use cargo::sources::CRATES_IO_INDEX; use cargo::util::Sha256; use flate2::write::GzEncoder; use flate2::Compression; @@ -11,42 +12,56 @@ use tar::{Builder, Header}; use url::Url; -use support::git::repo; -use support::paths; +use crate::support::git::repo; +use crate::support::paths; +/// Gets the path to the local index pretending to be crates.io. This is a Git repo +/// initialized with a `config.json` file pointing to `dl_path` for downloads +/// and `api_path` for uploads. pub fn registry_path() -> PathBuf { paths::root().join("registry") } -pub fn registry() -> Url { - Url::from_file_path(&*registry_path()).ok().unwrap() +pub fn registry_url() -> Url { + Url::from_file_path(registry_path()).ok().unwrap() } +/// Gets the path for local web API uploads. Cargo will place the contents of a web API +/// request here. For example, `api/v1/crates/new` is the result of publishing a crate. pub fn api_path() -> PathBuf { paths::root().join("api") } +pub fn api_url() -> Url { + Url::from_file_path(api_path()).ok().unwrap() +} +/// Gets the path where crates can be downloaded using the web API endpoint. Crates +/// should be organized as `{name}/{version}/download` to match the web API +/// endpoint. This is rarely used and must be manually set up. pub fn dl_path() -> PathBuf { paths::root().join("dl") } pub fn dl_url() -> Url { - Url::from_file_path(&*dl_path()).ok().unwrap() + Url::from_file_path(dl_path()).ok().unwrap() } +/// Gets the alternative-registry version of `registry_path`. pub fn alt_registry_path() -> PathBuf { paths::root().join("alternative-registry") } -pub fn alt_registry() -> Url { - Url::from_file_path(&*alt_registry_path()).ok().unwrap() +pub fn alt_registry_url() -> Url { + Url::from_file_path(alt_registry_path()).ok().unwrap() } +/// Gets the alternative-registry version of `dl_path`. pub fn alt_dl_path() -> PathBuf { paths::root().join("alt_dl") } pub fn alt_dl_url() -> String { - let base = Url::from_file_path(&*alt_dl_path()).ok().unwrap(); + let base = Url::from_file_path(alt_dl_path()).ok().unwrap(); format!("{}/{{crate}}/{{version}}/{{crate}}-{{version}}.crate", base) } +/// Gets the alternative-registry version of `api_path`. pub fn alt_api_path() -> PathBuf { paths::root().join("alt_api") } pub fn alt_api_url() -> Url { - Url::from_file_path(&*alt_api_path()).ok().unwrap() + Url::from_file_path(alt_api_path()).ok().unwrap() } /// A builder for creating a new package in a registry. @@ -144,9 +159,6 @@ t!(t!(File::create(&config)).write_all( format!( r#" - [registry] - token = "api-token" - [source.crates-io] registry = 'https://wut' replace-with = 'dummy-registry' @@ -157,25 +169,38 @@ [registries.alternative] index = '{alt}' "#, - reg = registry(), - alt = alt_registry() - ).as_bytes() + reg = registry_url(), + alt = alt_registry_url() + ) + .as_bytes() + )); + let credentials = paths::home().join(".cargo/credentials"); + t!(t!(File::create(&credentials)).write_all( + br#" + [registry] + token = "api-token" + + [registries.alternative] + token = "api-token" + "# )); - // Init a new registry + // Initialize a new registry. let _ = repo(®istry_path()) .file( "config.json", &format!( r#" - {{"dl":"{0}","api":"{0}"}} + {{"dl":"{}","api":"{}"}} "#, - dl_url() + dl_url(), + api_url() ), - ).build(); - fs::create_dir_all(dl_path().join("api/v1/crates")).unwrap(); + ) + .build(); + fs::create_dir_all(api_path().join("api/v1/crates")).unwrap(); - // Init an alt registry + // Initialize an alternative registry. repo(&alt_registry_path()) .file( "config.json", @@ -186,12 +211,13 @@ alt_dl_url(), alt_api_url() ), - ).build(); + ) + .build(); fs::create_dir_all(alt_api_path().join("api/v1/crates")).unwrap(); } impl Package { - /// Create a new package builder. + /// Creates a new package builder. /// Call `publish()` to finalize and build the package. pub fn new(name: &str, vers: &str) -> Package { init(); @@ -222,7 +248,7 @@ /// /// The name of the alternative registry is called "alternative". /// - /// See `unstable.html#alternate-registries` for more details on + /// See `src/doc/src/reference/registries.md` for more details on /// alternative registries. See `alt_registry.rs` for the tests that use /// this. pub fn alternative(&mut self, alternative: bool) -> &mut Package { @@ -230,13 +256,13 @@ self } - /// Add a file to the package. + /// Adds a file to the package. pub fn file(&mut self, name: &str, contents: &str) -> &mut Package { self.files.push((name.to_string(), contents.to_string())); self } - /// Add an "extra" file that is not rooted within the package. + /// Adds an "extra" file that is not rooted within the package. /// /// Normal files are automatically placed within a directory named /// `$PACKAGE-$VERSION`. This allows you to override that behavior, @@ -247,7 +273,7 @@ self } - /// Add a normal dependency. Example: + /// Adds a normal dependency. Example: /// ``` /// [dependencies] /// foo = {version = "1.0"} @@ -256,7 +282,7 @@ self.add_dep(&Dependency::new(name, vers)) } - /// Add a dependency with the given feature. Example: + /// Adds a dependency with the given feature. Example: /// ``` /// [dependencies] /// foo = {version = "1.0", "features": ["feat1", "feat2"]} @@ -265,7 +291,7 @@ self.add_dep(Dependency::new(name, vers).enable_features(features)) } - /// Add a platform-specific dependency. Example: + /// Adds a platform-specific dependency. Example: /// ``` /// [target.'cfg(windows)'.dependencies] /// foo = {version = "1.0"} @@ -274,13 +300,12 @@ self.add_dep(Dependency::new(name, vers).target(target)) } - /// Add a dependency to an alternative registry. - /// The given registry should be a URI to the alternative registry. - pub fn registry_dep(&mut self, name: &str, vers: &str, registry: &str) -> &mut Package { - self.add_dep(Dependency::new(name, vers).registry(registry)) + /// Adds a dependency to the alternative registry. + pub fn registry_dep(&mut self, name: &str, vers: &str) -> &mut Package { + self.add_dep(Dependency::new(name, vers).registry("alternative")) } - /// Add a dev-dependency. Example: + /// Adds a dev-dependency. Example: /// ``` /// [dev-dependencies] /// foo = {version = "1.0"} @@ -289,7 +314,7 @@ self.add_dep(Dependency::new(name, vers).dev()) } - /// Add a build-dependency. Example: + /// Adds a build-dependency. Example: /// ``` /// [build-dependencies] /// foo = {version = "1.0"} @@ -303,20 +328,20 @@ self } - /// Specify whether or not the package is "yanked". + /// Specifies whether or not the package is "yanked". pub fn yanked(&mut self, yanked: bool) -> &mut Package { self.yanked = yanked; self } - /// Add an entry in the `[features]` section + /// Adds an entry in the `[features]` section. pub fn feature(&mut self, name: &str, deps: &[&str]) -> &mut Package { let deps = deps.iter().map(|s| s.to_string()).collect(); self.features.insert(name.to_string(), deps); self } - /// Create the package and place it in the registry. + /// Creates the package and place it in the registry. /// /// This does not actually use Cargo's publishing system, but instead /// manually creates the entry in the registry on the filesystem. @@ -325,12 +350,22 @@ pub fn publish(&self) -> String { self.make_archive(); - // Figure out what we're going to write into the index + // Figure out what we're going to write into the index. let deps = self .deps .iter() .map(|dep| { - json!({ + // In the index, the `registry` is null if it is from the same registry. + // In Cargo.toml, it is None if it is from crates.io. + let registry_url = + match (self.alternative, dep.registry.as_ref().map(|s| s.as_ref())) { + (false, None) => None, + (false, Some("alternative")) => Some(alt_registry_url().to_string()), + (true, None) => Some(CRATES_IO_INDEX.to_string()), + (true, Some("alternative")) => None, + _ => panic!("registry_dep currently only supports `alternative`"), + }; + serde_json::json!({ "name": dep.name, "req": dep.vers, "features": dep.features, @@ -338,23 +373,25 @@ "target": dep.target, "optional": dep.optional, "kind": dep.kind, - "registry": dep.registry, + "registry": registry_url, "package": dep.package, }) - }).collect::>(); + }) + .collect::>(); let cksum = { let mut c = Vec::new(); t!(t!(File::open(&self.archive_dst())).read_to_end(&mut c)); cksum(&c) }; - let line = json!({ + let line = serde_json::json!({ "name": self.name, "vers": self.vers, "deps": deps, "cksum": cksum, "features": self.features, "yanked": self.yanked, - }).to_string(); + }) + .to_string(); let file = match self.name.len() { 1 => format!("1/{}", self.name), @@ -369,7 +406,7 @@ registry_path() }; - // Write file/line in the index + // Write file/line in the index. let dst = if self.local { registry_path.join("index").join(&file) } else { @@ -380,7 +417,7 @@ t!(fs::create_dir_all(dst.parent().unwrap())); t!(t!(File::create(&dst)).write_all((prev + &line[..] + "\n").as_bytes())); - // Add the new file to the index + // Add the new file to the index. if !self.local { let repo = t!(git2::Repository::open(®istry_path)); let mut index = t!(repo.index()); @@ -388,7 +425,7 @@ t!(index.write()); let id = t!(index.write_tree()); - // Commit this change + // Commit this change. let tree = t!(repo.find_tree(id)); let sig = t!(repo.signature()); let parent = t!(repo.refname_to_id("refs/heads/master")); @@ -407,14 +444,19 @@ } fn make_archive(&self) { + let features = if self.deps.iter().any(|dep| dep.registry.is_some()) { + "cargo-features = [\"alternative-registries\"]\n" + } else { + "" + }; let mut manifest = format!( r#" - [package] + {}[package] name = "{}" version = "{}" authors = [] "#, - self.name, self.vers + features, self.name, self.vers ); for dep in self.deps.iter() { let target = match dep.target { @@ -433,6 +475,10 @@ "#, target, kind, dep.name, dep.vers )); + if let Some(registry) = &dep.registry { + assert_eq!(registry, "alternative"); + manifest.push_str(&format!("registry-index = \"{}\"", alt_registry_url())); + } } let dst = self.archive_dst(); @@ -503,43 +549,43 @@ } } - /// Change this to `[build-dependencies]` + /// Changes this to `[build-dependencies]`. pub fn build(&mut self) -> &mut Self { self.kind = "build".to_string(); self } - /// Change this to `[dev-dependencies]` + /// Changes this to `[dev-dependencies]`. pub fn dev(&mut self) -> &mut Self { self.kind = "dev".to_string(); self } - /// Change this to `[target.$target.dependencies]` + /// Changes this to `[target.$target.dependencies]`. pub fn target(&mut self, target: &str) -> &mut Self { self.target = Some(target.to_string()); self } - /// Add `registry = $registry` to this dependency + /// Adds `registry = $registry` to this dependency. pub fn registry(&mut self, registry: &str) -> &mut Self { self.registry = Some(registry.to_string()); self } - /// Add `features = [ ... ]` to this dependency + /// Adds `features = [ ... ]` to this dependency. pub fn enable_features(&mut self, features: &[&str]) -> &mut Self { self.features.extend(features.iter().map(|s| s.to_string())); self } - /// Add `package = ...` to this dependency + /// Adds `package = ...` to this dependency. pub fn package(&mut self, pkg: &str) -> &mut Self { self.package = Some(pkg.to_string()); self } - /// Change this to an optional dependency + /// Changes this to an optional dependency. pub fn optional(&mut self, optional: bool) -> &mut Self { self.optional = optional; self diff -Nru cargo-0.33.0/tests/testsuite/support/resolver.rs cargo-0.35.0/tests/testsuite/support/resolver.rs --- cargo-0.33.0/tests/testsuite/support/resolver.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/support/resolver.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,7 +2,9 @@ use std::cmp::{max, min}; use std::collections::{BTreeMap, HashSet}; use std::fmt; -use std::time::{Duration, Instant}; +use std::time::Instant; + +use crate::support::slow_cpu_multiplier; use cargo::core::dependency::Kind; use cargo::core::resolver::{self, Method}; @@ -76,7 +78,7 @@ fn query( &mut self, dep: &Dependency, - f: &mut FnMut(Summary), + f: &mut dyn FnMut(Summary), fuzzy: bool, ) -> CargoResult<()> { for summary in self.0.iter() { @@ -117,7 +119,7 @@ // The largest test in our suite takes less then 30 sec. // So lets fail the test if we have ben running for two long. - assert!(start.elapsed() < Duration::from_secs(60)); + assert!(start.elapsed() < slow_cpu_multiplier(60)); resolve } @@ -172,7 +174,7 @@ } fn registry_loc() -> SourceId { - lazy_static! { + lazy_static::lazy_static! { static ref EXAMPLE_DOT_COM: SourceId = SourceId::for_registry(&"http://example.com".to_url().unwrap()).unwrap(); } @@ -228,6 +230,20 @@ .unwrap() } +pub fn remove_dep(sum: &Summary, ind: usize) -> Summary { + let mut deps = sum.dependencies().to_vec(); + deps.remove(ind); + // note: more things will need to be copied over in the future, but it works for now. + Summary::new( + sum.package_id(), + deps, + &BTreeMap::>::new(), + sum.links().map(|a| a.as_str()), + sum.namespaced_features(), + ) + .unwrap() +} + pub fn dep(name: &str) -> Dependency { dep_req(name, "*") } @@ -273,7 +289,7 @@ pub struct PrettyPrintRegistry(pub Vec); impl fmt::Debug for PrettyPrintRegistry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "vec![")?; for s in &self.0 { if s.dependencies().is_empty() { @@ -398,74 +414,85 @@ let list_of_raw_dependency = vec(raw_dependency, ..=max_deps); - (list_of_crates_with_versions, list_of_raw_dependency).prop_map( - |(crate_vers_by_name, raw_dependencies)| { - let list_of_pkgid: Vec<_> = crate_vers_by_name - .iter() - .flat_map(|(name, vers)| vers.iter().map(move |x| ((name.as_str(), &x.0), x.1))) - .collect(); - let len_all_pkgid = list_of_pkgid.len(); - let mut dependency_by_pkgid = vec![vec![]; len_all_pkgid]; - for (a, b, (c, d), k) in raw_dependencies { - let (a, b) = order_index(a, b, len_all_pkgid); - let ((dep_name, _), _) = list_of_pkgid[a]; - if (list_of_pkgid[b].0).0 == dep_name { - continue; + // By default a package depends only on other packages that have a smaller name, + // this helps make sure that all things in the resulting index are DAGs. + // If this is true then the DAG is maintained with grater instead. + let reverse_alphabetical = any::().no_shrink(); + + ( + list_of_crates_with_versions, + list_of_raw_dependency, + reverse_alphabetical, + ) + .prop_map( + |(crate_vers_by_name, raw_dependencies, reverse_alphabetical)| { + let list_of_pkgid: Vec<_> = crate_vers_by_name + .iter() + .flat_map(|(name, vers)| vers.iter().map(move |x| ((name.as_str(), &x.0), x.1))) + .collect(); + let len_all_pkgid = list_of_pkgid.len(); + let mut dependency_by_pkgid = vec![vec![]; len_all_pkgid]; + for (a, b, (c, d), k) in raw_dependencies { + let (a, b) = order_index(a, b, len_all_pkgid); + let (a, b) = if reverse_alphabetical { (b, a) } else { (a, b) }; + let ((dep_name, _), _) = list_of_pkgid[a]; + if (list_of_pkgid[b].0).0 == dep_name { + continue; + } + let s = &crate_vers_by_name[dep_name]; + let s_last_index = s.len() - 1; + let (c, d) = order_index(c, d, s.len()); + + dependency_by_pkgid[b].push(dep_req_kind( + &dep_name, + &if c == 0 && d == s_last_index { + "*".to_string() + } else if c == 0 { + format!("<={}", s[d].0) + } else if d == s_last_index { + format!(">={}", s[c].0) + } else if c == d { + format!("={}", s[c].0) + } else { + format!(">={}, <={}", s[c].0, s[d].0) + }, + match k { + 0 => Kind::Normal, + 1 => Kind::Build, + // => Kind::Development, // Development has not impact so don't gen + _ => panic!("bad index for Kind"), + }, + )) } - let s = &crate_vers_by_name[dep_name]; - let s_last_index = s.len() - 1; - let (c, d) = order_index(c, d, s.len()); - - dependency_by_pkgid[b].push(dep_req_kind( - &dep_name, - &if c == 0 && d == s_last_index { - "*".to_string() - } else if c == 0 { - format!("<={}", s[d].0) - } else if d == s_last_index { - format!(">={}", s[c].0) - } else if c == d { - format!("={}", s[c].0) - } else { - format!(">={}, <={}", s[c].0, s[d].0) - }, - match k { - 0 => Kind::Normal, - 1 => Kind::Build, - // => Kind::Development, // Development has not impact so don't gen - _ => panic!("bad index for Kind"), - }, - )) - } - PrettyPrintRegistry( - list_of_pkgid - .into_iter() - .zip(dependency_by_pkgid.into_iter()) - .map(|(((name, ver), allow_deps), deps)| { - pkg_dep( - (name, ver).to_pkgid(), - if !allow_deps { - vec![dep_req("bad", "*")] - } else { - let mut deps = deps; - deps.sort_by_key(|d| d.name_in_toml()); - deps.dedup_by_key(|d| d.name_in_toml()); - deps - }, - ) - }) - .collect(), - ) - }, - ) + PrettyPrintRegistry( + list_of_pkgid + .into_iter() + .zip(dependency_by_pkgid.into_iter()) + .map(|(((name, ver), allow_deps), deps)| { + pkg_dep( + (name, ver).to_pkgid(), + if !allow_deps { + vec![dep_req("bad", "*")] + } else { + let mut deps = deps; + deps.sort_by_key(|d| d.name_in_toml()); + deps.dedup_by_key(|d| d.name_in_toml()); + deps + }, + ) + }) + .collect(), + ) + }, + ) } /// This test is to test the generator to ensure /// that it makes registries with large dependency trees /// /// This is a form of randomized testing, if you are unlucky it can fail. -/// A failure on it's own is not a big dael. If you did not change the +/// A failure on its own is not a big deal. If you did not change the /// `registry_strategy` then feel free to retry without concern. #[test] fn meta_test_deep_trees_from_strategy() { @@ -518,7 +545,7 @@ .current(); let reg = registry(input.clone()); for this in input.iter().rev().take(10) { - let mut res = resolve( + let res = resolve( &pkg_id("root"), vec![dep_req(&this.name(), &format!("={}", this.version()))], ®, diff -Nru cargo-0.33.0/tests/testsuite/test.rs cargo-0.35.0/tests/testsuite/test.rs --- cargo-0.33.0/tests/testsuite/test.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/test.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,10 +2,11 @@ use std::io::prelude::*; use cargo; -use support::paths::CargoPathExt; -use support::registry::Package; -use support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, project}; -use support::{is_nightly, rustc_host, sleep_ms}; + +use crate::support::paths::CargoPathExt; +use crate::support::registry::Package; +use crate::support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, project}; +use crate::support::{is_nightly, rustc_host, sleep_ms}; #[test] fn cargo_test_simple() { @@ -26,7 +27,8 @@ fn test_hello() { assert_eq!(hello(), "hello") }"#, - ).build(); + ) + .build(); p.cargo("build").run(); assert!(p.bin("foo").is_file()); @@ -39,7 +41,8 @@ [COMPILING] foo v0.5.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("test test_hello ... ok") + ) + .with_stdout_contains("test test_hello ... ok") .run(); } @@ -57,7 +60,8 @@ [dependencies] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -66,7 +70,8 @@ #[test] fn test() { foo(); } "#, - ).file( + ) + .file( "tests/test.rs", r#" extern crate foo; @@ -74,7 +79,8 @@ #[test] fn test() { foo::foo(); } "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "pub fn bar() {}") .build(); @@ -92,7 +98,8 @@ [RUNNING] `[..]target/release/deps/test-[..][EXE]` [DOCTEST] foo [RUNNING] `rustdoc --test [..]lib.rs[..]`", - ).with_stdout_contains_n("test test ... ok", 2) + ) + .with_stdout_contains_n("test test ... ok", 2) .with_stdout_contains("running 0 tests") .run(); } @@ -117,7 +124,8 @@ [profile.release] overflow-checks = true "#, - ).file( + ) + .file( "src/foo.rs", r#" use std::panic; @@ -127,7 +135,8 @@ }); assert!(r.is_err()); }"#, - ).build(); + ) + .build(); p.cargo("build --release").run(); assert!(p.release_bin("foo").is_file()); @@ -145,7 +154,8 @@ fn main() {} #[test] fn test_hello() {} "#, - ).build(); + ) + .build(); p.cargo("test -v hello") .with_stderr( @@ -154,7 +164,8 @@ [RUNNING] `rustc [..] src/main.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]target/debug/deps/foo-[..][EXE] hello`", - ).with_stdout_contains("test test_hello ... ok") + ) + .with_stdout_contains("test test_hello ... ok") .run(); } @@ -167,20 +178,23 @@ pub fn foo() {} #[test] fn lib_test() {} ", - ).file( + ) + .file( "src/main.rs", " extern crate foo; fn main() {} #[test] fn bin_test() { foo::foo() } ", - ).file( + ) + .file( "tests/foo.rs", r#" extern crate foo; #[test] fn test_test() { foo::foo() } "#, - ).build(); + ) + .build(); p.cargo("test -v") .with_stdout_contains("test bin_test ... ok") @@ -208,7 +222,8 @@ fn test_hello() { assert_eq!(hello(), "nope") }"#, - ).build(); + ) + .build(); p.cargo("build").run(); assert!(p.bin("foo").is_file()); @@ -222,7 +237,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [ERROR] test failed, to rerun pass '--bin foo'", - ).with_stdout_contains( + ) + .with_stdout_contains( " running 1 test test test_hello ... FAILED @@ -231,7 +247,8 @@ ---- test_hello stdout ---- [..]thread 'test_hello' panicked at 'assertion failed:[..]", - ).with_stdout_contains("[..]`(left == right)`[..]") + ) + .with_stdout_contains("[..]`(left == right)`[..]") .with_stdout_contains("[..]left: `\"hello\"`,[..]") .with_stdout_contains("[..]right: `\"nope\"`[..]") .with_stdout_contains("[..]src/main.rs:12[..]") @@ -240,7 +257,8 @@ failures: test_hello ", - ).with_status(101) + ) + .with_status(101) .run(); } @@ -252,7 +270,8 @@ .file( "tests/footest.rs", "#[test] fn test_hello() { assert!(false) }", - ).build(); + ) + .build(); p.cargo("build").run(); assert!(p.bin("foo").is_file()); @@ -267,7 +286,8 @@ [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/footest-[..][EXE] [ERROR] test failed, to rerun pass '--test footest'", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .with_stdout_contains( "\ running 1 test @@ -279,12 +299,14 @@ [..]thread 'test_hello' panicked at 'assertion failed: false', \ tests/footest.rs:1[..] ", - ).with_stdout_contains( + ) + .with_stdout_contains( "\ failures: test_hello ", - ).with_status(101) + ) + .with_status(101) .run(); } @@ -302,7 +324,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [ERROR] test failed, to rerun pass '--lib'", - ).with_stdout_contains( + ) + .with_stdout_contains( "\ test test_hello ... FAILED @@ -312,12 +335,14 @@ [..]thread 'test_hello' panicked at 'assertion failed: false', \ src/lib.rs:1[..] ", - ).with_stdout_contains( + ) + .with_stdout_contains( "\ failures: test_hello ", - ).with_status(101) + ) + .with_status(101) .run(); } @@ -336,7 +361,8 @@ name = "baz" path = "src/main.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" /// @@ -350,7 +376,8 @@ pub fn foo(){} #[test] fn lib_test() {} "#, - ).file( + ) + .file( "src/main.rs", " #[allow(unused_extern_crates)] @@ -361,7 +388,8 @@ #[test] fn bin_test() {} ", - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -371,7 +399,8 @@ [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/baz-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test lib_test ... ok") + ) + .with_stdout_contains("test lib_test ... ok") .with_stdout_contains("test bin_test ... ok") .with_stdout_contains_n("test [..] ... ok", 3) .run(); @@ -391,7 +420,8 @@ [dependencies.bar] path = "../bar" "#, - ).file( + ) + .file( "src/lib.rs", " #[cfg(test)] @@ -406,7 +436,8 @@ bar::bar(); } ", - ).build(); + ) + .build(); let _p2 = project() .at("bar") .file("Cargo.toml", &basic_manifest("bar", "0.0.1")) @@ -421,7 +452,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target[..] [DOCTEST] foo", - ).with_stdout_contains("test bar_test ... ok") + ) + .with_stdout_contains("test bar_test ... ok") .with_stdout_contains_n("test [..] ... ok", 2) .run(); } @@ -441,7 +473,8 @@ name = "test" path = "src/test.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn get_hello() -> &'static str { "Hello" } @@ -449,7 +482,8 @@ #[test] fn internal_test() {} "#, - ).file( + ) + .file( "src/test.rs", r#" extern crate foo; @@ -457,7 +491,8 @@ #[test] fn external_test() { assert_eq!(foo::get_hello(), "Hello") } "#, - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -467,7 +502,8 @@ [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/test-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test internal_test ... ok") + ) + .with_stdout_contains("test internal_test ... ok") .with_stdout_contains("test external_test ... ok") .with_stdout_contains("running 0 tests") .run(); @@ -487,7 +523,8 @@ [[test]] name = "test" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("tests/test.rs", "#[test] fn foo() {}") .build(); @@ -505,7 +542,8 @@ #[test] fn internal_test() {} "#, - ).file( + ) + .file( "tests/external.rs", r#" extern crate foo; @@ -513,7 +551,8 @@ #[test] fn external_test() { assert_eq!(foo::get_hello(), "Hello") } "#, - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -523,7 +562,8 @@ [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/external-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test internal_test ... ok") + ) + .with_stdout_contains("test internal_test ... ok") .with_stdout_contains("test external_test ... ok") .with_stdout_contains("running 0 tests") .run(); @@ -538,7 +578,8 @@ r#" fn main() { panic!("Examples should not be run by 'cargo test'"); } "#, - ).build(); + ) + .build(); p.cargo("test").run(); } @@ -551,7 +592,8 @@ #[test] fn foo() {} #[test] fn bar() {} ", - ).build(); + ) + .build(); p.cargo("test bar") .with_stderr( @@ -560,7 +602,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test bar ... ok") + ) + .with_stdout_contains("test bar ... ok") .with_stdout_contains("running 0 tests") .run(); @@ -570,7 +613,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test foo ... ok") + ) + .with_stdout_contains("test foo ... ok") .with_stdout_contains("running 0 tests") .run(); } @@ -589,7 +633,8 @@ #[test] fn dummy_test() { } "#, - ).build(); + ) + .build(); for _ in 0..2 { p.cargo("test").run(); @@ -612,7 +657,8 @@ [[bin]] name = "foo" "#, - ).file("src/lib.rs", "#[test] fn lib_test() {}") + ) + .file("src/lib.rs", "#[test] fn lib_test() {}") .file( "src/main.rs", " @@ -622,7 +668,8 @@ #[test] fn bin_test() {} ", - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -632,7 +679,8 @@ [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains_n("test [..] ... ok", 2) + ) + .with_stdout_contains_n("test [..] ... ok", 2) .with_stdout_contains("running 0 tests") .run(); } @@ -652,7 +700,8 @@ #[test] fn foo_test() {} ", - ).file( + ) + .file( "tests/test.rs", " extern crate syntax; @@ -660,7 +709,8 @@ #[test] fn test() { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -670,7 +720,8 @@ [RUNNING] target/debug/deps/syntax-[..][EXE] [RUNNING] target/debug/deps/test-[..][EXE] [DOCTEST] syntax", - ).with_stdout_contains("test foo_test ... ok") + ) + .with_stdout_contains("test foo_test ... ok") .with_stdout_contains("test test ... ok") .with_stdout_contains_n("test [..] ... ok", 3) .run(); @@ -692,7 +743,8 @@ test = false doctest = false "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -703,7 +755,8 @@ #[test] fn test() { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -711,7 +764,8 @@ [COMPILING] syntax v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/syntax-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); } @@ -730,7 +784,8 @@ test = false doctest = false "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -741,7 +796,8 @@ #[test] fn test() { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -749,7 +805,8 @@ [COMPILING] syntax v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/syntax-[..][EXE]", - ).with_stdout_contains("test test ... ok") + ) + .with_stdout_contains("test test ... ok") .run(); } @@ -771,7 +828,8 @@ [[bin]] path = "src/main.rs" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -782,7 +840,8 @@ #[test] fn test() { syntax::foo() } ", - ).build(); + ) + .build(); p.cargo("test") .with_status(101) @@ -792,7 +851,8 @@ Caused by: binary target bin.name is required", - ).run(); + ) + .run(); } #[test] @@ -813,7 +873,8 @@ [[bench]] path = "src/bench.rs" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -824,7 +885,8 @@ #[test] fn test() { syntax::foo() } ", - ).file( + ) + .file( "src/bench.rs", " #![feature(test)] @@ -834,7 +896,8 @@ #[bench] fn external_bench(_b: &mut test::Bencher) {} ", - ).build(); + ) + .build(); p.cargo("test") .with_status(101) @@ -844,7 +907,8 @@ Caused by: benchmark target bench.name is required", - ).run(); + ) + .run(); } #[test] @@ -865,13 +929,15 @@ [[test]] path = "src/test.rs" "#, - ).file( + ) + .file( "src/lib.rs", r#" pub fn foo() {} pub fn get_hello() -> &'static str { "Hello" } "#, - ).file( + ) + .file( "src/main.rs", " extern crate syntax; @@ -881,7 +947,8 @@ #[test] fn test() { syntax::foo() } ", - ).file( + ) + .file( "src/test.rs", r#" extern crate syntax; @@ -889,7 +956,8 @@ #[test] fn external_test() { assert_eq!(syntax::get_hello(), "Hello") } "#, - ).build(); + ) + .build(); p.cargo("test") .with_status(101) @@ -899,7 +967,8 @@ Caused by: test target test.name is required", - ).run(); + ) + .run(); } #[test] @@ -920,7 +989,8 @@ [[example]] path = "examples/example.rs" "#, - ).file("src/lib.rs", "pub fn foo() {}") + ) + .file("src/lib.rs", "pub fn foo() {}") .file( "src/main.rs", " @@ -931,7 +1001,8 @@ #[test] fn test() { syntax::foo() } ", - ).file( + ) + .file( "examples/example.rs", r#" extern crate syntax; @@ -940,7 +1011,8 @@ println!("example1"); } "#, - ).build(); + ) + .build(); p.cargo("test") .with_status(101) @@ -950,7 +1022,8 @@ Caused by: example target example.name is required", - ).run(); + ) + .run(); } #[test] @@ -962,7 +1035,8 @@ fn main() { std::process::exit(101); } #[test] fn main_test() {} ", - ).file( + ) + .file( "tests/foo.rs", r#" use std::process::Command; @@ -972,7 +1046,8 @@ assert_eq!(status.code(), Some(101)); } "#, - ).build(); + ) + .build(); p.cargo("test -v") .with_stdout_contains("test main_test ... ok") @@ -998,7 +1073,8 @@ [dependencies.bar] path = "bar" "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar as the_bar; @@ -1008,7 +1084,8 @@ #[test] fn foo() { bar(); } "#, - ).file( + ) + .file( "tests/test.rs", r#" extern crate foo as the_foo; @@ -1016,7 +1093,8 @@ #[test] fn foo() { the_foo::bar(); } "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -1028,7 +1106,8 @@ name = "bar" crate_type = ["dylib"] "#, - ).file("bar/src/lib.rs", "pub fn baz() {}") + ) + .file("bar/src/lib.rs", "pub fn baz() {}") .build(); p.cargo("test") @@ -1039,7 +1118,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/test-[..][EXE]", - ).with_stdout_contains_n("test foo ... ok", 2) + ) + .with_stdout_contains_n("test foo ... ok", 2) .run(); p.root().move_into_the_past(); @@ -1049,7 +1129,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/test-[..][EXE]", - ).with_stdout_contains_n("test foo ... ok", 2) + ) + .with_stdout_contains_n("test foo ... ok", 2) .run(); } @@ -1065,7 +1146,8 @@ authors = [] build = "build.rs" "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "#[test] fn foo() {}") .build(); @@ -1076,7 +1158,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test foo ... ok") + ) + .with_stdout_contains("test foo ... ok") .with_stdout_contains("running 0 tests") .run(); @@ -1086,7 +1169,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test foo ... ok") + ) + .with_stdout_contains("test foo ... ok") .with_stdout_contains("running 0 tests") .run(); } @@ -1102,7 +1186,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test foo ... ok") + ) + .with_stdout_contains("test foo ... ok") .with_stdout_contains("running 0 tests") .run(); @@ -1121,7 +1206,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1143,7 +1229,8 @@ name="bin2" path="src/bin2.rs" "#, - ).file("src/bin1.rs", "#[test] fn test1() { }") + ) + .file("src/bin1.rs", "#[test] fn test1() { }") .file("src/bin2.rs", "#[test] fn test2() { }") .build(); @@ -1153,7 +1240,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/bin2-[..][EXE]", - ).with_stdout_contains("test test2 ... ok") + ) + .with_stdout_contains("test test2 ... ok") .run(); } @@ -1172,17 +1260,20 @@ name="mybin" path="src/mybin.rs" "#, - ).file( + ) + .file( "src/mybin.rs", "#[test] fn test_in_bin() { } fn main() { panic!(\"Don't execute me!\"); }", - ).file("tests/mytest.rs", "#[test] fn test_in_test() { }") + ) + .file("tests/mytest.rs", "#[test] fn test_in_test() { }") .file("benches/mybench.rs", "#[test] fn test_in_bench() { }") .file( "examples/myexm.rs", "#[test] fn test_in_exm() { } fn main() { panic!(\"Don't execute me!\"); }", - ).build(); + ) + .build(); prj.cargo("test --bins") .with_stderr( @@ -1190,7 +1281,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/mybin-[..][EXE]", - ).with_stdout_contains("test test_in_bin ... ok") + ) + .with_stdout_contains("test test_in_bin ... ok") .run(); } @@ -1209,7 +1301,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/b-[..][EXE]", - ).with_stdout_contains("test test_b ... ok") + ) + .with_stdout_contains("test test_b ... ok") .run(); } @@ -1228,16 +1321,19 @@ name="mybin" path="src/mybin.rs" "#, - ).file( + ) + .file( "src/mybin.rs", "#[test] fn test_in_bin() { } fn main() { panic!(\"Don't execute me!\"); }", - ).file("tests/mytest.rs", "#[test] fn test_in_test() { }") + ) + .file("tests/mytest.rs", "#[test] fn test_in_test() { }") .file("benches/mybench.rs", "#[test] fn test_in_bench() { }") .file( "examples/myexm.rs", "fn main() { compile_error!(\"Don't build me!\"); }", - ).build(); + ) + .build(); prj.cargo("test --tests") .with_stderr( @@ -1246,7 +1342,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/mybin-[..][EXE] [RUNNING] target/debug/deps/mytest-[..][EXE]", - ).with_stdout_contains("test test_in_test ... ok") + ) + .with_stdout_contains("test test_in_test ... ok") .run(); } @@ -1265,16 +1362,19 @@ name="mybin" path="src/mybin.rs" "#, - ).file( + ) + .file( "src/mybin.rs", "#[test] fn test_in_bin() { } fn main() { panic!(\"Don't execute me!\"); }", - ).file("tests/mytest.rs", "#[test] fn test_in_test() { }") + ) + .file("tests/mytest.rs", "#[test] fn test_in_test() { }") .file("benches/mybench.rs", "#[test] fn test_in_bench() { }") .file( "examples/myexm.rs", "fn main() { compile_error!(\"Don't build me!\"); }", - ).build(); + ) + .build(); prj.cargo("test --benches") .with_stderr( @@ -1283,7 +1383,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/mybin-[..][EXE] [RUNNING] target/debug/deps/mybench-[..][EXE]", - ).with_stdout_contains("test test_in_bench ... ok") + ) + .with_stdout_contains("test test_in_bench ... ok") .run(); } @@ -1309,21 +1410,25 @@ name = "myexm2" test = true "#, - ).file( + ) + .file( "src/mybin.rs", "#[test] fn test_in_bin() { } fn main() { panic!(\"Don't execute me!\"); }", - ).file("tests/mytest.rs", "#[test] fn test_in_test() { }") + ) + .file("tests/mytest.rs", "#[test] fn test_in_test() { }") .file("benches/mybench.rs", "#[test] fn test_in_bench() { }") .file( "examples/myexm1.rs", "#[test] fn test_in_exm() { } fn main() { panic!(\"Don't execute me!\"); }", - ).file( + ) + .file( "examples/myexm2.rs", "#[test] fn test_in_exm() { } fn main() { panic!(\"Don't execute me!\"); }", - ).build(); + ) + .build(); // Compiles myexm1 as normal, but does not run it. prj.cargo("test -v") @@ -1377,7 +1482,8 @@ path = "foo.rs" harness = false "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("foo.rs", "fn main() {}") .build(); @@ -1388,7 +1494,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/bar-[..][EXE] ", - ).run(); + ) + .run(); } #[test] @@ -1411,7 +1518,8 @@ name = "foo" doctest = false "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "d1/Cargo.toml", r#" @@ -1424,11 +1532,13 @@ name = "d1" doctest = false "#, - ).file("d1/src/lib.rs", "") + ) + .file("d1/src/lib.rs", "") .file( "d1/src/main.rs", "#[allow(unused_extern_crates)] extern crate d1; fn main() {}", - ).file( + ) + .file( "d2/Cargo.toml", r#" [package] @@ -1440,7 +1550,8 @@ name = "d2" doctest = false "#, - ).file("d2/src/lib.rs", "") + ) + .file("d2/src/lib.rs", "") .file( "d2/src/main.rs", "#[allow(unused_extern_crates)] extern crate d2; fn main() {}", @@ -1455,7 +1566,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/d1-[..][EXE] [RUNNING] target/debug/deps/d1-[..][EXE]", - ).with_stdout_contains_n("running 0 tests", 2) + ) + .with_stdout_contains_n("running 0 tests", 2) .run(); println!("d2"); @@ -1466,7 +1578,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/d2-[..][EXE] [RUNNING] target/debug/deps/d2-[..][EXE]", - ).with_stdout_contains_n("running 0 tests", 2) + ) + .with_stdout_contains_n("running 0 tests", 2) .run(); println!("whole"); @@ -1476,7 +1589,8 @@ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); } @@ -1496,13 +1610,15 @@ [dev-dependencies.c] path = "c" "#, - ).file( + ) + .file( "src/lib.rs", r#" #[cfg(test)] extern crate b; #[cfg(test)] extern crate c; "#, - ).file( + ) + .file( "b/Cargo.toml", r#" [package] @@ -1513,13 +1629,15 @@ [dependencies.foo] path = ".." "#, - ).file( + ) + .file( "b/src/lib.rs", r#" #[allow(unused_extern_crates)] extern crate foo; "#, - ).file("c/Cargo.toml", &basic_manifest("c", "0.0.1")) + ) + .file("c/Cargo.toml", &basic_manifest("c", "0.0.1")) .file("c/src/lib.rs", "") .build(); @@ -1541,10 +1659,12 @@ [dependencies.b] path = "b" "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate b;", - ).file( + ) + .file( "src/main.rs", r#" #[allow(unused_extern_crates)] @@ -1553,7 +1673,8 @@ extern crate foo; fn main() {} "#, - ).file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) + ) + .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -1576,7 +1697,8 @@ [dev-dependencies.bar] path = "bar" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/e1.rs", "extern crate bar; fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file( @@ -1596,7 +1718,8 @@ f8!(); } "#, - ).build(); + ) + .build(); p.cargo("test").run(); p.cargo("run --example e1 --release -v").run(); } @@ -1615,7 +1738,8 @@ [dependencies.d1] path = "d1" "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ``` @@ -1623,7 +1747,8 @@ /// ``` pub fn foo() {} "#, - ).file( + ) + .file( "d1/Cargo.toml", r#" [package] @@ -1635,7 +1760,8 @@ name = "d1" path = "d1.rs" "#, - ).file("d1/d1.rs", ""); + ) + .file("d1/d1.rs", ""); let p = p.build(); p.cargo("test -p d1") @@ -1645,7 +1771,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/d1[..][EXE] [DOCTEST] d1", - ).with_stdout_contains_n("running 0 tests", 2) + ) + .with_stdout_contains_n("running 0 tests", 2) .run(); } @@ -1664,7 +1791,8 @@ [RUNNING] `rustc [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(!p.bin("foo").is_file()); assert!(p.bin("examples/foo").is_file()); @@ -1679,7 +1807,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] [..]", - ).with_stdout("bin") + ) + .with_stdout("bin") .run(); assert!(p.bin("foo").is_file()); } @@ -1718,11 +1847,13 @@ [dev-dependencies.a] path = "a" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "examples/ex.rs", "#[allow(unused_extern_crates)] extern crate a; fn main() {}", - ).file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -1736,7 +1867,8 @@ [RUNNING] `rustc --crate-name ex [..] --extern a=[..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -1782,7 +1914,8 @@ [features] bar = [] "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ```rust @@ -1791,7 +1924,8 @@ #[cfg(feature = "bar")] pub fn foo() -> i32 { 1 } "#, - ).build(); + ) + .build(); p.cargo("test --features bar") .with_stderr( @@ -1800,7 +1934,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .with_stdout_contains("test [..] ... ok") .run(); } @@ -1817,7 +1952,8 @@ /// ``` pub fn foo() -> i32 { 1 } "#, - ).build(); + ) + .build(); p.cargo("test -v").run(); } @@ -1836,7 +1972,8 @@ [dev-dependencies] b = { path = "b" } "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ``` @@ -1844,7 +1981,8 @@ /// ``` pub fn foo() {} "#, - ).file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) + ) + .file("b/Cargo.toml", &basic_manifest("b", "0.0.1")) .file("b/src/lib.rs", "") .build(); @@ -1862,7 +2000,8 @@ /// ``` pub fn foo() {} "#, - ).file("tests/foo.rs", "") + ) + .file("tests/foo.rs", "") .build(); p.cargo("test --test=foo") @@ -1871,7 +2010,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .run(); } @@ -1891,7 +2031,8 @@ crate-type = ["rlib", "dylib"] test = false "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ``` @@ -1899,7 +2040,8 @@ /// ``` pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("test") .with_stderr( @@ -1907,13 +2049,14 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [DOCTEST] foo", - ).with_stdout_contains("test [..] ... ok") + ) + .with_stdout_contains("test [..] ... ok") .run(); } #[test] fn dylib_doctest2() { - // can't doctest dylibs as they're statically linked together + // Can't doc-test dylibs, as they're statically linked together. let p = project() .file( "Cargo.toml", @@ -1928,7 +2071,8 @@ crate-type = ["dylib"] test = false "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ``` @@ -1936,7 +2080,8 @@ /// ``` pub fn foo() {} "#, - ).build(); + ) + .build(); p.cargo("test").with_stdout("").run(); } @@ -1955,14 +2100,16 @@ [dev-dependencies] bar = { path = "bar" } "#, - ).file( + ) + .file( "src/lib.rs", r#" //! ``` //! extern crate bar; //! ``` "#, - ).file( + ) + .file( "bar/Cargo.toml", r#" [package] @@ -1973,13 +2120,15 @@ [dependencies] foo = { path = ".." } "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" #[allow(unused_extern_crates)] extern crate foo; "#, - ).build(); + ) + .build(); p.cargo("test") .with_stderr( "\ @@ -1988,7 +2137,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .with_stdout_contains("test [..] ... ok") .run(); } @@ -2007,7 +2157,8 @@ [dev-dependencies] bar = { path = "bar" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("examples/foo.rs", "fn main() {}") .file( "bar/Cargo.toml", @@ -2018,7 +2169,8 @@ authors = [] build = "build.rs" "#, - ).file("bar/src/lib.rs", "") + ) + .file("bar/src/lib.rs", "") .file("bar/build.rs", "fn main() {}") .build(); p.cargo("test").run(); @@ -2042,7 +2194,8 @@ x - 1 } "#, - ).file( + ) + .file( "tests/test_add_one.rs", r#" extern crate foo; @@ -2058,7 +2211,8 @@ assert_eq!(add_one(1), 1); } "#, - ).file( + ) + .file( "tests/test_sub_one.rs", r#" extern crate foo; @@ -2069,7 +2223,8 @@ assert_eq!(sub_one(1), 0); } "#, - ).build(); + ) + .build(); p.cargo("test --no-fail-fast") .with_status(101) .with_stderr_contains( @@ -2078,12 +2233,14 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..][EXE] [RUNNING] target/debug/deps/test_add_one-[..][EXE]", - ).with_stdout_contains("running 0 tests") + ) + .with_stdout_contains("running 0 tests") .with_stderr_contains( "\ [RUNNING] target/debug/deps/test_sub_one-[..][EXE] [DOCTEST] foo", - ).with_stdout_contains("test result: FAILED. [..]") + ) + .with_stdout_contains("test result: FAILED. [..]") .with_stdout_contains("test sub_one_test ... ok") .with_stdout_contains_n("test [..] ... ok", 3) .run(); @@ -2109,7 +2266,8 @@ name = "foo" doctest = false "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "d1/Cargo.toml", r#" @@ -2122,7 +2280,8 @@ name = "d1" doctest = false "#, - ).file("d1/src/lib.rs", "") + ) + .file("d1/src/lib.rs", "") .file( "d2/Cargo.toml", r#" @@ -2135,7 +2294,8 @@ name = "d2" doctest = false "#, - ).file("d2/src/lib.rs", ""); + ) + .file("d2/src/lib.rs", ""); let p = p.build(); p.cargo("test -p d1 -p d2") @@ -2169,7 +2329,8 @@ [RUNNING] `rustc [..] src/main.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2189,7 +2350,8 @@ [dependencies] a = { path = "a" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", ""); let p = p.build(); @@ -2211,7 +2373,8 @@ [dependencies] a = { path = "a", optional = true } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", ""); let p = p.build(); @@ -2224,7 +2387,8 @@ [RUNNING] `rustc [..] a/src/lib.rs [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -2245,7 +2409,8 @@ pub fn bar() { } "#, - ).file("tests/foo.rs", "this is not rust"); + ) + .file("tests/foo.rs", "this is not rust"); let p = p.build(); p.cargo("test --doc") @@ -2254,7 +2419,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [DOCTEST] foo", - ).with_stdout_contains("test [..] ... ok") + ) + .with_stdout_contains("test [..] ... ok") .run(); } @@ -2275,7 +2441,8 @@ [profile.dev] panic = 'abort' "#, - ).file( + ) + .file( "src/lib.rs", r#" extern crate bar; @@ -2283,7 +2450,8 @@ #[test] fn foo() {} "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) .file("bar/src/lib.rs", "") .build(); p.cargo("test -v").run(); @@ -2304,10 +2472,12 @@ harness = false doctest = false "#, - ).file( + ) + .file( "src/lib.rs", r#"#[cfg(test)] fn main() { println!("hello!"); }"#, - ).build(); + ) + .build(); p.cargo("test -v") .with_stdout("hello!\n") .with_stderr( @@ -2317,7 +2487,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `[..]` ", - ).run(); + ) + .run(); } #[test] @@ -2337,10 +2508,12 @@ [profile.release] panic = 'abort' "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate a;", - ).file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); p.cargo("test --release -v -p foo -p a").run(); @@ -2365,7 +2538,8 @@ path = "libs/feature_a" default-features = false "#, - ).file( + ) + .file( "src/lib.rs", r#" #[cfg(test)] @@ -2376,7 +2550,8 @@ } } "#, - ).file( + ) + .file( "libs/feature_a/Cargo.toml", r#" [package] @@ -2394,7 +2569,8 @@ [build-dependencies] mock_serde_codegen = { path = "../mock_serde_codegen", optional = true } "#, - ).file( + ) + .file( "libs/feature_a/src/lib.rs", r#" #[cfg(feature = "mock_serde_derive")] @@ -2407,14 +2583,17 @@ MSG } "#, - ).file( + ) + .file( "libs/mock_serde_derive/Cargo.toml", &basic_manifest("mock_serde_derive", "0.1.0"), - ).file("libs/mock_serde_derive/src/lib.rs", "") + ) + .file("libs/mock_serde_derive/src/lib.rs", "") .file( "libs/mock_serde_codegen/Cargo.toml", &basic_manifest("mock_serde_codegen", "0.1.0"), - ).file("libs/mock_serde_codegen/src/lib.rs", ""); + ) + .file("libs/mock_serde_codegen/src/lib.rs", ""); let p = p.build(); p.cargo("test --package feature_a --verbose") @@ -2422,14 +2601,16 @@ "\ [DOCTEST] feature_a [RUNNING] `rustdoc --test [..]mock_serde_codegen[..]`", - ).run(); + ) + .run(); p.cargo("test --verbose") .with_stderr_contains( "\ [DOCTEST] foo [RUNNING] `rustdoc --test [..]feature_a[..]`", - ).run(); + ) + .run(); } #[test] @@ -2451,10 +2632,12 @@ [profile.release] panic = 'abort' "#, - ).file( + ) + .file( "src/lib.rs", "#[allow(unused_extern_crates)] extern crate a;", - ).file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", ""); let p = p.build(); println!("test"); @@ -2482,7 +2665,8 @@ [workspace] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.0.1")) .file("a/src/lib.rs", "") .build(); @@ -2505,7 +2689,8 @@ [workspace] "#, - ).file("src/main.rs", "#[test] fn foo_test() {}") + ) + .file("src/main.rs", "#[test] fn foo_test() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "#[test] fn bar_test() {}") .build(); @@ -2529,7 +2714,8 @@ [workspace] members = ["bar", "baz"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/lib.rs", "#[test] pub fn bar() {}") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) @@ -2540,7 +2726,8 @@ .with_stdout_contains( "running 1 test test bar ... ok", - ).run(); + ) + .run(); } #[test] @@ -2552,7 +2739,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/lib.rs", "#[test] fn a() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "#[test] fn b() {}") @@ -2573,7 +2761,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/lib.rs", "#[test] fn a() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "#[test] fn b() {}") @@ -2594,7 +2783,8 @@ [workspace] members = ["a"] "#, - ).file( + ) + .file( "a/Cargo.toml", r#" [project] @@ -2604,7 +2794,8 @@ [dependencies] a = "0.1.0" "#, - ).file("a/src/lib.rs", "#[test] fn a() {}") + ) + .file("a/src/lib.rs", "#[test] fn a() {}") .build(); Package::new("a", "0.1.0").publish(); @@ -2627,7 +2818,8 @@ [dev-dependencies] b = { path = "b" } "#, - ).file( + ) + .file( "src/lib.rs", r#" /// ``` @@ -2637,7 +2829,8 @@ /// ``` pub fn a() {} "#, - ).file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) + ) + .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "pub fn b() {}") .build(); @@ -2653,31 +2846,36 @@ fn main() {} #[test] fn bin_a() {} "#, - ).file( + ) + .file( "src/bin/b.rs", r#" fn main() {} #[test] fn bin_b() {} "#, - ).file( + ) + .file( "src/bin/c.rs", r#" fn main() {} #[test] fn bin_c() { panic!(); } "#, - ).file( + ) + .file( "examples/a.rs", r#" fn main() {} #[test] fn example_a() {} "#, - ).file( + ) + .file( "examples/b.rs", r#" fn main() {} #[test] fn example_b() {} "#, - ).file("examples/c.rs", "#[test] fn example_c() { panic!(); }") + ) + .file("examples/c.rs", "#[test] fn example_c() { panic!(); }") .file("tests/a.rs", "#[test] fn test_a() {}") .file("tests/b.rs", "#[test] fn test_b() {}") .file("tests/c.rs", "does not compile") @@ -2709,7 +2907,8 @@ [workspace] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file( "b/src/lib.rs", @@ -2719,7 +2918,8 @@ /// ``` pub fn foo() {} ", - ).file( + ) + .file( "c/Cargo.toml", r#" [project] @@ -2729,7 +2929,8 @@ [dependencies] b = "0.1" "#, - ).file("c/src/lib.rs", "") + ) + .file("c/src/lib.rs", "") .build(); Package::new("b", "0.1.0").publish(); @@ -2765,7 +2966,8 @@ test env_test ... ok ", cargo.to_str().unwrap() - )).run(); + )) + .run(); } #[test] @@ -2796,7 +2998,8 @@ test result: ok. [..] ", - ).run(); + ) + .run(); } #[test] @@ -2812,7 +3015,8 @@ [dev-dependencies] foo = { path = "." } "#, - ).file("src/lib.rs", "#[test] fn test_lib() {}") + ) + .file("src/lib.rs", "#[test] fn test_lib() {}") .file("tests/foo.rs", "extern crate foo;") .build(); @@ -2822,7 +3026,9 @@ #[test] fn publish_a_crate_without_tests() { Package::new("testless", "0.1.0") - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "testless" version = "0.1.0" @@ -2830,15 +3036,14 @@ [[test]] name = "a_test" - "#) + "#, + ) .file("src/lib.rs", "") - // In real life, the package will have a test, // which would be excluded from .crate file by the // `exclude` field. Our test harness does not honor // exclude though, so let's just not add the file! // .file("tests/a_test.rs", "") - .publish(); let p = project() @@ -2852,7 +3057,8 @@ [dependencies] testless = "0.1.0" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("test").run(); @@ -2868,7 +3074,8 @@ [workspace] members = ["root", "proc_macro_dep"] "#, - ).file( + ) + .file( "root/Cargo.toml", r#" [project] @@ -2879,7 +3086,8 @@ [dependencies] proc_macro_dep = { path = "../proc_macro_dep" } "#, - ).file( + ) + .file( "root/src/lib.rs", r#" #[macro_use] @@ -2888,7 +3096,8 @@ #[derive(Noop)] pub struct X; "#, - ).file( + ) + .file( "proc_macro_dep/Cargo.toml", r#" [project] @@ -2902,7 +3111,8 @@ [dependencies] baz = "^0.1" "#, - ).file( + ) + .file( "proc_macro_dep/src/lib.rs", r#" extern crate baz; @@ -2914,7 +3124,8 @@ "".parse().unwrap() } "#, - ).build(); + ) + .build(); Package::new("bar", "0.1.0").publish(); Package::new("baz", "0.1.0") .dep("bar", "0.1") @@ -2934,7 +3145,8 @@ /// ``` pub fn this_works() {} "#, - ).file( + ) + .file( "tests/integ.rs", r#" #[test] @@ -2942,7 +3154,8 @@ panic!(); } "#, - ).build(); + ) + .build(); p.cargo("test --no-fail-fast") .with_status(101) .with_stdout_contains("test this_fails ... FAILED") @@ -2950,7 +3163,8 @@ .with_stderr_contains( "[ERROR] test failed, to rerun pass \ '--test integ'", - ).run(); + ) + .run(); } #[test] @@ -2962,7 +3176,8 @@ [workspace] members = ["a", "b"] "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/lib.rs", "#[test] fn t1() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "#[test] fn t1() {assert!(false)}") @@ -2989,10 +3204,11 @@ [profile.test] opt-level = 1 "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); - p.cargo("test -v --message-format=json") + p.cargo("test --lib -v --message-format=json") .with_json( r#" { @@ -3000,32 +3216,11 @@ "profile": { "debug_assertions": true, "debuginfo": 2, - "opt_level": "0", - "overflow_checks": true, - "test": false - }, - "features": [], - "package_id":"foo 0.0.1 ([..])", - "target":{ - "kind":["lib"], - "crate_types":["lib"], - "edition": "2015", - "name":"foo", - "src_path":"[..]lib.rs" - }, - "filenames":["[..].rlib"], - "fresh": false - } - - { - "reason":"compiler-artifact", - "profile": { - "debug_assertions": true, - "debuginfo": 2, "opt_level": "1", "overflow_checks": true, "test": true }, + "executable": "[..]/foo-[..]", "features": [], "package_id":"foo 0.0.1 ([..])", "target":{ @@ -3039,7 +3234,72 @@ "fresh": false } "#, - ).run(); + ) + .run(); +} + +#[test] +fn json_artifact_includes_executable_for_library_tests() { + let p = project() + .file("src/main.rs", "fn main() { }") + .file("src/lib.rs", r#"#[test] fn lib_test() {}"#) + .build(); + + p.cargo("test --lib -v --no-run --message-format=json") + .with_json( + r#" + { + "executable": "[..]/foo/target/debug/foo-[..][EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "lib" ], + "kind": [ "lib" ], + "edition": "2015", + "name": "foo", + "src_path": "[..]/foo/src/lib.rs" + } + } + "#, + ) + .run(); +} + +#[test] +fn json_artifact_includes_executable_for_integration_tests() { + let p = project() + .file( + "tests/integration_test.rs", + r#"#[test] fn integration_test() {}"#, + ) + .build(); + + p.cargo("test -v --no-run --message-format=json --test integration_test") + .with_json( + r#" + { + "executable": "[..]/foo/target/debug/integration_test-[..][EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "test" ], + "edition": "2015", + "name": "integration_test", + "src_path": "[..]/foo/tests/integration_test.rs" + } + } + "#, + ) + .run(); } #[test] @@ -3056,7 +3316,8 @@ [lib] test = false "#, - ).file("build.rs", "fn main() {}") + ) + .file("build.rs", "fn main() {}") .file("src/lib.rs", "") .build(); @@ -3076,14 +3337,16 @@ [lib] crate-type = ["staticlib"] "#, - ).file( + ) + .file( "src/lib.rs", r#" //! ``` //! assert_eq!(1,2); //! ``` "#, - ).build(); + ) + .build(); p.cargo("test --doc") .with_status(101) @@ -3091,7 +3354,8 @@ "\ [WARNING] doc tests are not supported for crate type(s) `staticlib` in package `foo` [ERROR] no library targets found in package `foo`", - ).run(); + ) + .run(); p.cargo("test") .with_stderr( @@ -3099,13 +3363,16 @@ [COMPILING] foo [..] [FINISHED] dev [..] [RUNNING] target/debug/deps/foo-[..]", - ).run(); + ) + .run(); } #[test] fn can_not_mix_doc_tests_and_regular_tests() { let p = project() - .file("src/lib.rs", "\ + .file( + "src/lib.rs", + "\ /// ``` /// assert_eq!(1, 1) /// ``` @@ -3114,17 +3381,21 @@ #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } } -") +", + ) .build(); p.cargo("test") - .with_stderr("\ + .with_stderr( + "\ [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/debug/deps/foo-[..] [DOCTEST] foo -") - .with_stdout(" +", + ) + .with_stdout( + " running 1 test test tests::it_works ... ok @@ -3135,33 +3406,43 @@ test src/lib.rs - foo (line 1) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out -\n") +\n", + ) .run(); p.cargo("test --lib") - .with_stderr("\ + .with_stderr( + "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -[RUNNING] target/debug/deps/foo-[..]\n") - .with_stdout(" +[RUNNING] target/debug/deps/foo-[..]\n", + ) + .with_stdout( + " running 1 test test tests::it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out -\n") +\n", + ) .run(); p.cargo("test --doc") - .with_stderr("\ + .with_stderr( + "\ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [DOCTEST] foo -") - .with_stdout(" +", + ) + .with_stdout( + " running 1 test test src/lib.rs - foo (line 1) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out -").run(); +", + ) + .run(); p.cargo("test --lib --doc") .with_status(101) @@ -3170,6 +3451,26 @@ } #[test] +fn can_not_no_run_doc_tests() { + let p = project() + .file( + "src/lib.rs", + r#" +/// ``` +/// let _x = 1 + "foo"; +/// ``` +pub fn foo() -> u8 { 1 } +"#, + ) + .build(); + + p.cargo("test --doc --no-run") + .with_status(101) + .with_stderr("[ERROR] Can't skip running doc tests with --no-run") + .run(); +} + +#[test] fn test_all_targets_lib() { let p = project().file("src/lib.rs", "").build(); @@ -3180,10 +3481,10 @@ [FINISHED] dev [..] [RUNNING] [..]foo[..] ", - ).run(); + ) + .run(); } - #[test] fn test_dep_with_dev() { Package::new("devdep", "0.1.0").publish(); diff -Nru cargo-0.33.0/tests/testsuite/tool_paths.rs cargo-0.35.0/tests/testsuite/tool_paths.rs --- cargo-0.33.0/tests/testsuite/tool_paths.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/tool_paths.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::rustc_host; -use support::{basic_lib_manifest, project}; +use crate::support::rustc_host; +use crate::support::{basic_lib_manifest, project}; #[test] fn pathless_tools() { @@ -18,7 +18,8 @@ "#, target ), - ).build(); + ) + .build(); foo.cargo("build --verbose") .with_stderr( @@ -27,7 +28,8 @@ [RUNNING] `rustc [..] -C ar=nonexistent-ar -C linker=nonexistent-linker [..]` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -59,7 +61,8 @@ ar = config.0, linker = config.1 ), - ).build(); + ) + .build(); foo.cargo("build --verbose").with_stderr("\ [COMPILING] foo v0.5.0 ([CWD]) @@ -97,7 +100,8 @@ ar = config.0, linker = config.1 ), - ).build(); + ) + .build(); let prefix = p.root().into_os_string().into_string().unwrap(); @@ -128,7 +132,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("run -- --param") .with_status(101) @@ -138,7 +143,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` ", - ).run(); + ) + .run(); p.cargo("test --test test --verbose -- --param") .with_status(101) @@ -149,7 +155,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `nonexistent-runner -r [..]/target/debug/deps/test-[..][EXE] --param` ", - ).run(); + ) + .run(); p.cargo("bench --bench bench --verbose -- --param") .with_status(101) @@ -161,7 +168,8 @@ [FINISHED] release [optimized] target(s) in [..] [RUNNING] `nonexistent-runner -r [..]/target/release/deps/bench-[..][EXE] --param --bench` ", - ).run(); + ) + .run(); } // can set a custom runner via `target.'cfg(..)'.runner` @@ -175,7 +183,8 @@ [target.'cfg(not(target_os = "none"))'] runner = "nonexistent-runner -r" "#, - ).build(); + ) + .build(); p.cargo("run -- --param") .with_status(101) @@ -185,7 +194,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` ", - )).run(); + )) + .run(); } // custom runner set via `target.$triple.runner` have precende over `target.'cfg(..)'.runner` @@ -207,7 +217,8 @@ "#, target ), - ).build(); + ) + .build(); p.cargo("run -- --param") .with_status(101) @@ -217,7 +228,8 @@ [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] `nonexistent-runner -r target/debug/foo[EXE] --param` ", - )).run(); + )) + .run(); } #[test] @@ -233,7 +245,8 @@ [target.'cfg(not(target_os = "none"))'] runner = "false" "#, - ).build(); + ) + .build(); p.cargo("run -- --param") .with_status(101) @@ -241,5 +254,6 @@ "\ [ERROR] several matching instances of `target.'cfg(..)'.runner` in `.cargo/config` ", - )).run(); + )) + .run(); } diff -Nru cargo-0.33.0/tests/testsuite/update.rs cargo-0.35.0/tests/testsuite/update.rs --- cargo-0.33.0/tests/testsuite/update.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/update.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,8 +1,8 @@ use std::fs::File; use std::io::prelude::*; -use support::registry::Package; -use support::{basic_manifest, project}; +use crate::support::registry::Package; +use crate::support::{basic_manifest, project}; #[test] fn minor_update_two_places() { @@ -20,7 +20,8 @@ log = "0.1" foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -32,7 +33,8 @@ [dependencies] log = "0.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -50,7 +52,8 @@ [dependencies] log = "0.1.1" "#, - ).unwrap(); + ) + .unwrap(); p.cargo("build").run(); } @@ -74,7 +77,8 @@ log = "0.1" foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -86,7 +90,8 @@ [dependencies] serde = "0.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -108,7 +113,8 @@ "\ [UPDATING] `[..]` index ", - ).run(); + ) + .run(); } #[test] @@ -130,7 +136,8 @@ log = "0.1" foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -142,7 +149,8 @@ [dependencies] serde = "0.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -156,7 +164,8 @@ [UPDATING] `[..]` index [UPDATING] serde v0.1.0 -> v0.1.1 ", - ).run(); + ) + .run(); } #[test] @@ -175,7 +184,8 @@ log = "0.1" # foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -187,7 +197,8 @@ [dependencies] log = "0.1.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -215,7 +226,8 @@ [dependencies] log = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -227,7 +239,8 @@ [dependencies] log = "0.1.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -253,7 +266,8 @@ log = "0.1" # bar = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -282,7 +296,8 @@ foo = "0.1" # bar = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); p.cargo("build").run(); @@ -308,7 +323,8 @@ [dependencies] bar = { path = "bar", version = "0.2.0-alpha" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0-alpha")) .file("bar/src/lib.rs", "") .file( @@ -323,7 +339,8 @@ name = "bar" version = "0.2.0" "#, - ).build(); + ) + .build(); p.cargo("build").run(); } @@ -347,7 +364,8 @@ serde = "0.2" foo = { path = "foo" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "foo/Cargo.toml", r#" @@ -359,7 +377,8 @@ [dependencies] serde = "0.1" "#, - ).file("foo/src/lib.rs", "") + ) + .file("foo/src/lib.rs", "") .build(); p.cargo("build").run(); @@ -372,7 +391,8 @@ [UPDATING] `[..]` index [UPDATING] serde v0.2.1 -> v0.2.0 ", - ).run(); + ) + .run(); } #[test] @@ -381,17 +401,76 @@ p.cargo("update").run(); - let mut lockfile = p.read_file("Cargo.lock"); - lockfile.insert_str(0, "# @generated\n"); - lockfile.insert_str(0, "# some other comment\n"); + let lockfile = p.read_lockfile(); + assert!(lockfile.starts_with("# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\n")); + + let mut lines = lockfile.lines().collect::>(); + lines.insert(2, "# some other comment"); + let mut lockfile = lines.join("\n"); + lockfile.push_str("\n"); // .lines/.join loses the last newline println!("saving Cargo.lock contents:\n{}", lockfile); p.change_file("Cargo.lock", &lockfile); p.cargo("update").run(); - let lockfile2 = p.read_file("Cargo.lock"); + let lockfile2 = p.read_lockfile(); println!("loaded Cargo.lock contents:\n{}", lockfile2); - assert!(lockfile == lockfile2); + assert_eq!(lockfile, lockfile2); +} + +#[test] +fn dry_run_update() { + Package::new("log", "0.1.0").publish(); + Package::new("serde", "0.1.0").dep("log", "0.1").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [dependencies] + serde = "0.1" + log = "0.1" + foo = { path = "foo" } + "#, + ) + .file("src/lib.rs", "") + .file( + "foo/Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + serde = "0.1" + "#, + ) + .file("foo/src/lib.rs", "") + .build(); + + p.cargo("build").run(); + let old_lockfile = p.read_file("Cargo.lock"); + + Package::new("log", "0.1.1").publish(); + Package::new("serde", "0.1.1").dep("log", "0.1").publish(); + + p.cargo("update -p serde --dry-run") + .with_stderr( + "\ +[UPDATING] `[..]` index +[UPDATING] serde v0.1.0 -> v0.1.1 +[WARNING] not updating lockfile due to dry run +", + ) + .run(); + let new_lockfile = p.read_file("Cargo.lock"); + assert_eq!(old_lockfile, new_lockfile) } diff -Nru cargo-0.33.0/tests/testsuite/verify_project.rs cargo-0.35.0/tests/testsuite/verify_project.rs --- cargo-0.33.0/tests/testsuite/verify_project.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/verify_project.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,4 +1,4 @@ -use support::{basic_bin_manifest, main_file, project}; +use crate::support::{basic_bin_manifest, main_file, project}; fn verify_project_success_output() -> String { r#"{"success":"true"}"#.into() @@ -46,13 +46,16 @@ #[test] fn cargo_verify_project_honours_unstable_features() { let p = project() - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" cargo-features = ["test-dummy-unstable"] [package] name = "foo" version = "0.0.1" - "#) + "#, + ) .file("src/lib.rs", "") .build(); diff -Nru cargo-0.33.0/tests/testsuite/version.rs cargo-0.35.0/tests/testsuite/version.rs --- cargo-0.33.0/tests/testsuite/version.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/version.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ +use crate::support::project; use cargo; -use support::project; #[test] fn simple() { @@ -36,6 +36,7 @@ [build] target-dir = 4 "#, - ).build(); + ) + .build(); p.cargo("version").run(); } diff -Nru cargo-0.33.0/tests/testsuite/warn_on_failure.rs cargo-0.35.0/tests/testsuite/warn_on_failure.rs --- cargo-0.33.0/tests/testsuite/warn_on_failure.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/warn_on_failure.rs 2019-04-01 21:32:07.000000000 +0000 @@ -1,5 +1,5 @@ -use support::registry::Package; -use support::{project, Project}; +use crate::support::registry::Package; +use crate::support::{project, Project}; static WARNING1: &'static str = "Hello! I'm a warning. :)"; static WARNING2: &'static str = "And one more!"; @@ -15,7 +15,8 @@ version = "0.0.1" build = "build.rs" "#, - ).file( + ) + .file( "build.rs", &format!( r#" @@ -29,7 +30,8 @@ "#, WARNING1, WARNING2 ), - ).file("src/lib.rs", &format!("fn f() {{ {} }}", lib_src)) + ) + .file("src/lib.rs", &format!("fn f() {{ {} }}", lib_src)) .publish(); } @@ -46,7 +48,8 @@ [dependencies] bar = "*" "#, - ).file("src/main.rs", &format!("fn main() {{ {} }}", main_src)) + ) + .file("src/main.rs", &format!("fn main() {{ {} }}", main_src)) .build() } @@ -65,7 +68,8 @@ [COMPILING] foo v0.0.1 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] diff -Nru cargo-0.33.0/tests/testsuite/workspaces.rs cargo-0.35.0/tests/testsuite/workspaces.rs --- cargo-0.33.0/tests/testsuite/workspaces.rs 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/tests/testsuite/workspaces.rs 2019-04-01 21:32:07.000000000 +0000 @@ -2,9 +2,9 @@ use std::fs::{self, File}; use std::io::{Read, Write}; -use support::registry::Package; -use support::sleep_ms; -use support::{basic_lib_manifest, basic_manifest, git, project}; +use crate::support::registry::Package; +use crate::support::sleep_ms; +use crate::support::{basic_lib_manifest, basic_manifest, git, project}; #[test] fn simple_explicit() { @@ -20,7 +20,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -30,7 +31,8 @@ authors = [] workspace = ".." "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").run(); @@ -60,7 +62,8 @@ members = ["bar"] default-members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -70,7 +73,8 @@ authors = [] workspace = ".." "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").run(); @@ -92,7 +96,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); @@ -125,7 +130,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}") .file("bar/src/lib.rs", ""); @@ -159,7 +165,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -171,7 +178,8 @@ [dependencies] baz = { path = "../baz" } "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .file("bar/src/lib.rs", "") .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("baz/src/main.rs", "fn main() {}") @@ -214,7 +222,8 @@ [workspace] "#, - ).file("foo/src/main.rs", "fn main() {}") + ) + .file("foo/src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -224,7 +233,8 @@ authors = [] workspace = "../foo" "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .file("bar/src/lib.rs", ""); let p = p.build(); @@ -248,7 +258,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -258,7 +269,8 @@ authors = [] workspace = ".." "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -269,7 +281,8 @@ - [..]Cargo.toml - [..]Cargo.toml ", - ).run(); + ) + .run(); } #[test] @@ -285,7 +298,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); @@ -301,7 +315,8 @@ this may be fixable [..] ", - ).run(); + ) + .run(); } #[test] @@ -316,7 +331,8 @@ authors = [] workspace = "foo" "#, - ).file("src/main.rs", "fn main() {}"); + ) + .file("src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -328,7 +344,8 @@ Caused by: [..] ", - ).run(); + ) + .run(); } #[test] @@ -345,7 +362,8 @@ [workspace] members = ["foo"] "#, - ).file("src/main.rs", "fn main() {}"); + ) + .file("src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -357,7 +375,8 @@ Caused by: [..] ", - ).run(); + ) + .run(); } #[test] @@ -373,7 +392,8 @@ [workspace] "#, - ).file("src/main.rs", "fn main() {}"); + ) + .file("src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").run(); @@ -393,7 +413,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -405,7 +426,8 @@ [workspace] members = [".."] "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -416,7 +438,8 @@ [..] [..] ", - ).run(); + ) + .run(); } #[test] @@ -431,7 +454,8 @@ authors = [] workspace = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); @@ -456,7 +480,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -466,7 +491,8 @@ authors = [] workspace = "../baz" "#, - ).file("bar/src/main.rs", "fn main() {}") + ) + .file("bar/src/main.rs", "fn main() {}") .file( "baz/Cargo.toml", r#" @@ -476,7 +502,8 @@ authors = [] workspace = "../baz" "#, - ).file("baz/src/main.rs", "fn main() {}"); + ) + .file("baz/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -487,7 +514,8 @@ expected: [..] actual: [..] ", - ).run(); + ) + .run(); } #[test] @@ -502,7 +530,8 @@ authors = [] workspace = "bar" "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -512,10 +541,16 @@ authors = [] workspace = ".." "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); - p.cargo("build").with_status(101).run(); + p.cargo("build") + .with_status(101) + .with_stderr( + "[ERROR] root of a workspace inferred but wasn't a root: [..]/foo/bar/Cargo.toml", + ) + .run(); } #[test] @@ -535,7 +570,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -547,7 +583,8 @@ [dependencies] dep1 = "< 0.1.5" "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); Package::new("dep1", "0.1.3").publish(); @@ -563,7 +600,8 @@ [COMPILING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -580,7 +618,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -592,7 +631,8 @@ [dependencies] dep1 = "*" "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); Package::new("dep1", "0.1.3").publish(); @@ -604,7 +644,8 @@ [DOWNLOADING] crates ... [DOWNLOADED] dep1 v0.1.3 ([..]) ", - ).run(); + ) + .run(); } #[test] @@ -624,7 +665,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -636,7 +678,8 @@ [dependencies] dep1 = "0.1" "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); Package::new("dep1", "0.1.0").publish(); @@ -658,7 +701,8 @@ [COMPILING] foo v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); p.cargo("build") .cwd(p.root().join("bar")) @@ -670,7 +714,8 @@ [COMPILING] bar v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); } #[test] @@ -682,7 +727,8 @@ [workspace] members = ["bar"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").cwd(p.root().join("bar")).run(); @@ -700,7 +746,8 @@ [workspace] members = ["bar"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build --package bar").run(); @@ -717,7 +764,8 @@ r#" [workspace] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -732,7 +780,8 @@ this may be fixable by adding `bar` to the `workspace.members` array of the \ manifest located at: [..] ", - ).run(); + ) + .run(); } #[test] @@ -744,7 +793,8 @@ [workspace] members = ["bar"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").run(); @@ -760,7 +810,8 @@ members = ["bar", "baz"] default-members = ["bar"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0")) .file("bar/src/main.rs", "fn main() {}") .file("baz/src/main.rs", "fn main() {}"); @@ -780,7 +831,8 @@ members = ["bar"] default-members = ["something-else"] "#, - ).file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build") @@ -790,7 +842,8 @@ error: package `[..]something-else` is listed in workspace’s default-members \ but is not a member. ", - ).run(); + ) + .run(); } #[test] @@ -809,7 +862,8 @@ error: manifest path `[..]` contains no package: The manifest is virtual, \ and the workspace has no members. ", - ).run(); + ) + .run(); } #[test] @@ -825,7 +879,8 @@ [workspace] members = ["bar"] "#, - ).file("src/main.rs", "") + ) + .file("src/main.rs", "") .file( "bar/Cargo.toml", r#" @@ -841,7 +896,8 @@ [..] [..] ", - ).run(); + ) + .run(); } #[test] @@ -861,7 +917,8 @@ [dependencies] p3 = { path = "p3" } "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "p1/Cargo.toml", r#" @@ -873,7 +930,8 @@ [dependencies] p2 = { path = "../p2" } "#, - ).file("p1/src/lib.rs", "") + ) + .file("p1/src/lib.rs", "") .file("p2/Cargo.toml", &basic_manifest("p2", "0.1.0")) .file("p2/src/lib.rs", "") .file("p3/Cargo.toml", &basic_manifest("p3", "0.1.0")) @@ -904,7 +962,8 @@ [workspace] "#, - ).file("src/lib.rs", ""); + ) + .file("src/lib.rs", ""); let p = p.build(); p.cargo("new --lib bar") @@ -922,7 +981,8 @@ root: [..] [CREATED] library `bar` package ", - ).run(); + ) + .run(); } #[test] @@ -942,7 +1002,8 @@ [dependencies] foo = "*" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file( "baz/Cargo.toml", r#" @@ -954,7 +1015,8 @@ [dependencies] bar = "*" "#, - ).file("baz/src/lib.rs", ""); + ) + .file("baz/src/lib.rs", ""); let p = p.build(); Package::new("foo", "1.0.0").publish(); @@ -982,13 +1044,15 @@ [workspace] members = ['lib', 'bin'] "#, - ).file("lib/Cargo.toml", &basic_manifest("lib", "0.1.0")) + ) + .file("lib/Cargo.toml", &basic_manifest("lib", "0.1.0")) .file( "lib/src/lib.rs", r#" pub fn foo() -> u32 { 0 } "#, - ).file( + ) + .file( "bin/Cargo.toml", r#" [package] @@ -998,7 +1062,8 @@ [dependencies] lib = { path = "../lib" } "#, - ).file( + ) + .file( "bin/src/main.rs", r#" extern crate lib; @@ -1022,6 +1087,7 @@ p.cargo("run") .cwd(p.root().join("bin")) .with_status(101) + .with_stderr_contains("[..]assertion[..]") .run(); } @@ -1035,9 +1101,11 @@ [workspace] members = ["foo"] "#, - ).file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) + ) + .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "") - }).unwrap(); + }) + .unwrap(); let p = project() .file( "Cargo.toml", @@ -1052,7 +1120,8 @@ "#, git_project.url() ), - ).file( + ) + .file( "src/lib.rs", r#" pub fn foo() -> u32 { 0 } @@ -1072,7 +1141,8 @@ [workspace] members = ["a"] "#, - ).file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) + ) + .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/main.rs", "fn main() {}") .file( "Cargo.lock", @@ -1100,7 +1170,8 @@ r#" [workspace] "#, - ).file("bar/Cargo.toml", &basic_manifest("foo", "0.1.0")) + ) + .file("bar/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); @@ -1126,7 +1197,8 @@ [workspace] "#, - ).file("src/main.rs", r#"fn main() {}"#) + ) + .file("src/main.rs", r#"fn main() {}"#) .file( "bar/Cargo.toml", r#" @@ -1138,7 +1210,8 @@ [dev-dependencies.baz] path = "../baz" "#, - ).file( + ) + .file( "bar/src/lib.rs", r#" pub fn init() {} @@ -1151,7 +1224,8 @@ baz::do_stuff(); } "#, - ).file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) + ) + .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0")) .file("baz/src/lib.rs", r#"pub fn do_stuff() {}"#); let p = p.build(); @@ -1187,7 +1261,8 @@ [workspace] members = ["../bar"] "#, - ).file("foo/src/main.rs", "fn main() {}") + ) + .file("foo/src/main.rs", "fn main() {}") .file( "bar/Cargo.toml", r#" @@ -1197,7 +1272,8 @@ authors = [] workspace = "../foo" "#, - ).file("bar/src/main.rs", "fn main() {}"); + ) + .file("bar/src/main.rs", "fn main() {}"); let p = p.build(); p.cargo("build").cwd(p.root().join("foo")).run(); @@ -1220,13 +1296,13 @@ [dependencies] subproj = { path = "./subproj" } "#, - ).file("src/main.rs", "fn main() {}") + ) + .file("src/main.rs", "fn main() {}") .file("subproj/Cargo.toml", &basic_manifest("subproj", "0.1.0")) .file("subproj/src/main.rs", "fn main() {}"); let p = p.build(); - p.cargo("build --manifest-path ./Cargo.toml") - .run(); + p.cargo("build --manifest-path ./Cargo.toml").run(); p.cargo("build --manifest-path ../Cargo.toml") .cwd(p.root().join("subproj")) @@ -1250,7 +1326,8 @@ [workspace] "#, - ).file("ws/src/lib.rs", r"extern crate foo;") + ) + .file("ws/src/lib.rs", r"extern crate foo;") .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", ""); let p = p.build(); @@ -1276,10 +1353,12 @@ [workspace] members = [ "../bar" ] "#, - ).file( + ) + .file( "ws/src/lib.rs", r"extern crate foo; pub fn f() { foo::f() }", - ).file( + ) + .file( "foo/Cargo.toml", r#" [project] @@ -1290,10 +1369,12 @@ [dependencies] bar = { path = "../bar" } "#, - ).file( + ) + .file( "foo/src/lib.rs", "extern crate bar; pub fn f() { bar::f() }", - ).file( + ) + .file( "bar/Cargo.toml", r#" [project] @@ -1302,7 +1383,8 @@ version = "0.1.0" authors = [] "#, - ).file("bar/src/lib.rs", "pub fn f() { }"); + ) + .file("bar/src/lib.rs", "pub fn f() { }"); let p = p.build(); p.cargo("build").cwd(p.root().join("ws")).run(); @@ -1337,10 +1419,12 @@ [workspace] "#, - ).file( + ) + .file( "ws/src/lib.rs", r"extern crate foo; pub fn f() { foo::f() }", - ).file( + ) + .file( "foo/Cargo.toml", r#" [project] @@ -1352,10 +1436,12 @@ [dependencies] bar = { path = "./bar" } "#, - ).file( + ) + .file( "foo/src/lib.rs", "extern crate bar; pub fn f() { bar::f() }", - ).file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + ) + .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) .file("foo/bar/src/lib.rs", "pub fn f() { }"); let p = p.build(); @@ -1384,7 +1470,8 @@ [workspace] exclude = ["foo"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", ""); let p = p.build(); @@ -1410,7 +1497,8 @@ members = ["foo/bar"] exclude = ["foo"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "") .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) @@ -1442,7 +1530,8 @@ [workspace] exclude = ["foo"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) .file("foo/src/lib.rs", "") .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) @@ -1460,7 +1549,9 @@ #[test] fn glob_syntax() { let p = project() - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.1.0" @@ -1469,30 +1560,40 @@ [workspace] members = ["crates/*"] exclude = ["crates/qux"] - "#) + "#, + ) .file("src/main.rs", "fn main() {}") - .file("crates/bar/Cargo.toml", r#" + .file( + "crates/bar/Cargo.toml", + r#" [project] name = "bar" version = "0.1.0" authors = [] workspace = "../.." - "#) + "#, + ) .file("crates/bar/src/main.rs", "fn main() {}") - .file("crates/baz/Cargo.toml", r#" + .file( + "crates/baz/Cargo.toml", + r#" [project] name = "baz" version = "0.1.0" authors = [] workspace = "../.." - "#) + "#, + ) .file("crates/baz/src/main.rs", "fn main() {}") - .file("crates/qux/Cargo.toml", r#" + .file( + "crates/qux/Cargo.toml", + r#" [project] name = "qux" version = "0.1.0" authors = [] - "#) + "#, + ) .file("crates/qux/src/main.rs", "fn main() {}"); let p = p.build(); @@ -1584,7 +1685,9 @@ #[test] fn glob_syntax_invalid_members() { let p = project() - .file("Cargo.toml", r#" + .file( + "Cargo.toml", + r#" [project] name = "foo" version = "0.1.0" @@ -1592,7 +1695,8 @@ [workspace] members = ["crates/*"] - "#) + "#, + ) .file("src/main.rs", "fn main() {}") .file("crates/bar/src/main.rs", "fn main() {}"); let p = p.build(); @@ -1606,17 +1710,18 @@ Caused by: [..] ", - ).run(); + ) + .run(); } -/// This is a freshness test for feature use with workspaces +/// This is a freshness test for feature use with workspaces. /// -/// feat_lib is used by caller1 and caller2, but with different features enabled. -/// This test ensures that alternating building caller1, caller2 doesn't force -/// recompile of feat_lib. +/// `feat_lib` is used by `caller1` and `caller2`, but with different features enabled. +/// This test ensures that alternating building `caller1`, `caller2` doesn't force +/// recompile of `feat_lib`. /// -/// Ideally once we solve https://github.com/rust-lang/cargo/issues/3620, then -/// a single cargo build at the top level will be enough. +/// Ideally, once we solve rust-lang/cargo#3620, then a single Cargo build at the top level +/// will be enough. #[test] fn dep_used_with_separate_features() { let p = project() @@ -1626,7 +1731,8 @@ [workspace] members = ["feat_lib", "caller1", "caller2"] "#, - ).file( + ) + .file( "feat_lib/Cargo.toml", r#" [project] @@ -1637,7 +1743,8 @@ [features] myfeature = [] "#, - ).file("feat_lib/src/lib.rs", "") + ) + .file("feat_lib/src/lib.rs", "") .file( "caller1/Cargo.toml", r#" @@ -1649,7 +1756,8 @@ [dependencies] feat_lib = { path = "../feat_lib" } "#, - ).file("caller1/src/main.rs", "fn main() {}") + ) + .file("caller1/src/main.rs", "fn main() {}") .file("caller1/src/lib.rs", "") .file( "caller2/Cargo.toml", @@ -1663,11 +1771,12 @@ feat_lib = { path = "../feat_lib", features = ["myfeature"] } caller1 = { path = "../caller1" } "#, - ).file("caller2/src/main.rs", "fn main() {}") + ) + .file("caller2/src/main.rs", "fn main() {}") .file("caller2/src/lib.rs", ""); let p = p.build(); - // Build the entire workspace + // Build the entire workspace. p.cargo("build --all") .with_stderr( "\ @@ -1676,14 +1785,15 @@ [..]Compiling caller2 v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); assert!(p.bin("caller1").is_file()); assert!(p.bin("caller2").is_file()); - // Build caller1. should build the dep library. Because the features + // Build `caller1`. Should build the dep library. Because the features // are different than the full workspace, it rebuilds. - // Ideally once we solve https://github.com/rust-lang/cargo/issues/3620, then - // a single cargo build at the top level will be enough. + // Ideally once we solve rust-lang/cargo#3620, then a single Cargo build at the top level + // will be enough. p.cargo("build") .cwd(p.root().join("caller1")) .with_stderr( @@ -1692,10 +1802,11 @@ [..]Compiling caller1 v0.1.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ", - ).run(); + ) + .run(); - // Alternate building caller2/caller1 a few times, just to make sure - // features are being built separately. Should not rebuild anything + // Alternate building `caller2`/`caller1` a few times, just to make sure + // features are being built separately. Should not rebuild anything. p.cargo("build") .cwd(p.root().join("caller2")) .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") @@ -1738,7 +1849,8 @@ } "#, ) - }).unwrap(); + }) + .unwrap(); let p = project() .file( "Cargo.toml", @@ -1755,7 +1867,8 @@ "#, git_project.url() ), - ).file("src/lib.rs", ""); + ) + .file("src/lib.rs", ""); let p = p.build(); p.cargo("build") @@ -1763,7 +1876,8 @@ .run(); } -/*FIXME: This fails because of how workspace.exclude and workspace.members are working. +// FIXME: this fails because of how workspace.exclude and workspace.members are working. +/* #[test] fn include_and_exclude() { let p = project() @@ -1799,7 +1913,8 @@ [workspace] members = ["a"] "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) .file("a/src/lib.rs", ""); let p = p.build(); @@ -1825,7 +1940,8 @@ std::process::exit(cmd.status().unwrap().code().unwrap()); } "#, - ).build(); + ) + .build(); p.cargo("build").run(); let src = p @@ -1847,7 +1963,8 @@ [dependencies] a = "0.1" "#, - ).file("src/lib.rs", "") + ) + .file("src/lib.rs", "") .build(); fs::copy(&src, p.root().join(src.file_name().unwrap())).unwrap(); @@ -1865,7 +1982,8 @@ [workspace] members = ["a"] "#, - ).file("a/Cargo.toml", &basic_lib_manifest("a")) + ) + .file("a/Cargo.toml", &basic_lib_manifest("a")) .file("a/src/lib.rs", "") .build(); @@ -1957,7 +2075,6 @@ .file("a/src/lib.rs", "") .build(); p.cargo("check") - .with_status(0) .with_stderr_contains(&format!( "\ [WARNING] {} for the non root package will be ignored, specify {} at the workspace root: @@ -1994,7 +2111,6 @@ .build(); p.cargo("check") - .with_status(0) .with_stderr_contains("[WARNING] [..]/foo/a/Cargo.toml: the cargo feature `edition`[..]") .run(); } diff -Nru cargo-0.33.0/.travis.yml cargo-0.35.0/.travis.yml --- cargo-0.33.0/.travis.yml 2019-01-02 21:49:06.000000000 +0000 +++ cargo-0.35.0/.travis.yml 2019-04-01 21:32:07.000000000 +0000 @@ -6,19 +6,12 @@ git: depth: 1 -# Using 'cache: cargo' to cache target/ and all of $HOME/.cargo/ -# doesn't work well: the cache is large and it takes several minutes -# to move it to and from S3. So instead we only cache the mdbook -# binary. -cache: - directories: - - $HOME/.cargo/bin/ - matrix: include: - env: TARGET=x86_64-unknown-linux-gnu ALT=i686-unknown-linux-gnu if: branch != master OR type = pull_request + - env: TARGET=x86_64-apple-darwin ALT=i686-apple-darwin os: osx @@ -30,29 +23,15 @@ rust: beta if: branch != master OR type = pull_request - # Minimum Rust supported channel. We enable these to make sure we - # continue to work on the advertised minimum Rust version. - # However cargo only supports the latest stable so this will get - # increased every 6 weeks or so when the first PR to use a new feature. - - env: TARGET=x86_64-unknown-linux-gnu - ALT=i686-unknown-linux-gnu - rust: 1.31.0 - script: - - rustup toolchain install nightly - - cargo +nightly generate-lockfile -Z minimal-versions - - cargo -V - - cargo test - if: branch != master OR type = pull_request - - env: TARGET=x86_64-unknown-linux-gnu ALT=i686-unknown-linux-gnu rust: nightly install: - - mdbook --help || cargo install mdbook --force + - travis_retry curl -Lf https://github.com/rust-lang-nursery/mdBook/releases/download/v0.1.7/mdbook-v0.1.7-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=$HOME/.cargo/bin script: - - cargo test - - cargo doc --no-deps - - (cd src/doc && mdbook build --dest-dir ../../target/doc) + - cargo test --features=deny-warnings || travis_terminate 1 + - cargo doc --no-deps || travis_terminate 1 + - (cd src/doc && mdbook build --dest-dir ../../target/doc) || travis_terminate 1 if: branch != master OR type = pull_request exclude: @@ -61,7 +40,7 @@ before_script: - rustup target add $ALT script: - - cargo test + - cargo test --features=deny-warnings notifications: email: diff -Nru cargo-0.33.0/vendor/aho-corasick/appveyor.yml cargo-0.35.0/vendor/aho-corasick/appveyor.yml --- cargo-0.33.0/vendor/aho-corasick/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/appveyor.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,26 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-gnu + BITS: 64 + MSYS2: 1 + - TARGET: x86_64-pc-windows-msvc + BITS: 64 + - TARGET: i686-pc-windows-gnu + BITS: 32 + MSYS2: 1 + - TARGET: i686-pc-windows-msvc + BITS: 32 +install: + - curl -sSf -o rustup-init.exe https://win.rustup.rs/ + - rustup-init.exe -y --default-host %TARGET% + - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin + - if defined MSYS2 set PATH=C:\msys64\mingw%BITS%\bin;%PATH% + - rustc -V + - cargo -V +build: false +test_script: + - cargo build --verbose + - cargo test --verbose +branches: + only: + - master diff -Nru cargo-0.33.0/vendor/aho-corasick/benches/bench.rs cargo-0.35.0/vendor/aho-corasick/benches/bench.rs --- cargo-0.33.0/vendor/aho-corasick/benches/bench.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/benches/bench.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,373 +0,0 @@ -#![feature(test)] - -extern crate aho_corasick; -extern crate test; - -use std::iter; - -use aho_corasick::{Automaton, AcAutomaton, Transitions}; -use test::Bencher; - -const HAYSTACK_RANDOM: &'static str = include_str!("random.txt"); -const HAYSTACK_SHERLOCK: &'static str = include_str!("sherlock.txt"); - -fn bench_aut_no_match, T: Transitions>( - b: &mut Bencher, - aut: AcAutomaton, - haystack: &str, -) { - b.bytes = haystack.len() as u64; - b.iter(|| assert!(aut.find(haystack).next().is_none())); -} - -fn bench_box_aut_no_match, T: Transitions>( - b: &mut Bencher, - aut: AcAutomaton, - haystack: &str, -) { - b.bytes = haystack.len() as u64; - let aut: &Automaton

= &aut; - b.iter(|| assert!(Automaton::find(&aut, haystack).next().is_none())); -} - -fn bench_full_aut_no_match, T: Transitions>( - b: &mut Bencher, - aut: AcAutomaton, - haystack: &str, -) { - let aut = aut.into_full(); - b.bytes = haystack.len() as u64; - b.iter(|| assert!(aut.find(haystack).next().is_none())); -} - -fn bench_full_aut_overlapping_no_match, T: Transitions>( - b: &mut Bencher, - aut: AcAutomaton, - haystack: &str, -) { - let aut = aut.into_full(); - b.bytes = haystack.len() as u64; - b.iter(|| assert!(aut.find_overlapping(haystack).count() == 0)); -} - -fn bench_naive_no_match(b: &mut Bencher, needles: Vec, haystack: &str) - where S: Into { - b.bytes = haystack.len() as u64; - let needles: Vec = needles.into_iter().map(Into::into).collect(); - b.iter(|| assert!(!naive_find(&needles, haystack))); -} - -#[bench] -fn bench_construction(b: &mut Bencher) { - b.iter(|| { - AcAutomaton::new(test::black_box( - [ - "ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BAK", "BaK", "Bak", "BaK", "HOL", - "HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh", "JoH", "Joh", "SHE", - "SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat", "aDL", "aDl", "adL", "adl", "bAK", - "bAk", "bAK", "baK", "bak", "baK", "hOL", "hOl", "hoL", "hol", "iRE", "iRe", - "irE", "ire", "jOH", "jOh", "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt", - "waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe", - ].iter() - .map(|x| *x), - )) - }) -} - -#[bench] -fn bench_full_construction(b: &mut Bencher) { - b.iter(|| { - AcAutomaton::new(test::black_box( - [ - "ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BAK", "BaK", "Bak", "BaK", "HOL", - "HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh", "JoH", "Joh", "SHE", - "SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat", "aDL", "aDl", "adL", "adl", "bAK", - "bAk", "bAK", "baK", "bak", "baK", "hOL", "hOl", "hoL", "hol", "iRE", "iRe", - "irE", "ire", "jOH", "jOh", "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt", - "waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe", - ].iter() - .map(|x| *x), - )).into_full() - }) -} - -fn haystack_same(letter: char) -> String { - iter::repeat(letter).take(10000).collect() -} - -macro_rules! aut_benches { - ($prefix:ident, $aut:expr, $bench:expr) => { - mod $prefix { -#![allow(unused_imports)] -use aho_corasick::{Automaton, AcAutomaton, Sparse}; -use test::Bencher; - -use super::{ - HAYSTACK_RANDOM, haystack_same, - bench_aut_no_match, bench_box_aut_no_match, - bench_full_aut_no_match, bench_full_aut_overlapping_no_match, -}; - -#[bench] -fn ac_one_byte(b: &mut Bencher) { - let aut = $aut(vec!["a"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_one_prefix_byte_no_match(b: &mut Bencher) { - let aut = $aut(vec!["zbc"]); - $bench(b, aut, &haystack_same('y')); -} - -#[bench] -fn ac_one_prefix_byte_every_match(b: &mut Bencher) { - // We lose the benefit of `memchr` because the first byte matches - // in every position in the haystack. - let aut = $aut(vec!["zbc"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_one_prefix_byte_random(b: &mut Bencher) { - let aut = $aut(vec!["zbc\x00"]); - $bench(b, aut, HAYSTACK_RANDOM); -} - -#[bench] -fn ac_two_bytes(b: &mut Bencher) { - let aut = $aut(vec!["a", "b"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_two_diff_prefix(b: &mut Bencher) { - let aut = $aut(vec!["abcdef", "bmnopq"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_two_one_prefix_byte_every_match(b: &mut Bencher) { - let aut = $aut(vec!["zbcdef", "zmnopq"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_two_one_prefix_byte_no_match(b: &mut Bencher) { - let aut = $aut(vec!["zbcdef", "zmnopq"]); - $bench(b, aut, &haystack_same('y')); -} - -#[bench] -fn ac_two_one_prefix_byte_random(b: &mut Bencher) { - let aut = $aut(vec!["zbcdef\x00", "zmnopq\x00"]); - $bench(b, aut, HAYSTACK_RANDOM); -} - -#[bench] -fn ac_ten_bytes(b: &mut Bencher) { - let aut = $aut(vec!["a", "b", "c", "d", "e", - "f", "g", "h", "i", "j"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_ten_diff_prefix(b: &mut Bencher) { - let aut = $aut(vec!["abcdef", "bbcdef", "cbcdef", "dbcdef", - "ebcdef", "fbcdef", "gbcdef", "hbcdef", - "ibcdef", "jbcdef"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_ten_one_prefix_byte_every_match(b: &mut Bencher) { - let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef", - "zecdef", "zfcdef", "zgcdef", "zhcdef", - "zicdef", "zjcdef"]); - $bench(b, aut, &haystack_same('z')); -} - -#[bench] -fn ac_ten_one_prefix_byte_no_match(b: &mut Bencher) { - let aut = $aut(vec!["zacdef", "zbcdef", "zccdef", "zdcdef", - "zecdef", "zfcdef", "zgcdef", "zhcdef", - "zicdef", "zjcdef"]); - $bench(b, aut, &haystack_same('y')); -} - -#[bench] -fn ac_ten_one_prefix_byte_random(b: &mut Bencher) { - let aut = $aut(vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00", - "zdcdef\x00", "zecdef\x00", "zfcdef\x00", - "zgcdef\x00", "zhcdef\x00", "zicdef\x00", - "zjcdef\x00"]); - $bench(b, aut, HAYSTACK_RANDOM); -} - } - } -} - -aut_benches!(dense, AcAutomaton::new, bench_aut_no_match); -aut_benches!(dense_boxed, AcAutomaton::new, bench_box_aut_no_match); -aut_benches!(sparse, AcAutomaton::<&str, Sparse>::with_transitions, - bench_aut_no_match); -aut_benches!(full, AcAutomaton::new, bench_full_aut_no_match); -aut_benches!(full_overlap, AcAutomaton::new, bench_full_aut_overlapping_no_match); - -// A naive multi-pattern search. -// We use this to benchmark *throughput*, so it should never match anything. -fn naive_find(needles: &[String], haystack: &str) -> bool { - for hi in 0..haystack.len() { - let rest = &haystack.as_bytes()[hi..]; - for needle in needles { - let needle = needle.as_bytes(); - if needle.len() > rest.len() { - continue; - } - if needle == &rest[..needle.len()] { - // should never happen in throughput benchmarks. - return true; - } - } - } - false -} - -#[bench] -fn naive_one_byte(b: &mut Bencher) { - bench_naive_no_match(b, vec!["a"], &haystack_same('z')); -} - -#[bench] -fn naive_one_prefix_byte_no_match(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbc"], &haystack_same('y')); -} - -#[bench] -fn naive_one_prefix_byte_every_match(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbc"], &haystack_same('z')); -} - -#[bench] -fn naive_one_prefix_byte_random(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbc\x00"], HAYSTACK_RANDOM); -} - -#[bench] -fn naive_two_bytes(b: &mut Bencher) { - bench_naive_no_match(b, vec!["a", "b"], &haystack_same('z')); -} - -#[bench] -fn naive_two_diff_prefix(b: &mut Bencher) { - bench_naive_no_match(b, vec!["abcdef", "bmnopq"], &haystack_same('z')); -} - -#[bench] -fn naive_two_one_prefix_byte_every_match(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('z')); -} - -#[bench] -fn naive_two_one_prefix_byte_no_match(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbcdef", "zmnopq"], &haystack_same('y')); -} - -#[bench] -fn naive_two_one_prefix_byte_random(b: &mut Bencher) { - bench_naive_no_match(b, vec!["zbcdef\x00", "zmnopq\x00"], HAYSTACK_RANDOM); -} - -#[bench] -fn naive_ten_bytes(b: &mut Bencher) { - let needles = vec!["a", "b", "c", "d", "e", - "f", "g", "h", "i", "j"]; - bench_naive_no_match(b, needles, &haystack_same('z')); -} - -#[bench] -fn naive_ten_diff_prefix(b: &mut Bencher) { - let needles = vec!["abcdef", "bbcdef", "cbcdef", "dbcdef", - "ebcdef", "fbcdef", "gbcdef", "hbcdef", - "ibcdef", "jbcdef"]; - bench_naive_no_match(b, needles, &haystack_same('z')); -} - -#[bench] -fn naive_ten_one_prefix_byte_every_match(b: &mut Bencher) { - let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef", - "zecdef", "zfcdef", "zgcdef", "zhcdef", - "zicdef", "zjcdef"]; - bench_naive_no_match(b, needles, &haystack_same('z')); -} - -#[bench] -fn naive_ten_one_prefix_byte_no_match(b: &mut Bencher) { - let needles = vec!["zacdef", "zbcdef", "zccdef", "zdcdef", - "zecdef", "zfcdef", "zgcdef", "zhcdef", - "zicdef", "zjcdef"]; - bench_naive_no_match(b, needles, &haystack_same('y')); -} - -#[bench] -fn naive_ten_one_prefix_byte_random(b: &mut Bencher) { - let needles = vec!["zacdef\x00", "zbcdef\x00", "zccdef\x00", - "zdcdef\x00", "zecdef\x00", "zfcdef\x00", - "zgcdef\x00", "zhcdef\x00", "zicdef\x00", - "zjcdef\x00"]; - bench_naive_no_match(b, needles, HAYSTACK_RANDOM); -} - - -// The organization above is just awful. Let's start over... - -mod sherlock { - use aho_corasick::{Automaton, AcAutomaton}; - use test::Bencher; - use super::HAYSTACK_SHERLOCK; - - macro_rules! sherlock { - ($name:ident, $count:expr, $pats:expr) => { - #[bench] - fn $name(b: &mut Bencher) { - let haystack = HAYSTACK_SHERLOCK; - let aut = AcAutomaton::new($pats).into_full(); - b.bytes = haystack.len() as u64; - b.iter(|| assert_eq!($count, aut.find(haystack).count())); - } - } - } - - sherlock!(name_alt1, 158, vec!["Sherlock", "Street"]); - - sherlock!(name_alt2, 558, vec!["Sherlock", "Holmes"]); - - sherlock!(name_alt3, 740, vec![ - "Sherlock", "Holmes", "Watson", "Irene", "Adler", "John", "Baker", - ]); - - sherlock!(name_alt3_nocase, 1764, vec![ - "ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BAK", "BaK", "Bak", "BaK", - "HOL", "HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh", - "JoH", "Joh", "SHE", "SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat", - "aDL", "aDl", "adL", "adl", "bAK", "bAk", "bAK", "baK", "bak", "baK", - "hOL", "hOl", "hoL", "hol", "iRE", "iRe", "irE", "ire", "jOH", "jOh", - "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt", "waT", "wat", - "ſHE", "ſHe", "ſhE", "ſhe", - ]); - - sherlock!(name_alt4, 582, vec!["Sher", "Hol"]); - - sherlock!(name_alt4_nocase, 1307, vec![ - "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "hOL", "hOl", - "hoL", "hol", "sHE", "sHe", "shE", "she", "ſHE", "ſHe", "ſhE", "ſhe", - ]); - - sherlock!(name_alt5, 639, vec!["Sherlock", "Holmes", "Watson"]); - - sherlock!(name_alt5_nocase, 1442, vec![ - "HOL", "HOl", "HoL", "Hol", "SHE", "SHe", "ShE", "She", "WAT", "WAt", - "WaT", "Wat", "hOL", "hOl", "hoL", "hol", "sHE", "sHe", "shE", "she", - "wAT", "wAt", "waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe", - ]); -} diff -Nru cargo-0.33.0/vendor/aho-corasick/benches/random.txt cargo-0.35.0/vendor/aho-corasick/benches/random.txt --- cargo-0.33.0/vendor/aho-corasick/benches/random.txt 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/benches/random.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,513 +0,0 @@ - -mnxnsynfvuugtbxsxbfxwreuspglnplefzwsp -tacfqcwnmodnmgnyiuvqoco -z - -qjuozfkexn -zoaxzncje -sldhqtmgxzyurfyzwazmmu -bbeuv -mzsrihycwcb -xzfqozfmlnpmrzpxxxytqs -xrg -mcplby -nmslhfgjowhzfxsvyddydnsyehdskbydbjksqtpet -indvfw -bvjvvw - -pddufodyqtyixbndtumndyz -xjjhtuvmsxhuwqulqtjhqrdqrmtbcphvyuqllocrnkpfv -zemshhz -wss -xewlrxfmgxnwgphcgefa -mbgsgbzrtthxweimcqzcaaheurdmd -osqefupespvh -z -tvvlakwzwjbrgjzfgubsmmonav -pjdskxcfgapsm -zqktqgkrcdrlskx -zwwfebhguskho -zlvvw -czwm -gojnpmboehlsazbexjjnuscqftrfufngygjdxcydib -d -afigycivicnknfxl -ljuwuopctiftfwctxecwipjnljyef -jonwbkodomzhqvlf -jdkizhognqsdogunwedjsmsdzho -zxvni -oynfjf -muvokjuqz -azuwrwtuxzfopwrcex -ixrjinlvxjmn -blaegnmbhsgsbmebwazaeguugtkowexgnqtbfkldadddv -tzabyoftyov -ctbtqbzscxzviuvcigwuwusrdro -ljynr -gnnnyyxslrhsbj -hhzlw -hijalf -rxlfqk -mhaofforwznvmcgplinludpgkucpa -gvvxsqqfmu -xxqhoyosixjfhjuxpv -faadjpvamjekreepizurntvwdynozfawsfawyms - -lcbutr -aqyxvpozkjrecrkl -lfmochahrr -ptqyomjlwo -vcmslulznx -lmlsskcihrmxauztuarydlp -beiqsrfnmvmlmybmwpektjbikvpggthpabqsgmjhnthvysuhwbigillugjsp -dfsuegseffwcsnvsrqedytblbpzbfeyfsq -kypvqctrkuds -ylqeduokzgdqaxelhftxnxbidu -bprzyayfopxdsmfhhfqowa -ymiutdtlfaaxpbtaeslv -ggago - -owpbicekdeykzfgcbgzobdvvrtetvcv -xsrlgingstiez -gyncqvq -xasohmeiwyscpehctmzmsnjklg -xsudghakxlw -dzqlfptjogzpkvwuticcyugnyopypuqqc -wlxshxbhdvuherumoppcc - -znyaptivzncvkpeyeipynqefjxjjcsgfqbnezeebtowdrbjaqjlbxwvyikrmxjwoxngqgvfpbniftnmszuxg -umwpwwyvufy -pallkjtnrmtauqxauewgygwkjjwebbkabhtxticxmxfujpxlrpzlrozfslkzfdsswlmmsbdgjwmjnummk -dhsxylejzityahtqqzmohrpzjprrsraztpnuagtyzfjdekthvdogfidksrdppr -ybc -fyukknoqfnkllkwflwempjijxgo -dltvlau -rhvrvlwsribfctuzodfqkdczfzxnetqqzflnhiyl -goxmcasmq -wljbhwkpahdotqhhrbhqzijv -lszewkgdmkezvgmbmllhpksdkoiwgkvqjmurshrptlctqsosuurndcuzjfwherotv -dudxxihygxblhgchbgzyzffb -eht -fvwxvqoltdcsd -rkuig -e -axhsacsmnicugul -rubtdlhjqndxdzzwfnkuzy -swxteuyxxsktkjgv -hzwwodlqaq -vxgecev -qnwla -vdxjuzpyoqhpmuunyffptopmeauhycs -dkzo -awrfzatzohslgvqlaezepmli -qgxatixvpkkhvkumbwmwcagtgyfljdok -amdnzstpvcqj -xsrvwvhjirzfgkessve -qezwbfltfbikbmoasvoflozsjhrljnszqiciuqmflrlqowwkoevuumh -babskcvavmtvsxqsewirucwzajjcfcqwsydydqo -ywfurpsl -edacsjjkjjewkxfoh -dcgkfpcjezurnuhiatrczcp -xsatnimwbcciu -grzmbrsvvcyigcbmcqfwiiknrohveubhyijxeyzfm -kqyewccgcqrrrznwxmoztlyseagbpyho -najju -nis -awgzdvfjkzlrsjcqfeacx -oisuflfigrjaex -desbdulyuwqxuxianyypybxwlql -ekmqgspvqpftpwswayh -egbyj -fznzprhvnnwcxgcc -wfdsueieosmugirxbymbpmfrspvrktjzguxm -qkjrufshwnfwwpbhukdjlaqvljlgubmqmhnha -hwqpudgnblhlxppbrmbznotteivuzguuwlhtkytky -w -yofkyzbpg -cenolnfnllkvhikrpttcxgqxmufvorekjruyjxmr - -hyexmpjijgzumawp -cdbevdilgopbzlo -fivelagckslkugdxprjxkylizewcptwxfhomzuituujixchadmnjoktnqa -csojvlinzmmkkfzqueamnuwkanzdzsavgohposbuoamoevehqrmcxdsuyelvvctoejzoertqormhaaxwofvjzekwt -sbkghhnhutrvwtyjaxndzyjamrhx -jjyqy -majwbnrhveuhrsbbbjrwpwuplifeseylqh -wyvutpxnkrnkuxxetjkkifpqb -dyzucmbcvgnjeecm -hz -uhnuipthxrzkqluosvk -lwqqzsdwiwvwaqfwlvubadlyizlo -jbd -oyzjeu -kydjkbsqxnbfiuesc -smeubjqrcxdvhsabzceyglqjzbfmoacmwvwjbhhxbr -uabipgecujfdfxpmdzrscdyvefizabgspqjrrkmgjt -xgvdgzryz -lw -uimob -ifhn -bqph -ole -g -wt -k -yslzrkwkundxfdibwqvucemepqxlmlpyngabbeciuzhptpjdetyngrtxrdtzmvq -ccwapidp - -bwvrgvmtshevrophy -ni -fdkplu -mdykey -i -rhsrenoetdggpjb -djmkplpeabsholx -judxtub -fooakqwvocvpcrvxqhvtmpvhkrecy -uuxscjillynilbkrgt -evtinrmilniguarqritpeipwochmdw -sxaqzjybydyvnmmjtdcgkjnqfcklbfpkdfyewgcukqoiegyfp -kg -ovrwieqhy -jcxqtkerzjwhs -xeonglszbgypafhmqcaseimzjgebkvigbqwsayrnrprtuvhsxyitfqygohgorcdnufbcyvevvgzmjrgjqqquwkszplogx -zdketqqv -yebckucwayckeezfvtnavglpjh -zorkfrwk -pad -xqaquxudybwtgixbfktinctfirjfdayh -rieknj -ebk -qzbcfywfdmhsdruhopovemafijbscagllkmhmof - -asbsnbddlobwoqatfhkbhhsymzqxjuixwreheugvngmgcuqpkjhhfwpbarqaxrwgwnjbanljlds -etevdvlc -lqyjrnmenhn -k -tsf -zczgeavcexh -jlpuxywtsrvnvluruqhecjca -ir -rikrgkmhwaosodkxgcnrexfmdrszhnmutpvwztg -bffjqovvkemctnsgeh -weysbhzixiipfithjfsk -usyzvaiyuhmksfluoirfbnsu -o -cgawpdakaszeafdtbdkqtlzkrpnoqomqvuaqcfmzgvfegovtfaonelpv -izmrcjlk -xmzemniyrzy -knqexaafsdlimdamcrprlshq -qkmqw -dntgjwsibclvposdwjuklvtejjjdjibgpyynqpgprvvaetshhmvfkcpb -otvazkrkklrxfotpopyjte -fghkcnpi -rulyaihsowvcgbzeiblhuhhfbmncqsuuqcxvseorn -exirzfmojnxcoqom -zsgpgtokun -zvamxfocorganbtlafifwdqmqtsnktbwwtewborq - -cxlnaspjqvsitjyzyriqsuorjsrvzqenisprttudxntsbqrpjtdkxnwcwgjyxmgtqljcrmrbrmyvosojzlumcmjcgfjsdehec -mvx -mt -mckr -teulvroifk -laaicc -koufy -bexmwsvyarnznebdfy -ripvviosbqijsxnjilwddaqaqemzsdarnxmfooxghoypizwtbueo -ljycycuqwfnzbambibqdixmkkvwtubepla -cis -kcg -vmbbiuuoamenzepuagpfujevfstqtndjxjchdvycfrrrowochtjdmkklgnhf -pmorrwguxkvdxpluatagaziin - -uwvzbmkmykjkmknzppklx -pnzxuvsrjunqxercsnvayhykcazdeclomdsasgkpqpiufyfqsxhj -yceizkddwojgweegcllaagpvrpo -ek -kuxxgbezqyxvfaxdwnqdgqsmneijunxzlwxkrs -ldldbrxmvtjlqxifngmactzqcygkvuteffcmvphevilabgukatqakamjlridznodcvblvlogulmcixxfimh -iuzjootuywjqklolzzhpeaynydjwtufjavbozxnzckuzdodkvkjfmhinelv -swlfkcufscfcovmghqwcrtxjukwafoeogrkgubbqgwzm -gjcylkwgzroubdssuqeykqjcmguso -fzq -srfvysoxtlylctp - -pbfeiuzwoyixews -ocvvunfsjnrtklmuuzjojw -xdjcnrpqhmpmpcwacpcdtmbsczvhllkqapzjuaf -nfnuvjz -fwnuiyqpn -wshxxxpzzxp -hibrxcfeqca - -wqhlllarl -bukcbojv -plrytapy -xm -vlgfqoyzdczqbbaxjwbjjevjhxgopuqvqcrj -vpjqfbdnsdxlbuuiqocvrhap -mgumjbvnnzgnrdru -gcgzugazxdcamrhczfzhtmdjj -uislwq -vooai -zjuqfmebuzsqngzekyajujkopvayxtdzvugwwucvlsbrnhitfotmhhmgddlzlvqrkcponictrfweuilfjiuoabkfdvpjiqjrrgi -aptjfhmrnxaq -hbs -w -mwmoxqvucwygunplzvxtxpk -fgmqmtlorfzytjdzffsosfccnfwugrsrynuej -rpmpenrhsxoefnblyumjqwvuyszyppnttuyvazjdug -zdzxraxkroknkmqgvuoqeqdtvclsvvuwmdwzfugcpteohlogxubyoebvrzbqzklvehfcqadtdrkpubfhmokzwyosogepwragcpwxo -ax -dz -de - -thvkdmnbdws - -ejmubw -umvwkaubzurf -wyxtxeluaoox -wwbioobtgmkebxo -miglgnafmdarzkeblyjctuayzyoeqnfnbtrcbymdzkzg -loavxq -kzhllgsenxlbgdbfzwbg -yxflogzsohlcycbyzegeubfflouvtuatixhjvicjegltjiy -jigqfjppafdiarc -mcnmwtachgearonfcymvjbrnljjxmlzkudvzqsarnfysmxlfrtlvjxwvpdbhvwysnvcdozfcruhjwnucdzakkilmlfgjiolcatpfusm - -n -pdjunfcz -dc -edxkkxabsbvmvifiinnoccki -bc -gwtwsvorwzfqpz -exidmexstfflkhi -s -s -c -wtcjfywlayhpbqktcepoybowtkrmnumqsg -ozclkgjdmdk -jmegtbunyexurvfexhqptnqzie -tkoenpagzwqfawlxvzaijsjqhmg -swodqfjpdqcbkc -ujokogocyaygdibgpglecis -shlmdmgonvpuaxlhrymkxtiytmv -brhk -jmsyiuomiywxhegilycjprkyfgojdo - -wzdzrgpdiosdsvkcw -odlnmsfnjrcsnflviwvawybpczdkzvdocpwrmavz -p -ubowamlskcqhdxuckrxa -fawhntiwhmdwkddnahmtajqqazpdygttqivhdiodkcpcwv -gmxujmmaufmbipaiulhurzkfdg -eixjhmbaeoybiwk -kumntgrgiofcmujlzbcopuobambsw -mnjkqiyb -iktwnsnv -hfuzcl -tqiyqvagbqgtowpjbedgjot -dfemvamelxadkztogliizdtsddoboafawficudlefo -raecmxiiibljryswntpfed -mbwrtsebkeegw -x -epp -he - -vnztrswhiusokqdkmsnpuswucvfhcthjbtam -baxlwidsgbdpzvnlj -tcbjjoadrzo -aiidahyllzzsg - -igebuubweicbssgddpmqxunrawavuglmpxrtkqsvjjtscibqiejjfgfnovokodmqcqitlteiakooupvzkwucucrfdzjvjbqbkgutoybmpfvhbutigdxhfiqfplyciz -cnrhbjdnjftwfwlwzrdkwhajgsizsi -qfntnt -okqyfnbresp -asyg -mjqdkdyggdxzwuzglays -h -ifaqcazoy -fol -vvsusbnugduxsceozmsarbp -epjwtorx -bwiuxxiyc -cw -bwogruhctwkfvbexjnwircykxyzjmats -kygiochfwlpsvmxcgmtjrgvfdptd -q -qmpqe - -z -jghffhqfoecmszunhxmzmzhlmbrvjabhrkihgjmvckhkfpaygjkg - -kfiyfgounmhlvhupswqdgws -ezzdpyqucqoocsdcjtruqpokldfkmjhqzoynirybsifyaxnaxppthjoqy -nwetlgzwrhkhtuubbkbepuhbllxspvagxrqokwnrhkbwdwtp -hlazomrhqogoaxypqaszwfxxmutvbpuuvpdffuqskcbzlwyzcssnflkwiydoveyxjnzllzhyozbsa -hwnitkwbxcyibbqsluuqywbk - -ozpfjsdrc -yoepefuy -lvmspzepnetra -genbrcrmuqfvkaouvuymoxhcxotjjhk -pcshyqgbmqdubsdajnyfqvxkqvywffzn -ukhcbyzwslqeq -otfrmcbnhbyffxqregqoufdxucjunwdhlqqeiiawbxlpqeyzzopfungrryqdykgizrhqodirvazm -dhpfhzyq -cloz -eduupqifolfekve -qiec -ishnjukvomntmdthlkajxpiwk -y -axl -tmyskjqkjsvumizlal -wvvolwewsfxhhdieuagdcuhwsgqvswpbkdkpxskloalmr -ryfmhe -z -mmbpgsyrfvzdatbjrjhuipwt -llzwizmmuulgwocowwmugtaoewkhnqxparvtynlffffdfcocdbba - -pyczkzbmcgrdnxnmezsx -gsqe -mcocxcolcynhpecstsn -opnpplkccobjuhtbhirpzfxuktmpsiwbvsgiaavvdge -wpaldxzasnrbvtugjwytvtfttrh -zxecurevkjiyxy -wtnovebcmglkktic -fdpwfgvlvovxrwh -bmwgdullzy -uzwhagxinwqifxjbcntqzqoxkmpqxhe -jrfizsnwxwnnhb -inapddlahrp - -ndtvkceobe -buskgghihdjmjlwfc -j -rkvffxwtmzoeruhlsurwtnuh -cbvkhfepkdishfpqvijzrpleuy -jzdpxjhcgqnybssfegvrnpgyehdqpgjwudbwrjbavp -xzzvgqdrdwajmdmj -vfatwsxvwfdbdhnijdujoyotwvwjipuuetichcfmvgrsnjpqaaezjtkvc -lbfoqgfshrtwgdqufwnfuitdrjydqctqixlzufkdbp -zgau -qefdpmtkecvtj -kuphldkvnzdtpd -dti -fpd -gfrliyegxsb -i -qsddsrmkyfgzrjeqnitmnypbcakh -vfbvbrpuogzhzrbmklvhji -nkz -xlufbaoblbmeub -alwuzxzmobwdukvwnkiwmuqhuxfhevogdnqtmxjptqznrk -cngpoty - -ms -qvenfg -dmeaffm -jycfgnanbmoamhmarkmjcagbp -ysqmbhopgx -jczbzgwedsp - -zxzwjrxcwdtleizjlvifjwgxiibezwxhtzywqdi -mtgnlu -xboxirdchurkfnklnpkapnqfxnhrxyseiujrznjm - -zm -atddskbghcahlhql -szshwzmmvu -befdtpouamwhiisyybispkchpjhownatawjfbx - -ennkzbrlygd -zbt -upphzpdwzmlhhhbqvjsfmbnrar -ddcs -ipbxgzyudjyongtcyygncojdufnufqpdppgvq -gc -isu -foa -wf -jdlvqxgfbowhohhyyngbcs -zjuwjyucdwblatsnywaaoftlcamfbcnw -lzrioesuhoeevczuwrnltmkahfwiu -uicggfbddqltnjyxfltbnaekncnyxsit -zkxsqkqrwrzrxgxbsgxatybfr - -ptvmfyxdcglbfipcguqthjygzqnpqssscukzawynidtchjrrxwuxifoe -w -ohu -vg -zagpowezvbniybgold -lhqseqcxteiqtgnpanpvrmvvlltxh -mtfnxn -wyodtg - -rawpbgtpbaktqzmmpzxmrlwpvvmdsl -widcfbirvswraukbmkhf -vplrueuxomjkqrtjgyxjdkexttzyozawyq -hrpbahllznvmjudzxpbbv -tlavfrxygjfipkupwnbacltcfepeg -icu -otxcu -aewazy -hl - -fmrp -qaacthwzohenzjr -xbyebba -rvkph -mkhhmh -swme -zjmdoypaktglcyzobquunvthcdwegtbywpijxd -jvkuhnxqc -gibhqgjojsxt -bodbktzomiqujtbstqiyquwvqgufphqstenxvddkvtdh -bpusrxkfi -zgp -pmxvgamydyakituvvsucsuidrlznupcsinltmrahulhepxmhoqtfvpjkxzhrrinncuh -jzgkjjhjqykzelaszvcwvvwbnzsxdeaerfnaravk -ynanrqyrxo -zsmuxofullob -brklgrcqefdyoczy -qkpls -snhqumae -iqdtzjadzzvnqvdvjfsaf -nfqfdqiramueblxkaqxbbkxwywzgdbndjjiqk -tc -kp -cpuckbjsxhtxmomfesgxdpz -oseif -ybhxbvyxrpkrexrhjzoaxxohrhsniewsrktjnaztn -ggelspdzhzbchruhbjbjidgjwdlhdycetqaswh -jkgivsngygkbqtlmoj -dwpnanfvitxg -ospxbwxp -wgvmvrnjescemdoiralbkvemalifxnyhrbdgodml -hjtsnkzknkplbzsiwmneefdkihnhsamjsrxggclyjqgpqltizi - - -sykgbuypwwhweab -nvdkkkskmtiwpoerkon -sx -sbyflwwiqylbskdlxesmylpaz -dnwcjenaluwesyywfaezznwkdwpoesxpu -kie -dslccwfryol -gfhomgfn -zprjtfqvkotktzidmoyrivall -bunvsqkysdelozemnjoeqfolruulpbipm -ullyzfahpkhkja -hwd -kvyqtprpuulgsk -zotbkcadnxmfvqmtlbxalhughceyfcibtzzj -vvpjbgxygl -hpic -mhrqd -dv -thehuzdbaacoidjoljbysnqwrrxxplrdznmgiukkvjqbopb -moszjt -rmtbunktkywqirveeqfa -kse -wbfflnatgzobjrxghjgvcsyxoruenxhyomutbptswjajawqjpqafpdcstkiyjuilimecgejpqmyciolgcmdpcstzdozbmnza diff -Nru cargo-0.33.0/vendor/aho-corasick/.cargo-checksum.json cargo-0.35.0/vendor/aho-corasick/.cargo-checksum.json --- cargo-0.33.0/vendor/aho-corasick/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"} \ No newline at end of file +{"files":{},"package":"e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/aho-corasick/Cargo.toml cargo-0.35.0/vendor/aho-corasick/Cargo.toml --- cargo-0.33.0/vendor/aho-corasick/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,18 +12,17 @@ [package] name = "aho-corasick" -version = "0.6.9" +version = "0.7.3" authors = ["Andrew Gallant "] -exclude = ["/benches/sherlock.txt", "/ci/*", "/.travis.yml", "/Makefile", "/ctags.rust", "/session.vim"] -description = "Fast multiple substring searching with finite state machines." +exclude = ["/aho-corasick-debug", "/bench", "/ci/*", "/.travis.yml"] +autotests = false +description = "Fast multiple substring searching." homepage = "https://github.com/BurntSushi/aho-corasick" readme = "README.md" -keywords = ["string", "search", "text", "aho", "corasick"] +keywords = ["string", "search", "text", "aho", "multi"] +categories = ["text-processing"] license = "Unlicense/MIT" repository = "https://github.com/BurntSushi/aho-corasick" -[profile.test] -debug = true - [profile.bench] debug = true @@ -32,41 +31,15 @@ [lib] name = "aho_corasick" - -[[bin]] -name = "aho-corasick-dot" -path = "src/main.rs" -test = false -bench = false -doc = false - -[[bench]] -name = "bench" -path = "benches/bench.rs" -test = false -bench = true [dependencies.memchr] -version = "2" -[dev-dependencies.csv] -version = "1" - -[dev-dependencies.docopt] -version = "1" - -[dev-dependencies.memmap] -version = "0.6" - -[dev-dependencies.quickcheck] -version = "0.7" +version = "2.2.0" default-features = false -[dev-dependencies.rand] -version = "0.5" - -[dev-dependencies.serde] -version = "1" +[features] +default = ["std"] +std = ["memchr/use_std"] +[badges.appveyor] +repository = "BurntSushi/regex-automata" -[dev-dependencies.serde_derive] -version = "1" [badges.travis-ci] repository = "BurntSushi/aho-corasick" diff -Nru cargo-0.33.0/vendor/aho-corasick/examples/dict-search.rs cargo-0.35.0/vendor/aho-corasick/examples/dict-search.rs --- cargo-0.33.0/vendor/aho-corasick/examples/dict-search.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/examples/dict-search.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -// This example demonstrates how to use the Aho-Corasick algorithm to rapidly -// scan text for matches in a large dictionary of keywords. This example by -// default reads your system's dictionary (~120,000 words). -extern crate aho_corasick; -extern crate csv; -extern crate docopt; -extern crate memmap; -extern crate serde; -#[macro_use] -extern crate serde_derive; - -use std::error::Error; -use std::fs::File; -use std::io::{self, BufRead, Write}; -use std::process; - -use aho_corasick::{Automaton, AcAutomaton, Match}; -use docopt::Docopt; -use memmap::Mmap; - -static USAGE: &'static str = " -Usage: dict-search [options] - dict-search --help - -Options: - -d , --dict Path to dictionary of keywords to search. - [default: /usr/share/dict/words] - -m , --min-len The minimum length for a keyword in UTF-8 - encoded bytes. [default: 5] - --overlapping Report overlapping matches. - -c, --count Show only the numebr of matches. - --memory-usage Show memory usage of automaton. - --full Use fully expanded transition matrix. - Warning: may use lots of memory. - -h, --help Show this usage message. -"; - -#[derive(Clone, Debug, Deserialize)] -struct Args { - arg_input: String, - flag_dict: String, - flag_min_len: usize, - flag_overlapping: bool, - flag_memory_usage: bool, - flag_full: bool, - flag_count: bool, -} - -fn main() { - let args: Args = Docopt::new(USAGE) - .and_then(|d| d.deserialize()) - .unwrap_or_else(|e| e.exit()); - match run(&args) { - Ok(()) => {} - Err(err) => { - writeln!(&mut io::stderr(), "{}", err).unwrap(); - process::exit(1); - } - } -} - -fn run(args: &Args) -> Result<(), Box> { - let aut = try!(build_automaton(&args.flag_dict, args.flag_min_len)); - if args.flag_memory_usage { - let (bytes, states) = if args.flag_full { - let aut = aut.into_full(); - (aut.heap_bytes(), aut.num_states()) - } else { - (aut.heap_bytes(), aut.num_states()) - }; - println!("{} bytes, {} states", bytes, states); - return Ok(()); - } - - let rdr = try!(File::open(&args.arg_input)); - if args.flag_full { - let aut = aut.into_full(); - if args.flag_overlapping { - if args.flag_count { - let mmap = unsafe { try!(Mmap::map(&rdr)) }; - println!("{}", aut.find_overlapping(&*mmap).count()); - } else { - try!(write_matches(&aut, aut.stream_find_overlapping(rdr))); - } - } else { - if args.flag_count { - let mmap = unsafe { try!(Mmap::map(&rdr)) }; - println!("{}", aut.find(&*mmap).count()); - } else { - try!(write_matches(&aut, aut.stream_find(rdr))); - } - } - } else { - if args.flag_overlapping { - if args.flag_count { - let mmap = unsafe { try!(Mmap::map(&rdr)) }; - println!("{}", aut.find_overlapping(&*mmap).count()); - } else { - try!(write_matches(&aut, aut.stream_find_overlapping(rdr))); - } - } else { - if args.flag_count { - let mmap = unsafe { try!(Mmap::map(&rdr)) }; - println!("{}", aut.find(&*mmap).count()); - } else { - try!(write_matches(&aut, aut.stream_find(rdr))); - } - } - } - Ok(()) -} - -fn write_matches(aut: &A, it: I) -> Result<(), Box> - where A: Automaton, I: Iterator> { - let mut wtr = csv::Writer::from_writer(io::stdout()); - try!(wtr.serialize(("pattern", "start", "end"))); - for m in it { - let m = try!(m); - try!(wtr.serialize((aut.pattern(m.pati), m.start, m.end))); - } - try!(wtr.flush()); - Ok(()) -} - -fn build_automaton( - dict_path: &str, - min_len: usize, -) -> Result, Box> { - let buf = io::BufReader::new(try!(File::open(dict_path))); - let mut lines = Vec::with_capacity(1 << 10); - for line in buf.lines() { - let line = try!(line); - if line.len() >= min_len { - lines.push(line); - } - } - Ok(AcAutomaton::with_transitions(lines)) -} diff -Nru cargo-0.33.0/vendor/aho-corasick/README.md cargo-0.35.0/vendor/aho-corasick/README.md --- cargo-0.33.0/vendor/aho-corasick/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,15 +1,14 @@ -This crate provides an implementation of the -[Aho-Corasick](http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm) -algorithm. Its intended use case is for fast substring matching, particularly -when matching multiple substrings in a search text. This is achieved by -compiling the substrings into a finite state machine. - -This implementation provides optimal algorithmic time complexity. Construction -of the finite state machine is `O(p)` where `p` is the length of the substrings -concatenated. Matching against search text is `O(n + p + m)`, where `n` is -the length of the search text and `m` is the number of matches. +aho-corasick +============ +A library for finding occurrences of many patterns at once. This library +provides multiple pattern search principally through an implementation of the +[Aho-Corasick algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm), +which builds a fast finite state machine for executing searches in linear time. +Features include case insensitive matching, overlapping matches and search & +replace in streams. -[![Build status](https://api.travis-ci.org/BurntSushi/aho-corasick.png)](https://travis-ci.org/BurntSushi/aho-corasick) +[![Linux build status](https://api.travis-ci.org/BurntSushi/aho-corasick.svg)](https://travis-ci.org/BurntSushi/aho-corasick) +[![Windows build status](https://ci.appveyor.com/api/projects/status/github/BurntSushi/aho-corasick?svg=true)](https://ci.appveyor.com/project/BurntSushi/aho-corasick) [![](http://meritbadge.herokuapp.com/aho-corasick)](https://crates.io/crates/aho-corasick) Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org). @@ -17,39 +16,175 @@ ### Documentation -[https://docs.rs/aho-corasick/](https://docs.rs/aho-corasick/). +https://docs.rs/aho-corasick -### Example +### Usage -The documentation contains several examples, and there is a more complete -example as a full program in `examples/dict-search.rs`. +Add this to your `Cargo.toml`: -Here is a quick example showing simple substring matching: +```toml +[dependencies] +aho-corasick = "0.7" +``` + +and this to your crate root (if you're using Rust 2015): + +```rust +extern crate aho_corasick; +``` + + +### Example: basic searching + +This example shows how to search for occurrences of multiple patterns +simultaneously. Each match includes the pattern that matched along with the +byte offsets of the match. + +```rust +use aho_corasick::AhoCorasick; + +let patterns = &["apple", "maple", "Snapple"]; +let haystack = "Nobody likes maple in their apple flavored Snapple."; + +let ac = AhoCorasick::new(patterns); +let mut matches = vec![]; +for mat in ac.find_iter(haystack) { + matches.push((mat.pattern(), mat.start(), mat.end())); +} +assert_eq!(matches, vec![ + (1, 13, 18), + (0, 28, 33), + (2, 43, 50), +]); +``` + + +### Example: case insensitivity + +This is like the previous example, but matches `Snapple` case insensitively +using `AhoCorasickBuilder`: + +```rust +use aho_corasick::AhoCorasickBuilder; + +let patterns = &["apple", "maple", "snapple"]; +let haystack = "Nobody likes maple in their apple flavored Snapple."; + +let ac = AhoCorasickBuilder::new() + .ascii_case_insensitive(true) + .build(patterns); +let mut matches = vec![]; +for mat in ac.find_iter(haystack) { + matches.push((mat.pattern(), mat.start(), mat.end())); +} +assert_eq!(matches, vec![ + (1, 13, 18), + (0, 28, 33), + (2, 43, 50), +]); +``` + + +### Example: replacing matches in a stream + +This example shows how to execute a search and replace on a stream without +loading the entire stream into memory first. + +```rust +use aho_corasick::AhoCorasick; + +# fn example() -> Result<(), ::std::io::Error> { +let patterns = &["fox", "brown", "quick"]; +let replace_with = &["sloth", "grey", "slow"]; + +// In a real example, these might be `std::fs::File`s instead. All you need to +// do is supply a pair of `std::io::Read` and `std::io::Write` implementations. +let rdr = "The quick brown fox."; +let mut wtr = vec![]; + +let ac = AhoCorasick::new(patterns); +ac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)?; +assert_eq!(b"The slow grey sloth.".to_vec(), wtr); +# Ok(()) }; example().unwrap() +``` + + +### Example: finding the leftmost first match + +In the textbook description of Aho-Corasick, its formulation is typically +structured such that it reports all possible matches, even when they overlap +with another. In many cases, overlapping matches may not be desired, such as +the case of finding all successive non-overlapping matches like you might with +a standard regular expression. + +Unfortunately the "obvious" way to modify the Aho-Corasick algorithm to do +this doesn't always work in the expected way, since it will report matches as +soon as they are seen. For example, consider matching the regex `Samwise|Sam` +against the text `Samwise`. Most regex engines (that are Perl-like, or +non-POSIX) will report `Samwise` as a match, but the standard Aho-Corasick +algorithm modified for reporting non-overlapping matches will report `Sam`. + +A novel contribution of this library is the ability to change the match +semantics of Aho-Corasick (without additional search time overhead) such that +`Samwise` is reported instead. For example, here's the standard approach: ```rust -use aho_corasick::{Automaton, AcAutomaton, Match}; +use aho_corasick::AhoCorasick; + +let patterns = &["Samwise", "Sam"]; +let haystack = "Samwise"; -let aut = AcAutomaton::new(vec!["apple", "maple"]); -let mut it = aut.find("I like maple apples."); -assert_eq!(it.next(), Some(Match { - pati: 1, - start: 7, - end: 12, -})); -assert_eq!(it.next(), Some(Match { - pati: 0, - start: 13, - end: 18, -})); -assert_eq!(it.next(), None); +let ac = AhoCorasick::new(patterns); +let mat = ac.find(haystack).expect("should have a match"); +assert_eq!("Sam", &haystack[mat.start()..mat.end()]); ``` +And now here's the leftmost-first version, which matches how a Perl-like +regex will work: -### Alternatives +```rust +use aho_corasick::{AhoCorasickBuilder, MatchKind}; + +let patterns = &["Samwise", "Sam"]; +let haystack = "Samwise"; + +let ac = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostFirst) + .build(patterns); +let mat = ac.find(haystack).expect("should have a match"); +assert_eq!("Samwise", &haystack[mat.start()..mat.end()]); +``` -Aho-Corasick is useful for matching multiple substrings against many long -strings. If your long string is fixed, then you might consider building a -[suffix array](https://github.com/BurntSushi/suffix) -of the search text (which takes `O(n)` time). Matches can then be found in -`O(plogn)` time. +In addition to leftmost-first semantics, this library also supports +leftmost-longest semantics, which match the POSIX behavior of a regular +expression alternation. See `MatchKind` in the docs for more details. + + +### Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.24.1`. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. In general, it will follow the `regex` crate's +policy, since `regex` is an important dependent. + + +### Future work + +Here are some plans for the future: + +* Assuming the current API is sufficient, I'd like to commit to it and release + a `1.0` version of this crate some time in the next 6-12 months. +* Despite the crate's name, it seems prudent to consolidate all + multi-pattern search optimizations into this crate so that they get the + widest possible use. A good place to start will be to move the regex + crate's Teddy algorithm into this one. (This is more than just a move. It + will require fleshing out the somewhat simplistic `Prefilter` design that + exists internally currently.) In the future, it would be good to loot + Hyperscan for some of its pertinent algorithms, such as FDR. +* Support stream searching with leftmost match semantics. Currently, only + standard match semantics are supported. Getting this right seems possible, + but is tricky since the match state needs to be propagated through multiple + searches. (With standard semantics, as soon as a match is seen the search + ends.) diff -Nru cargo-0.33.0/vendor/aho-corasick/src/ahocorasick.rs cargo-0.35.0/vendor/aho-corasick/src/ahocorasick.rs --- cargo-0.33.0/vendor/aho-corasick/src/ahocorasick.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/ahocorasick.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2032 @@ +use std::io; + +use automaton::Automaton; +use buffer::Buffer; +use dfa::{self, DFA}; +use error::Result; +use nfa::{self, NFA}; +use prefilter::PrefilterState; +use state_id::StateID; +use Match; + +/// An automaton for searching multiple strings in linear time. +/// +/// The `AhoCorasick` type supports a few basic ways of constructing an +/// automaton, including +/// [`AhoCorasick::new`](struct.AhoCorasick.html#method.new) +/// and +/// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured). +/// However, there are a fair number of configurable options that can be set +/// by using +/// [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html) +/// instead. Such options include, but are not limited to, how matches are +/// determined, simple case insensitivity, whether to use a DFA or not and +/// various knobs for controlling the space-vs-time trade offs taken when +/// building the automaton. +/// +/// If you aren't sure where to start, try beginning with +/// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured). +/// +/// # Resource usage +/// +/// Aho-Corasick automatons are always constructed in `O(p)` time, where `p` +/// is the combined length of all patterns being searched. With that said, +/// building an automaton can be fairly costly because of high constant +/// factors, particularly when enabling the +/// [DFA](struct.AhoCorasickBuilder.html#method.dfa) +/// option (which is disabled by default). For this reason, it's generally a +/// good idea to build an automaton once and reuse it as much as possible. +/// +/// Aho-Corasick automatons can also use a fair bit of memory. To get a +/// concrete idea of how much memory is being used, try using the +/// [`AhoCorasick::heap_bytes`](struct.AhoCorasick.html#method.heap_bytes) +/// method. +/// +/// # Examples +/// +/// This example shows how to search for occurrences of multiple patterns +/// simultaneously in a case insensitive fashion. Each match includes the +/// pattern that matched along with the byte offsets of the match. +/// +/// ``` +/// use aho_corasick::AhoCorasickBuilder; +/// +/// let patterns = &["apple", "maple", "snapple"]; +/// let haystack = "Nobody likes maple in their apple flavored Snapple."; +/// +/// let ac = AhoCorasickBuilder::new() +/// .ascii_case_insensitive(true) +/// .build(patterns); +/// let mut matches = vec![]; +/// for mat in ac.find_iter(haystack) { +/// matches.push((mat.pattern(), mat.start(), mat.end())); +/// } +/// assert_eq!(matches, vec![ +/// (1, 13, 18), +/// (0, 28, 33), +/// (2, 43, 50), +/// ]); +/// ``` +/// +/// This example shows how to replace matches with some other string: +/// +/// ``` +/// use aho_corasick::AhoCorasick; +/// +/// let patterns = &["fox", "brown", "quick"]; +/// let haystack = "The quick brown fox."; +/// let replace_with = &["sloth", "grey", "slow"]; +/// +/// let ac = AhoCorasick::new(patterns); +/// let result = ac.replace_all(haystack, replace_with); +/// assert_eq!(result, "The slow grey sloth."); +/// ``` +#[derive(Clone, Debug)] +pub struct AhoCorasick { + imp: Imp, + match_kind: MatchKind, +} + +impl AhoCorasick { + /// Create a new Aho-Corasick automaton using the default configuration. + /// + /// The default configuration optimizes for less space usage, but at the + /// expense of longer search times. To change the configuration, use + /// [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html) + /// for fine-grained control, or + /// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured) + /// for automatic configuration if you aren't sure which settings to pick. + /// + /// This uses the default + /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard) + /// match semantics, which reports a match as soon as it is found. This + /// corresponds to the standard match semantics supported by textbook + /// descriptions of the Aho-Corasick algorithm. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new(&[ + /// "foo", "bar", "baz", + /// ]); + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// ``` + pub fn new( + patterns: I, + ) -> AhoCorasick + where I: IntoIterator, + P: AsRef<[u8]> + { + AhoCorasickBuilder::new().build(patterns) + } + + /// Build an Aho-Corasick automaton with an automatically determined + /// configuration. + /// + /// Specifically, this requires a slice of patterns instead of an iterator + /// since the configuration is determined by looking at the patterns before + /// constructing the automaton. The idea here is to balance space and time + /// automatically. That is, when searching a small number of patterns, this + /// will attempt to use the fastest possible configuration since the total + /// space required will be small anyway. As the number of patterns grows, + /// this will fall back to slower configurations that use less space. + /// + /// If you want auto configuration but with match semantics different from + /// the default `MatchKind::Standard`, then use + /// [`AhoCorasickBuilder::auto_configure`](struct.AhoCorasickBuilder.html#method.auto_configure). + /// + /// # Examples + /// + /// Basic usage is just like `new`, except you must provide a slice: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new_auto_configured(&[ + /// "foo", "bar", "baz", + /// ]); + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// ``` + pub fn new_auto_configured( + patterns: &[B], + ) -> AhoCorasick + where B: AsRef<[u8]> + { + AhoCorasickBuilder::new().auto_configure(patterns).build(patterns) + } +} + +impl AhoCorasick { + /// Returns true if and only if this automaton matches the haystack at any + /// position. + /// + /// `haystack` may be any type that is cheaply convertible to a `&[u8]`. + /// This includes, but is not limited to, `String`, `&str`, `Vec`, and + /// `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new(&[ + /// "foo", "bar", "quux", "baz", + /// ]); + /// assert!(ac.is_match("xxx bar xxx")); + /// assert!(!ac.is_match("xxx qux xxx")); + /// ``` + pub fn is_match>(&self, haystack: B) -> bool { + self.earliest_find(haystack).is_some() + } + + /// Returns the location of the first detected match in `haystack`. + /// + /// This method has the same behavior regardless of the + /// [`MatchKind`](enum.MatchKind.html) + /// of this automaton. + /// + /// `haystack` may be any type that is cheaply convertible to a `&[u8]`. + /// This includes, but is not limited to, `String`, `&str`, `Vec`, and + /// `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new(&[ + /// "abc", "b", + /// ]); + /// let mat = ac.earliest_find("abcd").expect("should have match"); + /// assert_eq!(1, mat.pattern()); + /// assert_eq!((1, 2), (mat.start(), mat.end())); + /// ``` + pub fn earliest_find>(&self, haystack: B) -> Option { + let mut prestate = PrefilterState::new(self.max_pattern_len()); + let mut start = self.imp.start_state(); + self.imp.earliest_find_at( + &mut prestate, haystack.as_ref(), 0, &mut start, + ) + } + + /// Returns the location of the first match according to the match + /// semantics that this automaton was constructed with. + /// + /// When using `MatchKind::Standard`, this corresponds precisely to the + /// same behavior as + /// [`earliest_find`](struct.AhoCorasick.html#method.earliest_find). + /// Otherwise, match semantics correspond to either + /// [leftmost-first](enum.MatchKind.html#variant.LeftmostFirst) + /// or + /// [leftmost-longest](enum.MatchKind.html#variant.LeftmostLongest). + /// + /// `haystack` may be any type that is cheaply convertible to a `&[u8]`. + /// This includes, but is not limited to, `String`, `&str`, `Vec`, and + /// `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage, with standard semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::Standard) // default, not necessary + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("b", &haystack[mat.start()..mat.end()]); + /// ``` + /// + /// Now with leftmost-first semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("abc", &haystack[mat.start()..mat.end()]); + /// ``` + /// + /// And finally, leftmost-longest semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostLongest) + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("abcd", &haystack[mat.start()..mat.end()]); + /// ``` + pub fn find>(&self, haystack: B) -> Option { + let mut prestate = PrefilterState::new(self.max_pattern_len()); + let mut start = self.imp.start_state(); + self.imp.find_at(&mut prestate, haystack.as_ref(), 0, &mut start) + } + + /// Returns an iterator of non-overlapping matches, using the match + /// semantics that this automaton was constructed with. + /// + /// `haystack` may be any type that is cheaply convertible to a `&[u8]`. + /// This includes, but is not limited to, `String`, `&str`, `Vec`, and + /// `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage, with standard semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::Standard) // default, not necessary + /// .build(patterns); + /// let matches: Vec = ac + /// .find_iter(haystack) + /// .map(|mat| mat.pattern()) + /// .collect(); + /// assert_eq!(vec![2, 2, 2], matches); + /// ``` + /// + /// Now with leftmost-first semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let matches: Vec = ac + /// .find_iter(haystack) + /// .map(|mat| mat.pattern()) + /// .collect(); + /// assert_eq!(vec![0, 2, 0], matches); + /// ``` + /// + /// And finally, leftmost-longest semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostLongest) + /// .build(patterns); + /// let matches: Vec = ac + /// .find_iter(haystack) + /// .map(|mat| mat.pattern()) + /// .collect(); + /// assert_eq!(vec![0, 2, 1], matches); + /// ``` + pub fn find_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>( + &'a self, + haystack: &'b B, + ) -> FindIter<'a, 'b, S> { + FindIter::new(self, haystack.as_ref()) + } + + /// Returns an iterator of overlapping matches in the given `haystack`. + /// + /// Overlapping matches can _only_ be detected using + /// `MatchKind::Standard` semantics. If this automaton was constructed with + /// leftmost semantics, then this method will panic. To determine whether + /// this will panic at runtime, use the + /// [`AhoCorasick::supports_overlapping`](struct.AhoCorasick.html#method.supports_overlapping) + /// method. + /// + /// `haystack` may be any type that is cheaply convertible to a `&[u8]`. + /// This includes, but is not limited to, `String`, `&str`, `Vec`, and + /// `&[u8]` itself. + /// + /// # Panics + /// + /// This panics when `AhoCorasick::supports_overlapping` returns `false`. + /// That is, this panics when this automaton's match semantics are not + /// `MatchKind::Standard`. + /// + /// # Examples + /// + /// Basic usage, with standard semantics: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasick::new(patterns); + /// let matches: Vec = ac + /// .find_overlapping_iter(haystack) + /// .map(|mat| mat.pattern()) + /// .collect(); + /// assert_eq!(vec![2, 0, 2, 2, 0, 1], matches); + /// ``` + pub fn find_overlapping_iter<'a, 'b, B: ?Sized + AsRef<[u8]>>( + &'a self, + haystack: &'b B, + ) -> FindOverlappingIter<'a, 'b, S> { + FindOverlappingIter::new(self, haystack.as_ref()) + } + + /// Replace all matches with a corresponding value in the `replace_with` + /// slice given. Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// Replacements are determined by the index of the matching pattern. + /// For example, if the pattern with index `2` is found, then it is + /// replaced by `replace_with[2]`. + /// + /// # Panics + /// + /// This panics when `replace_with.len()` does not equal the total number + /// of patterns that are matched by this automaton. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let result = ac.replace_all(haystack, &["x", "y", "z"]); + /// assert_eq!("x the z to the xage", result); + /// ``` + pub fn replace_all( + &self, + haystack: &str, + replace_with: &[B], + ) -> String + where B: AsRef + { + assert_eq!( + replace_with.len(), self.pattern_count(), + "replace_all requires a replacement for every pattern \ + in the automaton" + ); + let mut dst = String::with_capacity(haystack.len()); + self.replace_all_with(haystack, &mut dst, |mat, _, dst| { + dst.push_str(replace_with[mat.pattern()].as_ref()); + true + }); + dst + } + + /// Replace all matches using raw bytes with a corresponding value in the + /// `replace_with` slice given. Matches correspond to the same matches as + /// reported by [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// Replacements are determined by the index of the matching pattern. + /// For example, if the pattern with index `2` is found, then it is + /// replaced by `replace_with[2]`. + /// + /// # Panics + /// + /// This panics when `replace_with.len()` does not equal the total number + /// of patterns that are matched by this automaton. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = b"append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let result = ac.replace_all_bytes(haystack, &["x", "y", "z"]); + /// assert_eq!(b"x the z to the xage".to_vec(), result); + /// ``` + pub fn replace_all_bytes( + &self, + haystack: &[u8], + replace_with: &[B], + ) -> Vec + where B: AsRef<[u8]> + { + assert_eq!( + replace_with.len(), self.pattern_count(), + "replace_all_bytes requires a replacement for every pattern \ + in the automaton" + ); + let mut dst = Vec::with_capacity(haystack.len()); + self.replace_all_with_bytes(haystack, &mut dst, |mat, _, dst| { + dst.extend(replace_with[mat.pattern()].as_ref()); + true + }); + dst + } + + /// Replace all matches using a closure called on each match. + /// Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// The closure accepts three parameters: the match found, the text of + /// the match and a string buffer with which to write the replaced text + /// (if any). If the closure returns `true`, then it continues to the next + /// match. If the closure returns false, then searching is stopped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let mut result = String::new(); + /// ac.replace_all_with(haystack, &mut result, |mat, _, dst| { + /// dst.push_str(&mat.pattern().to_string()); + /// true + /// }); + /// assert_eq!("0 the 2 to the 0age", result); + /// ``` + pub fn replace_all_with( + &self, + haystack: &str, + dst: &mut String, + mut replace_with: F, + ) where F: FnMut(&Match, &str, &mut String) -> bool + { + let mut last_match = 0; + for mat in self.find_iter(haystack) { + dst.push_str(&haystack[last_match..mat.start()]); + last_match = mat.end(); + replace_with(&mat, &haystack[mat.start()..mat.end()], dst); + } + dst.push_str(&haystack[last_match..]); + } + + /// Replace all matches using raw bytes with a closure called on each + /// match. Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// The closure accepts three parameters: the match found, the text of + /// the match and a byte buffer with which to write the replaced text + /// (if any). If the closure returns `true`, then it continues to the next + /// match. If the closure returns false, then searching is stopped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = b"append the app to the appendage"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let mut result = vec![]; + /// ac.replace_all_with_bytes(haystack, &mut result, |mat, _, dst| { + /// dst.extend(mat.pattern().to_string().bytes()); + /// true + /// }); + /// assert_eq!(b"0 the 2 to the 0age".to_vec(), result); + /// ``` + pub fn replace_all_with_bytes( + &self, + haystack: &[u8], + dst: &mut Vec, + mut replace_with: F, + ) where F: FnMut(&Match, &[u8], &mut Vec) -> bool + { + let mut last_match = 0; + for mat in self.find_iter(haystack) { + dst.extend(&haystack[last_match..mat.start()]); + last_match = mat.end(); + replace_with(&mat, &haystack[mat.start()..mat.end()], dst); + } + dst.extend(&haystack[last_match..]); + } + + /// Returns an iterator of non-overlapping matches in the given + /// stream. Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// The matches yielded by this iterator use absolute position offsets in + /// the stream given, where the first byte has index `0`. Matches are + /// yieled until the stream is exhausted. + /// + /// Each item yielded by the iterator is an `io::Result`, where an + /// error is yielded if there was a problem reading from the reader given. + /// + /// When searching a stream, an internal buffer is used. Therefore, callers + /// should avoiding providing a buffered reader, if possible. + /// + /// Searching a stream requires that the automaton was built with + /// `MatchKind::Standard` semantics. If this automaton was constructed + /// with leftmost semantics, then this method will panic. To determine + /// whether this will panic at runtime, use the + /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream) + /// method. + /// + /// # Memory usage + /// + /// In general, searching streams will use a constant amount of memory for + /// its internal buffer. The one requirement is that the internal buffer + /// must be at least the size of the longest possible match. In most use + /// cases, the default buffer size will be much larger than any individual + /// match. + /// + /// # Panics + /// + /// This panics when `AhoCorasick::supports_stream` returns `false`. + /// That is, this panics when this automaton's match semantics are not + /// `MatchKind::Standard`. This restriction may be lifted in the future. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// # fn example() -> Result<(), ::std::io::Error> { + /// let patterns = &["append", "appendage", "app"]; + /// let haystack = "append the app to the appendage"; + /// + /// let ac = AhoCorasick::new(patterns); + /// let mut matches = vec![]; + /// for result in ac.stream_find_iter(haystack.as_bytes()) { + /// let mat = result?; + /// matches.push(mat.pattern()); + /// } + /// assert_eq!(vec![2, 2, 2], matches); + /// # Ok(()) }; example().unwrap() + /// ``` + pub fn stream_find_iter<'a, R: io::Read>( + &'a self, + rdr: R, + ) -> StreamFindIter<'a, R, S> { + StreamFindIter::new(self, rdr) + } + + /// Search for and replace all matches of this automaton in + /// the given reader, and write the replacements to the given + /// writer. Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// Replacements are determined by the index of the matching pattern. + /// For example, if the pattern with index `2` is found, then it is + /// replaced by `replace_with[2]`. + /// + /// After all matches are replaced, the writer is _not_ flushed. + /// + /// If there was a problem reading from the given reader or writing to the + /// given writer, then the corresponding `io::Error` is returned and all + /// replacement is stopped. + /// + /// When searching a stream, an internal buffer is used. Therefore, callers + /// should avoiding providing a buffered reader, if possible. However, + /// callers may want to provide a buffered writer. + /// + /// Searching a stream requires that the automaton was built with + /// `MatchKind::Standard` semantics. If this automaton was constructed + /// with leftmost semantics, then this method will panic. To determine + /// whether this will panic at runtime, use the + /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream) + /// method. + /// + /// # Memory usage + /// + /// In general, searching streams will use a constant amount of memory for + /// its internal buffer. The one requirement is that the internal buffer + /// must be at least the size of the longest possible match. In most use + /// cases, the default buffer size will be much larger than any individual + /// match. + /// + /// # Panics + /// + /// This panics when `AhoCorasick::supports_stream` returns `false`. + /// That is, this panics when this automaton's match semantics are not + /// `MatchKind::Standard`. This restriction may be lifted in the future. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// # fn example() -> Result<(), ::std::io::Error> { + /// let patterns = &["fox", "brown", "quick"]; + /// let haystack = "The quick brown fox."; + /// let replace_with = &["sloth", "grey", "slow"]; + /// + /// let ac = AhoCorasick::new(patterns); + /// let mut result = vec![]; + /// ac.stream_replace_all(haystack.as_bytes(), &mut result, replace_with)?; + /// assert_eq!(b"The slow grey sloth.".to_vec(), result); + /// # Ok(()) }; example().unwrap() + /// ``` + pub fn stream_replace_all( + &self, + rdr: R, + wtr: W, + replace_with: &[B], + ) -> io::Result<()> + where R: io::Read, + W: io::Write, + B: AsRef<[u8]> + { + assert_eq!( + replace_with.len(), self.pattern_count(), + "stream_replace_all requires a replacement for every pattern \ + in the automaton" + ); + self.stream_replace_all_with(rdr, wtr, |mat, _, wtr| { + wtr.write_all(replace_with[mat.pattern()].as_ref()) + }) + } + + /// Search the given reader and replace all matches of this automaton + /// using the given closure. The result is written to the given + /// writer. Matches correspond to the same matches as reported by + /// [`find_iter`](struct.AhoCorasick.html#method.find_iter). + /// + /// The closure accepts three parameters: the match found, the text of + /// the match and the writer with which to write the replaced text + /// (if any). If the closure returns `true`, then it continues to the next + /// match. If the closure returns false, then searching is stopped. + /// + /// After all matches are replaced, the writer is _not_ flushed. + /// + /// If there was a problem reading from the given reader or writing to the + /// given writer, then the corresponding `io::Error` is returned and all + /// replacement is stopped. + /// + /// When searching a stream, an internal buffer is used. Therefore, callers + /// should avoiding providing a buffered reader, if possible. However, + /// callers may want to provide a buffered writer. + /// + /// Searching a stream requires that the automaton was built with + /// `MatchKind::Standard` semantics. If this automaton was constructed + /// with leftmost semantics, then this method will panic. To determine + /// whether this will panic at runtime, use the + /// [`AhoCorasick::supports_stream`](struct.AhoCorasick.html#method.supports_stream) + /// method. + /// + /// # Memory usage + /// + /// In general, searching streams will use a constant amount of memory for + /// its internal buffer. The one requirement is that the internal buffer + /// must be at least the size of the longest possible match. In most use + /// cases, the default buffer size will be much larger than any individual + /// match. + /// + /// # Panics + /// + /// This panics when `AhoCorasick::supports_stream` returns `false`. + /// That is, this panics when this automaton's match semantics are not + /// `MatchKind::Standard`. This restriction may be lifted in the future. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::io::Write; + /// use aho_corasick::AhoCorasick; + /// + /// # fn example() -> Result<(), ::std::io::Error> { + /// let patterns = &["fox", "brown", "quick"]; + /// let haystack = "The quick brown fox."; + /// + /// let ac = AhoCorasick::new(patterns); + /// let mut result = vec![]; + /// ac.stream_replace_all_with( + /// haystack.as_bytes(), + /// &mut result, + /// |mat, _, wtr| { + /// wtr.write_all(mat.pattern().to_string().as_bytes()) + /// }, + /// )?; + /// assert_eq!(b"The 2 1 0.".to_vec(), result); + /// # Ok(()) }; example().unwrap() + /// ``` + pub fn stream_replace_all_with( + &self, + rdr: R, + mut wtr: W, + mut replace_with: F, + ) -> io::Result<()> + where R: io::Read, + W: io::Write, + F: FnMut(&Match, &[u8], &mut W) -> io::Result<()> + { + let mut it = StreamChunkIter::new(self, rdr); + while let Some(result) = it.next() { + let chunk = result?; + match chunk { + StreamChunk::NonMatch { bytes, .. } => { + wtr.write_all(bytes)?; + } + StreamChunk::Match { bytes, mat } => { + replace_with(&mat, bytes, &mut wtr)?; + } + } + } + Ok(()) + } + + /// Returns the match kind used by this automaton. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasick, MatchKind}; + /// + /// let ac = AhoCorasick::new(&[ + /// "foo", "bar", "quux", "baz", + /// ]); + /// assert_eq!(&MatchKind::Standard, ac.match_kind()); + /// ``` + pub fn match_kind(&self) -> &MatchKind { + self.imp.match_kind() + } + + /// Returns the length of the longest pattern matched by this automaton. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new(&[ + /// "foo", "bar", "quux", "baz", + /// ]); + /// assert_eq!(4, ac.max_pattern_len()); + /// ``` + pub fn max_pattern_len(&self) -> usize { + self.imp.max_pattern_len() + } + + /// Return the total number of patterns matched by this automaton. + /// + /// This includes patterns that may never participate in a match. For + /// example, if + /// [`MatchKind::LeftmostFirst`](enum.MatchKind.html#variant.LeftmostFirst) + /// match semantics are used, and the patterns `Sam` and `Samwise` were + /// used to build the automaton, then `Samwise` can never participate in a + /// match because `Sam` will always take priority. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasick; + /// + /// let ac = AhoCorasick::new(&[ + /// "foo", "bar", "baz", + /// ]); + /// assert_eq!(3, ac.pattern_count()); + /// ``` + pub fn pattern_count(&self) -> usize { + self.imp.pattern_count() + } + + /// Returns true if and only if this automaton supports reporting + /// overlapping matches. + /// + /// If this returns false and overlapping matches are requested, then it + /// will result in a panic. + /// + /// Since leftmost matching is inherently incompatible with overlapping + /// matches, only + /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard) + /// supports overlapping matches. This is unlikely to change in the future. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::Standard) + /// .build(&["foo", "bar", "baz"]); + /// assert!(ac.supports_overlapping()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(&["foo", "bar", "baz"]); + /// assert!(!ac.supports_overlapping()); + /// ``` + pub fn supports_overlapping(&self) -> bool { + self.match_kind.supports_overlapping() + } + + /// Returns true if and only if this automaton supports stream searching. + /// + /// If this returns false and stream searching (or replacing) is attempted, + /// then it will result in a panic. + /// + /// Currently, only + /// [`MatchKind::Standard`](enum.MatchKind.html#variant.Standard) + /// supports streaming. This may be expanded in the future. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::Standard) + /// .build(&["foo", "bar", "baz"]); + /// assert!(ac.supports_stream()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(&["foo", "bar", "baz"]); + /// assert!(!ac.supports_stream()); + /// ``` + pub fn supports_stream(&self) -> bool { + self.match_kind.supports_stream() + } + + /// Returns the total amount of heap used by this automaton, in units of + /// bytes. + /// + /// # Examples + /// + /// This example shows the difference in heap usage between a few + /// configurations: + /// + /// ```ignore + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let ac = AhoCorasickBuilder::new() + /// .dfa(false) // default + /// .build(&["foo", "bar", "baz"]); + /// assert_eq!(10_336, ac.heap_bytes()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .dfa(false) // default + /// .ascii_case_insensitive(true) + /// .build(&["foo", "bar", "baz"]); + /// assert_eq!(10_384, ac.heap_bytes()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .dfa(true) + /// .byte_classes(false) + /// .build(&["foo", "bar", "baz"]); + /// assert_eq!(20_768, ac.heap_bytes()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .dfa(true) + /// .byte_classes(true) // default + /// .build(&["foo", "bar", "baz"]); + /// assert_eq!(1_248, ac.heap_bytes()); + /// + /// let ac = AhoCorasickBuilder::new() + /// .dfa(true) + /// .ascii_case_insensitive(true) + /// .build(&["foo", "bar", "baz"]); + /// assert_eq!(1_248, ac.heap_bytes()); + /// ``` + pub fn heap_bytes(&self) -> usize { + match self.imp { + Imp::NFA(ref nfa) => nfa.heap_bytes(), + Imp::DFA(ref dfa) => dfa.heap_bytes(), + } + } +} + +/// The internal implementation of Aho-Corasick, which is either an NFA or +/// a DFA. The NFA is slower but uses less memory. The DFA is faster but uses +/// more memory. +#[derive(Clone, Debug)] +enum Imp { + NFA(NFA), + DFA(DFA), +} + +impl Imp { + /// Returns the type of match semantics implemented by this automaton. + fn match_kind(&self) -> &MatchKind { + match *self { + Imp::NFA(ref nfa) => nfa.match_kind(), + Imp::DFA(ref dfa) => dfa.match_kind(), + } + } + + /// Returns the identifier of the start state. + fn start_state(&self) -> S { + match *self { + Imp::NFA(ref nfa) => nfa.start_state(), + Imp::DFA(ref dfa) => dfa.start_state(), + } + } + + /// The length, in bytes, of the longest pattern in this automaton. This + /// information is useful for maintaining correct buffer sizes when + /// searching on streams. + fn max_pattern_len(&self) -> usize { + match *self { + Imp::NFA(ref nfa) => nfa.max_pattern_len(), + Imp::DFA(ref dfa) => dfa.max_pattern_len(), + } + } + + /// The total number of patterns added to this automaton. This includes + /// patterns that may never match. The maximum matching pattern that can be + /// reported is exactly one less than this number. + fn pattern_count(&self) -> usize { + match *self { + Imp::NFA(ref nfa) => nfa.pattern_count(), + Imp::DFA(ref dfa) => dfa.pattern_count(), + } + } + + #[inline(always)] + fn overlapping_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + match_index: &mut usize, + ) -> Option { + match *self { + Imp::NFA(ref nfa) => { + nfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + Imp::DFA(ref dfa) => { + dfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + } + } + + #[inline(always)] + fn earliest_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + ) -> Option { + match *self { + Imp::NFA(ref nfa) => { + nfa.earliest_find_at(prestate, haystack, at, state_id) + } + Imp::DFA(ref dfa) => { + dfa.earliest_find_at(prestate, haystack, at, state_id) + } + } + } + + #[inline(always)] + fn find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + ) -> Option { + match *self { + Imp::NFA(ref nfa) => { + nfa.find_at(prestate, haystack, at, state_id) + } + Imp::DFA(ref dfa) => { + dfa.find_at(prestate, haystack, at, state_id) + } + } + } +} + +/// An iterator of non-overlapping matches in a particular haystack. +/// +/// This iterator yields matches according to the +/// [`MatchKind`](enum.MatchKind.html) +/// used by this automaton. +/// +/// This iterator is constructed via the +/// [`AhoCorasick::find_iter`](struct.AhoCorasick.html#method.find_iter) +/// method. +/// +/// The type variable `S` refers to the representation used for state +/// identifiers. (By default, this is `usize`.) +/// +/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton. +/// +/// The lifetime `'b` refers to the lifetime of the haystack being searched. +#[derive(Debug)] +pub struct FindIter<'a, 'b, S: 'a + StateID> { + fsm: &'a Imp, + prestate: PrefilterState, + haystack: &'b [u8], + pos: usize, + start: S, +} + +impl<'a, 'b, S: StateID> FindIter<'a, 'b, S> { + fn new(ac: &'a AhoCorasick, haystack: &'b [u8]) -> FindIter<'a, 'b, S> { + let prestate = PrefilterState::new(ac.max_pattern_len()); + let start = ac.imp.start_state(); + FindIter { fsm: &ac.imp, prestate, haystack, pos: 0, start } + } +} + +impl<'a, 'b, S: StateID> Iterator for FindIter<'a, 'b, S> { + type Item = Match; + + fn next(&mut self) -> Option { + if self.pos > self.haystack.len() { + return None; + } + let mut start = self.start; + let result = self.fsm.find_at( + &mut self.prestate, self.haystack, self.pos, &mut start, + ); + let mat = match result { + None => return None, + Some(mat) => mat, + }; + if mat.end() == self.pos { + // If the automaton can match the empty string and if we found an + // empty match, then we need to forcefully move the position. + self.pos += 1; + } else { + self.pos = mat.end(); + } + Some(mat) + } +} + +/// An iterator of overlapping matches in a particular haystack. +/// +/// This iterator will report all possible matches in a particular haystack, +/// even when the matches overlap. +/// +/// This iterator is constructed via the +/// [`AhoCorasick::find_overlapping_iter`](struct.AhoCorasick.html#method.find_overlapping_iter) +/// method. +/// +/// The type variable `S` refers to the representation used for state +/// identifiers. (By default, this is `usize`.) +/// +/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton. +/// +/// The lifetime `'b` refers to the lifetime of the haystack being searched. +#[derive(Debug)] +pub struct FindOverlappingIter<'a, 'b, S: 'a + StateID> { + fsm: &'a Imp, + prestate: PrefilterState, + haystack: &'b [u8], + pos: usize, + last_match_end: usize, + state_id: S, + match_index: usize, +} + +impl<'a, 'b, S: StateID> FindOverlappingIter<'a, 'b, S> { + fn new( + ac: &'a AhoCorasick, + haystack: &'b [u8], + ) -> FindOverlappingIter<'a, 'b, S> { + assert!( + ac.supports_overlapping(), + "automaton does not support overlapping searches" + ); + let prestate = PrefilterState::new(ac.max_pattern_len()); + FindOverlappingIter { + fsm: &ac.imp, + prestate, + haystack, + pos: 0, + last_match_end: 0, + state_id: ac.imp.start_state(), + match_index: 0, + } + } +} + +impl<'a, 'b, S: StateID> Iterator for FindOverlappingIter<'a, 'b, S> { + type Item = Match; + + fn next(&mut self) -> Option { + let result = self.fsm.overlapping_find_at( + &mut self.prestate, + self.haystack, + self.pos, + &mut self.state_id, + &mut self.match_index, + ); + match result { + None => return None, + Some(m) => { + self.pos = m.end(); + Some(m) + } + } + } +} + +/// An iterator that reports Aho-Corasick matches in a stream. +/// +/// This iterator yields elements of type `io::Result`, where an error +/// is reported if there was a problem reading from the underlying stream. +/// The iterator terminates only when the underlying stream reaches `EOF`. +/// +/// This iterator is constructed via the +/// [`AhoCorasick::stream_find_iter`](struct.AhoCorasick.html#method.stream_find_iter) +/// method. +/// +/// The type variable `R` refers to the `io::Read` stream that is being read +/// from. +/// +/// The type variable `S` refers to the representation used for state +/// identifiers. (By default, this is `usize`.) +/// +/// The lifetime `'a` refers to the lifetime of the `AhoCorasick` automaton. +#[derive(Debug)] +pub struct StreamFindIter<'a, R, S: 'a + StateID> { + it: StreamChunkIter<'a, R, S>, +} + +impl<'a, R: io::Read, S: StateID> StreamFindIter<'a, R, S> { + fn new(ac: &'a AhoCorasick, rdr: R) -> StreamFindIter<'a, R, S> { + StreamFindIter { + it: StreamChunkIter::new(ac, rdr), + } + } +} + +impl<'a, R: io::Read, S: StateID> Iterator for StreamFindIter<'a, R, S> { + type Item = io::Result; + + fn next(&mut self) -> Option> { + loop { + match self.it.next() { + None => return None, + Some(Err(err)) => return Some(Err(err)), + Some(Ok(StreamChunk::NonMatch { .. })) => {} + Some(Ok(StreamChunk::Match { mat, .. })) => { + return Some(Ok(mat)); + } + } + } + } +} + +/// An iterator over chunks in an underlying reader. Each chunk either +/// corresponds to non-matching bytes or matching bytes, but all bytes from +/// the underlying reader are reported in sequence. There may be an arbitrary +/// number of non-matching chunks before seeing a matching chunk. +/// +/// N.B. This does not actually implement Iterator because we need to borrow +/// from the underlying reader. But conceptually, it's still an iterator. +#[derive(Debug)] +struct StreamChunkIter<'a, R, S: 'a + StateID> { + /// The AC automaton. + fsm: &'a Imp, + /// State associated with this automaton's prefilter. It is a heuristic + /// for stopping the prefilter if it's deemed ineffective. + prestate: PrefilterState, + /// The source of bytes we read from. + rdr: R, + /// A fixed size buffer. This is what we actually search. There are some + /// invariants around the buffer's size, namely, it must be big enough to + /// contain the longest possible match. + buf: Buffer, + /// The ID of the FSM state we're currently in. + state_id: S, + /// The current position at which to start the next search in `buf`. + search_pos: usize, + /// The absolute position of `search_pos`, where `0` corresponds to the + /// position of the first byte read from `rdr`. + absolute_pos: usize, + /// The ending position of the last StreamChunk that was returned to the + /// caller. This position is used to determine whether we need to emit + /// non-matching bytes before emitting a match. + report_pos: usize, + /// A match that should be reported on the next call. + pending_match: Option, + /// Enabled only when the automaton can match the empty string. When + /// enabled, we need to execute one final search after consuming the + /// reader to find the trailing empty match. + has_empty_match_at_end: bool, +} + +/// A single chunk yielded by the stream chunk iterator. +/// +/// The `'r` lifetime refers to the lifetime of the stream chunk iterator. +#[derive(Debug)] +enum StreamChunk<'r> { + /// A chunk that does not contain any matches. + NonMatch { bytes: &'r [u8], start: usize }, + /// A chunk that precisely contains a match. + Match { bytes: &'r [u8], mat: Match }, +} + +impl<'a, R: io::Read, S: StateID> StreamChunkIter<'a, R, S> { + fn new(ac: &'a AhoCorasick, rdr: R) -> StreamChunkIter<'a, R, S> { + assert!( + ac.supports_stream(), + "stream searching is only supported for Standard match semantics" + ); + + let prestate = PrefilterState::new(ac.max_pattern_len()); + let buf = Buffer::new(ac.imp.max_pattern_len()); + let state_id = ac.imp.start_state(); + StreamChunkIter { + fsm: &ac.imp, + prestate, + rdr, + buf, + state_id, + absolute_pos: 0, + report_pos: 0, + search_pos: 0, + pending_match: None, + has_empty_match_at_end: ac.is_match(""), + } + } + + fn next<'r>(&'r mut self) -> Option>> { + loop { + if let Some(mut mat) = self.pending_match.take() { + let bytes = &self.buf.buffer()[mat.start()..mat.end()]; + self.report_pos = mat.end(); + mat = mat.increment(self.absolute_pos); + return Some(Ok(StreamChunk::Match { bytes, mat })); + } + if self.search_pos >= self.buf.len() { + if let Some(end) = self.unreported() { + let bytes = &self.buf.buffer()[self.report_pos..end]; + let start = self.absolute_pos + self.report_pos; + self.report_pos = end; + return Some(Ok(StreamChunk::NonMatch { bytes, start })); + } + if self.buf.len() >= self.buf.min_buffer_len() { + // This is the point at which we roll our buffer, which we + // only do if our buffer has at least the minimum amount of + // bytes in it. Before rolling, we update our various + // positions to be consistent with the buffer after it has + // been rolled. + + self.report_pos -= + self.buf.len() - self.buf.min_buffer_len(); + self.absolute_pos += + self.search_pos - self.buf.min_buffer_len(); + self.search_pos = self.buf.min_buffer_len(); + self.buf.roll(); + } + match self.buf.fill(&mut self.rdr) { + Err(err) => return Some(Err(err)), + Ok(false) => { + // We've hit EOF, but if there are still some + // unreported bytes remaining, return them now. + if self.report_pos < self.buf.len() { + let bytes = &self.buf.buffer()[self.report_pos..]; + let start = self.absolute_pos + self.report_pos; + self.report_pos = self.buf.len(); + + let chunk = StreamChunk::NonMatch { bytes, start }; + return Some(Ok(chunk)); + } else { + // We've reported everything, but there might still + // be a match at the very last position. + if !self.has_empty_match_at_end { + return None; + } + // fallthrough for another search to get trailing + // empty matches + self.has_empty_match_at_end = false; + } + } + Ok(true) => {} + } + } + let result = self.fsm.earliest_find_at( + &mut self.prestate, + self.buf.buffer(), + self.search_pos, + &mut self.state_id, + ); + match result { + None => { + self.search_pos = self.buf.len(); + } + Some(mat) => { + self.state_id = self.fsm.start_state(); + if mat.end() == self.search_pos { + // If the automaton can match the empty string and if + // we found an empty match, then we need to forcefully + // move the position. + self.search_pos += 1; + } else { + self.search_pos = mat.end(); + } + self.pending_match = Some(mat.clone()); + if self.report_pos < mat.start() { + let bytes = + &self.buf.buffer()[self.report_pos..mat.start()]; + let start = self.absolute_pos + self.report_pos; + self.report_pos = mat.start(); + + let chunk = StreamChunk::NonMatch { bytes, start }; + return Some(Ok(chunk)); + } + } + } + } + } + + fn unreported(&self) -> Option { + let end = self.search_pos.saturating_sub(self.buf.min_buffer_len()); + if self.report_pos < end { + Some(end) + } else { + None + } + } +} + +/// A builder for configuring an Aho-Corasick automaton. +#[derive(Clone, Debug)] +pub struct AhoCorasickBuilder { + nfa_builder: nfa::Builder, + dfa_builder: dfa::Builder, + dfa: bool, +} + +impl Default for AhoCorasickBuilder { + fn default() -> AhoCorasickBuilder { + AhoCorasickBuilder::new() + } +} + +impl AhoCorasickBuilder { + /// Create a new builder for configuring an Aho-Corasick automaton. + /// + /// If you don't need fine grained configuration or aren't sure which knobs + /// to set, try using + /// [`AhoCorasick::new_auto_configured`](struct.AhoCorasick.html#method.new_auto_configured) + /// instead. + pub fn new() -> AhoCorasickBuilder { + AhoCorasickBuilder { + nfa_builder: nfa::Builder::new(), + dfa_builder: dfa::Builder::new(), + dfa: false, + } + } + + /// Build an Aho-Corasick automaton using the configuration set on this + /// builder. + /// + /// A builder may be reused to create more automatons. + /// + /// This method will use the default for representing internal state + /// identifiers, which is `usize`. This guarantees that building the + /// automaton will succeed and is generally a good default, but can make + /// the size of the automaton 2-8 times bigger than it needs to be, + /// depending on your target platform. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasickBuilder; + /// + /// let patterns = &["foo", "bar", "baz"]; + /// let ac = AhoCorasickBuilder::new() + /// .build(patterns); + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// ``` + pub fn build( + &self, + patterns: I, + ) -> AhoCorasick + where I: IntoIterator, + P: AsRef<[u8]> + { + // The builder only returns an error if the chosen state ID + // representation is too small to fit all of the given patterns. In + // this case, since we fix the representation to usize, it will always + // work because it's impossible to overflow usize since the underlying + // storage would OOM long before that happens. + self.build_with_size::(patterns) + .expect("usize state ID type should always work") + } + + /// Build an Aho-Corasick automaton using the configuration set on this + /// builder with a specific state identifier representation. This only has + /// an effect when the `dfa` option is enabled. + /// + /// Generally, the choices for a state identifier representation are + /// `u8`, `u16`, `u32`, `u64` or `usize`, with `usize` being the default. + /// The advantage of choosing a smaller state identifier representation + /// is that the automaton produced will be smaller. This might be + /// beneficial for just generally using less space, or might even allow it + /// to fit more of the automaton in your CPU's cache, leading to overall + /// better search performance. + /// + /// Unlike the standard `build` method, this can report an error if the + /// state identifier representation cannot support the size of the + /// automaton. + /// + /// Note that the state identifier representation is determined by the + /// `S` type variable. This requires a type hint of some sort, either + /// by specifying the return type or using the turbofish, e.g., + /// `build_with_size::(...)`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; + /// + /// # fn example() -> Result<(), ::aho_corasick::Error> { + /// let patterns = &["foo", "bar", "baz"]; + /// let ac: AhoCorasick = AhoCorasickBuilder::new() + /// .build_with_size(patterns)?; + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// # Ok(()) }; example().unwrap() + /// ``` + /// + /// Or alternatively, with turbofish: + /// + /// ``` + /// use aho_corasick::AhoCorasickBuilder; + /// + /// # fn example() -> Result<(), ::aho_corasick::Error> { + /// let patterns = &["foo", "bar", "baz"]; + /// let ac = AhoCorasickBuilder::new() + /// .build_with_size::(patterns)?; + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// # Ok(()) }; example().unwrap() + /// ``` + pub fn build_with_size( + &self, + patterns: I, + ) -> Result> + where S: StateID, + I: IntoIterator, + P: AsRef<[u8]> + { + let nfa = self.nfa_builder.build(patterns)?; + let match_kind = nfa.match_kind().clone(); + let imp = + if self.dfa { + let dfa = self.dfa_builder.build(&nfa)?; + Imp::DFA(dfa) + } else { + Imp::NFA(nfa) + }; + Ok(AhoCorasick { imp, match_kind }) + } + + /// Automatically configure the settings on this builder according to the + /// patterns that will be used to construct the automaton. + /// + /// The idea here is to balance space and time automatically. That is, when + /// searching a small number of patterns, this will attempt to use the + /// fastest possible configuration since the total space required will be + /// small anyway. As the number of patterns grows, this will fall back to + /// slower configurations that use less space. + /// + /// This is guaranteed to never set `match_kind`, but any other option may + /// be overridden. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasickBuilder; + /// + /// let patterns = &["foo", "bar", "baz"]; + /// let ac = AhoCorasickBuilder::new() + /// .auto_configure(patterns) + /// .build(patterns); + /// assert_eq!(Some(1), ac.find("xxx bar xxx").map(|m| m.pattern())); + /// ``` + pub fn auto_configure>( + &mut self, + patterns: &[B], + ) -> &mut AhoCorasickBuilder { + // N.B. Currently we only use the length of `patterns` to make a + // decision here, and could therefore ask for an `ExactSizeIterator` + // instead. But it's conceivable that we might adapt this to look at + // the total number of bytes, which would requires a second pass. + // + // The logic here is fairly rudimentary at the moment, but probably + // OK. The idea here is to use the fastest thing possible for a small + // number of patterns. That is, a DFA with no byte classes, since byte + // classes require an extra indirection for every byte searched. With a + // moderate number of patterns, we still want a DFA, but save on both + // space and compilation time by enabling byte classes. Finally, fall + // back to the slower but smaller NFA. + if patterns.len() <= 100 { + // N.B. Using byte classes can actually be faster by improving + // locality, but this only really applies for multi-megabyte + // automata (i.e., automata that don't fit in your CPU's cache). + self.dfa(true).byte_classes(false); + } else if patterns.len() <= 5000 { + self.dfa(true); + } + self + } + + /// Set the desired match semantics. + /// + /// The default is `MatchKind::Standard`, which corresponds to the match + /// semantics supported by the standard textbook description of the + /// Aho-Corasick algorithm. Namely, matches are reported as soon as they + /// are found. Moreover, this is the only way to get overlapping matches + /// or do stream searching. + /// + /// The other kinds of match semantics that are supported are + /// `MatchKind::LeftmostFirst` and `MatchKind::LeftmostLongest`. The former + /// corresponds to the match you would get if you were to try to match + /// each pattern at each position in the haystack in the same order that + /// you give to the automaton. That is, it returns the leftmost match + /// corresponding the earliest pattern given to the automaton. The latter + /// corresponds to finding the longest possible match among all leftmost + /// matches. + /// + /// For more details on match semantics, see the + /// [documentation for `MatchKind`](enum.MatchKind.html). + /// + /// # Examples + /// + /// In these examples, we demonstrate the differences between match + /// semantics for a particular set of patterns in a specific order: + /// `b`, `abc`, `abcd`. + /// + /// Standard semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::Standard) // default, not necessary + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("b", &haystack[mat.start()..mat.end()]); + /// ``` + /// + /// Leftmost-first semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostFirst) + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("abc", &haystack[mat.start()..mat.end()]); + /// ``` + /// + /// Leftmost-longest semantics: + /// + /// ``` + /// use aho_corasick::{AhoCorasickBuilder, MatchKind}; + /// + /// let patterns = &["b", "abc", "abcd"]; + /// let haystack = "abcd"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .match_kind(MatchKind::LeftmostLongest) + /// .build(patterns); + /// let mat = ac.find(haystack).expect("should have a match"); + /// assert_eq!("abcd", &haystack[mat.start()..mat.end()]); + /// ``` + pub fn match_kind(&mut self, kind: MatchKind) -> &mut AhoCorasickBuilder { + self.nfa_builder.match_kind(kind); + self + } + + /// Enable ASCII-aware case insensitive matching. + /// + /// When this option is enabled, searching will be performed without + /// respect to case for ASCII letters (`a-z` and `A-Z`) only. + /// + /// Enabling this option does not change the search algorithm, but it may + /// increase the size of the automaton. + /// + /// **NOTE:** In the future, support for full Unicode case insensitivity + /// may be added, but ASCII case insensitivity is comparatively much + /// simpler to add. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use aho_corasick::AhoCorasickBuilder; + /// + /// let patterns = &["FOO", "bAr", "BaZ"]; + /// let haystack = "foo bar baz"; + /// + /// let ac = AhoCorasickBuilder::new() + /// .ascii_case_insensitive(true) + /// .build(patterns); + /// assert_eq!(3, ac.find_iter(haystack).count()); + /// ``` + pub fn ascii_case_insensitive( + &mut self, + yes: bool, + ) -> &mut AhoCorasickBuilder { + self.nfa_builder.ascii_case_insensitive(yes); + self + } + + /// Set the limit on how many NFA states use a dense representation for + /// their transitions. + /// + /// A dense representation uses more space, but supports faster access to + /// transitions at search time. Thus, this setting permits the control of a + /// space vs time trade off when using the NFA variant of Aho-Corasick. + /// + /// This limit is expressed in terms of the depth of a state, i.e., the + /// number of transitions from the starting state of the NFA. The idea is + /// that most of the time searching will be spent near the starting state + /// of the automaton, so states near the start state should use a dense + /// representation. States further away from the start state would then use + /// a sparse representation, which uses less space but is slower to access + /// transitions at search time. + /// + /// By default, this is set to a low but non-zero number. + /// + /// This setting has no effect if the `dfa` option is enabled. + pub fn dense_depth(&mut self, depth: usize) -> &mut AhoCorasickBuilder { + self.nfa_builder.dense_depth(depth); + self + } + + /// Compile the standard Aho-Corasick automaton into a deterministic finite + /// automaton (DFA). + /// + /// When this is disabled (which is the default), then a non-deterministic + /// finite automaton (NFA) is used instead. + /// + /// The main benefit to a DFA is that it can execute searches more quickly + /// than a DFA (perhaps 2-4 times as fast). The main drawback is that the + /// DFA uses more space and can take much longer to build. + /// + /// Enabling this option does not change the time complexity for + /// constructing the Aho-Corasick automaton (which is `O(p)` where + /// `p` is the total number of patterns being compiled). Enabling this + /// option does however reduce the time complexity of non-overlapping + /// searches from `O(n + p)` to `O(n)`, where `n` is the length of the + /// haystack. + /// + /// In general, it's a good idea to enable this if you're searching a + /// small number of fairly short patterns (~1000), or if you want the + /// fastest possible search without regard to compilation time or space + /// usage. + pub fn dfa(&mut self, yes: bool) -> &mut AhoCorasickBuilder { + self.dfa = yes; + self + } + + /// Enable heuristic prefilter optimizations. + /// + /// When enabled, searching will attempt to quickly skip to match + /// candidates using specialized literal search routines. A prefilter + /// cannot always be used, and is generally treated as a heuristic. It + /// can be useful to disable this if the prefilter is observed to be + /// sub-optimal for a particular workload. + /// + /// This is enabled by default. + pub fn prefilter(&mut self, yes: bool) -> &mut AhoCorasickBuilder { + self.nfa_builder.prefilter(yes); + self + } + + /// Shrink the size of the transition alphabet by mapping bytes to their + /// equivalence classes. This only has an effect when the `dfa` option is + /// enabled. + /// + /// When enabled, each a DFA will use a map from all possible bytes + /// to their corresponding equivalence class. Each equivalence class + /// represents a set of bytes that does not discriminate between a match + /// and a non-match in the DFA. For example, the patterns `bar` and `baz` + /// have at least five equivalence classes: singleton sets of `b`, `a`, `r` + /// and `z`, and a final set that contains every other byte. + /// + /// The advantage of this map is that the size of the transition table can + /// be reduced drastically from `#states * 256 * sizeof(id)` to + /// `#states * k * sizeof(id)` where `k` is the number of equivalence + /// classes. As a result, total space usage can decrease substantially. + /// Moreover, since a smaller alphabet is used, compilation becomes faster + /// as well. + /// + /// The disadvantage of this map is that every byte searched must be + /// passed through this map before it can be used to determine the next + /// transition. This has a small match time performance cost. However, if + /// the DFA is otherwise very large without byte classes, then using byte + /// classes can greatly improve memory locality and thus lead to better + /// overall performance. + /// + /// This option is enabled by default. + pub fn byte_classes(&mut self, yes: bool) -> &mut AhoCorasickBuilder { + self.dfa_builder.byte_classes(yes); + self + } + + /// Premultiply state identifiers in the transition table. This only has + /// an effect when the `dfa` option is enabled. + /// + /// When enabled, state identifiers are premultiplied to point to their + /// corresponding row in the transition table. That is, given the `i`th + /// state, its corresponding premultiplied identifier is `i * k` where `k` + /// is the alphabet size of the automaton. (The alphabet size is at most + /// 256, but is in practice smaller if byte classes is enabled.) + /// + /// When state identifiers are not premultiplied, then the identifier of + /// the `i`th state is `i`. + /// + /// The advantage of premultiplying state identifiers is that is saves a + /// multiplication instruction per byte when searching with a DFA. This has + /// been observed to lead to a 20% performance benefit in micro-benchmarks. + /// + /// The primary disadvantage of premultiplying state identifiers is + /// that they require a larger integer size to represent. For example, + /// if the DFA has 200 states, then its premultiplied form requires 16 + /// bits to represent every possible state identifier, where as its + /// non-premultiplied form only requires 8 bits. + /// + /// This option is enabled by default. + pub fn premultiply(&mut self, yes: bool) -> &mut AhoCorasickBuilder { + self.dfa_builder.premultiply(yes); + self + } +} + +/// A knob for controlling the match semantics of an Aho-Corasick automaton. +/// +/// There are two generally different ways that Aho-Corasick automatons can +/// report matches. The first way is the "standard" approach that results from +/// implementing most textbook explanations of Aho-Corasick. The second way is +/// to report only the leftmost non-overlapping matches. The leftmost approach +/// is in turn split into two different ways of resolving ambiguous matches: +/// leftmost-first and leftmost-longest. +/// +/// The `Standard` match kind is the default and is the only one that supports +/// overlapping matches and stream searching. (Trying to find overlapping +/// or streaming matches using leftmost match semantics will result in a +/// panic.) The `Standard` match kind will report matches as they are seen. +/// When searching for overlapping matches, then all possible matches are +/// reported. When searching for non-overlapping matches, the first match seen +/// is reported. For example, for non-overlapping matches, given the patterns +/// `abcd` and `b` and the subject string `abcdef`, only a match for `b` is +/// reported since it is detected first. The `abcd` match is never reported +/// since it overlaps with the `b` match. +/// +/// In contrast, the leftmost match kind always prefers the leftmost match +/// among all possible matches. Given the same example as above with `abcd` and +/// `b` as patterns and `abcdef` as the subject string, the leftmost match is +/// `abcd` since it begins before the `b` match, even though the `b` match is +/// detected before the `abcd` match. In this case, the `b` match is not +/// reported at all since it overlaps with the `abcd` match. +/// +/// The difference between leftmost-first and leftmost-longest is in how they +/// resolve ambiguous matches when there are multiple leftmost matches to +/// choose from. Leftmost-first always chooses the pattern that was provided +/// earliest, where as leftmost-longest always chooses the longest matching +/// pattern. For example, given the patterns `a` and `ab` and the subject +/// string `ab`, the leftmost-first match is `a` but the leftmost-longest match +/// is `ab`. Conversely, if the patterns were given in reverse order, i.e., +/// `ab` and `a`, then both the leftmost-first and leftmost-longest matches +/// would be `ab`. Stated differently, the leftmost-first match depends on the +/// order in which the patterns were given to the Aho-Corasick automaton. +/// Because of that, when leftmost-first matching is used, if a pattern `A` +/// that appears before a pattern `B` is a prefix of `B`, then it is impossible +/// to ever observe a match of `B`. +/// +/// If you're not sure which match kind to pick, then stick with the standard +/// kind, which is the default. In particular, if you need overlapping or +/// streaming matches, then you _must_ use the standard kind. The leftmost +/// kinds are useful in specific circumstances. For example, leftmost-first can +/// be very useful as a way to implement match priority based on the order of +/// patterns given and leftmost-longest can be useful for dictionary searching +/// such that only the longest matching words are reported. +/// +/// # Relationship with regular expression alternations +/// +/// Understanding match semantics can be a little tricky, and one easy way +/// to conceptualize non-overlapping matches from an Aho-Corasick automaton +/// is to think about them as a simple alternation of literals in a regular +/// expression. For example, let's say we wanted to match the strings +/// `Sam` and `Samwise`, which would turn into the regex `Sam|Samwise`. It +/// turns out that regular expression engines have two different ways of +/// matching this alternation. The first way, leftmost-longest, is commonly +/// found in POSIX compatible implementations of regular expressions (such as +/// `grep`). The second way, leftmost-first, is commonly found in backtracking +/// implementations such as Perl. (Some regex engines, such as RE2 and Rust's +/// regex engine do not use backtracking, but still implement leftmost-first +/// semantics in an effort to match the behavior of dominant backtracking +/// regex engines such as those found in Perl, Ruby, Python, Javascript and +/// PHP.) +/// +/// That is, when matching `Sam|Samwise` against `Samwise`, a POSIX regex +/// will match `Samwise` because it is the longest possible match, but a +/// Perl-like regex will match `Sam` since it appears earlier in the +/// alternation. Indeed, the regex `Sam|Samwise` in a Perl-like regex engine +/// will never match `Samwise` since `Sam` will always have higher priority. +/// Conversely, matching the regex `Samwise|Sam` against `Samwise` will lead to +/// a match of `Samwise` in both POSIX and Perl-like regexes since `Samwise` is +/// still longest match, but it also appears earlier than `Sam`. +/// +/// The "standard" match semantics of Aho-Corasick generally don't correspond +/// to the match semantics of any large group of regex implementations, so +/// there's no direct analogy that can be made here. Standard match semantics +/// are generally useful for overlapping matches, or if you just want to see +/// matches as they are detected. +/// +/// The main conclusion to draw from this section is that the match semantics +/// can be tweaked to precisely match either Perl-like regex alternations or +/// POSIX regex alternations. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum MatchKind { + /// Use standard match semantics, which support overlapping matches. When + /// used with non-overlapping matches, matches are reported as they are + /// seen. + Standard, + /// Use leftmost-first match semantics, which reports leftmost matches. + /// When there are multiple possible leftmost matches, the match + /// corresponding to the pattern that appeared earlier when constructing + /// the automaton is reported. + /// + /// This does **not** support overlapping matches or stream searching. If + /// this match kind is used, attempting to find overlapping matches or + /// stream matches will panic. + LeftmostFirst, + /// Use leftmost-longest match semantics, which reports leftmost matches. + /// When there are multiple possible leftmost matches, the longest match + /// is chosen. + /// + /// This does **not** support overlapping matches or stream searching. If + /// this match kind is used, attempting to find overlapping matches or + /// stream matches will panic. + LeftmostLongest, + /// Hints that destructuring should not be exhaustive. + /// + /// This enum may grow additional variants, so this makes sure clients + /// don't count on exhaustive matching. (Otherwise, adding a new variant + /// could break existing code.) + #[doc(hidden)] + __Nonexhaustive, +} + +/// The default match kind is `MatchKind::Standard`. +impl Default for MatchKind { + fn default() -> MatchKind { + MatchKind::Standard + } +} + +impl MatchKind { + fn supports_overlapping(&self) -> bool { + self.is_standard() + } + + fn supports_stream(&self) -> bool { + // TODO: It may be possible to support this. It's hard. + // + // See: https://github.com/rust-lang/regex/issues/425#issuecomment-471367838 + self.is_standard() + } + + pub(crate) fn is_standard(&self) -> bool { + *self == MatchKind::Standard + } + + pub(crate) fn is_leftmost(&self) -> bool { + *self == MatchKind::LeftmostFirst + || *self == MatchKind::LeftmostLongest + } + + pub(crate) fn is_leftmost_first(&self) -> bool { + *self == MatchKind::LeftmostFirst + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn oibits() { + use std::panic::{RefUnwindSafe, UnwindSafe}; + + fn assert_send() {} + fn assert_sync() {} + fn assert_unwind_safe() {} + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/autiter.rs cargo-0.35.0/vendor/aho-corasick/src/autiter.rs --- cargo-0.33.0/vendor/aho-corasick/src/autiter.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/autiter.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,530 +0,0 @@ -use std::io::{self, BufRead}; -use std::marker::PhantomData; - -use memchr::{memchr, memchr2, memchr3}; - -use super::{ROOT_STATE, StateIdx}; - -/// An abstraction over automatons and their corresponding iterators. -/// The type parameter `P` is the type of the pattern that was used to -/// construct this Automaton. -pub trait Automaton

{ - /// Return the next state given the current state and next character. - fn next_state(&self, si: StateIdx, b: u8) -> StateIdx; - - /// Return true if and only if the given state and current pattern index - /// indicate a match. - fn has_match(&self, si: StateIdx, outi: usize) -> bool; - - /// Build a match given the current state, pattern index and input index. - fn get_match(&self, si: StateIdx, outi: usize, texti: usize) -> Match; - - /// Return the set of bytes that have transitions in the root state. - fn start_bytes(&self) -> &[u8]; - - /// Returns all of the patterns matched by this automaton. - /// - /// The order of the patterns is the order in which they were added. - fn patterns(&self) -> &[P]; - - /// Returns the pattern indexed at `i`. - /// - /// The index corresponds to the position at which the pattern was added - /// to the automaton, starting at `0`. - fn pattern(&self, i: usize) -> &P; - - /// Return the number of patterns in the automaton. - #[inline] - fn len(&self) -> usize { - self.patterns().len() - } - - /// Returns true if the automaton has no patterns. - #[inline] - fn is_empty(&self) -> bool { - self.patterns().is_empty() - } - - /// Returns an iterator of non-overlapping matches in `s`. - fn find<'a, 's, Q: ?Sized + AsRef<[u8]>>( - &'a self, - s: &'s Q, - ) -> Matches<'a, 's, P, Self> - where Self: Sized { - Matches { - aut: self, - text: s.as_ref(), - texti: 0, - si: ROOT_STATE, - _m: PhantomData, - } - } - - /// Returns an iterator of overlapping matches in `s`. - fn find_overlapping<'a, 's, Q: ?Sized + AsRef<[u8]>>( - &'a self, - s: &'s Q, - ) -> MatchesOverlapping<'a, 's, P, Self> - where Self: Sized { - MatchesOverlapping { - aut: self, - text: s.as_ref(), - texti: 0, - si: ROOT_STATE, - outi: 0, - _m: PhantomData, - } - } - - /// Returns an iterator of non-overlapping matches in the given reader. - fn stream_find<'a, R: io::Read>( - &'a self, - rdr: R, - ) -> StreamMatches<'a, R, P, Self> - where Self: Sized { - StreamMatches { - aut: self, - buf: io::BufReader::new(rdr), - texti: 0, - si: ROOT_STATE, - _m: PhantomData, - } - } - - /// Returns an iterator of overlapping matches in the given reader. - fn stream_find_overlapping<'a, R: io::Read>( - &'a self, - rdr: R, - ) -> StreamMatchesOverlapping<'a, R, P, Self> - where Self: Sized { - StreamMatchesOverlapping { - aut: self, - buf: io::BufReader::new(rdr), - texti: 0, - si: ROOT_STATE, - outi: 0, - _m: PhantomData, - } - } -} - -impl<'a, P: AsRef<[u8]>, A: 'a + Automaton

+ ?Sized> - Automaton

for &'a A { - fn next_state(&self, si: StateIdx, b: u8) -> StateIdx { - (**self).next_state(si, b) - } - - fn has_match(&self, si: StateIdx, outi: usize) -> bool { - (**self).has_match(si, outi) - } - - fn start_bytes(&self) -> &[u8] { - (**self).start_bytes() - } - - fn patterns(&self) -> &[P] { - (**self).patterns() - } - - fn pattern(&self, i: usize) -> &P { - (**self).pattern(i) - } - - fn get_match(&self, si: StateIdx, outi: usize, texti: usize) -> Match { - (**self).get_match(si, outi, texti) - } -} - -/// Records a match in the search text. -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] -pub struct Match { - /// The pattern index. - /// - /// This corresponds to the ordering in which the matched pattern was - /// added to the automaton, starting at `0`. - pub pati: usize, - /// The starting byte offset of the match in the search text. - pub start: usize, - /// The ending byte offset of the match in the search text. - /// - /// (This can be re-captiulated with `pati` and adding the pattern's - /// length to `start`, but it is convenient to have it here.) - pub end: usize, -} - -/// An iterator of non-overlapping matches for in-memory text. -/// -/// This iterator yields `Match` values. -/// -/// `'a` is the lifetime of the automaton, `'s` is the lifetime of the -/// search text, and `P` is the type of the Automaton's pattern. -#[derive(Debug)] -pub struct Matches<'a, 's, P, A: 'a + Automaton

+ ?Sized> { - aut: &'a A, - text: &'s [u8], - texti: usize, - si: StateIdx, - _m: PhantomData

, -} - -// When there's an initial lone start byte, it is usually worth it -// to use `memchr` to skip along the input. The problem is that -// the skipping function is called in the inner match loop, which -// can be quite costly if the skipping condition is never met. -// Therefore, we lift the case analysis outside of the inner loop at -// the cost of repeating code. -// -// `step_to_match` is the version of the inner loop without skipping, -// and `skip_to_match` is the version with skipping. -#[inline(never)] -fn step_to_match + ?Sized>( - aut: &A, - text: &[u8], - mut texti: usize, - mut si: StateIdx -) -> Option<(usize, StateIdx)> { - while texti < text.len() { - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - if texti + 4 < text.len() { - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - } - } - None -} - -fn skip_to_match + ?Sized, F: Fn(&A, &[u8], usize) -> usize>( - aut: &A, - text: &[u8], - mut texti: usize, - mut si: StateIdx, - skip: F, -) -> Option<(usize, StateIdx)> { - if si == ROOT_STATE { - texti = skip(aut, text, texti); - } - while texti < text.len() { - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - if si == ROOT_STATE { - texti = skip(aut, text, texti + 1); - } else { - texti += 1; - if texti + 4 < text.len() { - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - si = aut.next_state(si, text[texti]); - if aut.has_match(si, 0) { - return Some((texti, si)); - } - texti += 1; - } - } - } - None -} - -#[inline] -fn skip1 + ?Sized>( - aut: &A, - text: &[u8], - at: usize, -) -> usize { - debug_assert!(aut.start_bytes().len() == 1); - let b = aut.start_bytes()[0]; - match memchr(b, &text[at..]) { - None => text.len(), - Some(i) => at + i, - } -} - -#[inline] -fn skip2 + ?Sized>( - aut: &A, - text: &[u8], - at: usize, -) -> usize { - debug_assert!(aut.start_bytes().len() == 2); - let (b1, b2) = (aut.start_bytes()[0], aut.start_bytes()[1]); - match memchr2(b1, b2, &text[at..]) { - None => text.len(), - Some(i) => at + i, - } -} - -#[inline] -fn skip3 + ?Sized>( - aut: &A, - text: &[u8], - at: usize, -) -> usize { - debug_assert!(aut.start_bytes().len() == 3); - let (b1, b2, b3) = ( - aut.start_bytes()[0], aut.start_bytes()[1], aut.start_bytes()[2], - ); - match memchr3(b1, b2, b3, &text[at..]) { - None => text.len(), - Some(i) => at + i, - } -} - -impl<'a, 's, P, A: Automaton

+ ?Sized> Iterator for Matches<'a, 's, P, A> { - type Item = Match; - - fn next(&mut self) -> Option { - if self.aut.start_bytes().len() == 1 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip1); - if let Some((texti, si)) = skip { - self.texti = texti + 1; - self.si = ROOT_STATE; - return Some(self.aut.get_match(si, 0, texti)); - } - } else if self.aut.start_bytes().len() == 2 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip2); - if let Some((texti, si)) = skip { - self.texti = texti + 1; - self.si = ROOT_STATE; - return Some(self.aut.get_match(si, 0, texti)); - } - } else if self.aut.start_bytes().len() == 3 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip3); - if let Some((texti, si)) = skip { - self.texti = texti + 1; - self.si = ROOT_STATE; - return Some(self.aut.get_match(si, 0, texti)); - } - } else { - let step = step_to_match(self.aut, self.text, self.texti, self.si); - if let Some((texti, si)) = step { - self.texti = texti + 1; - self.si = ROOT_STATE; - return Some(self.aut.get_match(si, 0, texti)); - } - } - None - } -} - -/// An iterator of non-overlapping matches for streaming text. -/// -/// This iterator yields `io::Result` values. -/// -/// `'a` is the lifetime of the automaton, `R` is the type of the underlying -/// `io::Read`er, and P is the type of the Automaton's pattern. -#[derive(Debug)] -pub struct StreamMatches<'a, R, P, A: 'a + Automaton

+ ?Sized> { - aut: &'a A, - buf: io::BufReader, - texti: usize, - si: StateIdx, - _m: PhantomData

, -} - -impl<'a, R: io::Read, P, A: Automaton

> - Iterator for StreamMatches<'a, R, P, A> { - type Item = io::Result; - - fn next(&mut self) -> Option> { - let mut m = None; - let mut consumed = 0; -'LOOP: loop { - self.buf.consume(consumed); - let bs = match self.buf.fill_buf() { - Err(err) => return Some(Err(err)), - Ok(bs) if bs.is_empty() => break, - Ok(bs) => bs, - }; - consumed = bs.len(); // is shortened if we find a match - for (i, &b) in bs.iter().enumerate() { - self.si = self.aut.next_state(self.si, b); - if self.aut.has_match(self.si, 0) { - m = Some(Ok(self.aut.get_match(self.si, 0, self.texti))); - consumed = i + 1; - self.texti += 1; - self.si = ROOT_STATE; - break 'LOOP; - } - self.texti += 1; - } - } - self.buf.consume(consumed); - m - } -} - -/// An iterator of overlapping matches for in-memory text. -/// -/// This iterator yields `Match` values. -/// -/// `'a` is the lifetime of the automaton, `'s` is the lifetime of the -/// search text, and `P` is the type of the Automaton's pattern. -#[derive(Debug)] -pub struct MatchesOverlapping<'a, 's, P, A: 'a + Automaton

+ ?Sized> { - aut: &'a A, - text: &'s [u8], - texti: usize, - si: StateIdx, - outi: usize, - _m: PhantomData

, -} - -impl<'a, 's, P, A: Automaton

+ ?Sized> - Iterator for MatchesOverlapping<'a, 's, P, A> { - type Item = Match; - - fn next(&mut self) -> Option { - if self.aut.has_match(self.si, self.outi) { - let m = self.aut.get_match(self.si, self.outi, self.texti); - self.outi += 1; - if !self.aut.has_match(self.si, self.outi) { - self.texti += 1; - } - return Some(m); - } - - self.outi = 0; - if self.aut.start_bytes().len() == 1 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip1); - if let Some((texti, si)) = skip { - self.texti = texti; - self.si = si; - return self.next(); - } - } else if self.aut.start_bytes().len() == 2 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip2); - if let Some((texti, si)) = skip { - self.texti = texti; - self.si = si; - return self.next(); - } - } else if self.aut.start_bytes().len() == 3 { - let skip = skip_to_match( - self.aut, self.text, self.texti, self.si, skip3); - if let Some((texti, si)) = skip { - self.texti = texti; - self.si = si; - return self.next(); - } - } else { - let step = step_to_match(self.aut, self.text, self.texti, self.si); - if let Some((texti, si)) = step { - self.texti = texti; - self.si = si; - return self.next(); - } - } - None - } -} - -/// An iterator of overlapping matches for streaming text. -/// -/// This iterator yields `io::Result` values. -/// -/// `'a` is the lifetime of the automaton, `R` is the type of the underlying -/// `io::Read`er, and P is the type of the Automaton's pattern. -#[derive(Debug)] -pub struct StreamMatchesOverlapping<'a, R, P, A: 'a + Automaton

+ ?Sized> { - aut: &'a A, - buf: io::BufReader, - texti: usize, - si: StateIdx, - outi: usize, - _m: PhantomData

, -} - -impl<'a, R: io::Read, P, A: Automaton

+ ?Sized> - Iterator for StreamMatchesOverlapping<'a, R, P, A> { - type Item = io::Result; - - fn next(&mut self) -> Option> { - if self.aut.has_match(self.si, self.outi) { - let m = self.aut.get_match(self.si, self.outi, self.texti); - self.outi += 1; - if !self.aut.has_match(self.si, self.outi) { - self.texti += 1; - } - return Some(Ok(m)); - } - let mut m = None; - let mut consumed = 0; - self.outi = 0; -'LOOP: loop { - self.buf.consume(consumed); - let bs = match self.buf.fill_buf() { - Err(err) => return Some(Err(err)), - Ok(bs) if bs.is_empty() => break, - Ok(bs) => bs, - }; - consumed = bs.len(); // is shortened if we find a match - for (i, &b) in bs.iter().enumerate() { - self.si = self.aut.next_state(self.si, b); - if self.aut.has_match(self.si, self.outi) { - m = Some(Ok(self.aut.get_match( - self.si, self.outi, self.texti))); - consumed = i + 1; - self.outi += 1; - if !self.aut.has_match(self.si, self.outi) { - self.texti += 1; - } - break 'LOOP; - } - self.texti += 1; - } - } - self.buf.consume(consumed); - m - } -} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/automaton.rs cargo-0.35.0/vendor/aho-corasick/src/automaton.rs --- cargo-0.33.0/vendor/aho-corasick/src/automaton.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/automaton.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,401 @@ +use ahocorasick::MatchKind; +use prefilter::{Prefilter, PrefilterState}; +use state_id::{StateID, dead_id, fail_id}; +use Match; + +// NOTE: This trait was essentially copied from regex-automata, with some +// wording changed since we use this trait for NFAs in addition to DFAs in this +// crate. Additionally, we do not export this trait. It's only used internally +// to reduce code duplication. The regex-automata crate needs to expose it +// because its Regex type is generic over implementations of this trait. In +// this crate, we can encapsulate everything behind the AhoCorasick type. + +/// A trait describing the interface of an Aho-Corasick finite state machine. +/// +/// Every automaton has exactly one fail state, one dead state and exactly one +/// start state. Generally, these correspond to the first, second and third +/// states, respectively. The failure state is always treated as a sentinel. +/// That is, no correct Aho-Corasick automaton will ever transition into the +/// fail state. The dead state, however, can be transitioned into, but only +/// when leftmost-first or leftmost-longest match semantics are enabled and +/// only when at least one match has been observed. +/// +/// Every automaton also has one or more match states, such that +/// `Automaton::is_match_state_unchecked(id)` returns `true` if and only if +/// `id` corresponds to a match state. +pub trait Automaton { + /// The representation used for state identifiers in this automaton. + /// + /// Typically, this is one of `u8`, `u16`, `u32`, `u64` or `usize`. + type ID: StateID; + + /// The type of matching that should be done. + fn match_kind(&self) -> &MatchKind; + + /// An optional prefilter for quickly skipping to the next candidate match. + /// A prefilter must report at least every match, although it may report + /// positions that do not correspond to a match. That is, it must not allow + /// false negatives, but can allow false positives. + /// + /// Currently, a prefilter only runs when the automaton is in the start + /// state. That is, the position reported by a prefilter should always + /// correspond to the start of a potential match. + fn prefilter(&self) -> Option<&Prefilter>; + + /// Return the identifier of this automaton's start state. + fn start_state(&self) -> Self::ID; + + /// Returns true if and only if the given state identifier refers to a + /// valid state. + fn is_valid(&self, id: Self::ID) -> bool; + + /// Returns true if and only if the given identifier corresponds to a match + /// state. + /// + /// The state ID given must be valid, or else implementors may panic. + fn is_match_state(&self, id: Self::ID) -> bool; + + /// Returns true if and only if the given identifier corresponds to a state + /// that is either the dead state or a match state. + /// + /// Depending on the implementation of the automaton, this routine can + /// be used to save a branch in the core matching loop. Nevertheless, + /// `is_match_state(id) || id == dead_id()` is always a valid + /// implementation. Indeed, this is the default implementation. + /// + /// The state ID given must be valid, or else implementors may panic. + fn is_match_or_dead_state(&self, id: Self::ID) -> bool { + id == dead_id() || self.is_match_state(id) + } + + /// If the given state is a match state, return the match corresponding + /// to the given match index. `end` must be the ending position of the + /// detected match. If no match exists or if `match_index` exceeds the + /// number of matches in this state, then `None` is returned. + /// + /// The state ID given must be valid, or else implementors may panic. + /// + /// If the given state ID is correct and if the `match_index` is less than + /// the number of matches for that state, then this is guaranteed to return + /// a match. + fn get_match( + &self, + id: Self::ID, + match_index: usize, + end: usize, + ) -> Option; + + /// Returns the number of matches for the given state. If the given state + /// is not a match state, then this returns 0. + /// + /// The state ID given must be valid, or else implementors must panic. + fn match_count(&self, id: Self::ID) -> usize; + + /// Given the current state that this automaton is in and the next input + /// byte, this method returns the identifier of the next state. The + /// identifier returned must always be valid and may never correspond to + /// the fail state. The returned identifier may, however, point to the + /// dead state. + /// + /// This is not safe so that implementors may look up the next state + /// without memory safety checks such as bounds checks. As such, callers + /// must ensure that the given identifier corresponds to a valid automaton + /// state. Implementors must, in turn, ensure that this routine is safe for + /// all valid state identifiers and for all possible `u8` values. + unsafe fn next_state_unchecked( + &self, + current: Self::ID, + input: u8, + ) -> Self::ID; + + /// Like next_state_unchecked, but debug_asserts that the underlying + /// implementation never returns a `fail_id()` for the next state. + unsafe fn next_state_unchecked_no_fail( + &self, + current: Self::ID, + input: u8, + ) -> Self::ID { + let next = self.next_state_unchecked(current, input); + // We should never see a transition to the failure state. + debug_assert!( + next != fail_id(), + "automaton should never return fail_id for next state" + ); + next + } + + /// Execute a search using standard match semantics. + /// + /// This can be used even when the automaton was constructed with leftmost + /// match semantics when you want to find the earliest possible match. This + /// can also be used as part of an overlapping search implementation. + /// + /// N.B. This does not report a match if `state_id` is given as a matching + /// state. As such, this should not be used directly. + #[inline(always)] + fn standard_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + if let Some(pre) = self.prefilter() { + self.standard_find_at_imp( + prestate, Some(pre), haystack, at, state_id, + ) + } else { + self.standard_find_at_imp( + prestate, None, haystack, at, state_id, + ) + } + } + + // It's important for this to always be inlined. Namely, it's only caller + // is standard_find_at, and the inlining should remove the case analysis + // for prefilter scanning when there is no prefilter available. + #[inline(always)] + fn standard_find_at_imp( + &self, + prestate: &mut PrefilterState, + prefilter: Option<&Prefilter>, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + // This is necessary for guaranteeing a safe API, since we use the + // state ID below in a function that exhibits UB if called with an + // invalid state ID. + assert!( + self.is_valid(*state_id), + "{} is not a valid state ID", + state_id.to_usize() + ); + unsafe { + let start = haystack.as_ptr(); + let end = haystack[haystack.len()..].as_ptr(); + let mut ptr = haystack[at..].as_ptr(); + while ptr < end { + if let Some(pre) = prefilter { + if prestate.is_effective() + && *state_id == self.start_state() + { + let at = ptr as usize - start as usize; + match pre.next_candidate(haystack, at) { + None => return None, + Some(i) => { + prestate.update(i - at); + ptr = start.offset(i as isize); + } + } + } + } + // SAFETY: next_state is safe for all possible u8 values, + // so the only thing we're concerned about is the validity + // of `state_id`. `state_id` either comes from the caller + // (in which case, we assert above that it is valid), or it + // comes from the return value of next_state, which is also + // guaranteed to be valid. + *state_id = self.next_state_unchecked_no_fail(*state_id, *ptr); + ptr = ptr.offset(1); + // This routine always quits immediately after seeing a + // match, and since dead states can only come after seeing + // a match, seeing a dead state here is impossible. + debug_assert!( + *state_id != dead_id(), + "standard find should never see a dead state" + ); + + let end = ptr as usize - start as usize; + if let Some(m) = self.get_match(*state_id, 0, end) { + return Some(m); + } + } + None + } + } + + /// Execute a search using leftmost (either first or longest) match + /// semantics. + /// + /// The principle difference between searching with standard semantics and + /// searching with leftmost semantics is that leftmost searching will + /// continue searching even after a match has been found. Once a match + /// is found, the search does not stop until either the haystack has been + /// exhausted or a dead state is observed in the automaton. (Dead states + /// only exist in automatons constructed with leftmost semantics.) That is, + /// we rely on the construction of the automaton to tell us when to quit. + #[inline(never)] + fn leftmost_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + if let Some(pre) = self.prefilter() { + self.leftmost_find_at_imp( + prestate, Some(pre), haystack, at, state_id, + ) + } else { + self.leftmost_find_at_imp( + prestate, None, haystack, at, state_id, + ) + } + } + + // It's important for this to always be inlined. Namely, it's only caller + // is leftmost_find_at, and the inlining should remove the case analysis + // for prefilter scanning when there is no prefilter available. + #[inline(always)] + fn leftmost_find_at_imp( + &self, + prestate: &mut PrefilterState, + prefilter: Option<&Prefilter>, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + debug_assert!(self.match_kind().is_leftmost()); + // This is necessary for guaranteeing a safe API, since we use the + // state ID below in a function that exhibits UB if called with an + // invalid state ID. + assert!( + self.is_valid(*state_id), + "{} is not a valid state ID", + state_id.to_usize() + ); + unsafe { + let start = haystack.as_ptr(); + let end = haystack[haystack.len()..].as_ptr(); + let mut ptr = haystack[at..].as_ptr(); + + let mut last_match = self.get_match(*state_id, 0, at); + while ptr < end { + if let Some(pre) = prefilter { + if prestate.is_effective() + && *state_id == self.start_state() + { + let at = ptr as usize - start as usize; + match pre.next_candidate(haystack, at) { + None => return None, + Some(i) => { + prestate.update(i - at); + ptr = start.offset(i as isize); + } + } + } + } + // SAFETY: next_state is safe for all possible u8 values, + // so the only thing we're concerned about is the validity + // of `state_id`. `state_id` either comes from the caller + // (in which case, we assert above that it is valid), or it + // comes from the return value of next_state, which is also + // guaranteed to be valid. + *state_id = self.next_state_unchecked_no_fail(*state_id, *ptr); + ptr = ptr.offset(1); + if self.is_match_or_dead_state(*state_id) { + if *state_id == dead_id() { + // The only way to enter into a dead state is if a + // match has been found, so we assert as much. This + // is different from normal automata, where you might + // enter a dead state if you know a subsequent match + // will never be found (regardless of whether a match + // has already been found). For Aho-Corasick, it is + // built so that we can match at any position, so the + // possibility of a match always exists. + debug_assert!( + last_match.is_some(), + "failure state should only be seen after match" + ); + return last_match; + } + let end = ptr as usize - start as usize; + last_match = self.get_match(*state_id, 0, end); + } + } + last_match + } + } + + /// Execute an overlapping search. + /// + /// When executing an overlapping match, the previous state ID in addition + /// to the previous match index should be given. If there are more matches + /// at the given state, then the match is reported and the given index is + /// incremented. + #[inline(always)] + fn overlapping_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + match_index: &mut usize, + ) -> Option { + let match_count = self.match_count(*state_id); + if *match_index < match_count { + // This is guaranteed to return a match since + // match_index < match_count. + let result = self.get_match( + *state_id, + *match_index, + at, + ); + debug_assert!(result.is_some(), "must be a match"); + *match_index += 1; + return result; + } + + *match_index = 0; + match self.standard_find_at(prestate, haystack, at, state_id) { + None => None, + Some(m) => { + *match_index = 1; + Some(m) + } + } + } + + /// Return the earliest match found. This returns as soon as we know that + /// we have a match. As such, this does not necessarily correspond to the + /// leftmost starting match, but rather, the leftmost position at which a + /// match ends. + #[inline(always)] + fn earliest_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + if *state_id == self.start_state() { + if let Some(m) = self.get_match(*state_id, 0, at) { + return Some(m); + } + } + self.standard_find_at(prestate, haystack, at, state_id) + } + + /// A convenience function for finding the next match according to the + /// match semantics of this automaton. For standard match semantics, this + /// finds the earliest match. Otherwise, the leftmost match is found. + #[inline(always)] + fn find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut Self::ID, + ) -> Option { + match *self.match_kind() { + MatchKind::Standard => { + self.earliest_find_at(prestate, haystack, at, state_id) + } + MatchKind::LeftmostFirst | MatchKind::LeftmostLongest => { + self.leftmost_find_at(prestate, haystack, at, state_id) + } + MatchKind::__Nonexhaustive => unreachable!(), + } + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/buffer.rs cargo-0.35.0/vendor/aho-corasick/src/buffer.rs --- cargo-0.33.0/vendor/aho-corasick/src/buffer.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/buffer.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,131 @@ +use std::cmp; +use std::io; +use std::ptr; + +/// The default buffer capacity that we use for the stream buffer. +const DEFAULT_BUFFER_CAPACITY: usize = 8 * (1<<10); // 8 KB + +/// A fairly simple roll buffer for supporting stream searches. +/// +/// This buffer acts as a temporary place to store a fixed amount of data when +/// reading from a stream. Its central purpose is to allow "rolling" some +/// suffix of the data to the beginning of the buffer before refilling it with +/// more data from the stream. For example, let's say we are trying to match +/// "foobar" on a stream. When we report the match, we'd like to not only +/// report the correct offsets at which the match occurs, but also the matching +/// bytes themselves. So let's say our stream is a file with the following +/// contents: `test test foobar test test`. Now assume that we happen to read +/// the aforementioned file in two chunks: `test test foo` and `bar test test`. +/// Naively, it would not be possible to report a single contiguous `foobar` +/// match, but this roll buffer allows us to do that. Namely, after the second +/// read, the contents of the buffer should be `st foobar test test`, where the +/// search should ultimately resume immediately after `foo`. (The prefix `st ` +/// is included because the roll buffer saves N bytes at the end of the buffer, +/// where N is the maximum possible length of a match.) +/// +/// A lot of the logic for dealing with this is unfortunately split out between +/// this roll buffer and the `StreamChunkIter`. +#[derive(Debug)] +pub struct Buffer { + /// The raw buffer contents. This has a fixed size and never increases. + buf: Vec, + /// The minimum size of the buffer, which is equivalent to the maximum + /// possible length of a match. This corresponds to the amount that we + /// roll + min: usize, + /// The end of the contents of this buffer. + end: usize, +} + +impl Buffer { + /// Create a new buffer for stream searching. The minimum buffer length + /// given should be the size of the maximum possible match length. + pub fn new(min_buffer_len: usize) -> Buffer { + let min = cmp::max(1, min_buffer_len); + // The minimum buffer amount is also the amount that we roll our + // buffer in order to support incremental searching. To this end, + // our actual capacity needs to be at least 1 byte bigger than our + // minimum amount, otherwise we won't have any overlap. In actuality, + // we want our buffer to be a bit bigger than that for performance + // reasons, so we set a lower bound of `8 * min`. + // + // TODO: It would be good to find a way to test the streaming + // implementation with the minimal buffer size. + let capacity = cmp::max(min * 8, DEFAULT_BUFFER_CAPACITY); + Buffer { + buf: vec![0; capacity], + min, + end: 0, + } + } + + /// Return the contents of this buffer. + #[inline] + pub fn buffer(&self) -> &[u8] { + &self.buf[..self.end] + } + + /// Return the minimum size of the buffer. The only way a buffer may be + /// smaller than this is if the stream itself contains less than the + /// minimum buffer amount. + #[inline] + pub fn min_buffer_len(&self) -> usize { + self.min + } + + /// Return the total length of the contents in the buffer. + #[inline] + pub fn len(&self) -> usize { + self.end + } + + /// Return all free capacity in this buffer. + fn free_buffer(&mut self) -> &mut [u8] { + &mut self.buf[self.end..] + } + + /// Refill the contents of this buffer by reading as much as possible into + /// this buffer's free capacity. If no more bytes could be read, then this + /// returns false. Otherwise, this reads until it has filled the buffer + /// past the minimum amount. + pub fn fill(&mut self, mut rdr: R) -> io::Result { + let mut readany = false; + loop { + let readlen = rdr.read(self.free_buffer())?; + if readlen == 0 { + return Ok(readany); + } + readany = true; + self.end += readlen; + if self.len() >= self.min { + return Ok(true); + } + } + } + + /// Roll the contents of the buffer so that the suffix of this buffer is + /// moved to the front and all other contents are dropped. The size of the + /// suffix corresponds precisely to the minimum buffer length. + /// + /// This should only be called when the entire contents of this buffer have + /// been searched. + pub fn roll(&mut self) { + let roll_start = self.end + .checked_sub(self.min) + .expect("buffer capacity should be bigger than minimum amount"); + let roll_len = self.min; + + assert!(roll_start + roll_len <= self.end); + unsafe { + // SAFETY: A buffer contains Copy data, so there's no problem + // moving it around. Safety also depends on our indices being in + // bounds, which they always should be, given the assert above. + ptr::copy( + self.buf[roll_start..].as_ptr(), + self.buf.as_mut_ptr(), + roll_len, + ); + } + self.end = roll_len; + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/classes.rs cargo-0.35.0/vendor/aho-corasick/src/classes.rs --- cargo-0.33.0/vendor/aho-corasick/src/classes.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/classes.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,243 @@ +use std::fmt; + +/// A representation of byte oriented equivalence classes. +/// +/// This is used in an FSM to reduce the size of the transition table. This can +/// have a particularly large impact not only on the total size of an FSM, but +/// also on compile times. +#[derive(Clone, Copy)] +pub struct ByteClasses([u8; 256]); + +impl ByteClasses { + /// Creates a new set of equivalence classes where all bytes are mapped to + /// the same class. + pub fn empty() -> ByteClasses { + ByteClasses([0; 256]) + } + + /// Creates a new set of equivalence classes where each byte belongs to + /// its own equivalence class. + pub fn singletons() -> ByteClasses { + let mut classes = ByteClasses::empty(); + for i in 0..256 { + classes.set(i as u8, i as u8); + } + classes + } + + /// Set the equivalence class for the given byte. + #[inline] + pub fn set(&mut self, byte: u8, class: u8) { + self.0[byte as usize] = class; + } + + /// Get the equivalence class for the given byte. + #[inline] + pub fn get(&self, byte: u8) -> u8 { + self.0[byte as usize] + } + + /// Get the equivalence class for the given byte while forcefully + /// eliding bounds checks. + #[inline] + pub unsafe fn get_unchecked(&self, byte: u8) -> u8 { + *self.0.get_unchecked(byte as usize) + } + + /// Return the total number of elements in the alphabet represented by + /// these equivalence classes. Equivalently, this returns the total number + /// of equivalence classes. + #[inline] + pub fn alphabet_len(&self) -> usize { + self.0[255] as usize + 1 + } + + /// Returns true if and only if every byte in this class maps to its own + /// equivalence class. Equivalently, there are 256 equivalence classes + /// and each class contains exactly one byte. + #[inline] + pub fn is_singleton(&self) -> bool { + self.alphabet_len() == 256 + } + + /// Returns an iterator over a sequence of representative bytes from each + /// equivalence class. Namely, this yields exactly N items, where N is + /// equivalent to the number of equivalence classes. Each item is an + /// arbitrary byte drawn from each equivalence class. + /// + /// This is useful when one is determinizing an NFA and the NFA's alphabet + /// hasn't been converted to equivalence classes yet. Picking an arbitrary + /// byte from each equivalence class then permits a full exploration of + /// the NFA instead of using every possible byte value. + pub fn representatives(&self) -> ByteClassRepresentatives { + ByteClassRepresentatives { classes: self, byte: 0, last_class: None } + } + + /// Returns all of the bytes in the given equivalence class. + /// + /// The second element in the tuple indicates the number of elements in + /// the array. + fn elements(&self, equiv: u8) -> ([u8; 256], usize) { + let (mut array, mut len) = ([0; 256], 0); + for b in 0..256 { + if self.get(b as u8) == equiv { + array[len] = b as u8; + len += 1; + } + } + (array, len) + } +} + +impl fmt::Debug for ByteClasses { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.is_singleton() { + write!(f, "ByteClasses({{singletons}})") + } else { + write!(f, "ByteClasses(")?; + for equiv in 0..self.alphabet_len() { + let (members, len) = self.elements(equiv as u8); + write!(f, " {} => {:?}", equiv, &members[..len])?; + } + write!(f, ")") + } + } +} + +/// An iterator over representative bytes from each equivalence class. +#[derive(Debug)] +pub struct ByteClassRepresentatives<'a> { + classes: &'a ByteClasses, + byte: usize, + last_class: Option, +} + +impl<'a> Iterator for ByteClassRepresentatives<'a> { + type Item = u8; + + fn next(&mut self) -> Option { + while self.byte < 256 { + let byte = self.byte as u8; + let class = self.classes.get(byte); + self.byte += 1; + + if self.last_class != Some(class) { + self.last_class = Some(class); + return Some(byte); + } + } + None + } +} + +/// A byte class builder keeps track of an *approximation* of equivalence +/// classes of bytes during NFA construction. That is, every byte in an +/// equivalence class cannot discriminate between a match and a non-match. +/// +/// For example, in the literals `abc` and `xyz`, the bytes [\x00-`], [d-w] +/// and [{-\xFF] never discriminate between a match and a non-match, precisely +/// because they never occur in the literals anywhere. +/// +/// Note though that this does not necessarily compute the minimal set of +/// equivalence classes. For example, in the literals above, the byte ranges +/// [\x00-`], [d-w] and [{-\xFF] are all treated as distinct equivalence +/// classes even though they could be treated a single class. The reason for +/// this is implementation complexity. In the future, we should endeavor to +/// compute the minimal equivalence classes since they can have a rather large +/// impact on the size of the DFA. +/// +/// The representation here is 256 booleans, all initially set to false. Each +/// boolean maps to its corresponding byte based on position. A `true` value +/// indicates the end of an equivalence class, where its corresponding byte +/// and all of the bytes corresponding to all previous contiguous `false` +/// values are in the same equivalence class. +/// +/// This particular representation only permits contiguous ranges of bytes to +/// be in the same equivalence class, which means that we can never discover +/// the true minimal set of equivalence classes. +#[derive(Debug)] +pub struct ByteClassBuilder(Vec); + +impl ByteClassBuilder { + /// Create a new builder of byte classes where all bytes are part of the + /// same equivalence class. + pub fn new() -> ByteClassBuilder { + ByteClassBuilder(vec![false; 256]) + } + + /// Indicate the the range of byte given (inclusive) can discriminate a + /// match between it and all other bytes outside of the range. + pub fn set_range(&mut self, start: u8, end: u8) { + debug_assert!(start <= end); + if start > 0 { + self.0[start as usize - 1] = true; + } + self.0[end as usize] = true; + } + + /// Build byte classes that map all byte values to their corresponding + /// equivalence class. The last mapping indicates the largest equivalence + /// class identifier (which is never bigger than 255). + pub fn build(&self) -> ByteClasses { + let mut classes = ByteClasses::empty(); + let mut class = 0u8; + let mut i = 0; + loop { + classes.set(i as u8, class as u8); + if i >= 255 { + break; + } + if self.0[i] { + class = class.checked_add(1).unwrap(); + } + i += 1; + } + classes + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn byte_classes() { + let mut set = ByteClassBuilder::new(); + set.set_range(b'a', b'z'); + + let classes = set.build(); + assert_eq!(classes.get(0), 0); + assert_eq!(classes.get(1), 0); + assert_eq!(classes.get(2), 0); + assert_eq!(classes.get(b'a' - 1), 0); + assert_eq!(classes.get(b'a'), 1); + assert_eq!(classes.get(b'm'), 1); + assert_eq!(classes.get(b'z'), 1); + assert_eq!(classes.get(b'z' + 1), 2); + assert_eq!(classes.get(254), 2); + assert_eq!(classes.get(255), 2); + + let mut set = ByteClassBuilder::new(); + set.set_range(0, 2); + set.set_range(4, 6); + let classes = set.build(); + assert_eq!(classes.get(0), 0); + assert_eq!(classes.get(1), 0); + assert_eq!(classes.get(2), 0); + assert_eq!(classes.get(3), 1); + assert_eq!(classes.get(4), 2); + assert_eq!(classes.get(5), 2); + assert_eq!(classes.get(6), 2); + assert_eq!(classes.get(7), 3); + assert_eq!(classes.get(255), 3); + } + + #[test] + fn full_byte_classes() { + let mut set = ByteClassBuilder::new(); + for i in 0..256u16 { + set.set_range(i as u8, i as u8); + } + assert_eq!(set.build().alphabet_len(), 256); + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/dfa.rs cargo-0.35.0/vendor/aho-corasick/src/dfa.rs --- cargo-0.33.0/vendor/aho-corasick/src/dfa.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/dfa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,688 @@ +use std::mem::size_of; + +use ahocorasick::MatchKind; +use automaton::Automaton; +use classes::ByteClasses; +use error::Result; +use nfa::{NFA, PatternID, PatternLength}; +use prefilter::{Prefilter, PrefilterObj, PrefilterState}; +use state_id::{StateID, dead_id, fail_id, premultiply_overflow_error}; +use Match; + +#[derive(Clone, Debug)] +pub enum DFA { + Standard(Standard), + ByteClass(ByteClass), + Premultiplied(Premultiplied), + PremultipliedByteClass(PremultipliedByteClass), +} + +impl DFA { + fn repr(&self) -> &Repr { + match *self { + DFA::Standard(ref dfa) => dfa.repr(), + DFA::ByteClass(ref dfa) => dfa.repr(), + DFA::Premultiplied(ref dfa) => dfa.repr(), + DFA::PremultipliedByteClass(ref dfa) => dfa.repr(), + } + } + + pub fn match_kind(&self) -> &MatchKind { + &self.repr().match_kind + } + + pub fn heap_bytes(&self) -> usize { + self.repr().heap_bytes + } + + pub fn max_pattern_len(&self) -> usize { + self.repr().max_pattern_len + } + + pub fn pattern_count(&self) -> usize { + self.repr().pattern_count + } + + pub fn start_state(&self) -> S { + self.repr().start_id + } + + #[inline(always)] + pub fn overlapping_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + match_index: &mut usize, + ) -> Option { + match *self { + DFA::Standard(ref dfa) => { + dfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + DFA::ByteClass(ref dfa) => { + dfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + DFA::Premultiplied(ref dfa) => { + dfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + DFA::PremultipliedByteClass(ref dfa) => { + dfa.overlapping_find_at( + prestate, haystack, at, state_id, match_index, + ) + } + } + } + + #[inline(always)] + pub fn earliest_find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + ) -> Option { + match *self { + DFA::Standard(ref dfa) => { + dfa.earliest_find_at(prestate, haystack, at, state_id) + } + DFA::ByteClass(ref dfa) => { + dfa.earliest_find_at(prestate, haystack, at, state_id) + } + DFA::Premultiplied(ref dfa) => { + dfa.earliest_find_at(prestate, haystack, at, state_id) + } + DFA::PremultipliedByteClass(ref dfa) => { + dfa.earliest_find_at(prestate, haystack, at, state_id) + } + } + } + + #[inline(always)] + pub fn find_at( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + at: usize, + state_id: &mut S, + ) -> Option { + match *self { + DFA::Standard(ref dfa) => { + dfa.find_at(prestate, haystack, at, state_id) + } + DFA::ByteClass(ref dfa) => { + dfa.find_at(prestate, haystack, at, state_id) + } + DFA::Premultiplied(ref dfa) => { + dfa.find_at(prestate, haystack, at, state_id) + } + DFA::PremultipliedByteClass(ref dfa) => { + dfa.find_at(prestate, haystack, at, state_id) + } + } + } +} + +#[derive(Clone, Debug)] +pub struct Standard(Repr); + +impl Standard { + fn repr(&self) -> &Repr { + &self.0 + } +} + +impl Automaton for Standard { + type ID = S; + + fn match_kind(&self) -> &MatchKind { + &self.repr().match_kind + } + + fn prefilter(&self) -> Option<&Prefilter> { + self.repr().prefilter.as_ref().map(|p| p.as_ref()) + } + + fn start_state(&self) -> S { + self.repr().start_id + } + + fn is_valid(&self, id: S) -> bool { + id.to_usize() < self.repr().state_count + } + + fn is_match_state(&self, id: S) -> bool { + self.repr().is_match_state(id) + } + + fn is_match_or_dead_state(&self, id: S) -> bool { + self.repr().is_match_or_dead_state(id) + } + + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + self.repr().get_match(id, match_index, end) + } + + fn match_count(&self, id: S) -> usize { + self.repr().match_count(id) + } + + unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S { + let o = current.to_usize() * 256 + input as usize; + *self.repr().trans.get_unchecked(o) + } +} + +#[derive(Clone, Debug)] +pub struct ByteClass(Repr); + +impl ByteClass { + fn repr(&self) -> &Repr { + &self.0 + } +} + +impl Automaton for ByteClass { + type ID = S; + + fn match_kind(&self) -> &MatchKind { + &self.repr().match_kind + } + + fn prefilter(&self) -> Option<&Prefilter> { + self.repr().prefilter.as_ref().map(|p| p.as_ref()) + } + + fn start_state(&self) -> S { + self.repr().start_id + } + + fn is_valid(&self, id: S) -> bool { + id.to_usize() < self.repr().state_count + } + + fn is_match_state(&self, id: S) -> bool { + self.repr().is_match_state(id) + } + + fn is_match_or_dead_state(&self, id: S) -> bool { + self.repr().is_match_or_dead_state(id) + } + + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + self.repr().get_match(id, match_index, end) + } + + fn match_count(&self, id: S) -> usize { + self.repr().match_count(id) + } + + unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S { + let alphabet_len = self.repr().byte_classes.alphabet_len(); + let input = self.repr().byte_classes.get_unchecked(input); + let o = current.to_usize() * alphabet_len + input as usize; + *self.repr().trans.get_unchecked(o) + } +} + +#[derive(Clone, Debug)] +pub struct Premultiplied(Repr); + +impl Premultiplied { + fn repr(&self) -> &Repr { + &self.0 + } +} + +impl Automaton for Premultiplied { + type ID = S; + + fn match_kind(&self) -> &MatchKind { + &self.repr().match_kind + } + + fn prefilter(&self) -> Option<&Prefilter> { + self.repr().prefilter.as_ref().map(|p| p.as_ref()) + } + + fn start_state(&self) -> S { + self.repr().start_id + } + + fn is_valid(&self, id: S) -> bool { + (id.to_usize() / 256) < self.repr().state_count + } + + fn is_match_state(&self, id: S) -> bool { + self.repr().is_match_state(id) + } + + fn is_match_or_dead_state(&self, id: S) -> bool { + self.repr().is_match_or_dead_state(id) + } + + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + if id > self.repr().max_match { + return None; + } + self.repr() + .matches + .get(id.to_usize() / 256) + .and_then(|m| m.get(match_index)) + .map(|&(id, len)| Match { pattern: id, len, end }) + } + + fn match_count(&self, id: S) -> usize { + let o = id.to_usize() / 256; + self.repr().matches[o].len() + } + + unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S { + let o = current.to_usize() + input as usize; + *self.repr().trans.get_unchecked(o) + } +} + +#[derive(Clone, Debug)] +pub struct PremultipliedByteClass(Repr); + +impl PremultipliedByteClass { + fn repr(&self) -> &Repr { + &self.0 + } +} + +impl Automaton for PremultipliedByteClass { + type ID = S; + + fn match_kind(&self) -> &MatchKind { + &self.repr().match_kind + } + + fn prefilter(&self) -> Option<&Prefilter> { + self.repr().prefilter.as_ref().map(|p| p.as_ref()) + } + + fn start_state(&self) -> S { + self.repr().start_id + } + + fn is_valid(&self, id: S) -> bool { + (id.to_usize() / self.repr().alphabet_len()) < self.repr().state_count + } + + fn is_match_state(&self, id: S) -> bool { + self.repr().is_match_state(id) + } + + fn is_match_or_dead_state(&self, id: S) -> bool { + self.repr().is_match_or_dead_state(id) + } + + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + if id > self.repr().max_match { + return None; + } + self.repr() + .matches + .get(id.to_usize() / self.repr().alphabet_len()) + .and_then(|m| m.get(match_index)) + .map(|&(id, len)| Match { pattern: id, len, end }) + } + + fn match_count(&self, id: S) -> usize { + let o = id.to_usize() / self.repr().alphabet_len(); + self.repr().matches[o].len() + } + + unsafe fn next_state_unchecked(&self, current: S, input: u8) -> S { + let input = self.repr().byte_classes.get_unchecked(input); + let o = current.to_usize() + input as usize; + *self.repr().trans.get_unchecked(o) + } +} + +#[derive(Clone, Debug)] +pub struct Repr { + match_kind: MatchKind, + premultiplied: bool, + start_id: S, + /// The length, in bytes, of the longest pattern in this automaton. This + /// information is useful for keeping correct buffer sizes when searching + /// on streams. + max_pattern_len: usize, + /// The total number of patterns added to this automaton. This includes + /// patterns that may never match. + pattern_count: usize, + state_count: usize, + max_match: S, + /// The number of bytes of heap used by this NFA's transition table. + heap_bytes: usize, + /// A prefilter for quickly detecting candidate matchs, if pertinent. + prefilter: Option, + byte_classes: ByteClasses, + trans: Vec, + matches: Vec>, +} + +impl Repr { + /// Returns the total alphabet size for this DFA. + /// + /// If byte classes are enabled, then this corresponds to the number of + /// equivalence classes. If they are disabled, then this is always 256. + fn alphabet_len(&self) -> usize { + self.byte_classes.alphabet_len() + } + + /// Returns true only if the given state is a match state. + fn is_match_state(&self, id: S) -> bool { + id <= self.max_match && id > dead_id() + } + + /// Returns true only if the given state is either a dead state or a match + /// state. + fn is_match_or_dead_state(&self, id: S) -> bool { + id <= self.max_match + } + + /// Get the ith match for the given state, where the end position of a + /// match was found at `end`. + /// + /// # Panics + /// + /// The caller must ensure that the given state identifier is valid, + /// otherwise this may panic. The `match_index` need not be valid. That is, + /// if the given state has no matches then this returns `None`. + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + if id > self.max_match { + return None; + } + self.matches + .get(id.to_usize()) + .and_then(|m| m.get(match_index)) + .map(|&(id, len)| Match { pattern: id, len, end }) + } + + /// Return the total number of matches for the given state. + /// + /// # Panics + /// + /// The caller must ensure that the given identifier is valid, or else + /// this panics. + fn match_count(&self, id: S) -> usize { + self.matches[id.to_usize()].len() + } + + /// Get the next state given `from` as the current state and `byte` as the + /// current input byte. + fn next_state(&self, from: S, byte: u8) -> S { + let alphabet_len = self.alphabet_len(); + let byte = self.byte_classes.get(byte); + self.trans[from.to_usize() * alphabet_len + byte as usize] + } + + /// Set the `byte` transition for the `from` state to point to `to`. + fn set_next_state(&mut self, from: S, byte: u8, to: S) { + let alphabet_len = self.alphabet_len(); + let byte = self.byte_classes.get(byte); + self.trans[from.to_usize() * alphabet_len + byte as usize] = to; + } + + /// Swap the given states in place. + fn swap_states(&mut self, id1: S, id2: S) { + assert!(!self.premultiplied, "can't swap states in premultiplied DFA"); + + let o1 = id1.to_usize() * self.alphabet_len(); + let o2 = id2.to_usize() * self.alphabet_len(); + for b in 0..self.alphabet_len() { + self.trans.swap(o1 + b, o2 + b); + } + self.matches.swap(id1.to_usize(), id2.to_usize()); + } + + /// This routine shuffles all match states in this DFA to the beginning + /// of the DFA such that every non-match state appears after every match + /// state. (With one exception: the special fail and dead states remain as + /// the first two states.) + /// + /// The purpose of doing this shuffling is to avoid an extra conditional + /// in the search loop, and in particular, detecting whether a state is a + /// match or not does not need to access any memory. + /// + /// This updates `self.max_match` to point to the last matching state as + /// well as `self.start` if the starting state was moved. + fn shuffle_match_states(&mut self) { + assert!( + !self.premultiplied, + "cannot shuffle match states of premultiplied DFA" + ); + + if self.state_count <= 1 { + return; + } + + let mut first_non_match = self.start_id.to_usize(); + while first_non_match < self.state_count + && self.matches[first_non_match].len() > 0 + { + first_non_match += 1; + } + + let mut swaps: Vec = vec![fail_id(); self.state_count]; + let mut cur = self.state_count - 1; + while cur > first_non_match { + if self.matches[cur].len() > 0 { + self.swap_states( + S::from_usize(cur), + S::from_usize(first_non_match), + ); + swaps[cur] = S::from_usize(first_non_match); + swaps[first_non_match] = S::from_usize(cur); + + first_non_match += 1; + while first_non_match < cur + && self.matches[first_non_match].len() > 0 + { + first_non_match += 1; + } + } + cur -= 1; + } + for id in (0..self.state_count).map(S::from_usize) { + let alphabet_len = self.alphabet_len(); + let offset = id.to_usize() * alphabet_len; + for next in &mut self.trans[offset..offset + alphabet_len] { + if swaps[next.to_usize()] != fail_id() { + *next = swaps[next.to_usize()]; + } + } + } + if swaps[self.start_id.to_usize()] != fail_id() { + self.start_id = swaps[self.start_id.to_usize()]; + } + self.max_match = S::from_usize(first_non_match - 1); + } + + fn premultiply(&mut self) -> Result<()> { + if self.premultiplied || self.state_count <= 1 { + return Ok(()); + } + + let alpha_len = self.alphabet_len(); + premultiply_overflow_error( + S::from_usize(self.state_count - 1), + alpha_len, + )?; + + for id in (2..self.state_count).map(S::from_usize) { + let offset = id.to_usize() * alpha_len; + for next in &mut self.trans[offset..offset + alpha_len] { + if *next == dead_id() { + continue; + } + *next = S::from_usize(next.to_usize() * alpha_len); + } + } + self.premultiplied = true; + self.start_id = S::from_usize(self.start_id.to_usize() * alpha_len); + self.max_match = S::from_usize(self.max_match.to_usize() * alpha_len); + Ok(()) + } + + /// Computes the total amount of heap used by this NFA in bytes. + fn calculate_size(&mut self) { + let mut size = + (self.trans.len() * size_of::()) + + (self.matches.len() * + size_of::>()); + for state_matches in &self.matches { + size += + state_matches.len() * size_of::<(PatternID, PatternLength)>(); + } + self.heap_bytes = size; + } +} + +/// A builder for configuring the determinization of an NFA into a DFA. +#[derive(Clone, Debug)] +pub struct Builder { + premultiply: bool, + byte_classes: bool, +} + +impl Builder { + /// Create a new builder for a DFA. + pub fn new() -> Builder { + Builder { + premultiply: true, + byte_classes: true, + } + } + + /// Build a DFA from the given NFA. + /// + /// This returns an error if the state identifiers exceed their + /// representation size. This can only happen when state ids are + /// premultiplied (which is enabled by default). + pub fn build(&self, nfa: &NFA) -> Result> { + let byte_classes = + if self.byte_classes { + nfa.byte_classes().clone() + } else { + ByteClasses::singletons() + }; + let alphabet_len = byte_classes.alphabet_len(); + let trans = vec![fail_id(); alphabet_len * nfa.state_len()]; + let matches = vec![vec![]; nfa.state_len()]; + let mut repr = Repr { + match_kind: nfa.match_kind().clone(), + premultiplied: false, + start_id: nfa.start_state(), + max_pattern_len: nfa.max_pattern_len(), + pattern_count: nfa.pattern_count(), + state_count: nfa.state_len(), + max_match: fail_id(), + heap_bytes: 0, + prefilter: nfa.prefilter_obj().map(|p| p.clone()), + byte_classes: byte_classes.clone(), + trans: trans, + matches: matches, + }; + for id in (0..nfa.state_len()).map(S::from_usize) { + repr.matches[id.to_usize()].extend_from_slice(nfa.matches(id)); + + let fail = nfa.failure_transition(id); + nfa.iter_all_transitions(&byte_classes, id, |b, mut next| { + if next == fail_id() { + next = nfa_next_state_memoized(nfa, &repr, id, fail, b); + } + repr.set_next_state(id, b, next); + }); + } + repr.shuffle_match_states(); + repr.calculate_size(); + if self.premultiply { + repr.premultiply()?; + if byte_classes.is_singleton() { + Ok(DFA::Premultiplied(Premultiplied(repr))) + } else { + Ok(DFA::PremultipliedByteClass(PremultipliedByteClass(repr))) + } + } else { + if byte_classes.is_singleton() { + Ok(DFA::Standard(Standard(repr))) + } else { + Ok(DFA::ByteClass(ByteClass(repr))) + } + } + } + + /// Whether to use byte classes or in the DFA. + pub fn byte_classes(&mut self, yes: bool) -> &mut Builder { + self.byte_classes = yes; + self + } + + /// Whether to premultiply state identifier in the DFA. + pub fn premultiply(&mut self, yes: bool) -> &mut Builder { + self.premultiply = yes; + self + } +} + +/// This returns the next NFA transition (including resolving failure +/// transitions), except once it sees a state id less than the id of the DFA +/// state that is currently being populated, then we no longer need to follow +/// failure transitions and can instead query the pre-computed state id from +/// the DFA itself. +/// +/// In general, this should only be called when a failure transition is seen. +fn nfa_next_state_memoized( + nfa: &NFA, + dfa: &Repr, + populating: S, + mut current: S, + input: u8, +) -> S { + loop { + if current < populating { + return dfa.next_state(current, input); + } + let next = nfa.next_state(current, input); + if next != fail_id() { + return next; + } + current = nfa.failure_transition(current); + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/error.rs cargo-0.35.0/vendor/aho-corasick/src/error.rs --- cargo-0.33.0/vendor/aho-corasick/src/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,103 @@ +use std::error; +use std::fmt; +use std::result; + +pub type Result = result::Result; + +/// An error that occurred during the construction of an Aho-Corasick +/// automaton. +#[derive(Clone, Debug)] +pub struct Error { + kind: ErrorKind, +} + +/// The kind of error that occurred. +#[derive(Clone, Debug)] +pub enum ErrorKind { + /// An error that occurs when constructing an automaton would require the + /// use of a state ID that overflows the chosen state ID representation. + /// For example, if one is using `u8` for state IDs and builds a DFA with + /// 257 states, then the last state's ID will be `256` which cannot be + /// represented with `u8`. + StateIDOverflow { + /// The maximum possible state ID. + max: usize, + }, + /// An error that occurs when premultiplication of state IDs is requested + /// when constructing an Aho-Corasick DFA, but doing so would overflow the + /// chosen state ID representation. + /// + /// When `max == requested_max`, then the state ID would overflow `usize`. + PremultiplyOverflow { + /// The maximum possible state id. + max: usize, + /// The maximum ID required by premultiplication. + requested_max: usize, + } +} + +impl Error { + /// Return the kind of this error. + pub fn kind(&self) -> &ErrorKind { + &self.kind + } + + pub(crate) fn state_id_overflow(max: usize) -> Error { + Error { kind: ErrorKind::StateIDOverflow { max } } + } + + pub(crate) fn premultiply_overflow( + max: usize, + requested_max: usize, + ) -> Error { + Error { kind: ErrorKind::PremultiplyOverflow { max, requested_max } } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match self.kind { + ErrorKind::StateIDOverflow { .. } => { + "state id representation too small" + } + ErrorKind::PremultiplyOverflow { .. } => { + "state id representation too small for premultiplication" + } + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.kind { + ErrorKind::StateIDOverflow { max } => { + write!( + f, + "building the automaton failed because it required \ + building more states that can be identified, where the \ + maximum ID for the chosen representation is {}", + max, + ) + } + ErrorKind::PremultiplyOverflow { max, requested_max } => { + if max == requested_max { + write!( + f, + "premultiplication of states requires the ability to \ + represent a state ID greater than what can fit on \ + this platform's usize, which is {}", + ::std::usize::MAX, + ) + } else { + write!( + f, + "premultiplication of states requires the ability to \ + represent at least a state ID of {}, but the chosen \ + representation only permits a maximum state ID of {}", + requested_max, max, + ) + } + } + } + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/full.rs cargo-0.35.0/vendor/aho-corasick/src/full.rs --- cargo-0.33.0/vendor/aho-corasick/src/full.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/full.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ -use std::fmt; -use std::mem; - -use super::{ - FAIL_STATE, - StateIdx, AcAutomaton, Transitions, Match, - usize_bytes, vec_bytes, -}; -use super::autiter::Automaton; - -/// A complete Aho-Corasick automaton. -/// -/// This uses a single transition matrix that permits each input character -/// to move to the next state with a single lookup in the matrix. -/// -/// This is as fast as it gets, but it is guaranteed to use a lot of memory. -/// Namely, it will use at least `4 * 256 * #states`, where the number of -/// states is capped at length of all patterns concatenated. -#[derive(Clone)] -pub struct FullAcAutomaton

{ - pats: Vec

, - trans: Vec, // row-major, where states are rows - out: Vec>, // indexed by StateIdx - start_bytes: Vec, -} - -impl> FullAcAutomaton

{ - /// Build a new expanded Aho-Corasick automaton from an existing - /// Aho-Corasick automaton. - pub fn new(ac: AcAutomaton) -> FullAcAutomaton

{ - let mut fac = FullAcAutomaton { - pats: vec![], - trans: vec![FAIL_STATE; 256 * ac.states.len()], - out: vec![vec![]; ac.states.len()], - start_bytes: vec![], - }; - fac.build_matrix(&ac); - fac.pats = ac.pats; - fac.start_bytes = ac.start_bytes; - fac - } - - #[doc(hidden)] - pub fn memory_usage(&self) -> usize { - self.pats.iter() - .map(|p| vec_bytes() + p.as_ref().len()) - .sum::() - + (4 * self.trans.len()) - + self.out.iter() - .map(|v| vec_bytes() + (usize_bytes() * v.len())) - .sum::() - + self.start_bytes.len() - } - - #[doc(hidden)] - pub fn heap_bytes(&self) -> usize { - self.pats.iter() - .map(|p| mem::size_of::

() + p.as_ref().len()) - .sum::() - + (4 * self.trans.len()) - + self.out.iter() - .map(|v| vec_bytes() + (usize_bytes() * v.len())) - .sum::() - + self.start_bytes.len() - } - - fn set(&mut self, si: StateIdx, i: u8, goto: StateIdx) { - let ns = self.num_states(); - self.trans[i as usize * ns + si as usize] = goto; - } - - #[doc(hidden)] - #[inline] - pub fn num_states(&self) -> usize { - self.out.len() - } -} - -impl> Automaton

for FullAcAutomaton

{ - #[inline] - fn next_state(&self, si: StateIdx, i: u8) -> StateIdx { - let at = i as usize * self.num_states() + si as usize; - unsafe { *self.trans.get_unchecked(at) } - } - - #[inline] - fn get_match(&self, si: StateIdx, outi: usize, texti: usize) -> Match { - let pati = self.out[si as usize][outi]; - let patlen = self.pats[pati].as_ref().len(); - let start = texti + 1 - patlen; - Match { - pati: pati, - start: start, - end: start + patlen, - } - } - - #[inline] - fn has_match(&self, si: StateIdx, outi: usize) -> bool { - unsafe { outi < self.out.get_unchecked(si as usize).len() } - } - - #[inline] - fn start_bytes(&self) -> &[u8] { - &self.start_bytes - } - - #[inline] - fn patterns(&self) -> &[P] { - &self.pats - } - - #[inline] - fn pattern(&self, i: usize) -> &P { - &self.pats[i] - } -} - -impl> FullAcAutomaton

{ - fn build_matrix(&mut self, ac: &AcAutomaton) { - for (si, s) in ac.states.iter().enumerate().skip(1) { - self.set_states(ac, si as StateIdx); - self.out[si].extend_from_slice(&s.out); - } - } - - fn set_states(&mut self, ac: &AcAutomaton, si: StateIdx) { - let current_state = &ac.states[si as usize]; - let first_fail_state = current_state.fail; - current_state.for_each_transition(move |b, maybe_si| { - let goto = if maybe_si == FAIL_STATE { - ac.memoized_next_state(self, si, first_fail_state, b) - } else { - maybe_si - }; - self.set(si, b, goto); - }); - } -} - -impl + fmt::Debug> fmt::Debug for FullAcAutomaton

{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FullAcAutomaton({:?})", self.pats) - } -} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/lib.rs cargo-0.35.0/vendor/aho-corasick/src/lib.rs --- cargo-0.33.0/vendor/aho-corasick/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,1082 +1,289 @@ /*! -An implementation of the -[Aho-Corasick string search algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm). +A library for finding occurrences of many patterns at once. This library +provides multiple pattern search principally through an implementation of the +[Aho-Corasick algorithm](https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm), +which builds a fast finite state machine for executing searches in linear time. + +Additionally, this library provides a number of configuration options for +building the automaton that permit controlling the space versus time trade +off. Other features include simple ASCII case insensitive matching, finding +overlapping matches, replacements, searching streams and even searching and +replacing text in streams. + +Finally, unlike all other (known) Aho-Corasick implementations, this one +supports enabling +[leftmost-first](enum.MatchKind.html#variant.LeftmostFirst) +or +[leftmost-longest](enum.MatchKind.html#variant.LeftmostFirst) +match semantics, using a (seemingly) novel alternative construction algorithm. +For more details on what match semantics means, see the +[`MatchKind`](enum.MatchKind.html) +type. + +# Overview + +This section gives a brief overview of the primary types in this crate: + +* [`AhoCorasick`](struct.AhoCorasick.html) is the primary type and represents + an Aho-Corasick automaton. This is the type you use to execute searches. +* [`AhoCorasickBuilder`](struct.AhoCorasickBuilder.html) can be used to build + an Aho-Corasick automaton, and supports configuring a number of options. +* [`Match`](struct.Match.html) represents a single match reported by an + Aho-Corasick automaton. Each match has two pieces of information: the pattern + that matched and the start and end byte offsets corresponding to the position + in the haystack at which it matched. + +# Example: basic searching + +This example shows how to search for occurrences of multiple patterns +simultaneously. Each match includes the pattern that matched along with the +byte offsets of the match. -The Aho-Corasick algorithm is principally useful when you need to search many -large texts for a fixed (possibly large) set of keywords. In particular, the -Aho-Corasick algorithm preprocesses the set of keywords by constructing a -finite state machine. The search phase is then a quick linear scan through the -text. Each character in the search text causes a state transition in the -automaton. Matches are reported when the automaton enters a match state. - -# Examples - -The main type exposed by this crate is `AcAutomaton`, which can be constructed -from an iterator of pattern strings: - -```rust -use aho_corasick::{Automaton, AcAutomaton}; - -let aut = AcAutomaton::new(vec!["apple", "maple"]); - -// AcAutomaton also implements `FromIterator`: -let aut: AcAutomaton<&str> = ["apple", "maple"].iter().cloned().collect(); ``` +use aho_corasick::AhoCorasick; -Finding matches can be done with `find`: - -```rust -use aho_corasick::{Automaton, AcAutomaton, Match}; - -let aut = AcAutomaton::new(vec!["apple", "maple"]); -let mut it = aut.find("I like maple apples."); -assert_eq!(it.next(), Some(Match { - pati: 1, - start: 7, - end: 12, -})); -assert_eq!(it.next(), Some(Match { - pati: 0, - start: 13, - end: 18, -})); -assert_eq!(it.next(), None); -``` +let patterns = &["apple", "maple", "Snapple"]; +let haystack = "Nobody likes maple in their apple flavored Snapple."; -Use `find_overlapping` if you want to report all matches, even if they -overlap with each other. - -```rust -use aho_corasick::{Automaton, AcAutomaton, Match}; - -let aut = AcAutomaton::new(vec!["abc", "a"]); -let matches: Vec<_> = aut.find_overlapping("abc").collect(); +let ac = AhoCorasick::new(patterns); +let mut matches = vec![]; +for mat in ac.find_iter(haystack) { + matches.push((mat.pattern(), mat.start(), mat.end())); +} assert_eq!(matches, vec![ - Match { pati: 1, start: 0, end: 1}, Match { pati: 0, start: 0, end: 3 }, + (1, 13, 18), + (0, 28, 33), + (2, 43, 50), ]); - -// Regular `find` will report only one match: -let matches: Vec<_> = aut.find("abc").collect(); -assert_eq!(matches, vec![Match { pati: 1, start: 0, end: 1}]); ``` -Finally, there are also methods for finding matches on *streams*. Namely, the -search text does not have to live in memory. It's useful to run this on files -that can't fit into memory: - -```no_run -use std::fs::File; - -use aho_corasick::{Automaton, AcAutomaton}; - -let aut = AcAutomaton::new(vec!["foo", "bar", "baz"]); -let rdr = File::open("search.txt").unwrap(); -for m in aut.stream_find(rdr) { - let m = m.unwrap(); // could be an IO error - println!("Pattern '{}' matched at: ({}, {})", - aut.pattern(m.pati), m.start, m.end); -} -``` +# Example: case insensitivity -There is also `stream_find_overlapping`, which is just like `find_overlapping`, -but it operates on streams. +This is like the previous example, but matches `Snapple` case insensitively +using `AhoCorasickBuilder`: -Please see `dict-search.rs` in this crate's `examples` directory for a more -complete example. It creates a large automaton from a dictionary and can do a -streaming match over arbitrarily large data. - -# Memory usage - -A key aspect of an Aho-Corasick implementation is how the state transitions -are represented. The easiest way to make the automaton fast is to store a -sparse 256-slot map in each state. It maps an input byte to a state index. -This makes the matching loop extremely fast, since it translates to a simple -pointer read. - -The problem is that as the automaton accumulates more states, you end up paying -a `256 * 4` (`4` is for the `u32` state index) byte penalty for every state -regardless of how many transitions it has. - -To solve this, only states near the root of the automaton have this sparse -map representation. States near the leaves of the automaton use a dense mapping -that requires a linear scan. - -(The specific limit currently set is `3`, so that states with a depth less than -or equal to `3` are less memory efficient. The result is that the memory usage -of the automaton stops growing rapidly past ~60MB, even for automatons with -thousands of patterns.) - -If you'd like to opt for the less-memory-efficient-but-faster version, then -you can construct an `AcAutomaton` with a `Sparse` transition strategy: - -```rust -use aho_corasick::{Automaton, AcAutomaton, Match, Sparse}; - -let aut = AcAutomaton::<&str, Sparse>::with_transitions(vec!["abc", "a"]); -let matches: Vec<_> = aut.find("abc").collect(); -assert_eq!(matches, vec![Match { pati: 1, start: 0, end: 1}]); ``` -*/ +use aho_corasick::AhoCorasickBuilder; -#![deny(missing_docs)] - -extern crate memchr; -#[cfg(test)] -extern crate quickcheck; -#[cfg(test)] -extern crate rand; - -use std::collections::VecDeque; -use std::fmt; -use std::iter::FromIterator; -use std::mem; - -pub use self::autiter::{ - Automaton, Match, - Matches, MatchesOverlapping, StreamMatches, StreamMatchesOverlapping, -}; -pub use self::full::FullAcAutomaton; +let patterns = &["apple", "maple", "snapple"]; +let haystack = "Nobody likes maple in their apple flavored Snapple."; -// We're specifying paths explicitly so that we can use -// these modules simultaneously from `main.rs`. -// Should probably make just make `main.rs` a separate crate. -#[path = "autiter.rs"] -mod autiter; -#[path = "full.rs"] -mod full; - -/// The integer type used for the state index. -/// -/// Limiting this to 32 bit integers can have a big impact on memory usage -/// when using the `Sparse` transition representation. -pub type StateIdx = u32; - -// Constants for special state indexes. -const FAIL_STATE: u32 = 0; -const ROOT_STATE: u32 = 1; - -// Limit the depth at which we use a sparse alphabet map. Once the limit is -// reached, a dense set is used (and lookup becomes O(n)). -// -// This does have a performance hit, but the (straight forward) alternative -// is to have a `256 * 4` byte overhead for every state. -// Given that Aho-Corasick is typically used for dictionary searching, this -// can lead to dramatic memory bloat. -// -// This limit should only be increased at your peril. Namely, in the worst -// case, `256^DENSE_DEPTH_THRESHOLD * 4` corresponds to the memory usage in -// bytes. A value of `1` gives us a good balance. This is also a happy point -// in the benchmarks. A value of `0` gives considerably worse times on certain -// benchmarks (e.g., `ac_ten_one_prefix_byte_every_match`) than even a value -// of `1`. A value of `2` is slightly better than `1` and it looks like gains -// level off at that point with not much observable difference when set to -// `3`. -// -// Why not make this user configurable? Well, it doesn't make much sense -// because we pay for it with case analysis in the matching loop. Increasing it -// doesn't have much impact on performance (outside of pathological cases?). -// -// N.B. Someone else seems to have discovered an alternative, but I haven't -// grokked it yet: https://github.com/mischasan/aho-corasick -const DENSE_DEPTH_THRESHOLD: u32 = 1; - -/// An Aho-Corasick finite automaton. -/// -/// The type parameter `P` is the type of the pattern that was used to -/// construct this AcAutomaton. -#[derive(Clone)] -pub struct AcAutomaton { - pats: Vec

, - states: Vec>, - start_bytes: Vec, +let ac = AhoCorasickBuilder::new() + .ascii_case_insensitive(true) + .build(patterns); +let mut matches = vec![]; +for mat in ac.find_iter(haystack) { + matches.push((mat.pattern(), mat.start(), mat.end())); } +assert_eq!(matches, vec![ + (1, 13, 18), + (0, 28, 33), + (2, 43, 50), +]); +``` -#[derive(Clone)] -struct State { - out: Vec, - fail: StateIdx, - goto: T, - depth: u32, -} - -impl> AcAutomaton

{ - /// Create a new automaton from an iterator of patterns. - /// - /// The patterns must be convertible to bytes (`&[u8]`) via the `AsRef` - /// trait. - pub fn new(pats: I) -> AcAutomaton - where I: IntoIterator { - AcAutomaton::with_transitions(pats) - } -} - -impl, T: Transitions> AcAutomaton { - /// Create a new automaton from an iterator of patterns. - /// - /// This constructor allows one to choose the transition representation. - /// - /// The patterns must be convertible to bytes (`&[u8]`) via the `AsRef` - /// trait. - pub fn with_transitions(pats: I) -> AcAutomaton - where I: IntoIterator { - AcAutomaton { - pats: vec![], // filled in later, avoid wrath of borrow checker - states: vec![State::new(0), State::new(0)], // empty and root - start_bytes: vec![], // also filled in later - }.build(pats.into_iter().collect()) - } - - /// Build out the entire automaton into a single matrix. - /// - /// This will make searching as fast as possible at the expense of using - /// at least `4 * 256 * #states` bytes of memory. - pub fn into_full(self) -> FullAcAutomaton

{ - FullAcAutomaton::new(self) - } - - #[doc(hidden)] - pub fn num_states(&self) -> usize { - self.states.len() - } - - #[doc(hidden)] - pub fn heap_bytes(&self) -> usize { - self.pats.iter() - .map(|p| mem::size_of::

() + p.as_ref().len()) - .sum::() - + self.states.iter() - .map(|s| mem::size_of::>() + s.heap_bytes()) - .sum::() - + self.start_bytes.len() - } +# Example: replacing matches in a stream - // The states of `full_automaton` should be set for all states < si - fn memoized_next_state( - &self, - full_automaton: &FullAcAutomaton

, - current_si: StateIdx, - mut si: StateIdx, - b: u8, - ) -> StateIdx { - loop { - if si < current_si { - return full_automaton.next_state(si, b); - } - let state = &self.states[si as usize]; - let maybe_si = state.goto(b); - if maybe_si != FAIL_STATE { - return maybe_si; - } else { - si = state.fail; - } - } - } -} +This example shows how to execute a search and replace on a stream without +loading the entire stream into memory first. -impl, T: Transitions> Automaton

for AcAutomaton { - #[inline] - fn next_state(&self, mut si: StateIdx, b: u8) -> StateIdx { - loop { - let state = &self.states[si as usize]; - let maybe_si = state.goto(b); - if maybe_si != FAIL_STATE { - si = maybe_si; - break; - } else { - si = state.fail; - } - } - si - } +``` +use aho_corasick::AhoCorasick; - #[inline] - fn get_match(&self, si: StateIdx, outi: usize, texti: usize) -> Match { - let pati = self.states[si as usize].out[outi]; - let patlen = self.pats[pati].as_ref().len(); - let start = texti + 1 - patlen; - Match { - pati: pati, - start: start, - end: start + patlen, - } - } +# fn example() -> Result<(), ::std::io::Error> { +let patterns = &["fox", "brown", "quick"]; +let replace_with = &["sloth", "grey", "slow"]; + +// In a real example, these might be `std::fs::File`s instead. All you need to +// do is supply a pair of `std::io::Read` and `std::io::Write` implementations. +let rdr = "The quick brown fox."; +let mut wtr = vec![]; + +let ac = AhoCorasick::new(patterns); +ac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)?; +assert_eq!(b"The slow grey sloth.".to_vec(), wtr); +# Ok(()) }; example().unwrap() +``` - #[inline] - fn has_match(&self, si: StateIdx, outi: usize) -> bool { - outi < self.states[si as usize].out.len() - } +# Example: finding the leftmost first match - #[inline] - fn start_bytes(&self) -> &[u8] { - &self.start_bytes - } +In the textbook description of Aho-Corasick, its formulation is typically +structured such that it reports all possible matches, even when they overlap +with another. In many cases, overlapping matches may not be desired, such as +the case of finding all successive non-overlapping matches like you might with +a standard regular expression. + +Unfortunately the "obvious" way to modify the Aho-Corasick algorithm to do +this doesn't always work in the expected way, since it will report matches as +soon as they are seen. For example, consider matching the regex `Samwise|Sam` +against the text `Samwise`. Most regex engines (that are Perl-like, or +non-POSIX) will report `Samwise` as a match, but the standard Aho-Corasick +algorithm modified for reporting non-overlapping matches will report `Sam`. + +A novel contribution of this library is the ability to change the match +semantics of Aho-Corasick (without additional search time overhead) such that +`Samwise` is reported instead. For example, here's the standard approach: - #[inline] - fn patterns(&self) -> &[P] { - &self.pats - } +``` +use aho_corasick::AhoCorasick; - #[inline] - fn pattern(&self, i: usize) -> &P { - &self.pats[i] - } -} +let patterns = &["Samwise", "Sam"]; +let haystack = "Samwise"; -// `(0..256).map(|b| b as u8)` optimizes poorly in debug builds so -// we use this small explicit iterator instead -struct AllBytesIter(i32); -impl Iterator for AllBytesIter { - type Item = u8; - #[inline] - fn next(&mut self) -> Option { - if self.0 < 256 { - let b = self.0 as u8; - self.0 += 1; - Some(b) - } else { - None - } - } -} +let ac = AhoCorasick::new(patterns); +let mat = ac.find(haystack).expect("should have a match"); +assert_eq!("Sam", &haystack[mat.start()..mat.end()]); +``` -impl AllBytesIter { - fn new() -> AllBytesIter { - AllBytesIter(0) - } -} +And now here's the leftmost-first version, which matches how a Perl-like +regex will work: -// Below contains code for *building* the automaton. It's a reasonably faithful -// translation of the description/psuedo-code from: -// http://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf - -impl, T: Transitions> AcAutomaton { - // This is the first phase and builds the initial keyword tree. - fn build(mut self, pats: Vec

) -> AcAutomaton { - for (pati, pat) in pats.iter().enumerate() { - if pat.as_ref().is_empty() { - continue; - } - let mut previ = ROOT_STATE; - for &b in pat.as_ref() { - if self.states[previ as usize].goto(b) != FAIL_STATE { - previ = self.states[previ as usize].goto(b); - } else { - let depth = self.states[previ as usize].depth + 1; - let nexti = self.add_state(State::new(depth)); - self.states[previ as usize].set_goto(b, nexti); - previ = nexti; - } - } - self.states[previ as usize].out.push(pati); - } - { - let root_state = &mut self.states[ROOT_STATE as usize]; - for c in AllBytesIter::new() { - if root_state.goto(c) == FAIL_STATE { - root_state.set_goto(c, ROOT_STATE); - } else { - self.start_bytes.push(c); - } - } - } - // If any of the start bytes are non-ASCII, then remove them all, - // because we don't want to be calling memchr on non-ASCII bytes. - // (Well, we could, but it requires being more clever. Simply using - // the prefix byte isn't good enough.) - if self.start_bytes.iter().any(|&b| b > 0x7F) { - self.start_bytes.clear(); - } - self.pats = pats; - self.fill() - } +``` +use aho_corasick::{AhoCorasickBuilder, MatchKind}; - // The second phase that fills in the back links. - fn fill(mut self) -> AcAutomaton { - // Fill up the queue with all non-root transitions out of the root - // node. Then proceed by breadth first traversal. - let mut q = VecDeque::new(); - self.states[ROOT_STATE as usize].for_each_transition(|_, si| { - if si != ROOT_STATE { - q.push_front(si); - } - }); - - let mut transitions = Vec::new(); - - while let Some(si) = q.pop_back() { - self.states[si as usize].for_each_ok_transition(|c, u| { - transitions.push((c, u)); - q.push_front(u); - }); - - for (c, u) in transitions.drain(..) { - let mut v = self.states[si as usize].fail; - loop { - let state = &self.states[v as usize]; - if state.goto(c) == FAIL_STATE { - v = state.fail; - } else { - break; - } - } - let ufail = self.states[v as usize].goto(c); - self.states[u as usize].fail = ufail; - - fn get_two(xs: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) { - if i < j { - let (before, after) = xs.split_at_mut(j); - (&mut before[i], &mut after[0]) - } else { - let (before, after) = xs.split_at_mut(i); - (&mut after[0], &mut before[j]) - } - } - - let (ufail_out, out) = get_two(&mut self.states, ufail as usize, u as usize); - out.out.extend_from_slice(&ufail_out.out); - } - } - self - } +let patterns = &["Samwise", "Sam"]; +let haystack = "Samwise"; - fn add_state(&mut self, state: State) -> StateIdx { - let i = self.states.len(); - self.states.push(state); - i as StateIdx - } -} +let ac = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostFirst) + .build(patterns); +let mat = ac.find(haystack).expect("should have a match"); +assert_eq!("Samwise", &haystack[mat.start()..mat.end()]); +``` -impl State { - fn new(depth: u32) -> State { - State { - out: vec![], - fail: 1, - goto: Transitions::new(depth), - depth: depth, - } - } +In addition to leftmost-first semantics, this library also supports +leftmost-longest semantics, which match the POSIX behavior of a regular +expression alternation. See +[`MatchKind`](enum.MatchKind.html) +for more details. + +# Prefilters + +While an Aho-Corasick automaton can perform admirably when compared to more +naive solutions, it is generally slower than more specialized algorithms that +are accelerated using vector instructions such as SIMD. + +For that reason, this library will internally use a "prefilter" to attempt +to accelerate searches when possible. Currently, this library has fairly +limited implementation that only applies when there are 3 or fewer unique +starting bytes among all patterns in an automaton. + +In the future, it is intended for this prefilter to grow more sophisticated +by pushing applicable optimizations from the +[`regex`](http://docs.rs/regex) +crate (and other places) down into this library. + +While a prefilter is generally good to have on by default since it works well +in the common case, it can lead to less predictable or even sub-optimal +performance in some cases. For that reason, prefilters can be disabled via +[`AhoCorasickBuilder::prefilter`](struct.AhoCorasickBuilder.html#method.prefilter). +*/ - fn goto(&self, b: u8) -> StateIdx { - self.goto.goto(b) - } +#![deny(missing_docs)] - fn set_goto(&mut self, b: u8, si: StateIdx) { - self.goto.set_goto(b, si); - } +// We can never be truly no_std, but we could be alloc-only some day, so +// require the std feature for now. +#[cfg(not(feature = "std"))] +compile_error!("`std` feature is currently required to build this crate"); - fn heap_bytes(&self) -> usize { - (self.out.len() * usize_bytes()) - + self.goto.heap_bytes() - } +extern crate memchr; - fn for_each_transition(&self, f: F) - where F: FnMut(u8, StateIdx) - { - self.goto.for_each_transition(f) - } +pub use ahocorasick::{ + AhoCorasick, AhoCorasickBuilder, MatchKind, + FindIter, FindOverlappingIter, StreamFindIter, +}; +pub use error::{Error, ErrorKind}; +pub use state_id::StateID; - fn for_each_ok_transition(&self, f: F) - where F: FnMut(u8, StateIdx) - { - self.goto.for_each_ok_transition(f) - } -} +mod ahocorasick; +mod automaton; +mod buffer; +mod dfa; +mod error; +mod classes; +mod prefilter; +mod nfa; +mod state_id; +#[cfg(test)] +mod tests; -/// An abstraction over state transition strategies. +/// A representation of a match reported by an Aho-Corasick automaton. /// -/// This is an attempt to let the caller choose the space/time trade offs -/// used for state transitions. +/// A match has two essential pieces of information: the identifier of the +/// pattern that matched, along with the start and end offsets of the match +/// in the haystack. /// -/// (It's possible that this interface is merely good enough for just the two -/// implementations in this crate.) -pub trait Transitions { - /// Return a new state at the given depth. - fn new(depth: u32) -> Self; - /// Return the next state index given the next character. - fn goto(&self, alpha: u8) -> StateIdx; - /// Set the next state index for the character given. - fn set_goto(&mut self, alpha: u8, si: StateIdx); - /// The memory use in bytes (on the heap) of this set of transitions. - fn heap_bytes(&self) -> usize; - - /// Iterates over each state - fn for_each_transition(&self, mut f: F) - where F: FnMut(u8, StateIdx) - { - for b in AllBytesIter::new() { - f(b, self.goto(b)); - } - } - - /// Iterates over each non-fail state - fn for_each_ok_transition(&self, mut f: F) - where - F: FnMut(u8, StateIdx), - { - self.for_each_transition(|b, si| { - if si != FAIL_STATE { - f(b, si); - } - }); - } -} - -/// State transitions that can be stored either sparsely or densely. +/// # Examples /// -/// This uses less space but at the expense of slower matching. -#[derive(Clone, Debug)] -pub struct Dense(DenseChoice); - -#[derive(Clone, Debug)] -enum DenseChoice { - Sparse(Box), - Dense(Vec<(u8, StateIdx)>), -} - -impl Transitions for Dense { - fn new(depth: u32) -> Dense { - if depth <= DENSE_DEPTH_THRESHOLD { - Dense(DenseChoice::Sparse(Box::new(Sparse::new(depth)))) - } else { - Dense(DenseChoice::Dense(vec![])) - } - } - - fn goto(&self, b1: u8) -> StateIdx { - match self.0 { - DenseChoice::Sparse(ref m) => m.goto(b1), - DenseChoice::Dense(ref m) => { - for &(b2, si) in m { - if b1 == b2 { - return si; - } - } - FAIL_STATE - } - } - } - - fn set_goto(&mut self, b: u8, si: StateIdx) { - match self.0 { - DenseChoice::Sparse(ref mut m) => m.set_goto(b, si), - DenseChoice::Dense(ref mut m) => m.push((b, si)), - } - } - - fn heap_bytes(&self) -> usize { - match self.0 { - DenseChoice::Sparse(_) => mem::size_of::(), - DenseChoice::Dense(ref m) => m.len() * (1 + 4), - } - } - - fn for_each_transition(&self, mut f: F) - where F: FnMut(u8, StateIdx) - { - match self.0 { - DenseChoice::Sparse(ref m) => m.for_each_transition(f), - DenseChoice::Dense(ref m) => { - let mut iter = m.iter(); - let mut b = 0i32; - while let Some(&(next_b, next_si)) = iter.next() { - while (b as u8) < next_b { - f(b as u8, FAIL_STATE); - b += 1; - } - f(b as u8, next_si); - b += 1; - } - while b < 256 { - f(b as u8, FAIL_STATE); - b += 1; - } - } - } - } - fn for_each_ok_transition(&self, mut f: F) - where - F: FnMut(u8, StateIdx), - { - match self.0 { - DenseChoice::Sparse(ref m) => m.for_each_ok_transition(f), - DenseChoice::Dense(ref m) => for &(b, si) in m { - f(b, si) - } - } - } -} - -/// State transitions that are always sparse. +/// Basic usage: /// -/// This can use enormous amounts of memory when there are many patterns, -/// but matching is very fast. -pub struct Sparse([StateIdx; 256]); - -impl Clone for Sparse { - fn clone(&self) -> Sparse { - Sparse(self.0) - } -} - -impl fmt::Debug for Sparse { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_tuple("Sparse").field(&&self.0[..]).finish() - } +/// ``` +/// use aho_corasick::AhoCorasick; +/// +/// let ac = AhoCorasick::new(&[ +/// "foo", "bar", "baz", +/// ]); +/// let mat = ac.find("xxx bar xxx").expect("should have a match"); +/// assert_eq!(1, mat.pattern()); +/// assert_eq!(4, mat.start()); +/// assert_eq!(7, mat.end()); +/// ``` +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Match { + /// The pattern id. + pattern: usize, + /// The length of this match, such that the starting position of the match + /// is `end - len`. + /// + /// We use length here because, other than the pattern id, the only + /// information about each pattern that the automaton stores is its length. + /// So using the length here is just a bit more natural. But it isn't + /// technically required. + len: usize, + /// The end offset of the match, exclusive. + end: usize, } -impl Transitions for Sparse { - fn new(_: u32) -> Sparse { - Sparse([0; 256]) - } - +impl Match { + /// Returns the identifier of the pattern that matched. + /// + /// The identifier of a pattern is derived from the position in which it + /// was originally inserted into the corresponding automaton. The first + /// pattern has identifier `0`, and each subsequent pattern is `1`, `2` + /// and so on. #[inline] - fn goto(&self, b: u8) -> StateIdx { - self.0[b as usize] - } - - fn set_goto(&mut self, b: u8, si: StateIdx) { - self.0[b as usize] = si; - } - - fn heap_bytes(&self) -> usize { - 0 - } -} - -impl> FromIterator for AcAutomaton { - /// Create an automaton from an iterator of strings. - fn from_iter(it: T) -> AcAutomaton where T: IntoIterator { - AcAutomaton::new(it) - } -} - -// Provide some question debug impls for viewing automatons. -// The custom impls mostly exist for special showing of sparse maps. - -impl + fmt::Debug, T: Transitions> - fmt::Debug for AcAutomaton { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::iter::repeat; - - try!(writeln!(f, "{}", repeat('-').take(79).collect::())); - try!(writeln!(f, "Patterns: {:?}", self.pats)); - for (i, state) in self.states.iter().enumerate().skip(1) { - try!(writeln!(f, "{:3}: {}", i, state.debug(i == 1))); - } - write!(f, "{}", repeat('-').take(79).collect::()) - } -} - -impl State { - fn debug(&self, root: bool) -> String { - format!("State {{ depth: {:?}, out: {:?}, fail: {:?}, goto: {{{}}} }}", - self.depth, self.out, self.fail, self.goto_string(root)) - } - - fn goto_string(&self, root: bool) -> String { - let mut goto = vec![]; - for b in AllBytesIter::new() { - let si = self.goto(b); - if (!root && si == FAIL_STATE) || (root && si == ROOT_STATE) { - continue; - } - goto.push(format!("{} => {}", b as char, si)); - } - goto.join(", ") - } -} - -impl fmt::Debug for State { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.debug(false)) - } -} - -impl AcAutomaton { - #[doc(hidden)] - pub fn dot(&self) -> String { - use std::fmt::Write; - let mut out = String::new(); - macro_rules! w { - ($w:expr, $($tt:tt)*) => { {write!($w, $($tt)*)}.unwrap() } - } - - w!(out, r#" -digraph automaton {{ - label=<{}>; - labelloc="l"; - labeljust="l"; - rankdir="LR"; -"#, self.pats.join(", ")); - for (i, s) in self.states.iter().enumerate().skip(1) { - let i = i as u32; - if s.out.is_empty() { - w!(out, " {};\n", i); - } else { - w!(out, " {} [peripheries=2];\n", i); - } - w!(out, " {} -> {} [style=dashed];\n", i, s.fail); - for b in AllBytesIter::new() { - let si = s.goto(b); - if si == FAIL_STATE || (i == ROOT_STATE && si == ROOT_STATE) { - continue; - } - w!(out, " {} -> {} [label={}];\n", i, si, b as char); - } - } - w!(out, "}}"); - out - } -} - -fn vec_bytes() -> usize { - usize_bytes() * 3 -} - -fn usize_bytes() -> usize { - let bits = usize::max_value().count_ones() as usize; - bits / 8 -} - -#[cfg(test)] -mod tests { - use std::collections::HashSet; - use std::io; - - use quickcheck::{Arbitrary, Gen, quickcheck}; - use rand::Rng; - - use super::{AcAutomaton, Automaton, Match, AllBytesIter}; - - fn aut_find(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - AcAutomaton::new(xs.to_vec()).find(&haystack).collect() - } - - fn aut_finds(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - let cur = io::Cursor::new(haystack.as_bytes()); - AcAutomaton::new(xs.to_vec()) - .stream_find(cur).map(|r| r.unwrap()).collect() - } - - fn aut_findf(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - AcAutomaton::new(xs.to_vec()).into_full().find(haystack).collect() + pub fn pattern(&self) -> usize { + self.pattern } - fn aut_findfs(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - let cur = io::Cursor::new(haystack.as_bytes()); - AcAutomaton::new(xs.to_vec()) - .into_full() - .stream_find(cur).map(|r| r.unwrap()).collect() - } - - fn aut_findo(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - AcAutomaton::new(xs.to_vec()).find_overlapping(haystack).collect() - } - - fn aut_findos(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - let cur = io::Cursor::new(haystack.as_bytes()); - AcAutomaton::new(xs.to_vec()) - .stream_find_overlapping(cur).map(|r| r.unwrap()).collect() - } - - fn aut_findfo(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - AcAutomaton::new(xs.to_vec()) - .into_full().find_overlapping(haystack).collect() - } - - fn aut_findfos(xs: &[S], haystack: &str) -> Vec - where S: Clone + AsRef<[u8]> { - let cur = io::Cursor::new(haystack.as_bytes()); - AcAutomaton::new(xs.to_vec()) - .into_full() - .stream_find_overlapping(cur).map(|r| r.unwrap()).collect() - } - - #[test] - fn one_pattern_one_match() { - let ns = vec!["a"]; - let hay = "za"; - let matches = vec![ - Match { pati: 0, start: 1, end: 2 }, - ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn one_pattern_many_match() { - let ns = vec!["a"]; - let hay = "zazazzzza"; - let matches = vec![ - Match { pati: 0, start: 1, end: 2 }, - Match { pati: 0, start: 3, end: 4 }, - Match { pati: 0, start: 8, end: 9 }, - ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn one_longer_pattern_one_match() { - let ns = vec!["abc"]; - let hay = "zazabcz"; - let matches = vec![ Match { pati: 0, start: 3, end: 6 } ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn one_longer_pattern_many_match() { - let ns = vec!["abc"]; - let hay = "zazabczzzzazzzabc"; - let matches = vec![ - Match { pati: 0, start: 3, end: 6 }, - Match { pati: 0, start: 14, end: 17 }, - ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn many_pattern_one_match() { - let ns = vec!["a", "b"]; - let hay = "zb"; - let matches = vec![ Match { pati: 1, start: 1, end: 2 } ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn many_pattern_many_match() { - let ns = vec!["a", "b"]; - let hay = "zbzazzzzb"; - let matches = vec![ - Match { pati: 1, start: 1, end: 2 }, - Match { pati: 0, start: 3, end: 4 }, - Match { pati: 1, start: 8, end: 9 }, - ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_one_match() { - let ns = vec!["abc", "xyz"]; - let hay = "zazxyzz"; - let matches = vec![ Match { pati: 1, start: 3, end: 6 } ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_many_match() { - let ns = vec!["abc", "xyz"]; - let hay = "zazxyzzzzzazzzabcxyz"; - let matches = vec![ - Match { pati: 1, start: 3, end: 6 }, - Match { pati: 0, start: 14, end: 17 }, - Match { pati: 1, start: 17, end: 20 }, - ]; - assert_eq!(&aut_find(&ns, hay), &matches); - assert_eq!(&aut_finds(&ns, hay), &matches); - assert_eq!(&aut_findf(&ns, hay), &matches); - assert_eq!(&aut_findfs(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_overlap_one_match() { - let ns = vec!["abc", "bc"]; - let hay = "zazabcz"; - let matches = vec![ - Match { pati: 0, start: 3, end: 6 }, - Match { pati: 1, start: 4, end: 6 }, - ]; - assert_eq!(&aut_findo(&ns, hay), &matches); - assert_eq!(&aut_findos(&ns, hay), &matches); - assert_eq!(&aut_findfo(&ns, hay), &matches); - assert_eq!(&aut_findfos(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_overlap_one_match_reverse() { - let ns = vec!["abc", "bc"]; - let hay = "xbc"; - let matches = vec![ Match { pati: 1, start: 1, end: 3 } ]; - assert_eq!(&aut_findo(&ns, hay), &matches); - assert_eq!(&aut_findos(&ns, hay), &matches); - assert_eq!(&aut_findfo(&ns, hay), &matches); - assert_eq!(&aut_findfos(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_overlap_many_match() { - let ns = vec!["abc", "bc", "c"]; - let hay = "zzzabczzzbczzzc"; - let matches = vec![ - Match { pati: 0, start: 3, end: 6 }, - Match { pati: 1, start: 4, end: 6 }, - Match { pati: 2, start: 5, end: 6 }, - Match { pati: 1, start: 9, end: 11 }, - Match { pati: 2, start: 10, end: 11 }, - Match { pati: 2, start: 14, end: 15 }, - ]; - assert_eq!(&aut_findo(&ns, hay), &matches); - assert_eq!(&aut_findos(&ns, hay), &matches); - assert_eq!(&aut_findfo(&ns, hay), &matches); - assert_eq!(&aut_findfos(&ns, hay), &matches); - } - - #[test] - fn many_longer_pattern_overlap_many_match_reverse() { - let ns = vec!["abc", "bc", "c"]; - let hay = "zzzczzzbczzzabc"; - let matches = vec![ - Match { pati: 2, start: 3, end: 4 }, - Match { pati: 1, start: 7, end: 9 }, - Match { pati: 2, start: 8, end: 9 }, - Match { pati: 0, start: 12, end: 15 }, - Match { pati: 1, start: 13, end: 15 }, - Match { pati: 2, start: 14, end: 15 }, - ]; - assert_eq!(&aut_findo(&ns, hay), &matches); - assert_eq!(&aut_findos(&ns, hay), &matches); - assert_eq!(&aut_findfo(&ns, hay), &matches); - assert_eq!(&aut_findfos(&ns, hay), &matches); - } - - #[test] - fn pattern_returns_original_type() { - let aut = AcAutomaton::new(vec!["apple", "maple"]); - - // Explicitly given this type to assert that the thing returned - // from the function is our original type. - let pat: &str = aut.pattern(0); - assert_eq!(pat, "apple"); - - // Also check the return type of the `patterns` function. - let pats: &[&str] = aut.patterns(); - assert_eq!(pats, &["apple", "maple"]); - } - - // Quickcheck time. - - // This generates very small ascii strings, which makes them more likely - // to interact in interesting ways with larger haystack strings. - #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] - pub struct SmallAscii(String); - - impl Arbitrary for SmallAscii { - fn arbitrary(g: &mut G) -> SmallAscii { - use std::char::from_u32; - SmallAscii((0..2) - .map(|_| from_u32(g.gen_range(97, 123)).unwrap()) - .collect()) - } - - fn shrink(&self) -> Box> { - Box::new(self.0.shrink().map(SmallAscii)) - } - } - - impl From for String { - fn from(s: SmallAscii) -> String { s.0 } - } - - impl AsRef<[u8]> for SmallAscii { - fn as_ref(&self) -> &[u8] { self.0.as_ref() } + /// The starting position of the match. + #[inline] + pub fn start(&self) -> usize { + self.end - self.len } - // This is the same arbitrary impl as `String`, except it has a bias toward - // ASCII characters. - #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] - pub struct BiasAscii(String); - - impl Arbitrary for BiasAscii { - fn arbitrary(g: &mut G) -> BiasAscii { - use std::char::from_u32; - let size = { let s = g.size(); g.gen_range(0, s) }; - let mut s = String::with_capacity(size); - for _ in 0..size { - if g.gen_bool(0.3) { - s.push(char::arbitrary(g)); - } else { - for _ in 0..5 { - s.push(from_u32(g.gen_range(97, 123)).unwrap()); - } - } - } - BiasAscii(s) - } - - fn shrink(&self) -> Box> { - Box::new(self.0.shrink().map(BiasAscii)) - } + /// The ending position of the match. + #[inline] + pub fn end(&self) -> usize { + self.end } - fn naive_find(xs: &[S], haystack: &str) -> Vec - where S: Clone + Into { - let needles: Vec = - xs.to_vec().into_iter().map(Into::into).collect(); - let mut matches = vec![]; - for hi in 0..haystack.len() { - for (pati, needle) in needles.iter().enumerate() { - let needle = needle.as_bytes(); - if needle.len() == 0 || needle.len() > haystack.len() - hi { - continue; - } - if needle == &haystack.as_bytes()[hi..hi+needle.len()] { - matches.push(Match { - pati: pati, - start: hi, - end: hi + needle.len(), - }); - } - } - } - matches + /// Returns true if and only if this match is empty. That is, when + /// `start() == end()`. + /// + /// An empty match can only be returned when the empty string was among + /// the patterns used to build the Aho-Corasick automaton. + #[inline] + pub fn is_empty(&self) -> bool { + self.len == 0 } - #[test] - fn qc_ac_equals_naive() { - fn prop(needles: Vec, haystack: BiasAscii) -> bool { - let aut_matches = aut_findo(&needles, &haystack.0); - let naive_matches = naive_find(&needles, &haystack.0); - // Ordering isn't always the same. I don't think we care, so do - // an unordered comparison. - let aset: HashSet = aut_matches.iter().cloned().collect(); - let nset: HashSet = naive_matches.iter().cloned().collect(); - aset == nset + #[inline] + fn increment(&self, by: usize) -> Match { + Match { + pattern: self.pattern, + len: self.len, + end: self.end + by, } - quickcheck(prop as fn(Vec, BiasAscii) -> bool); - } - - - #[test] - fn all_bytes_iter() { - let all_bytes = AllBytesIter::new().collect::>(); - assert_eq!(all_bytes[0], 0); - assert_eq!(all_bytes[255], 255); - assert!(AllBytesIter::new().enumerate().all(|(i, b)| b as usize == i)); } } diff -Nru cargo-0.33.0/vendor/aho-corasick/src/main.rs cargo-0.35.0/vendor/aho-corasick/src/main.rs --- cargo-0.33.0/vendor/aho-corasick/src/main.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/main.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -extern crate memchr; - -use std::env; - -use lib::AcAutomaton; - -#[allow(dead_code)] -mod lib; - -fn main() { - let aut = AcAutomaton::new(env::args().skip(1)); - println!("{}", aut.dot().trim()); -} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/nfa.rs cargo-0.35.0/vendor/aho-corasick/src/nfa.rs --- cargo-0.33.0/vendor/aho-corasick/src/nfa.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/nfa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1230 @@ +use std::collections::VecDeque; +use std::cmp; +use std::fmt; +use std::mem::size_of; + +use ahocorasick::MatchKind; +use automaton::Automaton; +use classes::{ByteClasses, ByteClassBuilder}; +use error::Result; +use prefilter::{self, Prefilter, PrefilterObj}; +use state_id::{StateID, dead_id, fail_id, usize_to_state_id}; +use Match; + +/// The identifier for a pattern, which is simply the position of the pattern +/// in the sequence of patterns given by the caller. +pub type PatternID = usize; + +/// The length of a pattern, in bytes. +pub type PatternLength = usize; + +/// An Aho-Corasick automaton, represented as an NFA. +/// +/// This is the classical formulation of Aho-Corasick, which involves building +/// up a prefix trie of a given set of patterns, and then wiring up failure +/// transitions between states in order to guarantee linear time matching. The +/// standard formulation is, technically, an NFA because of these failure +/// transitions. That is, one can see them as enabling the automaton to be in +/// multiple states at once. Indeed, during search, it is possible to check +/// the transitions on multiple states for a single input byte. +/// +/// This particular implementation not only supports the standard style of +/// matching, but also provides a mode for choosing leftmost-first or +/// leftmost-longest match semantics. When a leftmost mode is chosen, some +/// failure transitions that would otherwise be added are elided. See +/// the documentation of `MatchKind` for more details and examples on how the +/// match semantics may differ. +/// +/// If one wants a DFA, then it is necessary to first build an NFA and convert +/// it into a DFA. Note, however, that because we've constrained ourselves to +/// matching literal patterns, this does not need to use subset construction +/// for determinization. Instead, the DFA has at most a number of states +/// equivalent to the number of NFA states. The only real difference between +/// them is that all failure transitions are followed and pre-computed. This +/// uses much more memory, but also executes searches more quickly. +#[derive(Clone)] +pub struct NFA { + /// The match semantics built into this NFA. + match_kind: MatchKind, + /// The start state id as an index into `states`. + start_id: S, + /// The length, in bytes, of the longest pattern in this automaton. This + /// information is useful for keeping correct buffer sizes when searching + /// on streams. + max_pattern_len: usize, + /// The total number of patterns added to this automaton, including + /// patterns that may never be matched. + pattern_count: usize, + /// The number of bytes of heap used by this NFA's transition table. + heap_bytes: usize, + /// A prefilter for quickly skipping to candidate matches, if pertinent. + prefilter: Option, + /// A set of equivalence classes in terms of bytes. We compute this while + /// building the NFA, but don't use it in the NFA's states. Instead, we + /// use this for building the DFA. We store it on the NFA since it's easy + /// to compute while visiting the the patterns. + byte_classes: ByteClasses, + /// A set of states. Each state defines its own transitions, a fail + /// transition and a set of indices corresponding to matches. + /// + /// The first state is always the fail state, which is used only as a + /// sentinel. Namely, in the final NFA, no transition into the fail state + /// exists. (Well, they do, but they aren't followed. Instead, the state's + /// failure transition is followed.) + /// + /// The second state (index 1) is always the dead state. Dead states are + /// in every automaton, but only used when leftmost-{first,longest} match + /// semantics are enabled. Specifically, they instruct search to stop + /// at specific points in order to report the correct match location. In + /// the standard Aho-Corasick construction, there are no transitions to + /// the dead state. + /// + /// The third state (index 2) is generally intended to be the starting or + /// "root" state. + states: Vec>, +} + +impl NFA { + /// Returns the equivalence classes of bytes found while constructing + /// this NFA. + /// + /// Note that the NFA doesn't actually make use of these equivalence + /// classes. Instead, these are useful for building the DFA when desired. + pub fn byte_classes(&self) -> &ByteClasses { + &self.byte_classes + } + + /// Returns a start byte prefilter, if one exists. + pub fn prefilter_obj(&self) -> Option<&PrefilterObj> { + self.prefilter.as_ref() + } + + /// Returns the total number of heap bytes used by this NFA's transition + /// table. + pub fn heap_bytes(&self) -> usize { + self.heap_bytes + } + + /// Return the length of the longest pattern in this automaton. + pub fn max_pattern_len(&self) -> usize { + self.max_pattern_len + } + + /// Return the total number of patterns added to this automaton. + pub fn pattern_count(&self) -> usize { + self.pattern_count + } + + /// Returns the total number of states in this NFA. + pub fn state_len(&self) -> usize { + self.states.len() + } + + /// Returns the matches for the given state. + pub fn matches(&self, id: S) -> &[(PatternID, PatternLength)] { + &self.states[id.to_usize()].matches + } + + /// Returns an iterator over all transitions in the given state according + /// to the given equivalence classes, including transitions to `fail_id()`. + /// The number of transitions returned is always equivalent to the number + /// of equivalence classes. + pub fn iter_all_transitions( + &self, + byte_classes: &ByteClasses, + id: S, + f: F, + ) { + self.states[id.to_usize()].trans.iter_all(byte_classes, f); + } + + /// Returns the failure transition for the given state. + pub fn failure_transition(&self, id: S) -> S { + self.states[id.to_usize()].fail + } + + /// Returns the next state for the given state and input byte. + /// + /// Note that this does not follow failure transitions. As such, the id + /// returned may be `fail_id`. + pub fn next_state(&self, current: S, input: u8) -> S { + self.states[current.to_usize()].next_state(input) + } + + fn state(&self, id: S) -> &State { + &self.states[id.to_usize()] + } + + fn state_mut(&mut self, id: S) -> &mut State { + &mut self.states[id.to_usize()] + } + + fn start(&self) -> &State { + self.state(self.start_id) + } + + fn start_mut(&mut self) -> &mut State { + let id = self.start_id; + self.state_mut(id) + } + + fn iter_transitions_mut(&mut self, id: S) -> IterTransitionsMut { + IterTransitionsMut::new(self, id) + } + + fn copy_matches(&mut self, src: S, dst: S) { + let (src, dst) = get_two_mut( + &mut self.states, src.to_usize(), dst.to_usize(), + ); + dst.matches.extend_from_slice(&src.matches); + } + + fn copy_empty_matches(&mut self, dst: S) { + let start_id = self.start_id; + self.copy_matches(start_id, dst); + } + + fn add_dense_state(&mut self, depth: usize) -> Result { + let trans = Transitions::Dense(vec![fail_id(); 256]); + let id = usize_to_state_id(self.states.len())?; + self.states.push(State { + trans, + fail: self.start_id, + depth: depth, + matches: vec![], + }); + Ok(id) + } + + fn add_sparse_state(&mut self, depth: usize) -> Result { + let trans = Transitions::Sparse(vec![]); + let id = usize_to_state_id(self.states.len())?; + self.states.push(State { + trans, + fail: self.start_id, + depth: depth, + matches: vec![], + }); + Ok(id) + } +} + +impl Automaton for NFA { + type ID = S; + + fn match_kind(&self) -> &MatchKind { + &self.match_kind + } + + fn prefilter(&self) -> Option<&Prefilter> { + self.prefilter.as_ref().map(|p| p.as_ref()) + } + + fn start_state(&self) -> S { + self.start_id + } + + fn is_valid(&self, id: S) -> bool { + id.to_usize() < self.states.len() + } + + fn is_match_state(&self, id: S) -> bool { + self.states[id.to_usize()].is_match() + } + + fn get_match( + &self, + id: S, + match_index: usize, + end: usize, + ) -> Option { + let state = match self.states.get(id.to_usize()) { + None => return None, + Some(state) => state, + }; + state.matches + .get(match_index) + .map(|&(id, len)| Match { pattern: id, len, end }) + } + + fn match_count(&self, id: S) -> usize { + self.states[id.to_usize()].matches.len() + } + + unsafe fn next_state_unchecked(&self, mut current: S, input: u8) -> S { + // This terminates since: + // + // 1. `State.fail` never points to fail_id(). + // 2. All `State.fail` values point to a state closer to `start`. + // 3. The start state has no transitions to fail_id(). + loop { + let state = self.states.get_unchecked(current.to_usize()); + let next = state.next_state(input); + if next != fail_id() { + return next; + } + current = state.fail; + } + } +} + +/// A representation of an NFA state for an Aho-Corasick automaton. +/// +/// It contains the transitions to the next state, a failure transition for +/// cases where there exists no other transition for the current input byte, +/// the matches implied by visiting this state (if any) and the depth of this +/// state. The depth of a state is simply the distance from it to the start +/// state in the automaton, where the depth of the start state is 0. +#[derive(Clone, Debug)] +pub struct State { + trans: Transitions, + fail: S, + matches: Vec<(PatternID, PatternLength)>, + // TODO: Strictly speaking, this isn't needed for searching. It's only + // used when building an NFA that supports leftmost match semantics. We + // could drop this from the state and dynamically build a map only when + // computing failure transitions, but it's not clear which is better. + // Benchmark this. + depth: usize, +} + +impl State { + fn heap_bytes(&self) -> usize { + self.trans.heap_bytes() + + (self.matches.len() * size_of::<(PatternID, PatternLength)>()) + } + + fn add_match(&mut self, i: PatternID, len: PatternLength) { + self.matches.push((i, len)); + } + + fn is_match(&self) -> bool { + !self.matches.is_empty() + } + + fn get_longest_match_len(&self) -> Option { + // Why is this true? Because the first match in any matching state + // will always correspond to the match added to it during trie + // construction (since when we copy matches due to failure transitions, + // we always append them). Therefore, it follows that the first match + // must always be longest since any subsequent match must be from a + // failure transition, and a failure transition by construction points + // to a proper suffix. A proper suffix is, by definition, smaller. + self.matches.get(0).map(|&(_, len)| len) + } + + fn next_state(&self, input: u8) -> S { + self.trans.next_state(input) + } + + fn set_next_state(&mut self, input: u8, next: S) { + self.trans.set_next_state(input, next); + } +} + +/// A representation of transitions in an NFA. +/// +/// Transitions have either a sparse representation, which is slower for +/// lookups but uses less memory, or a dense representation, which is faster +/// for lookups but uses more memory. In the sparse representation, the absence +/// of a state implies a transition to `fail_id()`. Transitions to `dead_id()` +/// are still explicitly represented. +/// +/// For the NFA, by default, we use a dense representation for transitions for +/// states close to the start state because it's likely these are the states +/// that will be most frequently visited. +#[derive(Clone, Debug)] +enum Transitions { + Sparse(Vec<(u8, S)>), + Dense(Vec), +} + +impl Transitions { + fn heap_bytes(&self) -> usize { + match *self { + Transitions::Sparse(ref sparse) => { + sparse.len() * size_of::<(u8, S)>() + } + Transitions::Dense(ref dense) => { + dense.len() * size_of::() + } + } + } + + fn next_state(&self, input: u8) -> S { + match *self { + Transitions::Sparse(ref sparse) => { + for &(b, id) in sparse { + if b == input { + return id; + } + } + fail_id() + } + Transitions::Dense(ref dense) => { + // SAFETY: This is safe because all dense transitions have + // exactly 256 elements, so all u8 values are valid indices. + unsafe { *dense.get_unchecked(input as usize) } + } + } + } + + fn set_next_state(&mut self, input: u8, next: S) { + match *self { + Transitions::Sparse(ref mut sparse) => { + match sparse.binary_search_by_key(&input, |&(b, _)| b) { + Ok(i) => sparse[i] = (input, next), + Err(i) => sparse.insert(i, (input, next)), + } + } + Transitions::Dense(ref mut dense) => { + dense[input as usize] = next; + } + } + } + + /// Iterate over transitions in this state while skipping over transitions + /// to `fail_id()`. + fn iter(&self, mut f: F) { + match *self { + Transitions::Sparse(ref sparse) => { + for &(b, id) in sparse { + f(b, id); + } + } + Transitions::Dense(ref dense) => { + for b in AllBytesIter::new() { + let id = dense[b as usize]; + if id != fail_id() { + f(b, id); + } + } + } + } + } + + /// Iterate over all transitions in this state according to the given + /// equivalence classes, including transitions to `fail_id()`. + fn iter_all(&self, classes: &ByteClasses, mut f: F) { + if classes.is_singleton() { + match *self { + Transitions::Sparse(ref sparse) => { + sparse_iter(sparse, f); + } + Transitions::Dense(ref dense) => { + for b in AllBytesIter::new() { + f(b, dense[b as usize]); + } + } + } + } else { + // In this case, we only want to yield a single byte for each + // equivalence class. + match *self { + Transitions::Sparse(ref sparse) => { + let mut last_class = None; + sparse_iter(sparse, |b, next| { + let class = classes.get(b); + if last_class != Some(class) { + last_class = Some(class); + f(b, next); + } + }) + } + Transitions::Dense(ref dense) => { + for b in classes.representatives() { + f(b, dense[b as usize]); + } + } + } + } + } +} + +/// Iterator over transitions in a state, skipping transitions to `fail_id()`. +/// +/// This abstracts over the representation of NFA transitions, which may be +/// either in a sparse or dense representation. +/// +/// This somewhat idiosyncratically borrows the NFA mutably, so that when one +/// is iterating over transitions, the caller can still mutate the NFA. This +/// is useful when creating failure transitions. +#[derive(Debug)] +struct IterTransitionsMut<'a, S: StateID + 'a> { + nfa: &'a mut NFA, + state_id: S, + cur: usize, +} + +impl<'a, S: StateID> IterTransitionsMut<'a, S> { + fn new(nfa: &'a mut NFA, state_id: S) -> IterTransitionsMut<'a, S> { + IterTransitionsMut { nfa, state_id, cur: 0 } + } + + fn nfa(&mut self) -> &mut NFA { + self.nfa + } +} + +impl<'a, S: StateID> Iterator for IterTransitionsMut<'a, S> { + type Item = (u8, S); + + fn next(&mut self) -> Option<(u8, S)> { + match self.nfa.states[self.state_id.to_usize()].trans { + Transitions::Sparse(ref sparse) => { + if self.cur >= sparse.len() { + return None; + } + let i = self.cur; + self.cur += 1; + Some(sparse[i]) + } + Transitions::Dense(ref dense) => { + while self.cur < dense.len() { + // There are always exactly 255 transitions in dense repr. + debug_assert!(self.cur < 256); + + let b = self.cur as u8; + let id = dense[self.cur]; + self.cur += 1; + if id != fail_id() { + return Some((b, id)); + } + } + None + } + } + } +} + +/// A simple builder for configuring the NFA construction of Aho-Corasick. +#[derive(Clone, Debug)] +pub struct Builder { + dense_depth: usize, + match_kind: MatchKind, + prefilter: bool, + ascii_case_insensitive: bool, +} + +impl Default for Builder { + fn default() -> Builder { + Builder { + dense_depth: 2, + match_kind: MatchKind::default(), + prefilter: true, + ascii_case_insensitive: false, + } + } +} + +impl Builder { + pub fn new() -> Builder { + Builder::default() + } + + pub fn build( + &self, + patterns: I, + ) -> Result> + where I: IntoIterator, + P: AsRef<[u8]> + { + Compiler::new(self)?.compile(patterns) + } + + pub fn match_kind(&mut self, kind: MatchKind) -> &mut Builder { + self.match_kind = kind; + self + } + + pub fn dense_depth(&mut self, depth: usize) -> &mut Builder { + self.dense_depth = depth; + self + } + + pub fn prefilter(&mut self, yes: bool) -> &mut Builder { + self.prefilter = yes; + self + } + + pub fn ascii_case_insensitive(&mut self, yes: bool) -> &mut Builder { + self.ascii_case_insensitive = yes; + self + } +} + +/// A compiler uses a builder configuration and builds up the NFA formulation +/// of an Aho-Corasick automaton. This roughly corresponds to the standard +/// formulation described in textbooks. +#[derive(Debug)] +struct Compiler<'a, S: StateID> { + builder: &'a Builder, + nfa: NFA, + byte_classes: ByteClassBuilder, +} + +impl<'a, S: StateID> Compiler<'a, S> { + fn new(builder: &'a Builder) -> Result> { + Ok(Compiler { + builder: builder, + nfa: NFA { + match_kind: builder.match_kind, + start_id: usize_to_state_id(2)?, + max_pattern_len: 0, + pattern_count: 0, + heap_bytes: 0, + prefilter: None, + byte_classes: ByteClasses::singletons(), + states: vec![], + }, + byte_classes: ByteClassBuilder::new(), + }) + } + + fn compile( + mut self, + patterns: I, + ) -> Result> + where I: IntoIterator, + P: AsRef<[u8]> + { + self.add_state(0)?; // the fail state, which is never entered + self.add_state(0)?; // the dead state, only used for leftmost + self.add_state(0)?; // the start state + self.build_trie(patterns)?; + self.add_start_state_loop(); + self.add_dead_state_loop(); + if self.match_kind().is_leftmost() { + self.fill_failure_transitions_leftmost(); + } else { + self.fill_failure_transitions_standard(); + } + self.close_start_state_loop(); + self.nfa.byte_classes = self.byte_classes.build(); + self.build_prefilters(); + self.calculate_size(); + Ok(self.nfa) + } + + /// This sets up the initial prefix trie that makes up the Aho-Corasick + /// automaton. Effectively, it creates the basic structure of the + /// automaton, where every pattern given has a path from the start state to + /// the end of the pattern. + fn build_trie( + &mut self, + patterns: I, + ) -> Result<()> + where I: IntoIterator, + P: AsRef<[u8]> + { + 'PATTERNS: + for (pati, pat) in patterns.into_iter().enumerate() { + let pat = pat.as_ref(); + self.nfa.max_pattern_len = cmp::max( + self.nfa.max_pattern_len, pat.len(), + ); + self.nfa.pattern_count += 1; + + let mut prev = self.nfa.start_id; + let mut saw_match = false; + for (depth, &b) in pat.iter().enumerate() { + // When leftmost-first match semantics are requested, we + // specifically stop adding patterns when a previously added + // pattern is a prefix of it. We avoid adding it because + // leftmost-first semantics imply that the pattern can never + // match. This is not just an optimization to save space! It + // is necessary for correctness. In fact, this is the only + // difference in the automaton between the implementations for + // leftmost-first and leftmost-longest. + saw_match = saw_match || self.nfa.state(prev).is_match(); + if self.builder.match_kind.is_leftmost_first() && saw_match { + // Skip to the next pattern immediately. This avoids + // incorrectly adding a match after this loop terminates. + continue 'PATTERNS; + } + + // Add this byte to our equivalence classes. We don't use these + // for NFA construction. These are instead used only if we're + // building a DFA. They would technically be useful for the + // NFA, but it would require a second pass over the patterns. + self.byte_classes.set_range(b, b); + + // If the transition from prev using the current byte already + // exists, then just move through it. Otherwise, add a new + // state. We track the depth here so that we can determine + // how to represent transitions. States near the start state + // use a dense representation that uses more memory but is + // faster. Other states use a sparse representation that uses + // less memory but is slower. + let next = self.nfa.state(prev).next_state(b); + if next != fail_id() { + prev = next; + } else { + let next = self.add_state(depth + 1)?; + self.nfa.state_mut(prev).set_next_state(b, next); + if self.builder.ascii_case_insensitive { + if b'A' <= b && b <= b'Z' { + let b = b.to_ascii_lowercase(); + self.nfa.state_mut(prev).set_next_state(b, next); + } else if b'a' <= b && b <= b'z' { + let b = b.to_ascii_uppercase(); + self.nfa.state_mut(prev).set_next_state(b, next); + } + } + prev = next; + } + } + // Once the pattern has been added, log the match in the final + // state that it reached. + self.nfa.state_mut(prev).add_match(pati, pat.len()); + } + Ok(()) + } + + /// This routine creates failure transitions according to the standard + /// textbook formulation of the Aho-Corasick algorithm. + /// + /// Building failure transitions is the most interesting part of building + /// the Aho-Corasick automaton, because they are what allow searches to + /// be performed in linear time. Specifically, a failure transition is + /// a single transition associated with each state that points back to + /// the longest proper suffix of the pattern being searched. The failure + /// transition is followed whenever there exists no transition on the + /// current state for the current input byte. If there is no other proper + /// suffix, then the failure transition points back to the starting state. + /// + /// For example, let's say we built an Aho-Corasick automaton with the + /// following patterns: 'abcd' and 'cef'. The trie looks like this: + /// + /// ```ignore + /// a - S1 - b - S2 - c - S3 - d - S4* + /// / + /// S0 - c - S5 - e - S6 - f - S7* + /// ``` + /// + /// At this point, it should be fairly straight-forward to see how this + /// trie can be used in a simplistic way. At any given position in the + /// text we're searching (called the "subject" string), all we need to do + /// is follow the transitions in the trie by consuming one transition for + /// each byte in the subject string. If we reach a match state, then we can + /// report that location as a match. + /// + /// The trick comes when searching a subject string like 'abcef'. We'll + /// initially follow the transition from S0 to S1 and wind up in S3 after + /// observng the 'c' byte. At this point, the next byte is 'e' but state + /// S3 has no transition for 'e', so the search fails. We then would need + /// to restart the search at the next position in 'abcef', which + /// corresponds to 'b'. The match would fail, but the next search starting + /// at 'c' would finally succeed. The problem with this approach is that + /// we wind up searching the subject string potentially many times. In + /// effect, this makes the algorithm have worst case `O(n * m)` complexity, + /// where `n ~ len(subject)` and `m ~ len(all patterns)`. We would instead + /// like to achieve a `O(n + m)` worst case complexity. + /// + /// This is where failure transitions come in. Instead of dying at S3 in + /// the first search, the automaton can instruct the search to move to + /// another part of the automaton that corresponds to a suffix of what + /// we've seen so far. Recall that we've seen 'abc' in the subject string, + /// and the automaton does indeed have a non-empty suffix, 'c', that could + /// potentially lead to another match. Thus, the actual Aho-Corasick + /// automaton for our patterns in this case looks like this: + /// + /// ```ignore + /// a - S1 - b - S2 - c - S3 - d - S4* + /// / / + /// / ---------------- + /// / / + /// S0 - c - S5 - e - S6 - f - S7* + /// ``` + /// + /// That is, we have a failure transition from S3 to S5, which is followed + /// exactly in cases when we are in state S3 but see any byte other than + /// 'd' (that is, we've "failed" to find a match in this portion of our + /// trie). We know we can transition back to S5 because we've already seen + /// a 'c' byte, so we don't need to re-scan it. We can then pick back up + /// with the search starting at S5 and complete our match. + /// + /// Adding failure transitions to a trie is fairly simple, but subtle. The + /// key issue is that you might have multiple failure transition that you + /// need to follow. For example, look at the trie for the patterns + /// 'abcd', 'b', 'bcd' and 'cd': + /// + /// ```ignore + /// - a - S1 - b - S2 - c - S3 - d - S4* + /// / + /// S0 - b - S5* - c - S6 - d - S7* + /// \ + /// - c - S8 - d - S9* + /// ``` + /// + /// The failure transitions for this trie are defined from S2 to S5, + /// S3 to S6 and S6 to S8. Moreover, state S2 needs to track that it + /// corresponds to a match, since its failure transition to S5 is itself + /// a match state. + /// + /// Perhaps simplest way to think about adding these failure transitions + /// is recursively. That is, if you know the failure transitions for every + /// possible previous state that could be visited (e.g., when computing the + /// failure transition for S3, you already know the failure transitions + /// for S0, S1 and S2), then you can simply follow the failure transition + /// of the previous state and check whether the incoming transition is + /// defined after following the failure transition. + /// + /// For example, when determining the failure state for S3, by our + /// assumptions, we already know that there is a failure transition from + /// S2 (the previous state) to S5. So we follow that transition and check + /// whether the transition connecting S2 to S3 is defined. Indeed, it is, + /// as there is a transition from S5 to S6 for the byte 'c'. If no such + /// transition existed, we could keep following the failure transitions + /// until we reach the start state, which is the failure transition for + /// every state that has no corresponding proper suffix. + /// + /// We don't actually use recursion to implement this, but instead, use a + /// breadth first search of the automaton. Our base case is the start + /// state, whose failure transition is just a transition to itself. + fn fill_failure_transitions_standard(&mut self) { + // Initialize the queue for breadth first search with all transitions + // out of the start state. We handle the start state specially because + // we only want to follow non-self transitions. If we followed self + // transitions, then this would never terminate. + let mut queue = VecDeque::new(); + for b in AllBytesIter::new() { + let next = self.nfa.start().next_state(b); + if next != self.nfa.start_id { + queue.push_back(next); + } + } + while let Some(id) = queue.pop_front() { + let mut it = self.nfa.iter_transitions_mut(id); + while let Some((b, next)) = it.next() { + queue.push_back(next); + + let mut fail = it.nfa().state(id).fail; + while it.nfa().state(fail).next_state(b) == fail_id() { + fail = it.nfa().state(fail).fail; + } + fail = it.nfa().state(fail).next_state(b); + it.nfa().state_mut(next).fail = fail; + it.nfa().copy_matches(fail, next); + } + // If the start state is a match state, then this automaton can + // match the empty string. This implies all states are match states + // since every position matches the empty string, so copy the + // matches from the start state to every state. Strictly speaking, + // this is only necessary for overlapping matches since each + // non-empty non-start match state needs to report empty matches + // in addition to its own. For the non-overlapping case, such + // states only report the first match, which is never empty since + // it isn't a start state. + it.nfa().copy_empty_matches(id); + } + } + + /// This routine is just like fill_failure_transitions_standard, except + /// it adds failure transitions in a way that preserves leftmost match + /// semantics (for both leftmost-first and leftmost-longest). + /// + /// The algorithms are so similar that it would be possible to write it + /// generically. But doing so without overhead would require a bit of + /// ceremony, so we just copy it and add in the extra leftmost logic. + /// Moreover, the standard algorithm above is so simple that it feels like + /// a crime to disturb it. + /// + /// In effect, this proceeds just like the standard approach, but we + /// specifically add only a subset of all failure transitions. Namely, we + /// only add failure transitions that either do not occur after a match + /// or failure transitions that do occur after a match but preserve the + /// match. The comments in the implementation below should help. + /// + /// N.B. The only differences in the automaton between leftmost-first and + /// leftmost-longest are in trie construction. Otherwise, both have exactly + /// the same set of failure transitions. leftmost-longest adds everything + /// to the trie, where as leftmost-first skips any patterns for which there + /// exists a prefix of it that was added earlier. + /// + /// N.B. I came up with this algorithm on my own, and after scouring all of + /// the other AC implementations I know of (Perl, Snort, many on GitHub). + /// I couldn't find any that implement leftmost semantics like this. + /// Perl of course needs leftmost-first semantics, but they implement it + /// with a seeming hack at *search* time instead of encoding it into the + /// automaton. There are also a couple Java libraries that support leftmost + /// longest semantics, but they do it by building a queue of matches at + /// search time, which is even worse than what Perl is doing. ---AG + fn fill_failure_transitions_leftmost(&mut self) { + /// Represents an item in our queue of states to process. + /// + /// Fundamentally, this queue serves the same purpose as the queue + /// for filling failure transitions using the standard formulation. + /// In the leftmost case, though, we need to track a bit more + /// information. See comments below. + #[derive(Clone, Copy, Debug)] + struct QueuedState { + /// The id of the state to visit. + id: S, + /// The depth at which the first match was observed in the path + /// to this state. Note that this corresponds to the depth at + /// which the beginning of the match was detected. If no match + /// has been seen, then this is None. + match_at_depth: Option, + } + + impl QueuedState { + /// Create a queued state corresponding to the given NFA's start + /// state. + fn start(nfa: &NFA) -> QueuedState { + let match_at_depth = + if nfa.start().is_match() { + Some(0) + } else { + None + }; + QueuedState { id: nfa.start_id, match_at_depth } + } + + /// Return the next state to queue up. The given id must be a state + /// corresponding to a single transition from this queued state. + fn next_queued_state( + &self, + nfa: &NFA, + id: S, + ) -> QueuedState { + let match_at_depth = self.next_match_at_depth(nfa, id); + QueuedState { id, match_at_depth } + } + + /// Return the earliest depth at which a match has occurred for + /// the given state. The given state must correspond to a single + /// transition from this queued state. + fn next_match_at_depth( + &self, + nfa: &NFA, + next: S, + ) -> Option { + // This is a little tricky. If the previous state has already + // seen a match or if `next` isn't a match state, then nothing + // needs to change since a later state cannot find an earlier + // match. + match self.match_at_depth { + Some(x) => return Some(x), + None if nfa.state(next).is_match() => {} + None => return None, + } + let depth = + nfa.state(next).depth + - nfa.state(next).get_longest_match_len().unwrap() + + 1; + Some(depth) + } + } + + // Initialize the queue for breadth first search with all transitions + // out of the start state. We handle the start state specially because + // we only want to follow non-self transitions. If we followed self + // transitions, then this would never terminate. + let mut queue: VecDeque> = VecDeque::new(); + let start = QueuedState::start(&self.nfa); + for b in AllBytesIter::new() { + let next = self.nfa.start().next_state(b); + if next != start.id { + queue.push_back(start.next_queued_state(&self.nfa, next)); + } + } + while let Some(item) = queue.pop_front() { + let mut any_trans = false; + let mut it = self.nfa.iter_transitions_mut(item.id); + while let Some((b, next_id)) = it.next() { + any_trans = true; + + // Queue up the next state. + let next = item.next_queued_state(it.nfa(), next_id); + queue.push_back(next); + + // Find the failure state for next. Same as standard. + let mut fail = it.nfa().state(item.id).fail; + while it.nfa().state(fail).next_state(b) == fail_id() { + fail = it.nfa().state(fail).fail; + } + fail = it.nfa().state(fail).next_state(b); + + // This is the key difference from the standard formulation. + // Namely, if we've seen a match, then we only want a failure + // transition if the failure transition preserves the match + // we've seen. In general, this is not true of all failure + // transitions since they can point back to any suffix of what + // we've seen so far. Instead, we only want to point back to + // suffixes that contain any match we've seen. + // + // We achieve this by comparing the depth of the failure + // transition with the number of states between this state + // and the beginning of the earliest match detected. If the + // depth of the failure state is smaller than this difference, + // then it cannot contain the match. If it's bigger or equal + // to the difference, then it necessarily includes the match + // we've seen since all failure transitions correspond to a + // suffix. + // + // If we've determined that we don't want the failure + // transition, then we set this state's failure transition to + // the dead state. In other words, when a search hits this + // state, it will not continue and correctly stop. (N.B. A + // dead state is different than a fail state. A dead state + // MUST be preceded by a match and acts as a sentinel to search + // routines to terminate.) + // + // Understanding this is tricky, and it took me several days + // to think through this and get it right. If you want to grok + // it, then I'd recommend: 1) switch the implementation to + // always use the standard algorithm for filling in failure + // transitions, 2) run the test suite and 3) examine the test + // failures. Write out the automatons for them and try to work + // backwards by figuring out which failure transitions should + // be removed. You should arrive at the same rule used below. + if let Some(match_depth) = next.match_at_depth { + let fail_depth = it.nfa().state(fail).depth; + let next_depth = it.nfa().state(next.id).depth; + if next_depth - match_depth + 1 > fail_depth { + it.nfa().state_mut(next.id).fail = dead_id(); + continue; + } + } + it.nfa().state_mut(next.id).fail = fail; + it.nfa().copy_matches(fail, next.id); + } + // If there are no transitions for this state and if it's a match + // state, then we must set its failure transition to the dead + // state since we never want it to restart the search. + if !any_trans && it.nfa().state(item.id).is_match() { + it.nfa().state_mut(item.id).fail = dead_id(); + } + // We don't need to copy empty matches from the start state here + // because that's only necessary for overlapping matches and + // leftmost match kinds don't support overlapping matches. + } + } + + /// Construct prefilters from the automaton, if applicable. + fn build_prefilters(&mut self) { + if !self.builder.prefilter { + return; + } + + let mut builder = prefilter::StartBytesBuilder::new(); + for b in AllBytesIter::new() { + if self.nfa.start().next_state(b) != self.nfa.start_id { + builder.add(b); + } + } + self.nfa.prefilter = builder.build(); + } + + /// Set the failure transitions on the start state to loop back to the + /// start state. This effectively permits the Aho-Corasick automaton to + /// match at any position. This is also required for finding the next + /// state to terminate, namely, finding the next state should never return + /// a fail_id. + /// + /// This must be done after building the initial trie, since trie + /// construction depends on transitions to `fail_id` to determine whether a + /// state already exists or not. + fn add_start_state_loop(&mut self) { + let start_id = self.nfa.start_id; + let start = self.nfa.start_mut(); + for b in AllBytesIter::new() { + if start.next_state(b) == fail_id() { + start.set_next_state(b, start_id); + } + } + } + + /// Remove the start state loop by rewriting any transitions on the start + /// state back to the start state with transitions to the dead state. + /// + /// The loop is only closed when two conditions are met: the start state + /// is a match state and the match kind is leftmost-first or + /// leftmost-longest. + /// + /// The reason for this is that under leftmost semantics, a start state + /// that is also a match implies that we should never restart the search + /// process. We allow normal transitions out of the start state, but if + /// none exist, we transition to the dead state, which signals that + /// searching should stop. + fn close_start_state_loop(&mut self) { + if self.match_kind().is_leftmost() && self.nfa.start().is_match() { + let start_id = self.nfa.start_id; + let start = self.nfa.start_mut(); + for b in AllBytesIter::new() { + if start.next_state(b) == start_id { + start.set_next_state(b, dead_id()); + } + } + } + } + + /// Sets all transitions on the dead state to point back to the dead state. + /// Normally, missing transitions map back to the failure state, but the + /// point of the dead state is to act as a sink that can never be escaped. + fn add_dead_state_loop(&mut self) { + let dead = self.nfa.state_mut(dead_id()); + for b in AllBytesIter::new() { + dead.set_next_state(b, dead_id()); + } + } + + /// Computes the total amount of heap used by this NFA in bytes. + fn calculate_size(&mut self) { + let mut size = 0; + for state in &self.nfa.states { + size += state.heap_bytes(); + } + self.nfa.heap_bytes = size; + } + + /// Add a new state to the underlying NFA with the given depth. The depth + /// is used to determine how to represent the transitions. + /// + /// If adding the new state would overflow the chosen state ID + /// representation, then this returns an error. + fn add_state(&mut self, depth: usize) -> Result { + if depth < self.builder.dense_depth { + self.nfa.add_dense_state(depth) + } else { + self.nfa.add_sparse_state(depth) + } + } + + /// Returns the match kind configured on the underlying builder. + fn match_kind(&self) -> MatchKind { + self.builder.match_kind + } +} + +/// An iterator over every byte value. +/// +/// We use this instead of (0..256).map(|b| b as u8) because this optimizes +/// better in debug builds. +/// +/// We also use this instead of 0..=255 because we're targeting Rust 1.24 and +/// inclusive range syntax was stabilized in Rust 1.26. We can get rid of this +/// once our MSRV is Rust 1.26 or newer. +#[derive(Debug)] +struct AllBytesIter(u16); + +impl AllBytesIter { + fn new() -> AllBytesIter { + AllBytesIter(0) + } +} + +impl Iterator for AllBytesIter { + type Item = u8; + + fn next(&mut self) -> Option { + if self.0 >= 256 { + None + } else { + let b = self.0 as u8; + self.0 += 1; + Some(b) + } + } +} + +impl fmt::Debug for NFA { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + writeln!(f, "NFA(")?; + writeln!(f, "match_kind: {:?}", self.match_kind)?; + writeln!(f, "{}", "-".repeat(79))?; + for (id, s) in self.states.iter().enumerate() { + let mut trans = vec![]; + s.trans.iter(|byte, next| { + // The start state has a bunch of uninteresting transitions + // back into itself. It's questionable to hide them since they + // are critical to understanding the automaton, but they are + // very noisy without better formatting for contiugous ranges + // to the same state. + if id == self.start_id.to_usize() && next == self.start_id { + return; + } + // Similarly, the dead state has a bunch of uninteresting + // transitions too. + if id == dead_id() { + return; + } + trans.push(format!("{} => {}", escape(byte), next.to_usize())); + }); + writeln!(f, "{:04}: {}", id, trans.join(", "))?; + + let matches: Vec = s.matches + .iter() + .map(|&(pattern_id, _)| pattern_id.to_string()) + .collect(); + writeln!(f, " matches: {}", matches.join(", "))?; + writeln!(f, " fail: {}", s.fail.to_usize())?; + writeln!(f, " depth: {}", s.depth)?; + } + writeln!(f, "{}", "-".repeat(79))?; + writeln!(f, ")")?; + Ok(()) + } +} + +/// Iterate over all possible byte transitions given a sparse set. +fn sparse_iter(trans: &[(u8, S)], mut f: F) { + let mut byte = 0u16; + for &(b, id) in trans { + while byte < (b as u16) { + f(byte as u8, fail_id()); + byte += 1; + } + f(b, id); + byte += 1; + } + for b in byte..256 { + f(b as u8, fail_id()); + } +} + +/// Safely return two mutable borrows to two different locations in the given +/// slice. +/// +/// This panics if i == j. +fn get_two_mut(xs: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) { + assert!(i != j, "{} must not be equal to {}", i, j); + if i < j { + let (before, after) = xs.split_at_mut(j); + (&mut before[i], &mut after[0]) + } else { + let (before, after) = xs.split_at_mut(i); + (&mut after[0], &mut before[j]) + } +} + +/// Return the given byte as its escaped string form. +fn escape(b: u8) -> String { + use std::ascii; + + String::from_utf8(ascii::escape_default(b).collect::>()).unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn scratch() { + let nfa: NFA = Builder::new() + .dense_depth(0) + // .match_kind(MatchKind::LeftmostShortest) + .match_kind(MatchKind::LeftmostLongest) + // .build(&["abcd", "ce", "b"]) + // .build(&["ab", "bc"]) + // .build(&["b", "bcd", "ce"]) + // .build(&["abc", "bx"]) + // .build(&["abc", "bd", "ab"]) + // .build(&["abcdefghi", "hz", "abcdefgh"]) + // .build(&["abcd", "bce", "b"]) + .build(&["a", "ababcde"]) + .unwrap(); + println!("{:?}", nfa); + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/prefilter.rs cargo-0.35.0/vendor/aho-corasick/src/prefilter.rs --- cargo-0.33.0/vendor/aho-corasick/src/prefilter.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/prefilter.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,251 @@ +use std::fmt; +use std::panic::{RefUnwindSafe, UnwindSafe}; + +use memchr::{memchr, memchr2, memchr3}; + +/// A prefilter describes the behavior of fast literal scanners for quickly +/// skipping past bytes in the haystack that we know cannot possibly +/// participate in a match. +pub trait Prefilter: Send + Sync + RefUnwindSafe + UnwindSafe + fmt::Debug { + /// Returns the next possible match candidate. This may yield false + /// positives, so callers must "confirm" a match starting at the position + /// returned. This, however, must never produce false negatives. That is, + /// this must, at minimum, return the starting position of the next match + /// in the given haystack after or at the given position. + fn next_candidate(&self, haystack: &[u8], at: usize) -> Option; + + /// A method for cloning a prefilter, to work-around the fact that Clone + /// is not object-safe. + fn clone_prefilter(&self) -> Box; +} + +/// A convenience object for representing any type that implements Prefilter +/// and is cloneable. +#[derive(Debug)] +pub struct PrefilterObj(Box); + +impl Clone for PrefilterObj { + fn clone(&self) -> Self { + PrefilterObj(self.0.clone_prefilter()) + } +} + +impl PrefilterObj { + /// Create a new prefilter object. + pub fn new(t: T) -> PrefilterObj { + PrefilterObj(Box::new(t)) + } + + /// Return the underlying prefilter trait object. + pub fn as_ref(&self) -> &Prefilter { + &*self.0 + } +} + +/// PrefilterState tracks state associated with the effectiveness of a +/// prefilter. It is used to track how many bytes, on average, are skipped by +/// the prefilter. If this average dips below a certain threshold over time, +/// then the state renders the prefilter inert and stops using it. +/// +/// A prefilter state should be created for each search. (Where creating an +/// iterator via, e.g., `find_iter`, is treated as a single search.) +#[derive(Clone, Debug)] +pub struct PrefilterState { + /// The number of skips that has been executed. + skips: usize, + /// The total number of bytes that have been skipped. + skipped: usize, + /// The maximum length of a match. This is used to help determine how many + /// bytes on average should be skipped in order for a prefilter to be + /// effective. + max_match_len: usize, + /// Once this heuristic has been deemed ineffective, it will be inert + /// throughout the rest of its lifetime. This serves as a cheap way to + /// check inertness. + inert: bool, +} + +impl PrefilterState { + /// The minimum number of skip attempts to try before considering whether + /// a prefilter is effective or not. + const MIN_SKIPS: usize = 40; + + /// The minimum amount of bytes that skipping must average, expressed as + /// a factor of the multiple of the length of a possible match. + /// + /// That is, after MIN_SKIPS have occurred, if the average number of bytes + /// skipped ever falls below MIN_AVG_FACTOR, then this searcher is rendered + /// inert. + const MIN_AVG_FACTOR: usize = 2; + + /// Create a fresh prefilter state. + pub fn new(max_match_len: usize) -> PrefilterState { + PrefilterState { skips: 0, skipped: 0, max_match_len, inert: false } + } + + /// Update this state with the number of bytes skipped on the last + /// invocation of the prefilter. + #[inline] + pub fn update(&mut self, skipped: usize) { + self.skips += 1; + self.skipped += skipped; + } + + /// Return true if and only if this state indicates that a prefilter is + /// still effective. + #[inline] + pub fn is_effective(&mut self) -> bool { + if self.inert { + return false; + } + if self.skips < PrefilterState::MIN_SKIPS { + return true; + } + + let min_avg = PrefilterState::MIN_AVG_FACTOR * self.max_match_len; + if self.skipped >= min_avg * self.skips { + return true; + } + + // We're inert. + self.inert = true; + false + } +} + +/// A builder for construction a starting byte prefilter. +/// +/// A starting byte prefilter is a simplistic prefilter that looks for possible +/// matches by reporting all positions corresponding to a particular byte. This +/// generally only takes affect when there are at most 3 distinct possible +/// starting bytes. e.g., the patterns `foo`, `bar`, and `baz` have two +/// distinct starting bytes (`f` and `b`), and this prefiler returns all +/// occurrences of either `f` or `b`. +/// +/// In some cases, a heuristic frequency analysis may determine that it would +/// be better not to use this prefilter even when there are 3 or fewer distinct +/// starting bytes. +#[derive(Clone, Debug)] +pub struct StartBytesBuilder { + byteset: Vec, +} + +impl StartBytesBuilder { + /// Create a new builder for constructing a start byte prefilter. + pub fn new() -> StartBytesBuilder { + StartBytesBuilder { byteset: vec![false; 256] } + } + + /// Build the starting bytes prefilter. + /// + /// If there are more than 3 distinct starting bytes, or if heuristics + /// otherwise determine that this prefilter should not be used, then `None` + /// is returned. + pub fn build(&self) -> Option { + let (mut bytes, mut len) = ([0; 3], 0); + for b in 0..256 { + if !self.byteset[b] { + continue; + } + // We've exceeded our limit, so bail. + if len == 3 { + return None; + } + // We don't handle non-ASCII bytes for now. Getting non-ASCII + // bytes right is trickier, since we generally don't want to put + // a leading UTF-8 code unit into a prefilter that isn't ASCII, + // since they can frequently. Instead, it would be better to use a + // continuation byte, but this requires more sophisticated analysis + // of the automaton and a richer prefilter API. + if b > 0x7F { + return None; + } + bytes[len] = b as u8; + len += 1; + } + match len { + 0 => None, + 1 => { + Some(PrefilterObj::new(StartBytesOne { + byte1: bytes[0], + })) + } + 2 => { + Some(PrefilterObj::new(StartBytesTwo { + byte1: bytes[0], + byte2: bytes[1], + })) + } + 3 => { + Some(PrefilterObj::new(StartBytesThree { + byte1: bytes[0], + byte2: bytes[1], + byte3: bytes[2], + })) + } + _ => unreachable!(), + } + } + + /// Add a starting byte to this builder. + /// + /// In general, all possible starting bytes for an automaton should be + /// added to this builder before attempting to construct the prefilter. + pub fn add(&mut self, byte: u8) { + self.byteset[byte as usize] = true; + } +} + +/// A prefilter for scanning for a single starting byte. +#[derive(Clone, Debug)] +pub struct StartBytesOne { + byte1: u8, +} + +impl Prefilter for StartBytesOne { + fn next_candidate(&self, haystack: &[u8], at: usize) -> Option { + memchr(self.byte1, &haystack[at..]) + .map(|i| at + i) + } + + fn clone_prefilter(&self) -> Box { + Box::new(self.clone()) + } +} + +/// A prefilter for scanning for two starting bytes. +#[derive(Clone, Debug)] +pub struct StartBytesTwo { + byte1: u8, + byte2: u8, +} + +impl Prefilter for StartBytesTwo { + fn next_candidate(&self, haystack: &[u8], at: usize) -> Option { + memchr2(self.byte1, self.byte2, &haystack[at..]) + .map(|i| at + i) + } + + fn clone_prefilter(&self) -> Box { + Box::new(self.clone()) + } +} + +/// A prefilter for scanning for three starting bytes. +#[derive(Clone, Debug)] +pub struct StartBytesThree { + byte1: u8, + byte2: u8, + byte3: u8, +} + +impl Prefilter for StartBytesThree { + fn next_candidate(&self, haystack: &[u8], at: usize) -> Option { + memchr3(self.byte1, self.byte2, self.byte3, &haystack[at..]) + .map(|i| at + i) + } + + fn clone_prefilter(&self) -> Box { + Box::new(self.clone()) + } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/state_id.rs cargo-0.35.0/vendor/aho-corasick/src/state_id.rs --- cargo-0.33.0/vendor/aho-corasick/src/state_id.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/state_id.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,166 @@ +use std::fmt::Debug; +use std::hash::Hash; + +use error::{Error, Result}; + +// NOTE: Most of this code was copied from regex-automata, but without the +// (de)serialization specific stuff. + +/// Check that the premultiplication of the given state identifier can +/// fit into the representation indicated by `S`. If it cannot, or if it +/// overflows `usize` itself, then an error is returned. +pub fn premultiply_overflow_error( + last_state: S, + alphabet_len: usize, +) -> Result<()> { + let requested = match last_state.to_usize().checked_mul(alphabet_len) { + Some(requested) => requested, + None => return Err(Error::premultiply_overflow(0, 0)), + }; + if requested > S::max_id() { + return Err(Error::premultiply_overflow(S::max_id(), requested)); + } + Ok(()) +} + +/// Convert the given `usize` to the chosen state identifier +/// representation. If the given value cannot fit in the chosen +/// representation, then an error is returned. +pub fn usize_to_state_id(value: usize) -> Result { + if value > S::max_id() { + Err(Error::state_id_overflow(S::max_id())) + } else { + Ok(S::from_usize(value)) + } +} + +/// Return the unique identifier for an automaton's fail state in the chosen +/// representation indicated by `S`. +pub fn fail_id() -> S { + S::from_usize(0) +} + +/// Return the unique identifier for an automaton's fail state in the chosen +/// representation indicated by `S`. +pub fn dead_id() -> S { + S::from_usize(1) +} + +mod private { + /// Sealed stops crates other than aho-corasick from implementing any + /// traits that use it. + pub trait Sealed{} + impl Sealed for u8 {} + impl Sealed for u16 {} + impl Sealed for u32 {} + impl Sealed for u64 {} + impl Sealed for usize {} +} + +/// A trait describing the representation of an automaton's state identifier. +/// +/// The purpose of this trait is to safely express both the possible state +/// identifier representations that can be used in an automaton and to convert +/// between state identifier representations and types that can be used to +/// efficiently index memory (such as `usize`). +/// +/// In general, one should not need to implement this trait explicitly. Indeed, +/// for now, this trait is sealed such that it cannot be implemented by any +/// other type. In particular, this crate provides implementations for `u8`, +/// `u16`, `u32`, `u64` and `usize`. (`u32` and `u64` are only provided for +/// targets that can represent all corresponding values in a `usize`.) +/// +/// # Safety +/// +/// This trait is unsafe because the correctness of its implementations may be +/// relied upon by other unsafe code. For example, one possible way to +/// implement this trait incorrectly would be to return a maximum identifier +/// in `max_id` that is greater than the real maximum identifier. This will +/// likely result in wrap-on-overflow semantics in release mode, which can in +/// turn produce incorrect state identifiers. Those state identifiers may then +/// in turn access out-of-bounds memory in an automaton's search routine, where +/// bounds checks are explicitly elided for performance reasons. +pub unsafe trait StateID: + private::Sealed + + Clone + Copy + Debug + Eq + Hash + PartialEq + PartialOrd + Ord +{ + /// Convert from a `usize` to this implementation's representation. + /// + /// Implementors may assume that `n <= Self::max_id`. That is, implementors + /// do not need to check whether `n` can fit inside this implementation's + /// representation. + fn from_usize(n: usize) -> Self; + + /// Convert this implementation's representation to a `usize`. + /// + /// Implementors must not return a `usize` value greater than + /// `Self::max_id` and must not permit overflow when converting between the + /// implementor's representation and `usize`. In general, the preferred + /// way for implementors to achieve this is to simply not provide + /// implementations of `StateID` that cannot fit into the target platform's + /// `usize`. + fn to_usize(self) -> usize; + + /// Return the maximum state identifier supported by this representation. + /// + /// Implementors must return a correct bound. Doing otherwise may result + /// in memory unsafety. + fn max_id() -> usize; +} + +unsafe impl StateID for usize { + #[inline] + fn from_usize(n: usize) -> usize { n } + + #[inline] + fn to_usize(self) -> usize { self } + + #[inline] + fn max_id() -> usize { ::std::usize::MAX } +} + +unsafe impl StateID for u8 { + #[inline] + fn from_usize(n: usize) -> u8 { n as u8 } + + #[inline] + fn to_usize(self) -> usize { self as usize } + + #[inline] + fn max_id() -> usize { ::std::u8::MAX as usize } +} + +unsafe impl StateID for u16 { + #[inline] + fn from_usize(n: usize) -> u16 { n as u16 } + + #[inline] + fn to_usize(self) -> usize { self as usize } + + #[inline] + fn max_id() -> usize { ::std::u16::MAX as usize } +} + +#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] +unsafe impl StateID for u32 { + #[inline] + fn from_usize(n: usize) -> u32 { n as u32 } + + #[inline] + fn to_usize(self) -> usize { self as usize } + + #[inline] + fn max_id() -> usize { ::std::u32::MAX as usize } +} + +#[cfg(target_pointer_width = "64")] +unsafe impl StateID for u64 { + #[inline] + fn from_usize(n: usize) -> u64 { n as u64 } + + #[inline] + fn to_usize(self) -> usize { self as usize } + + #[inline] + fn max_id() -> usize { ::std::u64::MAX as usize } +} diff -Nru cargo-0.33.0/vendor/aho-corasick/src/tests.rs cargo-0.35.0/vendor/aho-corasick/src/tests.rs --- cargo-0.33.0/vendor/aho-corasick/src/tests.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/aho-corasick/src/tests.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,694 @@ +use std::collections::HashMap; +use std::io; +use std::usize; + +use {AhoCorasickBuilder, Match, MatchKind}; + +/// A description of a single test against an Aho-Corasick automaton. +/// +/// A single test may not necessarily pass on every configuration of an +/// Aho-Corasick automaton. The tests are categorized and grouped appropriately +/// below. +#[derive(Clone, Debug, Eq, PartialEq)] +struct SearchTest { + /// The name of this test, for debugging. + name: &'static str, + /// The patterns to search for. + patterns: &'static [&'static str], + /// The text to search. + haystack: &'static str, + /// Each match is a triple of (pattern_index, start, end), where + /// pattern_index is an index into `patterns` and `start`/`end` are indices + /// into `haystack`. + matches: &'static [(usize, usize, usize)], +} + +/// Short-hand constructor for SearchTest. We use it a lot below. +macro_rules! t { + ($name:ident, $patterns:expr, $haystack:expr, $matches:expr) => { + SearchTest { + name: stringify!($name), + patterns: $patterns, + haystack: $haystack, + matches: $matches, + } + } +} + +/// A collection of test groups. +type TestCollection = &'static [&'static [SearchTest]]; + +// Define several collections corresponding to the different type of match +// semantics supported by Aho-Corasick. These collections have some overlap, +// but each collection should have some tests that no other collection has. + +/// Tests for Aho-Corasick's standard non-overlapping match semantics. +const AC_STANDARD_NON_OVERLAPPING: TestCollection = &[ + BASICS, NON_OVERLAPPING, STANDARD, REGRESSION, +]; + +/// Tests for Aho-Corasick's standard overlapping match semantics. +const AC_STANDARD_OVERLAPPING: TestCollection = &[ + BASICS, OVERLAPPING, REGRESSION, +]; + +/// Tests for Aho-Corasick's leftmost-first match semantics. +const AC_LEFTMOST_FIRST: TestCollection = &[ + BASICS, NON_OVERLAPPING, LEFTMOST, LEFTMOST_FIRST, REGRESSION, +]; + +/// Tests for Aho-Corasick's leftmost-longest match semantics. +const AC_LEFTMOST_LONGEST: TestCollection = &[ + BASICS, NON_OVERLAPPING, LEFTMOST, LEFTMOST_LONGEST, REGRESSION, +]; + +// Now define the individual tests that make up the collections above. + +/// A collection of tests for the Aho-Corasick algorithm that should always be +/// true regardless of match semantics. That is, all combinations of +/// leftmost-{shortest, first, longest} x {overlapping, non-overlapping} +/// should produce the same answer. +const BASICS: &'static [SearchTest] = &[ + t!(basic000, &["a"], "", &[]), + t!(basic010, &["a"], "a", &[(0, 0, 1)]), + t!(basic020, &["a"], "aa", &[(0, 0, 1), (0, 1, 2)]), + t!(basic030, &["a"], "aaa", &[(0, 0, 1), (0, 1, 2), (0, 2, 3)]), + t!(basic040, &["a"], "aba", &[(0, 0, 1), (0, 2, 3)]), + t!(basic050, &["a"], "bba", &[(0, 2, 3)]), + t!(basic060, &["a"], "bbb", &[]), + t!(basic070, &["a"], "bababbbba", &[(0, 1, 2), (0, 3, 4), (0, 8, 9)]), + + t!(basic100, &["aa"], "", &[]), + t!(basic110, &["aa"], "aa", &[(0, 0, 2)]), + t!(basic120, &["aa"], "aabbaa", &[(0, 0, 2), (0, 4, 6)]), + t!(basic130, &["aa"], "abbab", &[]), + t!(basic140, &["aa"], "abbabaa", &[(0, 5, 7)]), + + t!(basic200, &["abc"], "abc", &[(0, 0, 3)]), + t!(basic210, &["abc"], "zazabzabcz", &[(0, 6, 9)]), + t!(basic220, &["abc"], "zazabczabcz", &[(0, 3, 6), (0, 7, 10)]), + + t!(basic300, &["a", "b"], "", &[]), + t!(basic310, &["a", "b"], "z", &[]), + t!(basic320, &["a", "b"], "b", &[(1, 0, 1)]), + t!(basic330, &["a", "b"], "a", &[(0, 0, 1)]), + t!(basic340, &["a", "b"], "abba", &[ + (0, 0, 1), (1, 1, 2), (1, 2, 3), (0, 3, 4), + ]), + t!(basic350, &["b", "a"], "abba", &[ + (1, 0, 1), (0, 1, 2), (0, 2, 3), (1, 3, 4), + ]), + t!(nover360, &["abc", "bc"], "xbc", &[ + (1, 1, 3), + ]), + + t!(basic400, &["foo", "bar"], "", &[]), + t!(basic410, &["foo", "bar"], "foobar", &[ + (0, 0, 3), (1, 3, 6), + ]), + t!(basic420, &["foo", "bar"], "barfoo", &[ + (1, 0, 3), (0, 3, 6), + ]), + t!(basic430, &["foo", "bar"], "foofoo", &[ + (0, 0, 3), (0, 3, 6), + ]), + t!(basic440, &["foo", "bar"], "barbar", &[ + (1, 0, 3), (1, 3, 6), + ]), + t!(basic450, &["foo", "bar"], "bafofoo", &[ + (0, 4, 7), + ]), + t!(basic460, &["bar", "foo"], "bafofoo", &[ + (1, 4, 7), + ]), + t!(basic470, &["foo", "bar"], "fobabar", &[ + (1, 4, 7), + ]), + t!(basic480, &["bar", "foo"], "fobabar", &[ + (0, 4, 7), + ]), + + t!(basic600, &[""], "", &[(0, 0, 0)]), + t!(basic610, &[""], "a", &[(0, 0, 0), (0, 1, 1)]), + t!(basic620, &[""], "abc", &[(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3)]), + + t!(basic700, &["yabcdef", "abcdezghi"], "yabcdefghi", &[ + (0, 0, 7), + ]), + t!(basic710, &["yabcdef", "abcdezghi"], "yabcdezghi", &[ + (1, 1, 10), + ]), + t!(basic720, &["yabcdef", "bcdeyabc", "abcdezghi"], "yabcdezghi", &[ + (2, 1, 10), + ]), +]; + +/// Tests for non-overlapping standard match semantics. +/// +/// These tests generally shouldn't pass for leftmost-{first,longest}, although +/// some do in order to write clearer tests. For example, standard000 will +/// pass with leftmost-first semantics, but standard010 will not. We write +/// both to emphasize how the match semantics work. +const STANDARD: &'static [SearchTest] = &[ + t!(standard000, &["ab", "abcd"], "abcd", &[(0, 0, 2)]), + t!(standard010, &["abcd", "ab"], "abcd", &[(1, 0, 2)]), + t!(standard020, &["abcd", "ab", "abc"], "abcd", &[(1, 0, 2)]), + t!(standard030, &["abcd", "abc", "ab"], "abcd", &[(2, 0, 2)]), + t!(standard040, &["a", ""], "a", &[(1, 0, 0), (1, 1, 1)]), + + t!(standard400, &["abcd", "bcd", "cd", "b"], "abcd", &[ + (3, 1, 2), (2, 2, 4), + ]), + t!(standard410, &["", "a"], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), + t!(standard420, &["", "a"], "aa", &[ + (0, 0, 0), (0, 1, 1), (0, 2, 2), + ]), + t!(standard430, &["", "a", ""], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), + t!(standard440, &["a", "", ""], "a", &[ + (1, 0, 0), (1, 1, 1), + ]), + t!(standard450, &["", "", "a"], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), +]; + +/// Tests for non-overlapping leftmost match semantics. These should pass for +/// both leftmost-first and leftmost-longest match kinds. Stated differently, +/// among ambiguous matches, the longest match and the match that appeared +/// first when constructing the automaton should always be the same. +const LEFTMOST: &'static [SearchTest] = &[ + t!(leftmost000, &["ab", "ab"], "abcd", &[(0, 0, 2)]), + t!(leftmost010, &["a", ""], "a", &[(0, 0, 1), (1, 1, 1)]), + t!(leftmost020, &["", ""], "a", &[(0, 0, 0), (0, 1, 1)]), + + t!(leftmost300, &["abcd", "bce", "b"], "abce", &[(1, 1, 4)]), + t!(leftmost310, &["abcd", "ce", "bc"], "abce", &[(2, 1, 3)]), + t!(leftmost320, &["abcd", "bce", "ce", "b"], "abce", &[(1, 1, 4)]), + t!(leftmost330, &["abcd", "bce", "cz", "bc"], "abcz", &[(3, 1, 3)]), + t!(leftmost340, &["bce", "cz", "bc"], "bcz", &[(2, 0, 2)]), + t!(leftmost350, &["abc", "bd", "ab"], "abd", &[(2, 0, 2)]), + t!(leftmost360, &["abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (2, 0, 8), + ]), + t!(leftmost370, &["abcdefghi", "cde", "hz", "abcdefgh"], "abcdefghz", &[ + (3, 0, 8), + ]), + t!(leftmost380, &["abcdefghi", "hz", "abcdefgh", "a"], "abcdefghz", &[ + (2, 0, 8), + ]), + t!(leftmost390, &["b", "abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (3, 0, 8), + ]), + t!(leftmost400, &["h", "abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (3, 0, 8), + ]), + t!(leftmost410, &["z", "abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (3, 0, 8), (0, 8, 9), + ]), +]; + +/// Tests for non-overlapping leftmost-first match semantics. These tests +/// should generally be specific to leftmost-first, which means they should +/// generally fail under leftmost-longest semantics. +const LEFTMOST_FIRST: &'static [SearchTest] = &[ + t!(leftfirst000, &["ab", "abcd"], "abcd", &[(0, 0, 2)]), + t!(leftfirst010, &["", "a"], "a", &[(0, 0, 0), (0, 1, 1)]), + t!(leftfirst011, &["", "a", ""], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), + t!(leftfirst012, &["a", "", ""], "a", &[ + (0, 0, 1), (1, 1, 1), + ]), + t!(leftfirst013, &["", "", "a"], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), + t!(leftfirst020, &["abcd", "ab"], "abcd", &[(0, 0, 4)]), + t!(leftfirst030, &["ab", "ab"], "abcd", &[(0, 0, 2)]), + + t!(leftlong100, &["abcdefg", "bcde", "bcdef"], "abcdef", &[(1, 1, 5)]), + t!(leftlong110, &["abcdefg", "bcdef", "bcde"], "abcdef", &[(1, 1, 6)]), + + t!(leftfirst300, &["abcd", "b", "bce"], "abce", &[(1, 1, 2)]), + t!(leftfirst310, &["abcd", "b", "bce", "ce"], "abce", &[ + (1, 1, 2), (3, 2, 4), + ]), + t!(leftfirst320, &["a", "abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (0, 0, 1), (2, 7, 9), + ]), + t!(leftfirst330, &["a", "abab"], "abab", &[(0, 0, 1), (0, 2, 3)]), +]; + +/// Tests for non-overlapping leftmost-longest match semantics. These tests +/// should generally be specific to leftmost-longest, which means they should +/// generally fail under leftmost-first semantics. +const LEFTMOST_LONGEST: &'static [SearchTest] = &[ + t!(leftlong000, &["ab", "abcd"], "abcd", &[(1, 0, 4)]), + t!(leftlong010, &["abcd", "bcd", "cd", "b"], "abcd", &[ + (0, 0, 4), + ]), + t!(leftlong020, &["", "a"], "a", &[ + (1, 0, 1), (0, 1, 1), + ]), + t!(leftlong021, &["", "a", ""], "a", &[ + (1, 0, 1), (0, 1, 1), + ]), + t!(leftlong022, &["a", "", ""], "a", &[ + (0, 0, 1), (1, 1, 1), + ]), + t!(leftlong023, &["", "", "a"], "a", &[ + (2, 0, 1), (0, 1, 1), + ]), + t!(leftlong030, &["", "a"], "aa", &[ + (1, 0, 1), (1, 1, 2), (0, 2, 2), + ]), + t!(leftlong040, &["a", "ab"], "a", &[(0, 0, 1)]), + t!(leftlong050, &["a", "ab"], "ab", &[(1, 0, 2)]), + t!(leftlong060, &["ab", "a"], "a", &[(1, 0, 1)]), + t!(leftlong070, &["ab", "a"], "ab", &[(0, 0, 2)]), + + t!(leftlong100, &["abcdefg", "bcde", "bcdef"], "abcdef", &[(2, 1, 6)]), + t!(leftlong110, &["abcdefg", "bcdef", "bcde"], "abcdef", &[(1, 1, 6)]), + + t!(leftlong300, &["abcd", "b", "bce"], "abce", &[(2, 1, 4)]), + t!(leftlong310, &["a", "abcdefghi", "hz", "abcdefgh"], "abcdefghz", &[ + (3, 0, 8), + ]), + t!(leftlong320, &["a", "abab"], "abab", &[(1, 0, 4)]), + t!(leftlong330, &["abcd", "b", "ce"], "abce", &[ + (1, 1, 2), (2, 2, 4), + ]), +]; + +/// Tests for non-overlapping match semantics. +/// +/// Generally these tests shouldn't pass when using overlapping semantics. +/// These should pass for both standard and leftmost match semantics. +const NON_OVERLAPPING: &'static [SearchTest] = &[ + t!(nover010, &["abcd", "bcd", "cd"], "abcd", &[ + (0, 0, 4), + ]), + t!(nover020, &["bcd", "cd", "abcd"], "abcd", &[ + (2, 0, 4), + ]), + t!(nover030, &["abc", "bc"], "zazabcz", &[ + (0, 3, 6), + ]), + + t!(nover100, &["ab", "ba"], "abababa", &[ + (0, 0, 2), (0, 2, 4), (0, 4, 6), + ]), + + t!(nover200, &["foo", "foo"], "foobarfoo", &[ + (0, 0, 3), (0, 6, 9), + ]), + + t!(nover300, &["", ""], "", &[ + (0, 0, 0), + ]), + t!(nover310, &["", ""], "a", &[ + (0, 0, 0), (0, 1, 1), + ]), +]; + +/// Tests for overlapping match semantics. +/// +/// This only supports standard match semantics, since leftmost-{first,longest} +/// do not support overlapping matches. +const OVERLAPPING: &'static [SearchTest] = &[ + t!(over000, &["abcd", "bcd", "cd", "b"], "abcd", &[ + (3, 1, 2), (0, 0, 4), (1, 1, 4), (2, 2, 4), + ]), + t!(over010, &["bcd", "cd", "b", "abcd"], "abcd", &[ + (2, 1, 2), (3, 0, 4), (0, 1, 4), (1, 2, 4), + ]), + t!(over020, &["abcd", "bcd", "cd"], "abcd", &[ + (0, 0, 4), (1, 1, 4), (2, 2, 4), + ]), + t!(over030, &["bcd", "abcd", "cd"], "abcd", &[ + (1, 0, 4), (0, 1, 4), (2, 2, 4), + ]), + t!(over040, &["bcd", "cd", "abcd"], "abcd", &[ + (2, 0, 4), (0, 1, 4), (1, 2, 4), + ]), + t!(over050, &["abc", "bc"], "zazabcz", &[ + (0, 3, 6), (1, 4, 6), + ]), + + t!(over100, &["ab", "ba"], "abababa", &[ + (0, 0, 2), (1, 1, 3), (0, 2, 4), (1, 3, 5), (0, 4, 6), (1, 5, 7), + ]), + + t!(over200, &["foo", "foo"], "foobarfoo", &[ + (0, 0, 3), (1, 0, 3), (0, 6, 9), (1, 6, 9), + ]), + + t!(over300, &["", ""], "", &[ + (0, 0, 0), (1, 0, 0), + ]), + t!(over310, &["", ""], "a", &[ + (0, 0, 0), (1, 0, 0), (0, 1, 1), (1, 1, 1), + ]), + t!(over320, &["", "a"], "a", &[ + (0, 0, 0), (1, 0, 1), (0, 1, 1), + ]), + t!(over330, &["", "a", ""], "a", &[ + (0, 0, 0), (2, 0, 0), (1, 0, 1), (0, 1, 1), (2, 1, 1), + ]), + t!(over340, &["a", "", ""], "a", &[ + (1, 0, 0), (2, 0, 0), (0, 0, 1), (1, 1, 1), (2, 1, 1), + ]), + t!(over350, &["", "", "a"], "a", &[ + (0, 0, 0), (1, 0, 0), (2, 0, 1), (0, 1, 1), (1, 1, 1), + ]), +]; + +/// Regression tests that are applied to all Aho-Corasick combinations. +/// +/// If regression tests are needed for specific match semantics, then add them +/// to the appropriate group above. +const REGRESSION: &'static [SearchTest] = &[ + t!(regression010, &["inf", "ind"], "infind", &[ + (0, 0, 3), (1, 3, 6), + ]), + t!(regression020, &["ind", "inf"], "infind", &[ + (1, 0, 3), (0, 3, 6), + ]), + t!(regression030, &["libcore/", "libstd/"], "libcore/char/methods.rs", &[ + (0, 0, 8), + ]), + t!(regression040, &["libstd/", "libcore/"], "libcore/char/methods.rs", &[ + (1, 0, 8), + ]), + t!(regression050, &["\x00\x00\x01", "\x00\x00\x00"], "\x00\x00\x00", &[ + (1, 0, 3), + ]), + t!(regression060, &["\x00\x00\x00", "\x00\x00\x01"], "\x00\x00\x00", &[ + (0, 0, 3), + ]), +]; + +// Now define a test for each combination of things above that we want to run. +// Since there are a few different combinations for each collection of tests, +// we define a couple of macros to avoid repetition drudgery. The testconfig +// macro constructs the automaton from a given match kind, and runs the search +// tests one-by-one over the given collection. The `with` parameter allows one +// to configure the builder with additional parameters. The testcombo macro +// invokes testconfig in precisely this way: it sets up several tests where +// each one turns a different knob on AhoCorasickBuilder. + +macro_rules! testconfig { + (overlapping, $name:ident, $collection:expr, $kind:ident, $with:expr) => { + #[test] + fn $name() { + run_search_tests($collection, |test| { + let mut builder = AhoCorasickBuilder::new(); + $with(&mut builder); + builder + .match_kind(MatchKind::$kind) + .build(test.patterns) + .find_overlapping_iter(test.haystack) + .collect() + }); + } + }; + (stream, $name:ident, $collection:expr, $kind:ident, $with:expr) => { + #[test] + fn $name() { + run_search_tests($collection, |test| { + let buf = io::BufReader::with_capacity( + 1, + test.haystack.as_bytes(), + ); + let mut builder = AhoCorasickBuilder::new(); + $with(&mut builder); + builder + .match_kind(MatchKind::$kind) + .build(test.patterns) + .stream_find_iter(buf) + .map(|result| result.unwrap()) + .collect() + }); + } + }; + ($name:ident, $collection:expr, $kind:ident, $with:expr) => { + #[test] + fn $name() { + run_search_tests($collection, |test| { + let mut builder = AhoCorasickBuilder::new(); + $with(&mut builder); + builder + .match_kind(MatchKind::$kind) + .build(test.patterns) + .find_iter(test.haystack) + .collect() + }); + } + }; +} + +macro_rules! testcombo { + ($name:ident, $collection:expr, $kind:ident) => { + mod $name { + use super::*; + + testconfig!(nfa_default, $collection, $kind, |_| ()); + testconfig!(nfa_no_prefilter, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.prefilter(false); + }); + testconfig!(nfa_all_sparse, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dense_depth(0); + }); + testconfig!(nfa_all_dense, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dense_depth(usize::MAX); + }); + testconfig!(dfa_default, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true); + }); + testconfig!(dfa_no_prefilter, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).prefilter(false); + }); + testconfig!(dfa_all_sparse, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).dense_depth(0); + }); + testconfig!(dfa_all_dense, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).dense_depth(usize::MAX); + }); + testconfig!(dfa_no_byte_class, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).byte_classes(false); + }); + testconfig!(dfa_no_premultiply, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).premultiply(false); + }); + testconfig!(dfa_no_byte_class_no_premultiply, $collection, $kind, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).byte_classes(false).premultiply(false); + }); + } + }; +} + +// Write out the combinations. +testcombo!(search_leftmost_longest, AC_LEFTMOST_LONGEST, LeftmostLongest); +testcombo!(search_leftmost_first, AC_LEFTMOST_FIRST, LeftmostFirst); +testcombo!( + search_standard_nonoverlapping, AC_STANDARD_NON_OVERLAPPING, Standard +); + +// Write out the overlapping combo by hand since there is only one of them. +testconfig!( + overlapping, + search_standard_overlapping_nfa_default, + AC_STANDARD_OVERLAPPING, + Standard, + |_| () +); +testconfig!( + overlapping, + search_standard_overlapping_nfa_all_sparse, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dense_depth(0); } +); +testconfig!( + overlapping, + search_standard_overlapping_nfa_all_dense, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dense_depth(usize::MAX); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_default, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_all_sparse, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true).dense_depth(0); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_all_dense, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true).dense_depth(usize::MAX); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_no_byte_class, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true).byte_classes(false); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_no_premultiply, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true).premultiply(false); } +); +testconfig!( + overlapping, + search_standard_overlapping_dfa_no_byte_class_no_premultiply, + AC_STANDARD_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { + b.dfa(true).byte_classes(false).premultiply(false); + } +); + +// Also write out tests manually for streams, since we only test the standard +// match semantics. We also don't bother testing different automaton +// configurations, since those are well covered by tests above. +testconfig!( + stream, + search_standard_stream_nfa_default, + AC_STANDARD_NON_OVERLAPPING, + Standard, + |_| () +); +testconfig!( + stream, + search_standard_stream_dfa_default, + AC_STANDARD_NON_OVERLAPPING, + Standard, + |b: &mut AhoCorasickBuilder| { b.dfa(true); } +); + +#[test] +fn search_tests_have_unique_names() { + let assert = |constname, tests: &[SearchTest]| { + let mut seen = HashMap::new(); // map from test name to position + for (i, test) in tests.iter().enumerate() { + if !seen.contains_key(test.name) { + seen.insert(test.name, i); + } else { + let last = seen[test.name]; + panic!( + "{} tests have duplicate names at positions {} and {}", + constname, last, i + ); + } + } + }; + assert("BASICS", BASICS); + assert("STANDARD", STANDARD); + assert("LEFTMOST", LEFTMOST); + assert("LEFTMOST_FIRST", LEFTMOST_FIRST); + assert("LEFTMOST_LONGEST", LEFTMOST_LONGEST); + assert("NON_OVERLAPPING", NON_OVERLAPPING); + assert("OVERLAPPING", OVERLAPPING); + assert("REGRESSION", REGRESSION); +} + +#[test] +#[should_panic] +fn stream_not_allowed_leftmost_first() { + let fsm = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostFirst) + .build(None::); + assert_eq!(fsm.stream_find_iter(&b""[..]).count(), 0); +} + +#[test] +#[should_panic] +fn stream_not_allowed_leftmost_longest() { + let fsm = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostLongest) + .build(None::); + assert_eq!(fsm.stream_find_iter(&b""[..]).count(), 0); +} + +#[test] +#[should_panic] +fn overlapping_not_allowed_leftmost_first() { + let fsm = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostFirst) + .build(None::); + assert_eq!(fsm.find_overlapping_iter("").count(), 0); +} + +#[test] +#[should_panic] +fn overlapping_not_allowed_leftmost_longest() { + let fsm = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostLongest) + .build(None::); + assert_eq!(fsm.find_overlapping_iter("").count(), 0); +} + +#[test] +fn state_id_too_small() { + let mut patterns = vec![]; + for c1 in (b'a'..b'z').map(|b| b as char) { + for c2 in (b'a'..b'z').map(|b| b as char) { + for c3 in (b'a'..b'z').map(|b| b as char) { + patterns.push(format!("{}{}{}", c1, c2, c3)); + } + } + } + let result = AhoCorasickBuilder::new() + .build_with_size::(&patterns); + assert!(result.is_err()); +} + +fn run_search_tests Vec>( + which: TestCollection, + mut f: F, +) { + let get_match_triples = + |matches: Vec| -> Vec<(usize, usize, usize)> { + matches.into_iter() + .map(|m| (m.pattern(), m.start(), m.end())) + .collect() + }; + for &tests in which { + for test in tests { + assert_eq!( + test.matches, + get_match_triples(f(&test)).as_slice(), + "test: {}, patterns: {:?}, haystack: {:?}", + test.name, + test.patterns, + test.haystack + ); + } + } +} diff -Nru cargo-0.33.0/vendor/backtrace/appveyor.yml cargo-0.35.0/vendor/backtrace/appveyor.yml --- cargo-0.33.0/vendor/backtrace/appveyor.yml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -environment: - matrix: - - TARGET: x86_64-pc-windows-gnu - MSYS_BITS: 64 - - TARGET: i686-pc-windows-gnu - MSYS_BITS: 32 - - TARGET: x86_64-pc-windows-msvc - - TARGET: i686-pc-windows-msvc -install: - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" - - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - - set PATH=%PATH%;C:\Program Files (x86)\Rust\bin - - if defined MSYS_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS_BITS%\bin - - rustc -V - - cargo -V - -build: false - -test_script: - - cargo test --target %TARGET% - - cargo build --target %TARGET% --no-default-features - - cargo build --target %TARGET% --no-default-features --features dbghelp - -branches: - only: - - master diff -Nru cargo-0.33.0/vendor/backtrace/azure-pipelines.yml cargo-0.35.0/vendor/backtrace/azure-pipelines.yml --- cargo-0.33.0/vendor/backtrace/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/azure-pipelines.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,158 @@ +trigger: + - master + +jobs: + - job: MSRV + pool: + vmImage: ubuntu-16.04 + steps: + - checkout: self + submodules: true + - template: ci/azure-install-rust.yml + - script: cargo build + displayName: "Build crate" + variables: + TOOLCHAIN: 1.25.0 + + - job: Docker + pool: + vmImage: ubuntu-16.04 + steps: + - checkout: self + submodules: true + - template: ci/azure-install-rust.yml + - bash: rustup target add $TARGET + displayName: "Install rust cross target" + - bash: | + set -e + cargo generate-lockfile + ./ci/run-docker.sh $TARGET + displayName: "Run tests in docker" + strategy: + matrix: + aarch64: + TARGET: aarch64-unknown-linux-gnu + armhv: + TARGET: arm-unknown-linux-gnueabihf + armv7: + TARGET: armv7-unknown-linux-gnueabihf + i586: + TARGET: i586-unknown-linux-gnu + i686: + TARGET: i686-unknown-linux-gnu + powerpc64: + TARGET: powerpc64-unknown-linux-gnu + mingw: + TARGET: x86_64-pc-windows-gnu + x86_64: + TARGET: x86_64-unknown-linux-gnu + gnu: + TARGET: x86_64-unknown-linux-musl + + android-arm: + TARGET: arm-linux-androideabi + android-armv7: + TARGET: armv7-linux-androideabi + android-aarch64: + TARGET: aarch64-linux-android + android-i686: + TARGET: i686-linux-android + android-x86_64: + TARGET: x86_64-linux-android + + - job: Linux + pool: + vmImage: ubuntu-16.04 + steps: + - template: ci/azure-test-all.yml + strategy: + matrix: + stable: + TOOLCHAIN: stable + beta: + TOOLCHAIN: beta + nightly: + TOOLCHAIN: nightly + + - job: macOS + pool: + vmImage: macos-10.13 + steps: + - template: ci/azure-test-all.yml + strategy: + matrix: + x86_64: + TARGET: x86_64-apple-darwin + + - job: iOS + pool: + vmImage: macos-10.13 + steps: + - checkout: self + submodules: true + - template: ci/azure-install-rust.yml + - script: rustup target add $TARGET + displayName: "Install rust cross target" + - bash: | + set -e + export SDK_PATH=`xcrun --show-sdk-path --sdk $SDK` + export RUSTFLAGS="-C link-arg=-isysroot -C link-arg=$SDK_PATH" + cargo test --no-run --target $TARGET + displayName: "Build for iOS" + strategy: + matrix: + aarch64: + TARGET: aarch64-apple-ios + SDK: iphoneos + armv7: + TARGET: armv7-apple-ios + SDK: iphoneos + armv7s: + TARGET: armv7s-apple-ios + SDK: iphoneos + i386: + TARGET: i386-apple-ios + SDK: iphonesimulator + x86_64: + TARGET: x86_64-apple-ios + SDK: iphonesimulator + + - job: wasm + pool: + vmImage: ubuntu-16.04 + steps: + - checkout: self + submodules: true + - template: ci/azure-install-rust.yml + - script: rustup target add wasm32-unknown-unknown + displayName: "Install rust cross target" + - script: cargo build --target wasm32-unknown-unknown + displayName: "Build for wasm" + + - job: Windows + pool: + vmImage: vs2017-win2016 + steps: + - template: ci/azure-test-all.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + i686-msvc: + TARGET: i686-pc-windows-msvc + x86_64-gnu: + TARGET: x86_64-pc-windows-gnu + i686-gnu: + TARGET: i686-pc-windows-gnu + + - job: Windows_arm64 + pool: + vmImage: windows-2019 + steps: + - template: ci/azure-install-rust.yml + - script: rustup target add aarch64-pc-windows-msvc + displayName: "Install rust cross target" + - script: cargo test --no-run --target aarch64-pc-windows-msvc + displayName: "Build for arm64" + - script: cargo test --no-run --target aarch64-pc-windows-msvc --features verify-winapi + displayName: "Build for arm64" diff -Nru cargo-0.33.0/vendor/backtrace/benches/benchmarks.rs cargo-0.35.0/vendor/backtrace/benches/benchmarks.rs --- cargo-0.33.0/vendor/backtrace/benches/benchmarks.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/benches/benchmarks.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,94 @@ +#![feature(test)] + +extern crate test; + +extern crate backtrace; + +#[cfg(feature = "std")] +use backtrace::Backtrace; + +#[bench] +#[cfg(feature = "std")] +fn trace(b: &mut test::Bencher) { + #[inline(never)] + fn the_function() { + backtrace::trace(|frame| { + let ip = frame.ip(); + test::black_box(ip); + true + }); + } + b.iter(the_function); +} + +#[bench] +#[cfg(feature = "std")] +fn trace_and_resolve_callback(b: &mut test::Bencher) { + #[inline(never)] + fn the_function() { + backtrace::trace(|frame| { + backtrace::resolve(frame.ip(), |symbol| { + let addr = symbol.addr(); + test::black_box(addr); + }); + true + }); + } + b.iter(the_function); +} + +#[bench] +#[cfg(feature = "std")] +fn trace_and_resolve_separate(b: &mut test::Bencher) { + #[inline(never)] + fn the_function(frames: &mut Vec<*mut std::ffi::c_void>) { + backtrace::trace(|frame| { + frames.push(frame.ip()); + true + }); + frames.iter().for_each(|frame_ip| { + backtrace::resolve(*frame_ip, |symbol| { + test::black_box(symbol); + }); + }); + } + let mut frames = Vec::with_capacity(1024); + b.iter(|| { + the_function(&mut frames); + frames.clear(); + }); +} + +#[bench] +#[cfg(feature = "std")] +fn new_unresolved(b: &mut test::Bencher) { + #[inline(never)] + fn the_function() { + let bt = Backtrace::new_unresolved(); + test::black_box(bt); + } + b.iter(the_function); +} + +#[bench] +#[cfg(feature = "std")] +fn new(b: &mut test::Bencher) { + #[inline(never)] + fn the_function() { + let bt = Backtrace::new(); + test::black_box(bt); + } + b.iter(the_function); +} + +#[bench] +#[cfg(feature = "std")] +fn new_unresolved_and_resolve_separate(b: &mut test::Bencher) { + #[inline(never)] + fn the_function() { + let mut bt = Backtrace::new_unresolved(); + bt.resolve(); + test::black_box(bt); + } + b.iter(the_function); +} diff -Nru cargo-0.33.0/vendor/backtrace/.cargo-checksum.json cargo-0.35.0/vendor/backtrace/.cargo-checksum.json --- cargo-0.33.0/vendor/backtrace/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5"} \ No newline at end of file +{"files":{},"package":"56acb7e9c23cb8c3a1f51713695c552a81ee667d9fd060d1ef407908480b7174"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/backtrace/Cargo.toml cargo-0.35.0/vendor/backtrace/Cargo.toml --- cargo-0.33.0/vendor/backtrace/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "backtrace" -version = "0.3.13" +version = "0.3.16" authors = ["Alex Crichton ", "The Rust Project Developers"] autoexamples = true autotests = true @@ -42,8 +42,13 @@ [[test]] name = "smoke" required-features = ["std"] +edition = "2018" [dependencies.addr2line] -version = "0.7.0" +version = "0.9.0" +optional = true + +[dependencies.backtrace-sys] +version = "0.1.17" optional = true [dependencies.cfg-if] @@ -55,21 +60,17 @@ default-features = false [dependencies.findshlibs] -version = "0.4.0" +version = "0.4.1" optional = true -[dependencies.gimli] -version = "0.16.0" -optional = true +[dependencies.libc] +version = "0.2.45" +default-features = false [dependencies.memmap] version = "0.7.0" optional = true -[dependencies.object] -version = "0.11" -optional = true - [dependencies.rustc-demangle] version = "0.1.4" @@ -92,20 +93,15 @@ dbghelp = [] default = ["std", "libunwind", "libbacktrace", "coresymbolication", "dladdr", "dbghelp"] dladdr = [] -gimli-symbolize = ["addr2line", "findshlibs", "gimli", "memmap", "object"] +gimli-symbolize = ["addr2line", "findshlibs", "memmap"] kernel32 = [] -libbacktrace = ["backtrace-sys", "std"] +libbacktrace = ["backtrace-sys"] libunwind = [] serialize-rustc = ["rustc-serialize"] serialize-serde = ["serde", "serde_derive"] std = [] unix-backtrace = [] -[target."cfg(all(unix, not(target_os = \"fuchsia\"), not(target_os = \"emscripten\"), not(target_os = \"macos\"), not(target_os = \"ios\")))".dependencies.backtrace-sys] -version = "0.1.17" -optional = true -[target."cfg(unix)".dependencies.libc] -version = "0.2.45" -default-features = false +verify-winapi = ["winapi/dbghelp", "winapi/handleapi", "winapi/libloaderapi", "winapi/minwindef", "winapi/processthreadsapi", "winapi/winbase", "winapi/winnt"] [target."cfg(windows)".dependencies.winapi] version = "0.3.3" -features = ["dbghelp", "processthreadsapi", "winnt", "minwindef"] +optional = true diff -Nru cargo-0.33.0/vendor/backtrace/ci/azure-install-rust.yml cargo-0.35.0/vendor/backtrace/ci/azure-install-rust.yml --- cargo-0.33.0/vendor/backtrace/ci/azure-install-rust.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/ci/azure-install-rust.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,23 @@ +steps: + - bash: | + set -e + toolchain=$TOOLCHAIN + if [ "$toolchain" = "" ]; then + toolchain=stable + fi + curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $toolchain + echo "##vso[task.prependpath]$HOME/.cargo/bin" + displayName: Install rust (unix) + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + curl -sSf -o rustup-init.exe https://win.rustup.rs + rustup-init.exe -y --default-toolchain stable-%TARGET% + echo ##vso[task.prependpath]%USERPROFILE%\.cargo\bin + displayName: Install rust (windows) + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + rustc -Vv + cargo -V + displayName: Query rust and cargo versions diff -Nru cargo-0.33.0/vendor/backtrace/ci/azure-test-all.yml cargo-0.35.0/vendor/backtrace/ci/azure-test-all.yml --- cargo-0.33.0/vendor/backtrace/ci/azure-test-all.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/ci/azure-test-all.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,43 @@ +steps: + - checkout: self + submodules: true + - template: azure-install-rust.yml + + - bash: cargo build --manifest-path backtrace-sys/Cargo.toml + displayName: "Build backtrace-sys" + - bash: cargo build + displayName: "Build backtrace" + - bash: cargo test + displayName: "Test backtrace" + - bash: cargo test --no-default-features + displayName: "Test backtrace (-default)" + - bash: cargo test --no-default-features --features 'std' + displayName: "Test backtrace (-default + std)" + - bash: cargo test --no-default-features --features 'libunwind std' + displayName: "Test backtrace (-default + libunwind)" + - bash: cargo test --no-default-features --features 'libunwind dladdr std' + displayName: "Test backtrace (-default + libunwind + dladdr)" + - bash: cargo test --no-default-features --features 'libunwind libbacktrace std' + displayName: "Test backtrace (-default + libunwind + libbacktrace)" + - bash: cargo test --no-default-features --features 'unix-backtrace std' + displayName: "Test backtrace (-default + unix-backtrace)" + - bash: cargo test --no-default-features --features 'unix-backtrace dladdr std' + displayName: "Test backtrace (-default + unix-backtrace + dladdr)" + - bash: cargo test --no-default-features --features 'unix-backtrace libbacktrace std' + displayName: "Test backtrace (-default + unix-backtrace + libbacktrace)" + - bash: cargo test --no-default-features --features 'serialize-serde std' + displayName: "Test backtrace (-default + serialize-serde + std)" + - bash: cargo test --no-default-features --features 'serialize-rustc std' + displayName: "Test backtrace (-default + serialize-rustc + std)" + - bash: cargo test --no-default-features --features 'serialize-rustc serialize-serde std' + displayName: "Test backtrace (-default + serialize-rustc + serialize-serde + std)" + - bash: cargo test --no-default-features --features 'cpp_demangle std' + displayName: "Test backtrace (-default + cpp_demangle + std)" + - bash: cargo test --no-default-features --features 'gimli-symbolize std' + displayName: "Test backtrace (-default + gimli-symbolize + std)" + - bash: cargo test --no-default-features --features 'dbghelp std' + displayName: "Test backtrace (-default + dbghelp + std)" + - bash: cargo test --no-default-features --features 'dbghelp std verify-winapi' + displayName: "Test backtrace (-default + dbghelp + std + verify-winapi)" + - bash: cd ./cpp_smoke_test && cargo test + displayName: "Test cpp_smoke_test" diff -Nru cargo-0.33.0/vendor/backtrace/ci/docker/powerpc-unknown-linux-gnu/Dockerfile cargo-0.35.0/vendor/backtrace/ci/docker/powerpc-unknown-linux-gnu/Dockerfile --- cargo-0.33.0/vendor/backtrace/ci/docker/powerpc-unknown-linux-gnu/Dockerfile 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/ci/docker/powerpc-unknown-linux-gnu/Dockerfile 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user ca-certificates \ - gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \ - qemu-system-ppc - -ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER=powerpc-linux-gnu-gcc \ - CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_RUNNER="qemu-ppc -cpu Vger -L /usr/powerpc-linux-gnu" diff -Nru cargo-0.33.0/vendor/backtrace/examples/raw.rs cargo-0.35.0/vendor/backtrace/examples/raw.rs --- cargo-0.33.0/vendor/backtrace/examples/raw.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/examples/raw.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,12 +4,20 @@ foo(); } -fn foo() { bar() } -fn bar() { baz() } -fn baz() { print() } +fn foo() { + bar() +} +fn bar() { + baz() +} +fn baz() { + print() +} -#[cfg(target_pointer_width = "32")] const HEX_WIDTH: usize = 10; -#[cfg(target_pointer_width = "64")] const HEX_WIDTH: usize = 20; +#[cfg(target_pointer_width = "32")] +const HEX_WIDTH: usize = 10; +#[cfg(target_pointer_width = "64")] +const HEX_WIDTH: usize = 20; fn print() { let mut cnt = 0; @@ -33,12 +41,10 @@ } if let Some(file) = symbol.filename() { if let Some(l) = symbol.lineno() { - print!("\n{:13}{:4$}@ {}:{}", "", "", file.display(), l, - HEX_WIDTH); + print!("\n{:13}{:4$}@ {}:{}", "", "", file.display(), l, HEX_WIDTH); } } println!(""); - }); if !resolved { println!(" - "); diff -Nru cargo-0.33.0/vendor/backtrace/.pc/update-dep-object.patch/Cargo.toml cargo-0.35.0/vendor/backtrace/.pc/update-dep-object.patch/Cargo.toml --- cargo-0.33.0/vendor/backtrace/.pc/update-dep-object.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/.pc/update-dep-object.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "backtrace" -version = "0.3.13" +version = "0.3.16" authors = ["Alex Crichton ", "The Rust Project Developers"] autoexamples = true autotests = true @@ -42,8 +42,13 @@ [[test]] name = "smoke" required-features = ["std"] +edition = "2018" [dependencies.addr2line] -version = "0.7.0" +version = "0.9.0" +optional = true + +[dependencies.backtrace-sys] +version = "0.1.17" optional = true [dependencies.cfg-if] @@ -55,21 +60,17 @@ default-features = false [dependencies.findshlibs] -version = "0.4.0" +version = "0.4.1" optional = true -[dependencies.gimli] -version = "0.16.0" -optional = true +[dependencies.libc] +version = "0.2.45" +default-features = false [dependencies.memmap] version = "0.7.0" optional = true -[dependencies.object] -version = "0.9.0" -optional = true - [dependencies.rustc-demangle] version = "0.1.4" @@ -92,20 +93,15 @@ dbghelp = [] default = ["std", "libunwind", "libbacktrace", "coresymbolication", "dladdr", "dbghelp"] dladdr = [] -gimli-symbolize = ["addr2line", "findshlibs", "gimli", "memmap", "object"] +gimli-symbolize = ["addr2line", "findshlibs", "memmap"] kernel32 = [] -libbacktrace = ["backtrace-sys", "std"] +libbacktrace = ["backtrace-sys"] libunwind = [] serialize-rustc = ["rustc-serialize"] serialize-serde = ["serde", "serde_derive"] std = [] unix-backtrace = [] -[target."cfg(all(unix, not(target_os = \"fuchsia\"), not(target_os = \"emscripten\"), not(target_os = \"macos\"), not(target_os = \"ios\")))".dependencies.backtrace-sys] -version = "0.1.17" -optional = true -[target."cfg(unix)".dependencies.libc] -version = "0.2.45" -default-features = false +verify-winapi = ["winapi/dbghelp", "winapi/handleapi", "winapi/libloaderapi", "winapi/minwindef", "winapi/processthreadsapi", "winapi/winbase", "winapi/winnt"] [target."cfg(windows)".dependencies.winapi] version = "0.3.3" -features = ["dbghelp", "processthreadsapi", "winnt", "minwindef"] +optional = true diff -Nru cargo-0.33.0/vendor/backtrace/README.md cargo-0.35.0/vendor/backtrace/README.md --- cargo-0.33.0/vendor/backtrace/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,6 @@ # backtrace-rs -[![Build Status](https://travis-ci.org/alexcrichton/backtrace-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/backtrace-rs) +[![Build Status](https://travis-ci.com/alexcrichton/backtrace-rs.svg?branch=master)](https://travis-ci.com/alexcrichton/backtrace-rs) [![Build status](https://ci.appveyor.com/api/projects/status/v4l9oj4aqbbgyx44?svg=true)](https://ci.appveyor.com/project/alexcrichton/backtrace-rs) [Documentation](https://docs.rs/backtrace) @@ -54,7 +54,7 @@ let symbol_address = frame.symbol_address(); // Resolve this instruction pointer to a symbol name - backtrace::resolve(ip, |symbol| { + backtrace::resolve_frame(frame, |symbol| { if let Some(name) = symbol.name() { // ... } diff -Nru cargo-0.33.0/vendor/backtrace/src/backtrace/dbghelp.rs cargo-0.35.0/vendor/backtrace/src/backtrace/dbghelp.rs --- cargo-0.33.0/vendor/backtrace/src/backtrace/dbghelp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/backtrace/dbghelp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,26 +13,57 @@ use core::mem; use core::prelude::v1::*; -use winapi::shared::minwindef::*; -use winapi::um::processthreadsapi; -use winapi::um::winnt::{self, CONTEXT}; -use winapi::um::dbghelp; -use winapi::um::dbghelp::*; - +use dbghelp; +use windows::*; use types::c_void; -pub struct Frame { - inner: STACKFRAME64, +#[derive(Clone, Copy)] +pub enum Frame { + New(STACKFRAME_EX), + Old(STACKFRAME64), } +// we're just sending around raw pointers and reading them, never interpreting +// them so this should be safe to both send and share across threads. +unsafe impl Send for Frame {} +unsafe impl Sync for Frame {} + impl Frame { pub fn ip(&self) -> *mut c_void { - self.inner.AddrPC.Offset as *mut _ + self.addr_pc().Offset as *mut _ } pub fn symbol_address(&self) -> *mut c_void { self.ip() } + + fn addr_pc(&self) -> &ADDRESS64 { + match self { + Frame::New(new) => &new.AddrPC, + Frame::Old(old) => &old.AddrPC, + } + } + + fn addr_pc_mut(&mut self) -> &mut ADDRESS64 { + match self { + Frame::New(new) => &mut new.AddrPC, + Frame::Old(old) => &mut old.AddrPC, + } + } + + fn addr_frame_mut(&mut self) -> &mut ADDRESS64 { + match self { + Frame::New(new) => &mut new.AddrFrame, + Frame::Old(old) => &mut old.AddrFrame, + } + } + + fn addr_stack_mut(&mut self) -> &mut ADDRESS64 { + match self { + Frame::New(new) => &mut new.AddrStack, + Frame::Old(old) => &mut old.AddrStack, + } + } } #[repr(C, align(16))] // required by `CONTEXT`, is a FIXME in winapi right now @@ -41,59 +72,112 @@ #[inline(always)] pub unsafe fn trace(cb: &mut FnMut(&super::Frame) -> bool) { // Allocate necessary structures for doing the stack walk - let process = processthreadsapi::GetCurrentProcess(); - let thread = processthreadsapi::GetCurrentThread(); + let process = GetCurrentProcess(); + let thread = GetCurrentThread(); let mut context = mem::zeroed::(); - winnt::RtlCaptureContext(&mut context.0); - let mut frame = super::Frame { - inner: Frame { inner: mem::zeroed() }, - }; - let image = init_frame(&mut frame.inner.inner, &context.0); + RtlCaptureContext(&mut context.0); - // Initialize this process's symbols - let _c = ::dbghelp_init(); + // Ensure this process's symbols are initialized + let dbghelp = match dbghelp::init() { + Ok(dbghelp) => dbghelp, + Err(()) => return, // oh well... + }; - // And now that we're done with all the setup, do the stack walking! - while dbghelp::StackWalk64(image as DWORD, - process, - thread, - &mut frame.inner.inner, - &mut context.0 as *mut CONTEXT as *mut _, - None, - Some(dbghelp::SymFunctionTableAccess64), - Some(dbghelp::SymGetModuleBase64), - None) == TRUE { - if frame.inner.inner.AddrPC.Offset == frame.inner.inner.AddrReturn.Offset || - frame.inner.inner.AddrPC.Offset == 0 || - frame.inner.inner.AddrReturn.Offset == 0 { - break + // Attempt to use `StackWalkEx` if we can, but fall back to `StackWalk64` + // since it's in theory supported on more systems. + match (*dbghelp.dbghelp()).StackWalkEx() { + Some(StackWalkEx) => { + let mut frame = super::Frame { + inner: Frame::New(mem::zeroed()), + }; + let image = init_frame(&mut frame.inner, &context.0); + let frame_ptr = match &mut frame.inner { + Frame::New(ptr) => ptr as *mut STACKFRAME_EX, + _ => unreachable!(), + }; + + while StackWalkEx( + image as DWORD, + process, + thread, + frame_ptr, + &mut context.0 as *mut CONTEXT as *mut _, + None, + Some(dbghelp.SymFunctionTableAccess64()), + Some(dbghelp.SymGetModuleBase64()), + None, + 0, + ) == TRUE + { + if !cb(&frame) { + break; } - - if !cb(&frame) { - break + } + } + None => { + let mut frame = super::Frame { + inner: Frame::Old(mem::zeroed()), + }; + let image = init_frame(&mut frame.inner, &context.0); + let frame_ptr = match &mut frame.inner { + Frame::Old(ptr) => ptr as *mut STACKFRAME64, + _ => unreachable!(), + }; + + while dbghelp.StackWalk64()( + image as DWORD, + process, + thread, + frame_ptr, + &mut context.0 as *mut CONTEXT as *mut _, + None, + Some(dbghelp.SymFunctionTableAccess64()), + Some(dbghelp.SymGetModuleBase64()), + None, + ) == TRUE + { + if !cb(&frame) { + break; + } + } } } } #[cfg(target_arch = "x86_64")] -fn init_frame(frame: &mut STACKFRAME64, ctx: &CONTEXT) -> WORD { - frame.AddrPC.Offset = ctx.Rip as u64; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = ctx.Rsp as u64; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = ctx.Rbp as u64; - frame.AddrFrame.Mode = AddrModeFlat; - winnt::IMAGE_FILE_MACHINE_AMD64 +fn init_frame(frame: &mut Frame, ctx: &CONTEXT) -> WORD { + frame.addr_pc_mut().Offset = ctx.Rip as u64; + frame.addr_pc_mut().Mode = AddrModeFlat; + frame.addr_stack_mut().Offset = ctx.Rsp as u64; + frame.addr_stack_mut().Mode = AddrModeFlat; + frame.addr_frame_mut().Offset = ctx.Rbp as u64; + frame.addr_frame_mut().Mode = AddrModeFlat; + + IMAGE_FILE_MACHINE_AMD64 } #[cfg(target_arch = "x86")] -fn init_frame(frame: &mut STACKFRAME64, ctx: &CONTEXT) -> WORD { - frame.AddrPC.Offset = ctx.Eip as u64; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = ctx.Esp as u64; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = ctx.Ebp as u64; - frame.AddrFrame.Mode = AddrModeFlat; - winnt::IMAGE_FILE_MACHINE_I386 +fn init_frame(frame: &mut Frame, ctx: &CONTEXT) -> WORD { + frame.addr_pc_mut().Offset = ctx.Eip as u64; + frame.addr_pc_mut().Mode = AddrModeFlat; + frame.addr_stack_mut().Offset = ctx.Esp as u64; + frame.addr_stack_mut().Mode = AddrModeFlat; + frame.addr_frame_mut().Offset = ctx.Ebp as u64; + frame.addr_frame_mut().Mode = AddrModeFlat; + + IMAGE_FILE_MACHINE_I386 +} + +#[cfg(target_arch = "aarch64")] +fn init_frame(frame: &mut Frame, ctx: &CONTEXT) -> WORD { + frame.addr_pc_mut().Offset = ctx.Pc as u64; + frame.addr_pc_mut().Mode = AddrModeFlat; + frame.addr_stack_mut().Offset = ctx.Sp as u64; + frame.addr_stack_mut().Mode = AddrModeFlat; + unsafe { + frame.addr_frame_mut().Offset = ctx.u.s().Fp as u64; + } + frame.addr_frame_mut().Mode = AddrModeFlat; + IMAGE_FILE_MACHINE_ARM64 } diff -Nru cargo-0.33.0/vendor/backtrace/src/backtrace/libunwind.rs cargo-0.35.0/vendor/backtrace/src/backtrace/libunwind.rs --- cargo-0.33.0/vendor/backtrace/src/backtrace/libunwind.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/backtrace/libunwind.rs 2019-05-15 11:26:24.000000000 +0000 @@ -10,15 +10,30 @@ use types::c_void; -pub struct Frame { - ctx: *mut uw::_Unwind_Context, +pub enum Frame { + Raw(*mut uw::_Unwind_Context), + Cloned { + ip: *mut c_void, + symbol_address: *mut c_void, + }, } +// With a raw libunwind pointer it should only ever be access in a readonly +// threadsafe fashion, so it's `Sync`. When sending to other threads via `Clone` +// we always switch to a version which doesn't retain interior pointers, so we +// should be `Send` as well. +unsafe impl Send for Frame {} +unsafe impl Sync for Frame {} + impl Frame { pub fn ip(&self) -> *mut c_void { + let ctx = match *self { + Frame::Raw(ctx) => ctx, + Frame::Cloned { ip, .. } => return ip, + }; let mut ip_before_insn = 0; let mut ip = unsafe { - uw::_Unwind_GetIPInfo(self.ctx, &mut ip_before_insn) as *mut c_void + uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut c_void }; if !ip.is_null() && ip_before_insn == 0 { // this is a non-signaling frame, so `ip` refers to the address @@ -29,6 +44,10 @@ } pub fn symbol_address(&self) -> *mut c_void { + if let Frame::Cloned { symbol_address, .. } = *self { + return symbol_address; + } + // dladdr() on osx gets whiny when we use FindEnclosingFunction, and // it appears to work fine without it, so we only use // FindEnclosingFunction on non-osx platforms. In doing so, we get a @@ -47,6 +66,15 @@ } } +impl Clone for Frame { + fn clone(&self) -> Frame { + Frame::Cloned { + ip: self.ip(), + symbol_address: self.symbol_address(), + } + } +} + #[inline(always)] pub unsafe fn trace(mut cb: &mut FnMut(&super::Frame) -> bool) { uw::_Unwind_Backtrace(trace_fn, &mut cb as *mut _ as *mut _); @@ -55,7 +83,7 @@ arg: *mut c_void) -> uw::_Unwind_Reason_Code { let cb = unsafe { &mut *(arg as *mut &mut FnMut(&super::Frame) -> bool) }; let cx = super::Frame { - inner: Frame { ctx: ctx }, + inner: Frame::Raw(ctx), }; let mut bomb = ::Bomb { enabled: true }; @@ -113,12 +141,14 @@ // available since GCC 4.2.0, should be fine for our purpose #[cfg(all(not(all(target_os = "android", target_arch = "arm")), + not(all(target_os = "freebsd", target_arch = "arm")), not(all(target_os = "linux", target_arch = "arm"))))] pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, ip_before_insn: *mut c_int) -> libc::uintptr_t; #[cfg(all(not(target_os = "android"), + not(all(target_os = "freebsd", target_arch = "arm")), not(all(target_os = "linux", target_arch = "arm"))))] pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void; @@ -128,6 +158,7 @@ // expansion of the macro. This is all copy/pasted directly from the // header file with the definition of _Unwind_GetIP. #[cfg(any(all(target_os = "android", target_arch = "arm"), + all(target_os = "freebsd", target_arch = "arm"), all(target_os = "linux", target_arch = "arm")))] pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t { #[repr(C)] @@ -175,6 +206,7 @@ // This function doesn't exist on Android or ARM/Linux, so make it same // to _Unwind_GetIP #[cfg(any(all(target_os = "android", target_arch = "arm"), + all(target_os = "freebsd", target_arch = "arm"), all(target_os = "linux", target_arch = "arm")))] pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context, ip_before_insn: *mut c_int) @@ -187,6 +219,7 @@ // This function also doesn't exist on Android or ARM/Linux, so make it // a no-op #[cfg(any(target_os = "android", + all(target_os = "freebsd", target_arch = "arm"), all(target_os = "linux", target_arch = "arm")))] pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void diff -Nru cargo-0.33.0/vendor/backtrace/src/backtrace/mod.rs cargo-0.35.0/vendor/backtrace/src/backtrace/mod.rs --- cargo-0.33.0/vendor/backtrace/src/backtrace/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/backtrace/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -40,7 +40,6 @@ /// }); /// } /// ``` -#[inline(always)] #[cfg(feature = "std")] pub fn trace bool>(cb: F) { let _guard = ::lock::lock(); @@ -52,20 +51,19 @@ /// This function does not have synchronization guarentees but is available /// when the `std` feature of this crate isn't compiled in. See the `trace` /// function for more documentation and examples. -#[inline(never)] pub unsafe fn trace_unsynchronized bool>(mut cb: F) { trace_imp(&mut cb) } - /// A trait representing one frame of a backtrace, yielded to the `trace` /// function of this crate. /// /// The tracing function's closure will be yielded frames, and the frame is /// virtually dispatched as the underlying implementation is not always known /// until runtime. +#[derive(Clone)] pub struct Frame { - inner: FrameImp, + pub(crate) inner: FrameImp, } impl Frame { @@ -104,26 +102,27 @@ } cfg_if! { - if #[cfg(all(unix, + if #[cfg(any(all(unix, not(target_os = "emscripten"), not(all(target_os = "ios", target_arch = "arm")), - feature = "libunwind"))] { + feature = "libunwind"), + target_env="sgx"))] { mod libunwind; use self::libunwind::trace as trace_imp; - use self::libunwind::Frame as FrameImp; + pub(crate) use self::libunwind::Frame as FrameImp; } else if #[cfg(all(unix, not(target_os = "emscripten"), feature = "unix-backtrace"))] { mod unix_backtrace; use self::unix_backtrace::trace as trace_imp; - use self::unix_backtrace::Frame as FrameImp; + pub(crate) use self::unix_backtrace::Frame as FrameImp; } else if #[cfg(all(windows, feature = "dbghelp"))] { mod dbghelp; use self::dbghelp::trace as trace_imp; - use self::dbghelp::Frame as FrameImp; + pub(crate) use self::dbghelp::Frame as FrameImp; } else { mod noop; use self::noop::trace as trace_imp; - use self::noop::Frame as FrameImp; + pub(crate) use self::noop::Frame as FrameImp; } } diff -Nru cargo-0.33.0/vendor/backtrace/src/backtrace/noop.rs cargo-0.35.0/vendor/backtrace/src/backtrace/noop.rs --- cargo-0.33.0/vendor/backtrace/src/backtrace/noop.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/backtrace/noop.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,6 +3,7 @@ #[inline(always)] pub fn trace(_cb: &mut FnMut(&super::Frame) -> bool) {} +#[derive(Clone)] pub struct Frame; impl Frame { diff -Nru cargo-0.33.0/vendor/backtrace/src/backtrace/unix_backtrace.rs cargo-0.35.0/vendor/backtrace/src/backtrace/unix_backtrace.rs --- cargo-0.33.0/vendor/backtrace/src/backtrace/unix_backtrace.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/backtrace/unix_backtrace.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,16 +13,21 @@ use types::c_void; +#[derive(Clone)] pub struct Frame { - addr: *mut c_void, + addr: usize, } impl Frame { - pub fn ip(&self) -> *mut c_void { self.addr } - pub fn symbol_address(&self) -> *mut c_void { self.addr } + pub fn ip(&self) -> *mut c_void { + self.addr as *mut c_void + } + pub fn symbol_address(&self) -> *mut c_void { + self.ip() + } } -extern { +extern "C" { fn backtrace(buf: *mut *mut c_void, sz: c_int) -> c_int; } @@ -38,10 +43,12 @@ for addr in buf[..cnt as usize].iter() { let cx = super::Frame { - inner: Frame { addr: *addr }, + inner: Frame { + addr: *addr as usize, + }, }; if !cb(&cx) { - return + return; } } } diff -Nru cargo-0.33.0/vendor/backtrace/src/capture.rs cargo-0.35.0/vendor/backtrace/src/capture.rs --- cargo-0.33.0/vendor/backtrace/src/capture.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/capture.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ -use std::prelude::v1::*; use std::fmt; use std::path::{Path, PathBuf}; +use std::prelude::v1::*; -use {trace, resolve, SymbolName}; use types::c_void; +use {resolve, resolve_frame, trace, Symbol, SymbolName}; /// Representation of an owned and self-contained backtrace. /// @@ -23,19 +23,44 @@ actual_start_index: usize, } +fn _assert_send_sync() { + fn _assert() {} + _assert::(); +} + /// Captured version of a frame in a backtrace. /// /// This type is returned as a list from `Backtrace::frames` and represents one /// stack frame in a captured backtrace. #[derive(Clone)] -#[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable, RustcEncodable))] -#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))] pub struct BacktraceFrame { - ip: usize, - symbol_address: usize, + frame: Frame, symbols: Option>, } +#[derive(Clone)] +enum Frame { + Raw(::Frame), + #[allow(dead_code)] + Deserialized { ip: usize, symbol_address: usize }, +} + +impl Frame { + fn ip(&self) -> *mut c_void { + match *self { + Frame::Raw(ref f) => f.ip(), + Frame::Deserialized { ip, .. } => ip as *mut c_void, + } + } + + fn symbol_address(&self) -> *mut c_void { + match *self { + Frame::Raw(ref f) => f.symbol_address(), + Frame::Deserialized { symbol_address, .. } => symbol_address as *mut c_void, + } + } +} + /// Captured version of a symbol in a backtrace. /// /// This type is returned as a list from `BacktraceFrame::symbols` and @@ -68,6 +93,7 @@ /// ``` #[inline(never)] // want to make sure there's a frame here to remove pub fn new() -> Backtrace { + let _guard = lock_and_platform_init(); let mut bt = Self::create(Self::new as usize); bt.resolve(); bt @@ -93,6 +119,7 @@ /// ``` #[inline(never)] // want to make sure there's a frame here to remove pub fn new_unresolved() -> Backtrace { + let _guard = lock_and_platform_init(); Self::create(Self::new_unresolved as usize) } @@ -105,15 +132,14 @@ trace(|frame| { let ip = frame.ip() as usize; frames.push(BacktraceFrame { - ip, - symbol_address: frame.symbol_address() as usize, + frame: Frame::Raw(frame.clone()), symbols: None, }); - if cfg!(not(all(target_os = "windows", target_arch = "x86"))) && - ip >= ip_lo && - ip <= ip_hi && - actual_start_index.is_none() + if cfg!(not(all(target_os = "windows", target_arch = "x86"))) + && ip >= ip_lo + && ip <= ip_hi + && actual_start_index.is_none() { actual_start_index = Some(frames.len()); } @@ -141,16 +167,25 @@ /// If this backtrace has been previously resolved or was created through /// `new`, this function does nothing. pub fn resolve(&mut self) { + let _guard = lock_and_platform_init(); for frame in self.frames.iter_mut().filter(|f| f.symbols.is_none()) { let mut symbols = Vec::new(); - resolve(frame.ip as *mut _, |symbol| { - symbols.push(BacktraceSymbol { - name: symbol.name().map(|m| m.as_bytes().to_vec()), - addr: symbol.addr().map(|a| a as usize), - filename: symbol.filename().map(|m| m.to_owned()), - lineno: symbol.lineno(), - }); - }); + { + let sym = |symbol: &Symbol| { + symbols.push(BacktraceSymbol { + name: symbol.name().map(|m| m.as_bytes().to_vec()), + addr: symbol.addr().map(|a| a as usize), + filename: symbol.filename().map(|m| m.to_owned()), + lineno: symbol.lineno(), + }); + }; + match frame.frame { + Frame::Raw(ref f) => resolve_frame(f, sym), + Frame::Deserialized { ip, .. } => { + resolve(ip as *mut c_void, sym); + } + } + } frame.symbols = Some(symbols); } } @@ -174,12 +209,12 @@ impl BacktraceFrame { /// Same as `Frame::ip` pub fn ip(&self) -> *mut c_void { - self.ip as *mut c_void + self.frame.ip() as *mut c_void } /// Same as `Frame::symbol_address` pub fn symbol_address(&self) -> *mut c_void { - self.symbol_address as *mut c_void + self.frame.symbol_address() as *mut c_void } /// Returns the list of symbols that this frame corresponds to. @@ -229,14 +264,29 @@ }; for (idx, frame) in iter.enumerate() { - let ip = frame.ip(); + // To reduce TCB size in Sgx enclave, we do not want to implement symbol resolution functionality. + // Rather, we can print the offset of the address here, which could be later mapped to + // correct function. + let ip: *mut c_void; + #[cfg(target_env = "sgx")] + { + ip = usize::wrapping_sub( + frame.ip() as _, + std::os::fortanix_sgx::mem::image_base() as _, + ) as _; + } + #[cfg(not(target_env = "sgx"))] + { + ip = frame.ip(); + } + write!(fmt, "\n{:4}: ", idx)?; let symbols = match frame.symbols { Some(ref s) => s, None => { write!(fmt, " ({:?})", ip)?; - continue + continue; } }; if symbols.len() == 0 { @@ -274,3 +324,160 @@ Backtrace::new() } } + +impl fmt::Debug for BacktraceFrame { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("BacktraceFrame") + .field("ip", &self.ip()) + .field("symbol_address", &self.symbol_address()) + .finish() + } +} + +impl fmt::Debug for BacktraceSymbol { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("BacktraceSymbol") + .field("name", &self.name()) + .field("addr", &self.addr()) + .field("filename", &self.filename()) + .field("lineno", &self.lineno()) + .finish() + } +} + +// When using `dbghelp` on Windows this is a performance optimization. If +// we don't do this then `SymInitializeW` is called once per trace and once per +// frame during resolution. That function, however, takes quite some time! To +// help speed it up this function can amortize the calls necessary by ensuring +// that the scope this is called in only initializes when this is called and +// doesn't reinitialize for the rest of the scope. +#[cfg(all(windows, feature = "dbghelp"))] +fn lock_and_platform_init() -> impl Drop { + use std::mem::ManuallyDrop; + + struct Cleanup { + _lock: crate::lock::LockGuard, + + // Need to make sure this is cleaned up before `_lock` + dbghelp_cleanup: Option>, + } + + impl Drop for Cleanup { + fn drop(&mut self) { + if let Some(cleanup) = self.dbghelp_cleanup.as_mut() { + // Unsafety here should be ok since we're only dropping this in + // `Drop` to ensure it's dropped before the lock, and `Drop` + // should only be called once. + unsafe { + ManuallyDrop::drop(cleanup); + } + } + } + } + + // Unsafety here should be ok because we only acquire the `dbghelp` + // initialization (the unsafe part) after acquiring the global lock for this + // crate. Note that we're also careful to drop it before the lock is + // dropped. + unsafe { + Cleanup { + _lock: crate::lock::lock(), + dbghelp_cleanup: crate::dbghelp::init().ok().map(ManuallyDrop::new), + } + } +} + +#[cfg(not(all(windows, feature = "dbghelp")))] +fn lock_and_platform_init() {} + +#[cfg(feature = "serialize-rustc")] +mod rustc_serialize_impls { + use super::*; + use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; + + #[derive(RustcEncodable, RustcDecodable)] + struct SerializedFrame { + ip: usize, + symbol_address: usize, + symbols: Option>, + } + + impl Decodable for BacktraceFrame { + fn decode(d: &mut D) -> Result + where + D: Decoder, + { + let frame: SerializedFrame = SerializedFrame::decode(d)?; + Ok(BacktraceFrame { + frame: Frame::Deserialized { + ip: frame.ip, + symbol_address: frame.symbol_address, + }, + symbols: frame.symbols, + }) + } + } + + impl Encodable for BacktraceFrame { + fn encode(&self, e: &mut E) -> Result<(), E::Error> + where + E: Encoder, + { + let BacktraceFrame { frame, symbols } = self; + SerializedFrame { + ip: frame.ip() as usize, + symbol_address: frame.symbol_address() as usize, + symbols: symbols.clone(), + } + .encode(e) + } + } +} + +#[cfg(feature = "serialize-serde")] +mod serde_impls { + extern crate serde; + + use self::serde::de::Deserializer; + use self::serde::ser::Serializer; + use self::serde::{Deserialize, Serialize}; + use super::*; + + #[derive(Serialize, Deserialize)] + struct SerializedFrame { + ip: usize, + symbol_address: usize, + symbols: Option>, + } + + impl Serialize for BacktraceFrame { + fn serialize(&self, s: S) -> Result + where + S: Serializer, + { + let BacktraceFrame { frame, symbols } = self; + SerializedFrame { + ip: frame.ip() as usize, + symbol_address: frame.symbol_address() as usize, + symbols: symbols.clone(), + } + .serialize(s) + } + } + + impl<'a> Deserialize<'a> for BacktraceFrame { + fn deserialize(d: D) -> Result + where + D: Deserializer<'a>, + { + let frame: SerializedFrame = SerializedFrame::deserialize(d)?; + Ok(BacktraceFrame { + frame: Frame::Deserialized { + ip: frame.ip, + symbol_address: frame.symbol_address, + }, + symbols: frame.symbols, + }) + } + } +} diff -Nru cargo-0.33.0/vendor/backtrace/src/dbghelp.rs cargo-0.35.0/vendor/backtrace/src/dbghelp.rs --- cargo-0.33.0/vendor/backtrace/src/dbghelp.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/dbghelp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,342 @@ +//! A module to assist in managing dbghelp bindings on Windows +//! +//! Backtraces on Windows (at least for MSVC) are largely powered through +//! `dbghelp.dll` and the various functions that it contains. These functions +//! are currently loaded *dynamically* rather than linking to `dbghelp.dll` +//! statically. This is currently done by the standard library (and is in theory +//! required there), but is an effort to help reduce the static dll dependencies +//! of a library since backtraces are typically pretty optional. That being +//! said, `dbghelp.dll` almost always successfully loads on Windows. +//! +//! Note though that since we're loading all this support dynamically we can't +//! actually use the raw definitions in `winapi`, but rather we need to define +//! the function pointer types ourselves and use that. We don't really want to +//! be in the business of duplicating winapi, so we have a Cargo feature +//! `verify-winapi` which asserts that all bindings match those in winapi and +//! this feature is enabled on CI. + +#![allow(non_snake_case)] + +use core::mem; +use core::ptr; +use windows::*; + +// Work around `SymGetOptions` and `SymSetOptions` not being present in winapi +// itself. Otherwise this is only used when we're double-checking types against +// winapi. +#[cfg(feature = "verify-winapi")] +mod dbghelp { + pub use winapi::um::dbghelp::{ + StackWalk64, SymCleanup, SymFromAddrW, SymFunctionTableAccess64, SymGetLineFromAddrW64, + SymGetModuleBase64, SymInitializeW, + }; + use windows::*; + + extern "system" { + // Not defined in winapi yet + pub fn SymGetOptions() -> u32; + pub fn SymSetOptions(_: u32); + + // This is defined in winapi, but it's incorrect (FIXME winapi-rs#768) + pub fn StackWalkEx( + MachineType: DWORD, + hProcess: HANDLE, + hThread: HANDLE, + StackFrame: LPSTACKFRAME_EX, + ContextRecord: PVOID, + ReadMemoryRoutine: PREAD_PROCESS_MEMORY_ROUTINE64, + FunctionTableAccessRoutine: PFUNCTION_TABLE_ACCESS_ROUTINE64, + GetModuleBaseRoutine: PGET_MODULE_BASE_ROUTINE64, + TranslateAddress: PTRANSLATE_ADDRESS_ROUTINE64, + Flags: DWORD, + ) -> BOOL; + + // Not defined in winapi yet + pub fn SymFromInlineContextW( + hProcess: HANDLE, + Address: DWORD64, + InlineContext: ULONG, + Displacement: PDWORD64, + Symbol: PSYMBOL_INFOW, + ) -> BOOL; + pub fn SymGetLineFromInlineContextW( + hProcess: HANDLE, + dwAddr: DWORD64, + InlineContext: ULONG, + qwModuleBaseAddress: DWORD64, + pdwDisplacement: PDWORD, + Line: PIMAGEHLP_LINEW64, + ) -> BOOL; + } + + pub fn assert_equal_types(a: T, _b: T) -> T { + a + } +} + +// This macro is used to define a `Dbghelp` structure which internally contains +// all the function pointers that we might load. +macro_rules! dbghelp { + (extern "system" { + $(fn $name:ident($($arg:ident: $argty:ty),*) -> $ret: ty;)* + }) => ( + pub struct Dbghelp { + /// The loaded DLL for `dbghelp.dll` + dll: HMODULE, + + // Each function pointer for each function we might use + $($name: usize,)* + } + + static mut DBGHELP: Dbghelp = Dbghelp { + // Initially we haven't loaded the DLL + dll: 0 as *mut _, + // Initiall all functions are set to zero to say they need to be + // dynamically loaded. + $($name: 0,)* + }; + + // Convenience typedef for each function type. + $(pub type $name = unsafe extern "system" fn($($argty),*) -> $ret;)* + + impl Dbghelp { + /// Attempts to open `dbghelp.dll`. Returns success if it works or + /// error if `LoadLibraryW` fails. + /// + /// Panics if library is already loaded. + fn open(&mut self) -> Result<(), ()> { + assert!(self.dll.is_null()); + let lib = [ + 'd' as u16, + 'b' as u16, + 'g' as u16, + 'h' as u16, + 'e' as u16, + 'l' as u16, + 'p' as u16, + '.' as u16, + 'd' as u16, + 'l' as u16, + 'l' as u16, + 0, + ]; + unsafe { + self.dll = LoadLibraryW(lib.as_ptr()); + if self.dll.is_null() { + Err(()) + } else { + Ok(()) + } + } + } + + /// Unloads `dbghelp.dll`, resetting all function pointers to zero + /// as well. + fn close(&mut self) { + assert!(!self.dll.is_null()); + unsafe { + $(self.$name = 0;)* + FreeLibrary(self.dll); + self.dll = ptr::null_mut(); + } + } + + // Function for each method we'd like to use. When called it will + // either read the cached function pointer or load it and return the + // loaded value. Loads are asserted to succeed. + $(pub fn $name(&mut self) -> Option<$name> { + unsafe { + if self.$name == 0 { + let name = concat!(stringify!($name), "\0"); + self.$name = self.symbol(name.as_bytes())?; + } + let ret = mem::transmute::(self.$name); + #[cfg(feature = "verify-winapi")] + dbghelp::assert_equal_types(ret, dbghelp::$name); + Some(ret) + } + })* + + fn symbol(&self, symbol: &[u8]) -> Option { + unsafe { + match GetProcAddress(self.dll, symbol.as_ptr() as *const _) as usize { + 0 => None, + n => Some(n), + } + } + } + } + + // Convenience proxy to use the cleanup locks to reference dbghelp + // functions. + #[allow(dead_code)] + impl Cleanup { + $(pub fn $name(&self) -> $name { + unsafe { + DBGHELP.$name().unwrap() + } + })* + + pub fn dbghelp(&self) -> *mut Dbghelp { + unsafe { + &mut DBGHELP + } + } + } + ) + +} + +const SYMOPT_DEFERRED_LOADS: DWORD = 0x00000004; + +dbghelp! { + extern "system" { + fn SymGetOptions() -> DWORD; + fn SymSetOptions(options: DWORD) -> (); + fn SymInitializeW( + handle: HANDLE, + path: PCWSTR, + invade: BOOL + ) -> BOOL; + fn SymCleanup(handle: HANDLE) -> BOOL; + fn StackWalk64( + MachineType: DWORD, + hProcess: HANDLE, + hThread: HANDLE, + StackFrame: LPSTACKFRAME64, + ContextRecord: PVOID, + ReadMemoryRoutine: PREAD_PROCESS_MEMORY_ROUTINE64, + FunctionTableAccessRoutine: PFUNCTION_TABLE_ACCESS_ROUTINE64, + GetModuleBaseRoutine: PGET_MODULE_BASE_ROUTINE64, + TranslateAddress: PTRANSLATE_ADDRESS_ROUTINE64 + ) -> BOOL; + fn SymFunctionTableAccess64( + hProcess: HANDLE, + AddrBase: DWORD64 + ) -> PVOID; + fn SymGetModuleBase64( + hProcess: HANDLE, + AddrBase: DWORD64 + ) -> DWORD64; + fn SymFromAddrW( + hProcess: HANDLE, + Address: DWORD64, + Displacement: PDWORD64, + Symbol: PSYMBOL_INFOW + ) -> BOOL; + fn SymGetLineFromAddrW64( + hProcess: HANDLE, + dwAddr: DWORD64, + pdwDisplacement: PDWORD, + Line: PIMAGEHLP_LINEW64 + ) -> BOOL; + fn StackWalkEx( + MachineType: DWORD, + hProcess: HANDLE, + hThread: HANDLE, + StackFrame: LPSTACKFRAME_EX, + ContextRecord: PVOID, + ReadMemoryRoutine: PREAD_PROCESS_MEMORY_ROUTINE64, + FunctionTableAccessRoutine: PFUNCTION_TABLE_ACCESS_ROUTINE64, + GetModuleBaseRoutine: PGET_MODULE_BASE_ROUTINE64, + TranslateAddress: PTRANSLATE_ADDRESS_ROUTINE64, + Flags: DWORD + ) -> BOOL; + fn SymFromInlineContextW( + hProcess: HANDLE, + Address: DWORD64, + InlineContext: ULONG, + Displacement: PDWORD64, + Symbol: PSYMBOL_INFOW + ) -> BOOL; + fn SymGetLineFromInlineContextW( + hProcess: HANDLE, + dwAddr: DWORD64, + InlineContext: ULONG, + qwModuleBaseAddress: DWORD64, + pdwDisplacement: PDWORD, + Line: PIMAGEHLP_LINEW64 + ) -> BOOL; + } +} + +pub struct Cleanup; + +// Number of times `init` has been called on this thread. This is externally +// synchronized and doesn't use internal synchronization on our behalf. +static mut COUNT: usize = 0; + +// Used to restore `SymSetOptions` and `SymGetOptions` values. +static mut OPTS_ORIG: DWORD = 0; + +/// Unsafe because this requires external synchronization, must be done +/// inside of the same lock as all other backtrace operations. +/// +/// Note that the `Dbghelp` returned must also be dropped within the same +/// lock. +#[cfg(all(windows, feature = "dbghelp"))] +pub unsafe fn init() -> Result { + // Initializing symbols has significant overhead, but initializing only + // once without cleanup causes problems for external sources. For + // example, the standard library checks the result of SymInitializeW + // (which returns an error if attempting to initialize twice) and in + // the event of an error, will not print a backtrace on panic. + // Presumably, external debuggers may have similar issues. + // + // As a compromise, we'll keep track of the number of internal + // initialization requests within a single API call in order to + // minimize the number of init/cleanup cycles. + if COUNT > 0 { + COUNT += 1; + return Ok(Cleanup); + } + + // Actually load `dbghelp.dll` into the process here, returning an error if + // that fails. + DBGHELP.open()?; + + OPTS_ORIG = DBGHELP.SymGetOptions().unwrap()(); + + // Ensure that the `SYMOPT_DEFERRED_LOADS` flag is set, because + // according to MSVC's own docs about this: "This is the fastest, most + // efficient way to use the symbol handler.", so let's do that! + DBGHELP.SymSetOptions().unwrap()(OPTS_ORIG | SYMOPT_DEFERRED_LOADS); + + let ret = DBGHELP.SymInitializeW().unwrap()(GetCurrentProcess(), ptr::null_mut(), TRUE); + if ret != TRUE { + // Symbols may have been initialized by another library or an + // external debugger + DBGHELP.SymSetOptions().unwrap()(OPTS_ORIG); + DBGHELP.close(); + Err(()) + } else { + COUNT += 1; + Ok(Cleanup) + } +} + +impl Drop for Cleanup { + fn drop(&mut self) { + unsafe { + COUNT -= 1; + if COUNT != 0 { + return; + } + + // Clean up after ourselves by cleaning up symbols and restoring the + // symbol options to their original value. This is currently + // required to cooperate with libstd as libstd's backtracing will + // assert symbol initialization succeeds and will clean up after the + // backtrace is finished. + DBGHELP.SymCleanup().unwrap()(GetCurrentProcess()); + DBGHELP.SymSetOptions().unwrap()(OPTS_ORIG); + + // We can in theory leak this to stay in a global and we simply + // always reuse it, but for now let's be tidy and release all our + // resources. If we get bug reports the we could basically elide + // this `close()` (and the one above) and then update `open` to be a + // noop if it's already opened. + DBGHELP.close(); + } + } +} diff -Nru cargo-0.33.0/vendor/backtrace/src/dylib.rs cargo-0.35.0/vendor/backtrace/src/dylib.rs --- cargo-0.33.0/vendor/backtrace/src/dylib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/dylib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -16,25 +16,28 @@ impl Dylib { pub unsafe fn get<'a, T>(&self, sym: &'a Symbol) -> Option<&'a T> { - self.load().and_then(|handle| { - sym.get(handle) - }) + self.load().and_then(|handle| sym.get(handle)) } pub unsafe fn init(&self, path: &str) -> bool { if self.init.load(Ordering::SeqCst) != 0 { - return true + return true; } assert!(path.as_bytes()[path.len() - 1] == 0); let ptr = libc::dlopen(path.as_ptr() as *const c_char, libc::RTLD_LAZY); if ptr.is_null() { - return false + return false; } - match self.init.compare_and_swap(0, ptr as usize, Ordering::SeqCst) { + match self + .init + .compare_and_swap(0, ptr as usize, Ordering::SeqCst) + { 0 => {} - _ => { libc::dlclose(ptr); } + _ => { + libc::dlclose(ptr); + } } - return true + return true; } unsafe fn load(&self) -> Option<*mut c_void> { @@ -49,7 +52,8 @@ unsafe fn get(&self, handle: *mut c_void) -> Option<&T> { assert_eq!(mem::size_of::(), mem::size_of_val(&self.addr)); if self.addr.load(Ordering::SeqCst) == 0 { - self.addr.store(fetch(handle, self.name.as_ptr()), Ordering::SeqCst) + self.addr + .store(fetch(handle, self.name.as_ptr()), Ordering::SeqCst) } if self.addr.load(Ordering::SeqCst) == 1 { None diff -Nru cargo-0.33.0/vendor/backtrace/src/lib.rs cargo-0.35.0/vendor/backtrace/src/lib.rs --- cargo-0.33.0/vendor/backtrace/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -37,7 +37,7 @@ //! //! ```toml //! [dependencies] -//! backtrace = "0.2" +//! backtrace = "0.3" //! ``` //! //! Next: @@ -53,7 +53,7 @@ //! let symbol_address = frame.symbol_address(); //! //! // Resolve this instruction pointer to a symbol name -//! backtrace::resolve(ip, |symbol| { +//! backtrace::resolve_frame(frame, |symbol| { //! if let Some(name) = symbol.name() { //! // ... //! } @@ -71,13 +71,14 @@ #![doc(html_root_url = "https://docs.rs/backtrace")] #![deny(missing_docs)] #![no_std] +#![cfg_attr(target_env = "sgx", feature(sgx_platform))] #[cfg(feature = "std")] -#[macro_use] extern crate std; +#[macro_use] +extern crate std; -#[cfg(unix)] extern crate libc; -#[cfg(windows)] +#[cfg(all(windows, feature = "verify-winapi"))] extern crate winapi; #[cfg(feature = "serde_derive")] @@ -99,9 +100,7 @@ if #[cfg(all(feature = "gimli-symbolize", unix, target_os = "linux"))] { extern crate addr2line; extern crate findshlibs; - extern crate gimli; extern crate memmap; - extern crate object; } } @@ -114,6 +113,7 @@ mod backtrace; pub use symbolize::{resolve_unsynchronized, Symbol, SymbolName}; +pub use symbolize::resolve_frame_unsynchronized; mod symbolize; pub use types::BytesOrWideString; @@ -122,7 +122,7 @@ cfg_if! { if #[cfg(feature = "std")] { pub use backtrace::trace; - pub use symbolize::resolve; + pub use symbolize::{resolve, resolve_frame}; pub use capture::{Backtrace, BacktraceFrame, BacktraceSymbol}; mod capture; } @@ -145,11 +145,11 @@ #[allow(dead_code)] #[cfg(feature = "std")] mod lock { - use std::cell::Cell; use std::boxed::Box; - use std::sync::{Once, Mutex, MutexGuard, ONCE_INIT}; + use std::cell::Cell; + use std::sync::{Mutex, MutexGuard, Once, ONCE_INIT}; - pub struct LockGuard(MutexGuard<'static, ()>); + pub struct LockGuard(Option>); static mut LOCK: *mut Mutex<()> = 0 as *mut _; static INIT: Once = ONCE_INIT; @@ -157,39 +157,30 @@ impl Drop for LockGuard { fn drop(&mut self) { - LOCK_HELD.with(|slot| { - assert!(slot.get()); - slot.set(false); - }); + if self.0.is_some() { + LOCK_HELD.with(|slot| { + assert!(slot.get()); + slot.set(false); + }); + } } } - pub fn lock() -> Option { + pub fn lock() -> LockGuard { if LOCK_HELD.with(|l| l.get()) { - return None + return LockGuard(None); } LOCK_HELD.with(|s| s.set(true)); unsafe { INIT.call_once(|| { LOCK = Box::into_raw(Box::new(Mutex::new(()))); }); - Some(LockGuard((*LOCK).lock().unwrap())) + LockGuard(Some((*LOCK).lock().unwrap())) } } } -// requires external synchronization #[cfg(all(windows, feature = "dbghelp"))] -unsafe fn dbghelp_init() { - use winapi::shared::minwindef; - use winapi::um::{dbghelp, processthreadsapi}; - - static mut INITIALIZED: bool = false; - - if !INITIALIZED { - dbghelp::SymInitializeW(processthreadsapi::GetCurrentProcess(), - 0 as *mut _, - minwindef::TRUE); - INITIALIZED = true; - } -} +mod dbghelp; +#[cfg(windows)] +mod windows; diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/coresymbolication.rs cargo-0.35.0/vendor/backtrace/src/symbolize/coresymbolication.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/coresymbolication.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/coresymbolication.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,6 +13,7 @@ use core::mem; use core::ptr; use core::slice; +#[allow(deprecated)] // atomic initializer is relative new currently use core::sync::atomic::ATOMIC_USIZE_INIT; use libc::{self, Dl_info, c_char, c_int}; @@ -21,6 +22,7 @@ use dylib::Dylib; use dylib::Symbol as DylibSymbol; use types::{BytesOrWideString, c_void}; +use symbolize::ResolveWhat; #[repr(C)] #[derive(Copy, Clone, PartialEq)] @@ -68,22 +70,35 @@ } } - pub fn filename_raw(&self) -> Option { + fn filename_bytes(&self) -> Option<&[u8]> { match *self { Symbol::Core { path, .. } => { if path.is_null() { None } else { - Some(BytesOrWideString::Bytes(unsafe { + Some(unsafe { let len = libc::strlen(path); slice::from_raw_parts(path as *const u8, len) - })) + }) } } Symbol::Dladdr(_) => None, } } + pub fn filename_raw(&self) -> Option { + self.filename_bytes().map(BytesOrWideString::Bytes) + } + + #[cfg(feature = "std")] + pub fn filename(&self) -> Option<&::std::path::Path> { + use std::os::unix::prelude::*; + use std::path::Path; + use std::ffi::OsStr; + + self.filename_bytes().map(OsStr::from_bytes).map(Path::new) + } + pub fn lineno(&self) -> Option { match *self { Symbol::Core { lineno: 0, .. } => None, @@ -93,12 +108,14 @@ } } +#[allow(deprecated)] // atomic initializer is relative new currently static CORESYMBOLICATION: Dylib = Dylib { init: ATOMIC_USIZE_INIT }; macro_rules! dlsym { (extern { $(fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty;)* }) => ($( + #[allow(deprecated)] // atomic initializer is relative new currently static $name: ::dylib::Symbol $ret> = ::dylib::Symbol { name: concat!(stringify!($name), "\0"), @@ -177,7 +194,8 @@ rv } -pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(&super::Symbol)) { +pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) { + let addr = what.address_or_ip(); if try_resolve(addr, cb) { return } diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/dbghelp.rs cargo-0.35.0/vendor/backtrace/src/symbolize/dbghelp.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/dbghelp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/dbghelp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -15,23 +15,20 @@ // moved in rustc 1.26.0 (ish). As a result, in std mode we use `std::char` to // retain compatibility with rustc 1.25.0, but in `no_std` mode (which is // 1.30.0+ already) we use `core::char`. -#[cfg(feature = "std")] -use std::char; #[cfg(not(feature = "std"))] use core::char; +#[cfg(feature = "std")] +use std::char; use core::mem; use core::slice; -use winapi::ctypes::*; -use winapi::shared::basetsd::*; -use winapi::shared::minwindef::*; -use winapi::um::processthreadsapi; -use winapi::um::dbghelp; -use winapi::um::dbghelp::*; - +use backtrace::FrameImp as Frame; +use dbghelp; +use symbolize::ResolveWhat; +use types::{c_void, BytesOrWideString}; +use windows::*; use SymbolName; -use types::BytesOrWideString; // Store an OsString on std so we can provide the symbol name and filename. pub struct Symbol { @@ -55,11 +52,8 @@ } pub fn filename_raw(&self) -> Option { - self.filename.map(|slice| { - unsafe { - BytesOrWideString::Wide(&*slice) - } - }) + self.filename + .map(|slice| unsafe { BytesOrWideString::Wide(&*slice) }) } pub fn lineno(&self) -> Option { @@ -67,15 +61,78 @@ } #[cfg(feature = "std")] - pub fn filename(&self) -> Option<&::std::ffi::OsString> { - self._filename_cache.as_ref() + pub fn filename(&self) -> Option<&::std::path::Path> { + use std::path::Path; + + self._filename_cache.as_ref().map(Path::new) } } #[repr(C, align(8))] struct Aligned8(T); -pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(&super::Symbol)) { +pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) { + // Ensure this process's symbols are initialized + let dbghelp = match dbghelp::init() { + Ok(dbghelp) => dbghelp, + Err(()) => return, // oh well... + }; + + match what { + ResolveWhat::Address(addr) => resolve_without_inline(&dbghelp, addr, cb), + ResolveWhat::Frame(frame) => match &frame.inner { + Frame::New(frame) => resolve_with_inline(&dbghelp, frame, cb), + Frame::Old(_) => resolve_without_inline(&dbghelp, frame.ip(), cb), + }, + } +} + +unsafe fn resolve_with_inline( + dbghelp: &dbghelp::Cleanup, + frame: &STACKFRAME_EX, + cb: &mut FnMut(&super::Symbol), +) { + do_resolve( + |info| { + dbghelp.SymFromInlineContextW()( + GetCurrentProcess(), + frame.AddrPC.Offset, + frame.InlineFrameContext, + &mut 0, + info, + ) + }, + |line| { + dbghelp.SymGetLineFromInlineContextW()( + GetCurrentProcess(), + frame.AddrPC.Offset, + frame.InlineFrameContext, + 0, + &mut 0, + line, + ) + }, + cb, + ) +} + +unsafe fn resolve_without_inline( + dbghelp: &dbghelp::Cleanup, + addr: *mut c_void, + cb: &mut FnMut(&super::Symbol), +) { + do_resolve( + |info| dbghelp.SymFromAddrW()(GetCurrentProcess(), addr as DWORD64, &mut 0, info), + |line| dbghelp.SymGetLineFromAddrW64()(GetCurrentProcess(), addr as DWORD64, &mut 0, line), + cb, + ) +} + +unsafe fn do_resolve( + sym_from_addr: impl FnOnce(*mut SYMBOL_INFOW) -> BOOL, + get_line_from_addr: impl FnOnce(&mut IMAGEHLP_LINEW64) -> BOOL, + cb: &mut FnMut(&super::Symbol), +) { const SIZE: usize = 2 * MAX_SYM_NAME + mem::size_of::(); let mut data = Aligned8([0u8; SIZE]); let data = &mut data.0; @@ -86,22 +143,14 @@ // due to struct alignment. info.SizeOfStruct = 88; - let _c = ::dbghelp_init(); - - let mut displacement = 0u64; - let ret = dbghelp::SymFromAddrW(processthreadsapi::GetCurrentProcess(), - addr as DWORD64, - &mut displacement, - info); - if ret != TRUE { - return + if sym_from_addr(info) != TRUE { + return; } // If the symbol name is greater than MaxNameLen, SymFromAddrW will // give a buffer of (MaxNameLen - 1) characters and set NameLen to // the real value. - let name_len = ::core::cmp::min(info.NameLen as usize, - info.MaxNameLen as usize - 1); + let name_len = ::core::cmp::min(info.NameLen as usize, info.MaxNameLen as usize - 1); let name_ptr = info.Name.as_ptr() as *const u16; let name = slice::from_raw_parts(name_ptr, name_len); @@ -120,7 +169,7 @@ remaining = &mut tmp[len..]; name_len += len; } else { - break + break; } } } @@ -128,15 +177,10 @@ let mut line = mem::zeroed::(); line.SizeOfStruct = mem::size_of::() as DWORD; - let mut displacement = 0; - let ret = dbghelp::SymGetLineFromAddrW64(processthreadsapi::GetCurrentProcess(), - addr as DWORD64, - &mut displacement, - &mut line); let mut filename = None; let mut lineno = None; - if ret == TRUE { + if get_line_from_addr(&mut line) == TRUE { lineno = Some(line.LineNumber as u32); let base = line.FileName; @@ -150,7 +194,6 @@ filename = Some(slice::from_raw_parts(base, len) as *const [u16]); } - cb(&super::Symbol { inner: Symbol { name, @@ -165,11 +208,8 @@ #[cfg(feature = "std")] unsafe fn cache(filename: Option<*const [u16]>) -> Option<::std::ffi::OsString> { use std::os::windows::ffi::OsStringExt; - filename.map(|f| { - ::std::ffi::OsString::from_wide(&*f) - }) + filename.map(|f| ::std::ffi::OsString::from_wide(&*f)) } #[cfg(not(feature = "std"))] -unsafe fn cache(_filename: Option<*const [u16]>) { -} +unsafe fn cache(_filename: Option<*const [u16]>) {} diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/dladdr.rs cargo-0.35.0/vendor/backtrace/src/symbolize/dladdr.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/dladdr.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/dladdr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -12,6 +12,7 @@ use types::{BytesOrWideString, c_void}; use libc::{self, Dl_info}; +use symbolize::ResolveWhat; use SymbolName; @@ -40,12 +41,18 @@ None } + #[cfg(feature = "std")] + pub fn filename(&self) -> Option<&::std::path::Path> { + None + } + pub fn lineno(&self) -> Option { None } } -pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(&super::Symbol)) { +pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) { + let addr = what.address_or_ip(); let mut info: super::Symbol = super::Symbol { inner: Symbol { inner: mem::zeroed(), diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/gimli.rs cargo-0.35.0/vendor/backtrace/src/symbolize/gimli.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/gimli.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/gimli.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,23 +1,23 @@ use addr2line; +use addr2line::object::{self, Object}; use findshlibs::{self, Segment, SharedLibrary}; -use gimli; +use libc::c_void; use memmap::Mmap; -use object::{self, Object}; use std::cell::RefCell; use std::env; use std::fs::File; use std::mem; -use libc::c_void; -use std::path::PathBuf; -use std::u32; +use std::path::{Path, PathBuf}; use std::prelude::v1::*; +use std::u32; -use SymbolName; +use symbolize::ResolveWhat; use types::BytesOrWideString; +use SymbolName; const MAPPINGS_CACHE_SIZE: usize = 4; -type Dwarf = addr2line::Context>; +type Dwarf = addr2line::Context; type Symbols<'map> = object::SymbolMap<'map>; struct Mapping { @@ -33,7 +33,7 @@ // TODO: not completely safe, see https://github.com/danburkert/memmap-rs/issues/25 let map = unsafe { Mmap::map(&file).ok()? }; let (dwarf, symbols) = { - let object = object::File::parse(&*map).ok()?; + let object = object::ElfFile::parse(&*map).ok()?; let dwarf = addr2line::Context::new(&object).ok()?; let symbols = object.symbol_map(); // Convert to 'static lifetimes. @@ -108,7 +108,9 @@ }); } -pub fn resolve(addr: *mut c_void, cb: &mut FnMut(&super::Symbol)) { +pub fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) { + let addr = what.address_or_ip(); + // First, find the file containing the segment that the given AVMA (after // relocation) address falls within. Use the containing segment to compute // the SVMA (before relocation) address. @@ -190,11 +192,7 @@ } impl Symbol { - fn new(addr: usize, - file: Option, - line: Option, - name: Option) - -> Symbol { + fn new(addr: usize, file: Option, line: Option, name: Option) -> Symbol { Symbol { addr, file, @@ -212,15 +210,22 @@ } pub fn filename_raw(&self) -> Option { - self.file.as_ref().map(|f| BytesOrWideString::Bytes(f.as_bytes())) + self.file + .as_ref() + .map(|f| BytesOrWideString::Bytes(f.as_bytes())) + } + + pub fn filename(&self) -> Option<&Path> { + self.file.as_ref().map(Path::new) } pub fn lineno(&self) -> Option { - self.line - .and_then(|l| if l > (u32::MAX as u64) { + self.line.and_then(|l| { + if l > (u32::MAX as u64) { None } else { Some(l as u32) - }) + } + }) } } diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/libbacktrace.rs cargo-0.35.0/vendor/backtrace/src/symbolize/libbacktrace.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/libbacktrace.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/libbacktrace.rs 2019-05-15 11:26:24.000000000 +0000 @@ -12,14 +12,13 @@ extern crate backtrace_sys as bt; -use std::ffi::CStr; -use std::{ptr, slice}; -use std::sync::{ONCE_INIT, Once}; +use core::{ptr, slice}; use libc::{self, c_char, c_int, c_void, uintptr_t}; use SymbolName; +use symbolize::ResolveWhat; use types::BytesOrWideString; pub enum Symbol { @@ -44,7 +43,13 @@ if ptr.is_null() { None } else { - Some(SymbolName::new(unsafe { CStr::from_ptr(ptr).to_bytes() })) + unsafe { + let len = libc::strlen(ptr); + Some(SymbolName::new(slice::from_raw_parts( + ptr as *const u8, + len, + ))) + } } } @@ -53,22 +58,50 @@ Symbol::Syminfo { pc, .. } => pc, Symbol::Pcinfo { pc, .. } => pc, }; - if pc == 0 {None} else {Some(pc as *mut _)} + if pc == 0 { + None + } else { + Some(pc as *mut _) + } } - pub fn filename_raw(&self) -> Option { + fn filename_bytes(&self) -> Option<&[u8]> { match *self { Symbol::Syminfo { .. } => None, Symbol::Pcinfo { filename, .. } => { let ptr = filename as *const u8; unsafe { let len = libc::strlen(filename); - Some(BytesOrWideString::Bytes(slice::from_raw_parts(ptr, len))) + Some(slice::from_raw_parts(ptr, len)) } } } } + pub fn filename_raw(&self) -> Option { + self.filename_bytes().map(BytesOrWideString::Bytes) + } + + #[cfg(feature = "std")] + pub fn filename(&self) -> Option<&::std::path::Path> { + use std::path::Path; + + #[cfg(unix)] + fn bytes2path(bytes: &[u8]) -> Option<&Path> { + use std::ffi::OsStr; + use std::os::unix::prelude::*; + Some(Path::new(OsStr::from_bytes(bytes))) + } + + #[cfg(windows)] + fn bytes2path(bytes: &[u8]) -> Option<&Path> { + use std::str; + str::from_utf8(bytes).ok().map(Path::new) + } + + self.filename_bytes().and_then(bytes2path) + } + pub fn lineno(&self) -> Option { match *self { Symbol::Syminfo { .. } => None, @@ -77,44 +110,53 @@ } } -extern fn error_cb(_data: *mut c_void, _msg: *const c_char, - _errnum: c_int) { +extern "C" fn error_cb(_data: *mut c_void, _msg: *const c_char, _errnum: c_int) { // do nothing for now } -extern fn syminfo_cb(data: *mut c_void, - pc: uintptr_t, - symname: *const c_char, - _symval: uintptr_t, - _symsize: uintptr_t) { +extern "C" fn syminfo_cb( + data: *mut c_void, + pc: uintptr_t, + symname: *const c_char, + _symval: uintptr_t, + _symsize: uintptr_t, +) { unsafe { - call(data, &super::Symbol { - inner: Symbol::Syminfo { - pc: pc, - symname: symname, + call( + data, + &super::Symbol { + inner: Symbol::Syminfo { + pc: pc, + symname: symname, + }, }, - }); + ); } } -extern fn pcinfo_cb(data: *mut c_void, - pc: uintptr_t, - filename: *const c_char, - lineno: c_int, - function: *const c_char) -> c_int { +extern "C" fn pcinfo_cb( + data: *mut c_void, + pc: uintptr_t, + filename: *const c_char, + lineno: c_int, + function: *const c_char, +) -> c_int { unsafe { if filename.is_null() || function.is_null() { - return -1 + return -1; } - call(data, &super::Symbol { - inner: Symbol::Pcinfo { - pc: pc, - filename: filename, - lineno: lineno, - function: function, + call( + data, + &super::Symbol { + inner: Symbol::Pcinfo { + pc: pc, + filename: filename, + lineno: lineno, + function: function, + }, }, - }); - return 0 + ); + return 0; } } @@ -136,44 +178,185 @@ // that is calculated the first time this is requested. Remember that // backtracing all happens serially (one global lock). // -// Things don't work so well on not-Linux since libbacktrace can't track down -// that executable this is. We at one point used env::current_exe but it turns -// out that there are some serious security issues with that approach. -// -// Specifically, on certain platforms like BSDs, a malicious actor can cause an -// arbitrary file to be placed at the path returned by current_exe. libbacktrace -// does not behave defensively in the presence of ill-formed DWARF information, -// and has been demonstrated to segfault in at least one case. There is no -// evidence at the moment to suggest that a more carefully constructed file -// can't cause arbitrary code execution. As a result of all of this, we don't -// hint libbacktrace with the path to the current process. +// Note the lack of synchronization here is due to the requirement that +// `resolve` is externally synchronized. unsafe fn init_state() -> *mut bt::backtrace_state { static mut STATE: *mut bt::backtrace_state = 0 as *mut _; - static INIT: Once = ONCE_INIT; - INIT.call_once(|| { - // Our libbacktrace may not have multithreading support, so - // set `threaded = 0` and synchronize ourselves. - STATE = bt::backtrace_create_state(ptr::null(), 0, error_cb, - ptr::null_mut()); - }); - STATE + if !STATE.is_null() { + return STATE; + } + + STATE = bt::backtrace_create_state( + load_filename(), + // Don't exercise threadsafe capabilities of libbacktrace since + // we're always calling it in a synchronized fashion. + 0, + error_cb, + ptr::null_mut(), // no extra data + ); + + return STATE; + + // Note that for libbacktrace to operate at all it needs to find the DWARF + // debug info for the current executable. It typically does that via a + // number of mechanisms including, but not limited to: + // + // * /proc/self/exe on supported platforms + // * The filename passed in explicitly when creating state + // + // The libbacktrace library is a big wad of C code. This naturally means + // it's got memory safety vulnerabilities, especially when handling + // malformed debuginfo. Libstd has run into plenty of these historically. + // + // If /proc/self/exe is used then we can typically ignore these as we + // assume that libbacktrace is "mostly correct" and otherwise doesn't do + // weird things with "attempted to be correct" dwarf debug info. + // + // If we pass in a filename, however, then it's possible on some platforms + // (like BSDs) where a malicious actor can cause an arbitrary file to be + // placed at that location. This means that if we tell libbacktrace about a + // filename it may be using an arbitrary file, possibly causing segfaults. + // If we don't tell libbacktrace anything though then it won't do anything + // on platforms that don't support paths like /proc/self/exe! + // + // Given all that we try as hard as possible to *not* pass in a filename, + // but we must on platforms that don't support /proc/self/exe at all. + cfg_if! { + if #[cfg(any(target_os = "macos", target_os = "ios"))] { + // Note that ideally we'd use `std::env::current_exe`, but we can't + // require `std` here. + // + // Use `_NSGetExecutablePath` to load the current executable path + // into a static area (which if it's too small just give up). + // + // Note that we're seriously trusting libbacktrace here to not die + // on corrupt executables, but it surely does... + unsafe fn load_filename() -> *const libc::c_char { + const N: usize = 256; + static mut BUF: [u8; N] = [0; N]; + extern { + fn _NSGetExecutablePath( + buf: *mut libc::c_char, + bufsize: *mut u32, + ) -> libc::c_int; + } + let mut sz: u32 = BUF.len() as u32; + let ptr = BUF.as_mut_ptr() as *mut libc::c_char; + if _NSGetExecutablePath(ptr, &mut sz) == 0 { + ptr + } else { + ptr::null() + } + } + } else if #[cfg(windows)] { + use windows::*; + + // Windows has a mode of opening files where after it's opened it + // can't be deleted. That's in general what we want here because we + // want to ensure that our executable isn't changing out from under + // us after we hand it off to libbacktrace, hopefully mitigating the + // ability to pass in arbitrary data into libbacktrace (which may be + // mishandled). + // + // Given that we do a bit of a dance here to attempt to get a sort + // of lock on our own image: + // + // * Get a handle to the current process, load its filename. + // * Open a file to that filename with the right flags. + // * Reload the current process's filename, making sure it's the same + // + // If that all passes we in theory have indeed opened our process's + // file and we're guaranteed it won't change. FWIW a bunch of this + // is copied from libstd historically, so this is my best + // interpretation of what was happening. + unsafe fn load_filename() -> *const libc::c_char { + load_filename_opt().unwrap_or(ptr::null()) + } + + unsafe fn load_filename_opt() -> Result<*const libc::c_char, ()> { + const N: usize = 256; + // This lives in static memory so we can return it.. + static mut BUF: [i8; N] = [0; N]; + // ... and this lives on the stack since it's temporary + let mut stack_buf = [0; N]; + let name1 = query_full_name(&mut BUF)?; + + let handle = CreateFileA( + name1.as_ptr(), + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + ptr::null_mut(), + OPEN_EXISTING, + 0, + ptr::null_mut(), + ); + if handle.is_null() { + return Err(()); + } + + let name2 = query_full_name(&mut stack_buf)?; + if name1 != name2 { + CloseHandle(handle); + return Err(()) + } + // intentionally leak `handle` here because having that open + // should preserve our lock on this file name. + Ok(name1.as_ptr()) + } + + unsafe fn query_full_name(buf: &mut [i8]) -> Result<&[i8], ()> { + let p1 = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId()); + let mut len = buf.len() as u32; + let rc = QueryFullProcessImageNameA(p1, 0, buf.as_mut_ptr(), &mut len); + CloseHandle(p1); + + // We want to return a slice that is nul-terminated, so if + // everything was filled in and it equals the total length + // then equate that to failure. + // + // Otherwise when returning success make sure the nul byte is + // included in the slice. + if rc == 0 || len == buf.len() as u32 { + Err(()) + } else { + assert_eq!(buf[len as usize], 0); + Ok(&buf[..(len + 1) as usize]) + } + } + + + } else { + unsafe fn load_filename() -> *const libc::c_char { + ptr::null() + } + } + } } -pub unsafe fn resolve(symaddr: *mut c_void, mut cb: &mut FnMut(&super::Symbol)) -{ +pub unsafe fn resolve(what: ResolveWhat, mut cb: &mut FnMut(&super::Symbol)) { + let symaddr = what.address_or_ip(); + // backtrace errors are currently swept under the rug let state = init_state(); if state.is_null() { - return + return; } - let ret = bt::backtrace_pcinfo(state, symaddr as uintptr_t, - pcinfo_cb, error_cb, - &mut cb as *mut _ as *mut _); + let ret = bt::backtrace_pcinfo( + state, + symaddr as uintptr_t, + pcinfo_cb, + error_cb, + &mut cb as *mut _ as *mut _, + ); if ret != 0 { - bt::backtrace_syminfo(state, symaddr as uintptr_t, - syminfo_cb, error_cb, - &mut cb as *mut _ as *mut _); + bt::backtrace_syminfo( + state, + symaddr as uintptr_t, + syminfo_cb, + error_cb, + &mut cb as *mut _ as *mut _, + ); } } diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/mod.rs cargo-0.35.0/vendor/backtrace/src/symbolize/mod.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,8 +7,10 @@ } } -use types::{BytesOrWideString, c_void}; use rustc_demangle::{try_demangle, Demangle}; +use types::{c_void, BytesOrWideString}; + +use backtrace::Frame; /// Resolve an address to a symbol, passing the symbol to the specified /// closure. @@ -23,6 +25,9 @@ /// Symbols yielded represent the execution at the specified `addr`, returning /// file/line pairs for that address (if available). /// +/// Note that if you have a `Frame` then it's recommended to use the +/// `resolve_frame` function instead of this one. +/// /// # Required features /// /// This function requires the `std` feature of the `backtrace` crate to be @@ -51,17 +56,79 @@ unsafe { resolve_unsynchronized(addr, cb) } } +/// Resolve a previously capture frame to a symbol, passing the symbol to the +/// specified closure. +/// +/// This functin performs the same function as `resolve` except that it takes a +/// `Frame` as an argument instead of an address. This can allow some platform +/// implementations of backtracing to provide more accurate symbol information +/// or information about inline frames for example. It's recommended to use this +/// if you can. +/// +/// # Required features +/// +/// This function requires the `std` feature of the `backtrace` crate to be +/// enabled, and the `std` feature is enabled by default. +/// +/// # Example +/// +/// ``` +/// extern crate backtrace; +/// +/// fn main() { +/// backtrace::trace(|frame| { +/// backtrace::resolve_frame(frame, |symbol| { +/// // ... +/// }); +/// +/// false // only look at the top frame +/// }); +/// } +/// ``` +#[cfg(feature = "std")] +pub fn resolve_frame(frame: &Frame, cb: F) { + let _guard = ::lock::lock(); + unsafe { resolve_frame_unsynchronized(frame, cb) } +} + +pub enum ResolveWhat<'a> { + Address(*mut c_void), + Frame(&'a Frame), +} + +impl<'a> ResolveWhat<'a> { + #[allow(dead_code)] + fn address_or_ip(&self) -> *mut c_void { + match *self { + ResolveWhat::Address(a) => a, + ResolveWhat::Frame(ref f) => f.ip(), + } + } +} + /// Same as `resolve`, only unsafe as it's unsynchronized. /// /// This function does not have synchronization guarentees but is available when /// the `std` feature of this crate isn't compiled in. See the `resolve` /// function for more documentation and examples. pub unsafe fn resolve_unsynchronized(addr: *mut c_void, mut cb: F) - where F: FnMut(&Symbol) +where + F: FnMut(&Symbol), { - resolve_imp(addr as *mut _, &mut cb) + resolve_imp(ResolveWhat::Address(addr), &mut cb) } +/// Same as `resolve_frame`, only unsafe as it's unsynchronized. +/// +/// This function does not have synchronization guarentees but is available +/// when the `std` feature of this crate isn't compiled in. See the +/// `resolve_frame` function for more documentation and examples. +pub unsafe fn resolve_frame_unsynchronized(frame: &Frame, mut cb: F) +where + F: FnMut(&Symbol), +{ + resolve_imp(ResolveWhat::Frame(frame), &mut cb) +} /// A trait representing the resolution of a symbol in a file. /// @@ -101,7 +168,6 @@ self.inner.filename_raw() } - /// Returns the line number for where this symbol is currently executing. /// /// This return value is typically `Some` if `filename` returns `Some`, and @@ -119,28 +185,9 @@ /// /// This function requires the `std` feature to be enabled for this crate. #[cfg(feature = "std")] + #[allow(unreachable_code)] pub fn filename(&self) -> Option<&Path> { - #[cfg(unix)] - { - use std::ffi::OsStr; - use std::os::unix::ffi::OsStrExt; - - match self.filename_raw() { - Some(BytesOrWideString::Bytes(slice)) => { - Some(Path::new(OsStr::from_bytes(slice))) - } - None => None, - _ => unreachable!(), - } - } - #[cfg(windows)] - { - self.inner.filename().map(Path::new) - } - #[cfg(all(not(windows), not(unix)))] - { - None - } + self.inner.filename() } } @@ -154,7 +201,8 @@ d.field("addr", &addr); } - #[cfg(feature = "std")] { + #[cfg(feature = "std")] + { if let Some(filename) = self.filename() { d.field("filename", &filename); } @@ -230,14 +278,14 @@ } } - /// Returns the raw symbol name as a `str` if the symbols is valid utf-8. + /// Returns the raw (mangled) symbol name as a `str` if the symbol is valid utf-8. + /// + /// Use the `Display` implementation if you want the demangled version. pub fn as_str(&self) -> Option<&'a str> { self.demangled .as_ref() .map(|s| s.as_str()) - .or_else(|| { - str::from_utf8(self.bytes).ok() - }) + .or_else(|| str::from_utf8(self.bytes).ok()) } /// Returns the raw symbol name as a list of bytes @@ -246,16 +294,16 @@ } } -fn format_symbol_name(fmt: fn(&str, &mut fmt::Formatter) -> fmt::Result, - mut bytes: &[u8], - f: &mut fmt::Formatter) - -> fmt::Result -{ +fn format_symbol_name( + fmt: fn(&str, &mut fmt::Formatter) -> fmt::Result, + mut bytes: &[u8], + f: &mut fmt::Formatter, +) -> fmt::Result { while bytes.len() > 0 { match str::from_utf8(bytes) { Ok(name) => { fmt(name, f)?; - break + break; } Err(err) => { fmt("\u{FFFD}", f)?; @@ -333,7 +381,7 @@ } cfg_if! { - if #[cfg(all(windows, feature = "dbghelp"))] { + if #[cfg(all(windows, target_env = "msvc", feature = "dbghelp"))] { mod dbghelp; use self::dbghelp::resolve as resolve_imp; use self::dbghelp::Symbol as SymbolImp; @@ -344,16 +392,6 @@ mod gimli; use self::gimli::resolve as resolve_imp; use self::gimli::Symbol as SymbolImp; - } else if #[cfg(all(feature = "libbacktrace", - unix, - not(target_os = "fuchsia"), - not(target_os = "emscripten"), - not(target_os = "macos"), - not(target_os = "ios")))] { - mod libbacktrace; - use self::libbacktrace::resolve as resolve_imp; - use self::libbacktrace::Symbol as SymbolImp; - // Note that we only enable coresymbolication on iOS when debug assertions // are enabled because it's helpful in debug mode but it looks like apps get // rejected from the app store if they use this API, see #92 for more info @@ -363,6 +401,13 @@ mod coresymbolication; use self::coresymbolication::resolve as resolve_imp; use self::coresymbolication::Symbol as SymbolImp; + } else if #[cfg(all(feature = "libbacktrace", + any(unix, all(windows, target_env = "gnu")), + not(target_os = "fuchsia"), + not(target_os = "emscripten")))] { + mod libbacktrace; + use self::libbacktrace::resolve as resolve_imp; + use self::libbacktrace::Symbol as SymbolImp; } else if #[cfg(all(unix, not(target_os = "emscripten"), feature = "dladdr"))] { diff -Nru cargo-0.33.0/vendor/backtrace/src/symbolize/noop.rs cargo-0.35.0/vendor/backtrace/src/symbolize/noop.rs --- cargo-0.33.0/vendor/backtrace/src/symbolize/noop.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/symbolize/noop.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,8 @@ use types::{BytesOrWideString, c_void}; use SymbolName; +use symbolize::ResolveWhat; -pub unsafe fn resolve(_addr: *mut c_void, _cb: &mut FnMut(&super::Symbol)) { +pub unsafe fn resolve(_addr: ResolveWhat, _cb: &mut FnMut(&super::Symbol)) { } pub struct Symbol; @@ -19,6 +20,11 @@ None } + #[cfg(feature = "std")] + pub fn filename(&self) -> Option<&::std::path::Path> { + None + } + pub fn lineno(&self) -> Option { None } diff -Nru cargo-0.33.0/vendor/backtrace/src/windows.rs cargo-0.35.0/vendor/backtrace/src/windows.rs --- cargo-0.33.0/vendor/backtrace/src/windows.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/src/windows.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,559 @@ +//! A module to define the FFI definitions we use on Windows for `dbghelp.dll` +//! +//! This module uses a custom macro, `ffi!`, to wrap all definitions to +//! automatically generate tests to assert that our definitions here are the +//! same as `winapi`. +//! +//! This module largely exists to integrate into libstd itself where winapi is +//! not currently available. + +#![allow(bad_style, dead_code)] + +cfg_if! { + if #[cfg(feature = "verify-winapi")] { + pub use self::winapi::c_void; + pub use self::winapi::HINSTANCE; + pub use self::winapi::FARPROC; + pub use self::winapi::LPSECURITY_ATTRIBUTES; + + mod winapi { + pub use winapi::ctypes::*; + pub use winapi::shared::basetsd::*; + pub use winapi::shared::minwindef::*; + pub use winapi::um::dbghelp::*; + pub use winapi::um::handleapi::*; + pub use winapi::um::libloaderapi::*; + pub use winapi::um::processthreadsapi::*; + pub use winapi::um::winbase::*; + pub use winapi::um::winnt::*; + pub use winapi::um::fileapi::*; + pub use winapi::um::minwinbase::*; + } + } else { + pub use core::ffi::c_void; + pub type HINSTANCE = *mut c_void; + pub type FARPROC = *mut c_void; + pub type LPSECURITY_ATTRIBUTES = *mut c_void; + } +} + +macro_rules! ffi { + () => (); + + (#[repr($($r:tt)*)] pub struct $name:ident { $(pub $field:ident: $ty:ty,)* } $($rest:tt)*) => ( + #[repr($($r)*)] + #[cfg(not(feature = "verify-winapi"))] + #[derive(Copy, Clone)] + pub struct $name { + $(pub $field: $ty,)* + } + + #[cfg(feature = "verify-winapi")] + pub use self::winapi::$name; + + #[test] + #[cfg(feature = "verify-winapi")] + fn $name() { + use core::mem; + + #[repr($($r)*)] + pub struct $name { + $(pub $field: $ty,)* + } + + assert_eq!( + mem::size_of::<$name>(), + mem::size_of::(), + concat!("size of ", stringify!($name), " is wrong"), + ); + assert_eq!( + mem::align_of::<$name>(), + mem::align_of::(), + concat!("align of ", stringify!($name), " is wrong"), + ); + + type Winapi = winapi::$name; + + fn assert_same(_: T, _: T) {} + + unsafe { + let a = &*(mem::align_of::<$name>() as *const $name); + let b = &*(mem::align_of::() as *const Winapi); + + $( + ffi!(@test_fields a b $field $ty); + )* + } + } + + ffi!($($rest)*); + ); + + // Handling verification against unions in winapi requires some special care + (@test_fields $a:ident $b:ident FltSave $ty:ty) => ( + // Skip this field on x86_64 `CONTEXT` since it's a union and a bit funny + ); + (@test_fields $a:ident $b:ident D $ty:ty) => ({ + let a = &$a.D; + let b = $b.D(); + assert_same(a, b); + assert_eq!(a as *const $ty, b as *const $ty, "misplaced field D"); + }); + (@test_fields $a:ident $b:ident s $ty:ty) => ({ + let a = &$a.s; + let b = $b.s(); + assert_same(a, b); + assert_eq!(a as *const $ty, b as *const $ty, "misplaced field s"); + }); + + // Otherwise test all fields normally. + (@test_fields $a:ident $b:ident $field:ident $ty:ty) => ({ + let a = &$a.$field; + let b = &$b.$field; + assert_same(a, b); + assert_eq!(a as *const $ty, b as *const $ty, + concat!("misplaced field ", stringify!($field))); + }); + + (pub type $name:ident = $ty:ty; $($rest:tt)*) => ( + pub type $name = $ty; + + #[cfg(feature = "verify-winapi")] + #[allow(dead_code)] + const $name: () = { + fn _foo() { + trait SameType {} + impl SameType for (T, T) {} + fn assert_same() {} + + assert_same::<($name, winapi::$name)>(); + } + }; + + ffi!($($rest)*); + ); + + (pub const $name:ident: $ty:ty = $val:expr; $($rest:tt)*) => ( + pub const $name: $ty = $val; + + #[cfg(feature = "verify-winapi")] + #[allow(unused_imports)] + mod $name { + use super::*; + #[test] + fn assert_valid() { + let x: $ty = winapi::$name; + assert_eq!(x, $val); + } + } + + + ffi!($($rest)*); + ); + + (extern "system" { $(pub fn $name:ident($($args:tt)*) -> $ret:ty;)* } $($rest:tt)*) => ( + extern "system" { + $(pub fn $name($($args)*) -> $ret;)* + } + + $( + #[cfg(feature = "verify-winapi")] + mod $name { + #[test] + fn assert_same() { + use super::*; + + assert_eq!($name as usize, winapi::$name as usize); + let mut x: unsafe extern "system" fn($($args)*) -> $ret; + x = $name; + drop(x); + x = winapi::$name; + drop(x); + } + } + )* + + ffi!($($rest)*); + ); + + (impl $name:ident { $($i:tt)* } $($rest:tt)*) => ( + #[cfg(not(feature = "verify-winapi"))] + impl $name { + $($i)* + } + + ffi!($($rest)*); + ); +} + +ffi! { + #[repr(C)] + pub struct STACKFRAME64 { + pub AddrPC: ADDRESS64, + pub AddrReturn: ADDRESS64, + pub AddrFrame: ADDRESS64, + pub AddrStack: ADDRESS64, + pub AddrBStore: ADDRESS64, + pub FuncTableEntry: PVOID, + pub Params: [DWORD64; 4], + pub Far: BOOL, + pub Virtual: BOOL, + pub Reserved: [DWORD64; 3], + pub KdHelp: KDHELP64, + } + + pub type LPSTACKFRAME64 = *mut STACKFRAME64; + + #[repr(C)] + pub struct STACKFRAME_EX { + pub AddrPC: ADDRESS64, + pub AddrReturn: ADDRESS64, + pub AddrFrame: ADDRESS64, + pub AddrStack: ADDRESS64, + pub AddrBStore: ADDRESS64, + pub FuncTableEntry: PVOID, + pub Params: [DWORD64; 4], + pub Far: BOOL, + pub Virtual: BOOL, + pub Reserved: [DWORD64; 3], + pub KdHelp: KDHELP64, + pub StackFrameSize: DWORD, + pub InlineFrameContext: DWORD, + } + + pub type LPSTACKFRAME_EX = *mut STACKFRAME_EX; + + #[repr(C)] + pub struct IMAGEHLP_LINEW64 { + pub SizeOfStruct: DWORD, + pub Key: PVOID, + pub LineNumber: DWORD, + pub FileName: PWSTR, + pub Address: DWORD64, + } + + pub type PIMAGEHLP_LINEW64 = *mut IMAGEHLP_LINEW64; + + #[repr(C)] + pub struct SYMBOL_INFOW { + pub SizeOfStruct: ULONG, + pub TypeIndex: ULONG, + pub Reserved: [ULONG64; 2], + pub Index: ULONG, + pub Size: ULONG, + pub ModBase: ULONG64, + pub Flags: ULONG, + pub Value: ULONG64, + pub Address: ULONG64, + pub Register: ULONG, + pub Scope: ULONG, + pub Tag: ULONG, + pub NameLen: ULONG, + pub MaxNameLen: ULONG, + pub Name: [WCHAR; 1], + } + + pub type PSYMBOL_INFOW = *mut SYMBOL_INFOW; + + pub type PTRANSLATE_ADDRESS_ROUTINE64 = Option< + unsafe extern "system" fn(hProcess: HANDLE, hThread: HANDLE, lpaddr: LPADDRESS64) -> DWORD64, + >; + pub type PGET_MODULE_BASE_ROUTINE64 = + Option DWORD64>; + pub type PFUNCTION_TABLE_ACCESS_ROUTINE64 = + Option PVOID>; + pub type PREAD_PROCESS_MEMORY_ROUTINE64 = Option< + unsafe extern "system" fn( + hProcess: HANDLE, + qwBaseAddress: DWORD64, + lpBuffer: PVOID, + nSize: DWORD, + lpNumberOfBytesRead: LPDWORD, + ) -> BOOL, + >; + + #[repr(C)] + pub struct ADDRESS64 { + pub Offset: DWORD64, + pub Segment: WORD, + pub Mode: ADDRESS_MODE, + } + + pub type LPADDRESS64 = *mut ADDRESS64; + + pub type ADDRESS_MODE = u32; + + #[repr(C)] + pub struct KDHELP64 { + pub Thread: DWORD64, + pub ThCallbackStack: DWORD, + pub ThCallbackBStore: DWORD, + pub NextCallback: DWORD, + pub FramePointer: DWORD, + pub KiCallUserMode: DWORD64, + pub KeUserCallbackDispatcher: DWORD64, + pub SystemRangeStart: DWORD64, + pub KiUserExceptionDispatcher: DWORD64, + pub StackBase: DWORD64, + pub StackLimit: DWORD64, + pub BuildVersion: DWORD, + pub Reserved0: DWORD, + pub Reserved1: [DWORD64; 4], + } + + pub const MAX_SYM_NAME: usize = 2000; + pub const AddrModeFlat: ADDRESS_MODE = 3; + pub const TRUE: BOOL = 1; + pub const FALSE: BOOL = 0; + pub const PROCESS_QUERY_INFORMATION: DWORD = 0x400; + pub const IMAGE_FILE_MACHINE_ARM64: u16 = 43620; + pub const IMAGE_FILE_MACHINE_AMD64: u16 = 34404; + pub const IMAGE_FILE_MACHINE_I386: u16 = 332; + pub const FILE_SHARE_READ: DWORD = 0x1; + pub const FILE_SHARE_WRITE: DWORD = 0x2; + pub const OPEN_EXISTING: DWORD = 0x3; + pub const GENERIC_READ: DWORD = 0x80000000; + + pub type DWORD = u32; + pub type PDWORD = *mut u32; + pub type BOOL = i32; + pub type DWORD64 = u64; + pub type PDWORD64 = *mut u64; + pub type HANDLE = *mut c_void; + pub type PVOID = HANDLE; + pub type PCWSTR = *const u16; + pub type LPSTR = *mut i8; + pub type LPCSTR = *const i8; + pub type PWSTR = *mut u16; + pub type WORD = u16; + pub type ULONG = u32; + pub type ULONG64 = u64; + pub type WCHAR = u16; + pub type PCONTEXT = *mut CONTEXT; + pub type LPDWORD = *mut DWORD; + pub type DWORDLONG = u64; + pub type HMODULE = HINSTANCE; + + extern "system" { + pub fn GetCurrentProcess() -> HANDLE; + pub fn GetCurrentThread() -> HANDLE; + pub fn RtlCaptureContext(ContextRecord: PCONTEXT) -> (); + pub fn LoadLibraryW(a: *const u16) -> HMODULE; + pub fn FreeLibrary(h: HMODULE) -> BOOL; + pub fn GetProcAddress(h: HMODULE, name: *const i8) -> FARPROC; + pub fn OpenProcess( + dwDesiredAccess: DWORD, + bInheitHandle: BOOL, + dwProcessId: DWORD, + ) -> HANDLE; + pub fn GetCurrentProcessId() -> DWORD; + pub fn CloseHandle(h: HANDLE) -> BOOL; + pub fn QueryFullProcessImageNameA( + hProcess: HANDLE, + dwFlags: DWORD, + lpExeName: LPSTR, + lpdwSize: PDWORD, + ) -> BOOL; + pub fn CreateFileA( + lpFileName: LPCSTR, + dwDesiredAccess: DWORD, + dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, + hTemplateFile: HANDLE, + ) -> HANDLE; + } +} + +#[cfg(target_arch = "aarch64")] +ffi! { + #[repr(C, align(16))] + pub struct CONTEXT { + pub ContextFlags: DWORD, + pub Cpsr: DWORD, + pub u: CONTEXT_u, + pub Sp: u64, + pub Pc: u64, + pub V: [ARM64_NT_NEON128; 32], + pub Fpcr: DWORD, + pub Fpsr: DWORD, + pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS], + pub Bvr: [DWORD64; ARM64_MAX_BREAKPOINTS], + pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS], + pub Wvr: [DWORD64; ARM64_MAX_WATCHPOINTS], + } + + #[repr(C)] + pub struct CONTEXT_u { + pub s: CONTEXT_u_s, + } + + impl CONTEXT_u { + pub unsafe fn s(&self) -> &CONTEXT_u_s { + &self.s + } + } + + #[repr(C)] + pub struct CONTEXT_u_s { + pub X0: u64, + pub X1: u64, + pub X2: u64, + pub X3: u64, + pub X4: u64, + pub X5: u64, + pub X6: u64, + pub X7: u64, + pub X8: u64, + pub X9: u64, + pub X10: u64, + pub X11: u64, + pub X12: u64, + pub X13: u64, + pub X14: u64, + pub X15: u64, + pub X16: u64, + pub X17: u64, + pub X18: u64, + pub X19: u64, + pub X20: u64, + pub X21: u64, + pub X22: u64, + pub X23: u64, + pub X24: u64, + pub X25: u64, + pub X26: u64, + pub X27: u64, + pub X28: u64, + pub Fp: u64, + pub Lr: u64, + } + + pub const ARM64_MAX_BREAKPOINTS: usize = 8; + pub const ARM64_MAX_WATCHPOINTS: usize = 2; + + #[repr(C)] + pub struct ARM64_NT_NEON128 { + pub D: [f64; 2], + } +} + +#[cfg(target_arch = "x86")] +ffi! { + #[repr(C)] + pub struct CONTEXT { + pub ContextFlags: DWORD, + pub Dr0: DWORD, + pub Dr1: DWORD, + pub Dr2: DWORD, + pub Dr3: DWORD, + pub Dr6: DWORD, + pub Dr7: DWORD, + pub FloatSave: FLOATING_SAVE_AREA, + pub SegGs: DWORD, + pub SegFs: DWORD, + pub SegEs: DWORD, + pub SegDs: DWORD, + pub Edi: DWORD, + pub Esi: DWORD, + pub Ebx: DWORD, + pub Edx: DWORD, + pub Ecx: DWORD, + pub Eax: DWORD, + pub Ebp: DWORD, + pub Eip: DWORD, + pub SegCs: DWORD, + pub EFlags: DWORD, + pub Esp: DWORD, + pub SegSs: DWORD, + pub ExtendedRegisters: [u8; 512], + } + + #[repr(C)] + pub struct FLOATING_SAVE_AREA { + pub ControlWord: DWORD, + pub StatusWord: DWORD, + pub TagWord: DWORD, + pub ErrorOffset: DWORD, + pub ErrorSelector: DWORD, + pub DataOffset: DWORD, + pub DataSelector: DWORD, + pub RegisterArea: [u8; 80], + pub Spare0: DWORD, + } +} + +#[cfg(target_arch = "x86_64")] +ffi! { + #[repr(C, align(8))] + pub struct CONTEXT { + pub P1Home: DWORDLONG, + pub P2Home: DWORDLONG, + pub P3Home: DWORDLONG, + pub P4Home: DWORDLONG, + pub P5Home: DWORDLONG, + pub P6Home: DWORDLONG, + + pub ContextFlags: DWORD, + pub MxCsr: DWORD, + + pub SegCs: WORD, + pub SegDs: WORD, + pub SegEs: WORD, + pub SegFs: WORD, + pub SegGs: WORD, + pub SegSs: WORD, + pub EFlags: DWORD, + + pub Dr0: DWORDLONG, + pub Dr1: DWORDLONG, + pub Dr2: DWORDLONG, + pub Dr3: DWORDLONG, + pub Dr6: DWORDLONG, + pub Dr7: DWORDLONG, + + pub Rax: DWORDLONG, + pub Rcx: DWORDLONG, + pub Rdx: DWORDLONG, + pub Rbx: DWORDLONG, + pub Rsp: DWORDLONG, + pub Rbp: DWORDLONG, + pub Rsi: DWORDLONG, + pub Rdi: DWORDLONG, + pub R8: DWORDLONG, + pub R9: DWORDLONG, + pub R10: DWORDLONG, + pub R11: DWORDLONG, + pub R12: DWORDLONG, + pub R13: DWORDLONG, + pub R14: DWORDLONG, + pub R15: DWORDLONG, + + pub Rip: DWORDLONG, + + pub FltSave: FLOATING_SAVE_AREA, + + pub VectorRegister: [M128A; 26], + pub VectorControl: DWORDLONG, + + pub DebugControl: DWORDLONG, + pub LastBranchToRip: DWORDLONG, + pub LastBranchFromRip: DWORDLONG, + pub LastExceptionToRip: DWORDLONG, + pub LastExceptionFromRip: DWORDLONG, + } + + #[repr(C)] + pub struct M128A { + pub Low: u64, + pub High: i64, + } +} + +#[repr(C)] +#[cfg(target_arch = "x86_64")] +#[derive(Copy, Clone)] +pub struct FLOATING_SAVE_AREA { + _Dummy: [u8; 512], +} diff -Nru cargo-0.33.0/vendor/backtrace/tests/long_fn_name.rs cargo-0.35.0/vendor/backtrace/tests/long_fn_name.rs --- cargo-0.33.0/vendor/backtrace/tests/long_fn_name.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/tests/long_fn_name.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,5 @@ extern crate backtrace; -#[cfg(all(windows, feature = "dbghelp"))] -extern crate winapi; - use backtrace::Backtrace; // 50-character module name @@ -23,9 +20,7 @@ #[test] #[cfg(all(windows, feature = "dbghelp", target_env = "msvc"))] fn test_long_fn_name() { - use winapi::um::dbghelp; - use _234567890_234567890_234567890_234567890_234567890:: - _234567890_234567890_234567890_234567890_234567890 as S; + use _234567890_234567890_234567890_234567890_234567890::_234567890_234567890_234567890_234567890_234567890 as S; // 10 repetitions of struct name, so fully qualified function name is // atleast 10 * (50 + 50) * 2 = 2000 characters long. @@ -44,9 +39,7 @@ if let Some(function_name) = symbols[0].name() { let function_name = function_name.as_str().unwrap(); - if function_name.contains( - "::_234567890_234567890_234567890_234567890_234567890") - { + if function_name.contains("::_234567890_234567890_234567890_234567890_234567890") { found_long_name_frame = true; assert!(function_name.len() > 200); } diff -Nru cargo-0.33.0/vendor/backtrace/tests/skip_inner_frames.rs cargo-0.35.0/vendor/backtrace/tests/skip_inner_frames.rs --- cargo-0.33.0/vendor/backtrace/tests/skip_inner_frames.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/tests/skip_inner_frames.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,12 +5,21 @@ const FRAME_RANGE: usize = 128; // should be close enough not to give false positives #[test] -#[cfg_attr(any(not(any(feature = "libunwind", feature = "unix-backtrace", feature = "dbghelp")), all(target_os = "windows", target_arch = "x86")), ignore)] +#[cfg_attr( + any( + not(any( + all(unix, feature = "libunwind", feature = "unix-backtrace"), + all(windows, feature = "dbghelp") + )), + all(target_os = "windows", target_arch = "x86") + ), + ignore +)] fn backtrace_new_unresolved_should_start_with_call_site_trace() { let mut b = Backtrace::new_unresolved(); b.resolve(); - println!("{:?}", b); - println!("{:#?}", b); + println!("{:?}", b); + println!("{:#?}", b); assert!(!b.frames().is_empty()); @@ -22,7 +31,16 @@ } #[test] -#[cfg_attr(any(not(any(feature = "libunwind", feature = "unix-backtrace", feature = "dbghelp")), all(target_os = "windows", target_arch = "x86")), ignore)] +#[cfg_attr( + any( + not(any( + all(unix, feature = "libunwind", feature = "unix-backtrace"), + all(feature = "dbghelp", windows) + )), + all(target_os = "windows", target_arch = "x86") + ), + ignore +)] fn backtrace_new_should_start_with_call_site_trace() { let b = Backtrace::new(); println!("{:?}", b); diff -Nru cargo-0.33.0/vendor/backtrace/tests/smoke.rs cargo-0.35.0/vendor/backtrace/tests/smoke.rs --- cargo-0.33.0/vendor/backtrace/tests/smoke.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace/tests/smoke.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,25 +1,25 @@ extern crate backtrace; -use std::os::raw::c_void; +use backtrace::Frame; use std::thread; static LIBUNWIND: bool = cfg!(all(unix, feature = "libunwind")); static UNIX_BACKTRACE: bool = cfg!(all(unix, feature = "unix-backtrace")); -static LIBBACKTRACE: bool = cfg!(all(unix, feature = "libbacktrace")) && - !cfg!(target_os = "fuchsia") && !cfg!(target_os = "macos") && - !cfg!(target_os = "ios"); -static CORESYMBOLICATION: bool = cfg!(all(any(target_os = "macos", target_os = "ios"), - feature = "coresymbolication")); +static LIBBACKTRACE: bool = cfg!(feature = "libbacktrace") + && !cfg!(target_os = "fuchsia"); +static CORESYMBOLICATION: bool = cfg!(all( + any(target_os = "macos", target_os = "ios"), + feature = "coresymbolication" +)); static DLADDR: bool = cfg!(all(unix, feature = "dladdr")) && !cfg!(target_os = "fuchsia"); static DBGHELP: bool = cfg!(all(windows, feature = "dbghelp")); static MSVC: bool = cfg!(target_env = "msvc"); -static GIMLI_SYMBOLIZE: bool = cfg!(all(feature = "gimli-symbolize", - unix, - target_os = "linux")); +static GIMLI_SYMBOLIZE: bool = cfg!(all(feature = "gimli-symbolize", unix, target_os = "linux")); #[test] // FIXME: shouldn't ignore this test on i686-msvc, unsure why it's failing #[cfg_attr(all(target_arch = "x86", target_env = "msvc"), ignore)] +#[rustfmt::skip] // we care about line numbers here fn smoke_test_frames() { frame_1(line!()); #[inline(never)] fn frame_1(start_line: u32) { frame_2(start_line) } @@ -28,7 +28,7 @@ #[inline(never)] fn frame_4(start_line: u32) { let mut v = Vec::new(); backtrace::trace(|cx| { - v.push((cx.ip(), cx.symbol_address())); + v.push(cx.clone()); true }); @@ -36,38 +36,75 @@ assert!(!LIBUNWIND); assert!(!UNIX_BACKTRACE); assert!(!DBGHELP); - return + return; } - // On 32-bit windows apparently the first frame isn't our backtrace - // frame but it's actually this frame. I'm not entirely sure why, but at - // least it seems consistent? - let o = if cfg!(all(windows, target_pointer_width = "32")) {1} else {0}; - // frame offset 0 is the `backtrace::trace` function, but that's generic - assert_frame(&v, o, 1, frame_4 as usize, "frame_4", - "tests/smoke.rs", start_line + 6); - assert_frame(&v, o, 2, frame_3 as usize, "frame_3", "tests/smoke.rs", - start_line + 3); - assert_frame(&v, o, 3, frame_2 as usize, "frame_2", "tests/smoke.rs", - start_line + 2); - assert_frame(&v, o, 4, frame_1 as usize, "frame_1", "tests/smoke.rs", - start_line + 1); - assert_frame(&v, o, 5, smoke_test_frames as usize, - "smoke_test_frames", "", 0); + // Various platforms have various bits of weirdness about their + // backtraces. To find a good starting spot let's search through the + // frames + let target = frame_4 as usize; + let offset = v + .iter() + .map(|frame| frame.symbol_address() as usize) + .enumerate() + .filter_map(|(i, sym)| { + if sym >= target { + Some((sym, i)) + } else { + None + } + }) + .min() + .unwrap() + .1; + let mut frames = v[offset..].iter(); + + assert_frame( + frames.next().unwrap(), + frame_4 as usize, + "frame_4", + "tests/smoke.rs", + start_line + 6, + ); + assert_frame( + frames.next().unwrap(), + frame_3 as usize, + "frame_3", + "tests/smoke.rs", + start_line + 3, + ); + assert_frame( + frames.next().unwrap(), + frame_2 as usize, + "frame_2", + "tests/smoke.rs", + start_line + 2, + ); + assert_frame( + frames.next().unwrap(), + frame_1 as usize, + "frame_1", + "tests/smoke.rs", + start_line + 1, + ); + assert_frame( + frames.next().unwrap(), + smoke_test_frames as usize, + "smoke_test_frames", + "", + 0, + ); } - fn assert_frame(syms: &[(*mut c_void, *mut c_void)], - offset: usize, - idx: usize, - actual_fn_pointer: usize, - expected_name: &str, - expected_file: &str, - expected_line: u32) { - if offset > idx { return } - println!("frame: {}", idx); - let (ip, sym) = syms[idx - offset]; - let ip = ip as usize; - let sym = sym as usize; + fn assert_frame( + frame: &Frame, + actual_fn_pointer: usize, + expected_name: &str, + expected_file: &str, + expected_line: u32, + ) { + let ip = frame.ip() as usize; + let sym = frame.symbol_address() as usize; assert!(ip >= sym); assert!(sym >= actual_fn_pointer); @@ -86,7 +123,7 @@ let mut addr = None; let mut line = None; let mut file = None; - backtrace::resolve(ip as *mut c_void, |sym| { + backtrace::resolve_frame(frame, |sym| { resolved += 1; name = sym.name().map(|v| v.to_string()); addr = sym.addr(); @@ -103,17 +140,18 @@ // * linux dladdr doesn't work (only consults local symbol table) // * windows dbghelp isn't great for GNU - if can_resolve && - !(cfg!(target_os = "linux") && DLADDR) && - !(DBGHELP && !MSVC) - { + if can_resolve && !(cfg!(target_os = "linux") && DLADDR) && !(DBGHELP && !MSVC) { let name = name.expect("didn't find a name"); // in release mode names get weird as functions can get merged // together with `mergefunc`, so only assert this in debug mode if cfg!(debug_assertions) { - assert!(name.contains(expected_name), - "didn't find `{}` in `{}`", expected_name, name); + assert!( + name.contains(expected_name), + "didn't find `{}` in `{}`", + expected_name, + name + ); } } @@ -125,13 +163,21 @@ let line = line.expect("didn't find a line number"); let file = file.expect("didn't find a line number"); if !expected_file.is_empty() { - assert!(file.ends_with(expected_file), - "{:?} didn't end with {:?}", file, expected_file); + assert!( + file.ends_with(expected_file), + "{:?} didn't end with {:?}", + file, + expected_file + ); } if expected_line != 0 { - assert!(line == expected_line, - "bad line number on frame for `{}`: {} != {}", - expected_name, line, expected_line); + assert!( + line == expected_line, + "bad line number on frame for `{}`: {} != {}", + expected_name, + line, + expected_line + ); } } } @@ -139,18 +185,20 @@ #[test] fn many_threads() { - let threads = (0..16).map(|_| { - thread::spawn(|| { - for _ in 0..16 { - backtrace::trace(|frame| { - backtrace::resolve(frame.ip(), |symbol| { - let _s = symbol.name().map(|s| s.to_string()); + let threads = (0..16) + .map(|_| { + thread::spawn(|| { + for _ in 0..16 { + backtrace::trace(|frame| { + backtrace::resolve(frame.ip(), |symbol| { + let _s = symbol.name().map(|s| s.to_string()); + }); + true }); - true - }); - } + } + }) }) - }).collect::>(); + .collect::>(); for t in threads { t.join().unwrap() diff -Nru cargo-0.33.0/vendor/backtrace-sys/build.rs.orig cargo-0.35.0/vendor/backtrace-sys/build.rs.orig --- cargo-0.33.0/vendor/backtrace-sys/build.rs.orig 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/backtrace-sys/build.rs.orig 2019-05-15 11:26:24.000000000 +0000 @@ -1,108 +1,10 @@ -extern crate cc; - -use std::env; -use std::path::PathBuf; -use std::fs::File; +use std::process::Command; fn main() { - let target = env::var("TARGET").unwrap(); - - if target.contains("msvc") || // libbacktrace isn't used on MSVC windows - target.contains("emscripten") || // no way this will ever compile for emscripten - target.contains("cloudabi") || - target.contains("wasm32") - { - println!("cargo:rustc-cfg=empty"); - return - } - - let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - - let mut build = cc::Build::new(); - build - .include("src/libbacktrace") - .include(&out_dir) - .warnings(false) - .file("src/libbacktrace/alloc.c") - .file("src/libbacktrace/dwarf.c") - .file("src/libbacktrace/fileline.c") - .file("src/libbacktrace/posix.c") - .file("src/libbacktrace/read.c") - .file("src/libbacktrace/sort.c") - .file("src/libbacktrace/state.c"); - - // No need to have any symbols reexported form shared objects - build.flag("-fvisibility=hidden"); - - if target.contains("darwin") { - build.file("src/libbacktrace/macho.c"); - } else if target.contains("windows") { - build.file("src/libbacktrace/pecoff.c"); - } else { - build.file("src/libbacktrace/elf.c"); - - let pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap(); - if pointer_width == "64" { - build.define("BACKTRACE_ELF_SIZE", "64"); - } else { - build.define("BACKTRACE_ELF_SIZE", "32"); - } - } - - File::create(out_dir.join("backtrace-supported.h")).unwrap(); - build.define("BACKTRACE_SUPPORTED", "1"); - build.define("BACKTRACE_USES_MALLOC", "1"); - build.define("BACKTRACE_SUPPORTS_THREADS", "0"); - build.define("BACKTRACE_SUPPORTS_DATA", "0"); - - File::create(out_dir.join("config.h")).unwrap(); - if !target.contains("apple-ios") && - !target.contains("solaris") && - !target.contains("redox") && - !target.contains("android") && - !target.contains("haiku") { - build.define("HAVE_DL_ITERATE_PHDR", "1"); - } - build.define("_GNU_SOURCE", "1"); - build.define("_LARGE_FILES", "1"); - - // When we're built as part of the Rust compiler, this is used to enable - // debug information in libbacktrace itself. - let any_debug = env::var("RUSTC_DEBUGINFO").unwrap_or_default() == "true" || - env::var("RUSTC_DEBUGINFO_LINES").unwrap_or_default() == "true"; - build.debug(any_debug); - - let syms = [ - "backtrace_full", - "backtrace_dwarf_add", - "backtrace_initialize", - "backtrace_pcinfo", - "backtrace_syminfo", - "backtrace_get_view", - "backtrace_release_view", - "backtrace_alloc", - "backtrace_free", - "backtrace_vector_finish", - "backtrace_vector_grow", - "backtrace_vector_release", - "backtrace_close", - "backtrace_open", - "backtrace_print", - "backtrace_simple", - "backtrace_qsort", - "backtrace_create_state", - "backtrace_uncompress_zdebug", - ]; - let prefix = if cfg!(feature = "rustc-dep-of-std") { - println!("cargo:rustc-cfg=rdos"); - "__rdos_" - } else { - println!("cargo:rustc-cfg=rbt"); - "__rbt_" - }; - for sym in syms.iter() { - build.define(sym, &format!("{}{}", prefix, sym)[..]); - } - - build.compile("backtrace"); + let search_dir = Command::new("sh") + .args(&["-c", "gcc -print-search-dirs | sed -ne 's/^install: //p'"]) + .output().expect("failed to find gcc install dir").stdout; + println!("cargo:rustc-link-lib=static=backtrace"); + println!("cargo:rustc-link-search=native={}", String::from_utf8(search_dir).unwrap().trim_right()); + println!("dh-cargo:deb-built-using=backtrace=0~={}", "libgcc-[0-9]+-dev .*"); } diff -Nru cargo-0.33.0/vendor/bit-set/.cargo-checksum.json cargo-0.35.0/vendor/bit-set/.cargo-checksum.json --- cargo-0.33.0/vendor/bit-set/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/bit-set/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"} \ No newline at end of file +{"files":{},"package":"e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/bit-set/Cargo.toml cargo-0.35.0/vendor/bit-set/Cargo.toml --- cargo-0.33.0/vendor/bit-set/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/bit-set/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "bit-set" -version = "0.5.0" +version = "0.5.1" authors = ["Alexis Beingessner "] description = "A set of bits" homepage = "https://github.com/contain-rs/bit-set" diff -Nru cargo-0.33.0/vendor/bit-vec/.cargo-checksum.json cargo-0.35.0/vendor/bit-vec/.cargo-checksum.json --- cargo-0.33.0/vendor/bit-vec/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/bit-vec/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"} \ No newline at end of file +{"files":{},"package":"f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/bit-vec/Cargo.toml cargo-0.35.0/vendor/bit-vec/Cargo.toml --- cargo-0.33.0/vendor/bit-vec/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/bit-vec/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "bit-vec" -version = "0.5.0" +version = "0.5.1" authors = ["Alexis Beingessner "] description = "A vector of bits" homepage = "https://github.com/contain-rs/bit-vec" diff -Nru cargo-0.33.0/vendor/bit-vec/src/lib.rs cargo-0.35.0/vendor/bit-vec/src/lib.rs --- cargo-0.33.0/vendor/bit-vec/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/bit-vec/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -100,19 +100,20 @@ #[macro_use] extern crate alloc; #[cfg(not(feature="std"))] -use alloc::Vec; +use alloc::prelude::Vec; use core::cmp::Ordering; use core::cmp; +#[cfg(feature="std")] use core::fmt; use core::hash; -use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat}; use core::iter::FromIterator; use core::slice; use core::{u8, usize}; +use core::iter::repeat; type MutBlocks<'a, B> = slice::IterMut<'a, B>; -type MatchWords<'a, B> = Chain>, Skip>>>>; +//type MatchWords<'a, B> = Chain>, Skip>>>>; use core::ops::*; @@ -148,12 +149,12 @@ } macro_rules! bit_block_impl { - ($(($t: ty, $size: expr)),*) => ($( + ($(($t: ident, $size: expr)),*) => ($( impl BitBlock for $t { #[inline] fn bits() -> usize { $size } #[inline] - fn from_byte(byte: u8) -> Self { byte as $t } + fn from_byte(byte: u8) -> Self { $t::from(byte) } #[inline] fn count_ones(self) -> usize { self.count_ones() as usize } #[inline] @@ -176,7 +177,7 @@ fn reverse_bits(byte: u8) -> u8 { let mut result = 0; for i in 0..u8::bits() { - result = result | ((byte >> i) & 1) << (u8::bits() - 1 - i); + result |= ((byte >> i) & 1) << (u8::bits() - 1 - i); } result } @@ -291,7 +292,7 @@ let nblocks = blocks_for_bits::(nbits); let mut bit_vec = BitVec { storage: vec![if bit { !B::zero() } else { B::zero() }; nblocks], - nbits: nbits + nbits, }; bit_vec.fix_last_block(); bit_vec @@ -338,8 +339,8 @@ for i in 0..complete_words { let mut accumulator = B::zero(); for idx in 0..B::bytes() { - accumulator = accumulator | - (B::from_byte(reverse_bits(bytes[i * B::bytes() + idx])) << (idx * 8)) + accumulator |= + B::from_byte(reverse_bits(bytes[i * B::bytes() + idx])) << (idx * 8) } bit_vec.storage.push(accumulator); } @@ -347,8 +348,8 @@ if extra_bytes > 0 { let mut last_word = B::zero(); for (i, &byte) in bytes[complete_words * B::bytes()..].iter().enumerate() { - last_word = last_word | - (B::from_byte(reverse_bits(byte)) << (i * 8)); + last_word |= + B::from_byte(reverse_bits(byte)) << (i * 8); } bit_vec.storage.push(last_word); } @@ -1183,6 +1184,7 @@ } } +#[cfg(feature="std")] impl fmt::Debug for BitVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self { diff -Nru cargo-0.33.0/vendor/bstr/.cargo-checksum.json cargo-0.35.0/vendor/bstr/.cargo-checksum.json --- cargo-0.33.0/vendor/bstr/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"853b090ce0f45d0265902666bf88039ea3da825e33796716c511a1ec9c170036"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/bstr/Cargo.toml cargo-0.35.0/vendor/bstr/Cargo.toml --- cargo-0.33.0/vendor/bstr/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,68 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "bstr" +version = "0.1.3" +authors = ["Andrew Gallant "] +exclude = ["/ci/*", "/.travis.yml", "/appveyor.yml"] +description = "A string type that is not required to be valid UTF-8." +homepage = "https://github.com/BurntSushi/bstr" +documentation = "https://docs.rs/bstr" +readme = "README.md" +keywords = ["string", "str", "byte", "bytes", "text"] +categories = ["text-processing", "encoding"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/BurntSushi/bstr" +[profile.release] +debug = true + +[lib] +bench = false +[dependencies.lazy_static] +version = "1.2" +optional = true + +[dependencies.memchr] +version = "2.1.2" +default-features = false + +[dependencies.regex-automata] +version = "0.1.5" +optional = true +default-features = false + +[dependencies.serde] +version = "1.0.85" +optional = true +default-features = false +[dev-dependencies.quickcheck] +version = "0.8.1" +default-features = false + +[dev-dependencies.ucd-parse] +version = "0.1.3" + +[dev-dependencies.unicode-segmentation] +version = "1.2.1" + +[features] +default = ["std", "unicode"] +serde1 = ["std", "serde1-nostd", "serde/std"] +serde1-nostd = ["serde"] +std = ["memchr/use_std"] +unicode = ["lazy_static", "regex-automata"] +[badges.appveyor] +repository = "BurntSushi/bstr" + +[badges.travis-ci] +repository = "BurntSushi/bstr" diff -Nru cargo-0.33.0/vendor/bstr/COPYING cargo-0.35.0/vendor/bstr/COPYING --- cargo-0.33.0/vendor/bstr/COPYING 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/COPYING 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. diff -Nru cargo-0.33.0/vendor/bstr/examples/graphemes.rs cargo-0.35.0/vendor/bstr/examples/graphemes.rs --- cargo-0.33.0/vendor/bstr/examples/graphemes.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/graphemes.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,24 @@ +extern crate bstr; + +use std::error::Error; +use std::io::{self, Write}; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + stdin.lock().for_byte_line_with_terminator(|line| { + let end = line + .grapheme_indices() + .map(|(_, end, _)| end) + .take(10) + .last() + .unwrap_or(line.len()); + stdout.write_all(line[..end].trim_end().as_bytes())?; + stdout.write_all(b"\n")?; + Ok(true) + })?; + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/graphemes-std.rs cargo-0.35.0/vendor/bstr/examples/graphemes-std.rs --- cargo-0.33.0/vendor/bstr/examples/graphemes-std.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/graphemes-std.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,28 @@ +extern crate unicode_segmentation; + +use std::error::Error; +use std::io::{self, BufRead, Write}; + +use unicode_segmentation::UnicodeSegmentation; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + let mut stdout = io::BufWriter::new(io::stdout()); + + let mut line = String::new(); + while stdin.read_line(&mut line)? > 0 { + let end = line + .grapheme_indices(true) + .map(|(start, g)| start + g.len()) + .take(10) + .last() + .unwrap_or(line.len()); + #[allow(deprecated)] // for Rust 1.28.0 + stdout.write_all(line[..end].trim_right().as_bytes())?; + stdout.write_all(b"\n")?; + + line.clear(); + } + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/lines.rs cargo-0.35.0/vendor/bstr/examples/lines.rs --- cargo-0.33.0/vendor/bstr/examples/lines.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/lines.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,19 @@ +extern crate bstr; + +use std::error::Error; +use std::io::{self, Write}; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + stdin.lock().for_byte_line_with_terminator(|line| { + if line.contains("Dimension") { + stdout.write_all(line.as_bytes())?; + } + Ok(true) + })?; + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/lines-std.rs cargo-0.35.0/vendor/bstr/examples/lines-std.rs --- cargo-0.33.0/vendor/bstr/examples/lines-std.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/lines-std.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,17 @@ +use std::error::Error; +use std::io::{self, BufRead, Write}; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + let mut stdout = io::BufWriter::new(io::stdout()); + + let mut line = String::new(); + while stdin.read_line(&mut line)? > 0 { + if line.contains("Dimension") { + stdout.write_all(line.as_bytes())?; + } + line.clear(); + } + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/uppercase.rs cargo-0.35.0/vendor/bstr/examples/uppercase.rs --- cargo-0.33.0/vendor/bstr/examples/uppercase.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/uppercase.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +extern crate bstr; + +use std::error::Error; +use std::io::{self, Write}; + +use bstr::BString; +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + let mut upper = BString::new(); + stdin.lock().for_byte_line_with_terminator(|line| { + upper.clear(); + line.to_uppercase_into(&mut upper); + stdout.write_all(upper.as_bytes())?; + Ok(true) + })?; + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/uppercase-std.rs cargo-0.35.0/vendor/bstr/examples/uppercase-std.rs --- cargo-0.33.0/vendor/bstr/examples/uppercase-std.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/uppercase-std.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,15 @@ +use std::error::Error; +use std::io::{self, BufRead, Write}; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + let mut stdout = io::BufWriter::new(io::stdout()); + + let mut line = String::new(); + while stdin.read_line(&mut line)? > 0 { + stdout.write_all(line.to_uppercase().as_bytes())?; + line.clear(); + } + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/words.rs cargo-0.35.0/vendor/bstr/examples/words.rs --- cargo-0.33.0/vendor/bstr/examples/words.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/words.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,17 @@ +extern crate bstr; + +use std::error::Error; +use std::io; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut words = 0; + stdin.lock().for_byte_line_with_terminator(|line| { + words += line.words().count(); + Ok(true) + })?; + println!("{}", words); + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/examples/words-std.rs cargo-0.35.0/vendor/bstr/examples/words-std.rs --- cargo-0.33.0/vendor/bstr/examples/words-std.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/examples/words-std.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,20 @@ +extern crate unicode_segmentation; + +use std::error::Error; +use std::io::{self, BufRead}; + +use unicode_segmentation::UnicodeSegmentation; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + + let mut words = 0; + let mut line = String::new(); + while stdin.read_line(&mut line)? > 0 { + words += line.unicode_words().count(); + line.clear(); + } + println!("{}", words); + Ok(()) +} diff -Nru cargo-0.33.0/vendor/bstr/LICENSE-APACHE cargo-0.35.0/vendor/bstr/LICENSE-APACHE --- cargo-0.33.0/vendor/bstr/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/LICENSE-APACHE 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff -Nru cargo-0.33.0/vendor/bstr/LICENSE-MIT cargo-0.35.0/vendor/bstr/LICENSE-MIT --- cargo-0.33.0/vendor/bstr/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/LICENSE-MIT 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff -Nru cargo-0.33.0/vendor/bstr/README.md cargo-0.35.0/vendor/bstr/README.md --- cargo-0.33.0/vendor/bstr/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,252 @@ +bstr +==== +This crate provides a `BString` and `BStr` types that are conventionally UTF-8 +for Rust. They differ from the standard library's `String` and `str` types in +that they are not required to be valid UTF-8, but may be fully or partially +valid UTF-8. + +[![Linux build status](https://api.travis-ci.org/BurntSushi/bstr.svg)](https://travis-ci.org/BurntSushi/bstr) +[![Windows build status](https://ci.appveyor.com/api/projects/status/github/BurntSushi/bstr?svg=true)](https://ci.appveyor.com/project/BurntSushi/bstr) +[![](http://meritbadge.herokuapp.com/bstr)](https://crates.io/crates/bstr) + + +### Documentation + +https://docs.rs/bstr + + +### When should I use byte strings? + +See this part of the documentation for more details: +https://docs.rs/bstr/0.1.0/bstr/#when-should-i-use-byte-strings. + +The short story is that byte strings are useful when it is inconvenient or +incorrect to require valid UTF-8. + + +### Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +bstr = "0.1" +``` + + +### Examples + +The following two examples exhibit both the API features of byte strings and +the I/O convenience functions provided for reading line-by-line quickly. + +This first example simply shows how to efficiently iterate over lines in +stdin, and print out lines containing a particular substring: + +```rust +use std::error::Error; +use std::io::{self, Write}; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + stdin.lock().for_byte_line_with_terminator(|line| { + if line.contains("Dimension") { + stdout.write_all(line.as_bytes())?; + } + Ok(true) + })?; + Ok(()) +} +``` + +This example shows how to count all of the words (Unicode-aware) in stdin, +line-by-line: + +```rust +use std::error::Error; +use std::io; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut words = 0; + stdin.lock().for_byte_line_with_terminator(|line| { + words += line.words().count(); + Ok(true) + })?; + println!("{}", words); + Ok(()) +} +``` + +This example shows how to convert a stream on stdin to uppercase without +performing UTF-8 validation _and_ amortizing allocation. On standard ASCII +text, this is quite a bit faster than what you can (easily) do with standard +library APIs. (N.B. Any invalid UTF-8 bytes are passed through unchanged.) + +```rust +use std::error::Error; +use std::io::{self, Write}; + +use bstr::BString; +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + let mut upper = BString::new(); + stdin.lock().for_byte_line_with_terminator(|line| { + upper.clear(); + line.to_uppercase_into(&mut upper); + stdout.write_all(upper.as_bytes())?; + Ok(true) + })?; + Ok(()) +} +``` + +This example shows how to extract the first 10 visual characters (as grapheme +clusters) from each line, where invalid UTF-8 sequences are generally treated +as a single character and are passed through correctly: + +```rust +use std::error::Error; +use std::io::{self, Write}; + +use bstr::io::BufReadExt; + +fn main() -> Result<(), Box> { + let stdin = io::stdin(); + let mut stdout = io::BufWriter::new(io::stdout()); + + stdin.lock().for_byte_line_with_terminator(|line| { + let end = line + .grapheme_indices() + .map(|(_, end, _)| end) + .take(10) + .last() + .unwrap_or(line.len()); + stdout.write_all(line[..end].trim_end().as_bytes())?; + stdout.write_all(b"\n")?; + Ok(true) + })?; + Ok(()) +} +``` + + +### Cargo features + +This crates comes with a few features that control standard library, serde +and Unicode support. + +* `std` - **Enabled** by default. This provides APIs that require the standard + library, such as `BString`. +* `unicode` - **Enabled** by default. This provides APIs that require sizable + Unicode data compiled into the binary. This includes, but is not limited to, + grapheme/word/sentence segmenters. When this is disabled, basic support such + as UTF-8 decoding is still included. +* `serde1` - **Disabled** by default. Enables implementations of serde traits + for the `BStr` and `BString` types. +* `serde1-nostd` - **Disabled** by default. Enables implementations of serde + traits for the `BStr` type only, intended for use without the standard + library. Generally, you either want `serde1` or `serde1-nostd`, not both. + + +### Minimum Rust version policy + +This crate's minimum supported `rustc` version (MSRV) is `1.28.0`. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. MSRV may be bumped in minor version releases. + + +### Future work + +Since this is meant to be a core crate, getting a `1.0` release is a priority. +My hope is to move to `1.0` within the next year and commit to its API so that +`bstr` can be used as a public dependency. + +A large part of the API surface area was taken from the standard library, so +from an API design perspective, a good portion of this crate should be mature. +The main differences from the standard library are in how the various substring +search routines work. The standard library provides generic infrastructure for +supporting different types of searches with a single method, where as this +library prefers to define new methods for each type of search and drop the +generic infrastructure. + +Some _probable_ future considerations for APIs include, but are not limited to: + +* A convenience layer on top of the `aho-corasick` crate. +* Unicode normalization. +* More sophisticated support for dealing with Unicode case, perhaps by + combining the use cases supported by [`caseless`](http://docs.rs/caseless) + and [`unicase`](https://docs.rs/unicase). +* Add facilities for dealing with OS strings and file paths, probably via + simple conversion routines. + +Here are some examples that are _probably_ out of scope for this crate: + +* Regular expressions. +* Unicode collation. + +The exact scope isn't quite clear, but I expect we can iterate on it. + +In general, as stated below, this crate is an experiment in bringing lots of +related APIs together into a single crate while simultaneously attempting to +keep the total number of dependencies low. Indeed, every dependency of `bstr`, +except for `memchr`, is optional. + + +### High level motivation + +Strictly speaking, the `bstr` crate provides very little that can't already be +achieved with a `Vec`/`&[u8]` and the ecosystem of library crates. For +example: + +* The standard library's + [`Utf8Error`](https://doc.rust-lang.org/std/str/struct.Utf8Error.html) + can be used for incremental lossy decoding of `&[u8]`. +* The + [`unicode-segmentation`](https://unicode-rs.github.io/unicode-segmentation/unicode_segmentation/index.html) + crate can be used for iterating over graphemes (or words), but is only + implemented for `&str` types. One could use `Utf8Error` above to implement + grapheme iteration with the same semantics as what `bstr` provides (automatic + Unicode replacement codepoint substitution). +* The [`twoway`](https://docs.rs/twoway/0.2.0/twoway/) crate can be used for + fast substring searching on `&[u8]`. + +So why create `bstr`? Part of the point of the `bstr` crate is to provide a +uniform API of coupled components instead of relying on users to piece together +loosely coupled components from the crate ecosystem. For example, if you wanted +to perform a search and replace in a `Vec`, then writing the code to do +that with the `twoway` crate is not that difficult, but it's still additional +glue code you have to write. This work adds up depending on what you're doing. +Consider, for example, trimming and splitting, along with their different +variants. + +In other words, `bstr` is partially a way of pushing back against the +micro-crate ecosystem that appears to be evolving. It's not clear to me whether +this experiment will be successful or not, but it is definitely a goal of +`bstr` to keep its dependency list lightweight. For example, `serde` is an +optional dependency because there is no feasible alternative, but `twoway` is +not, where we instead prefer to implement our own substring search. In service +of this philosophy, currently, the only required dependency of `bstr` is +`memchr`. + + +### License + +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. diff -Nru cargo-0.33.0/vendor/bstr/rustfmt.toml cargo-0.35.0/vendor/bstr/rustfmt.toml --- cargo-0.33.0/vendor/bstr/rustfmt.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/rustfmt.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +disable_all_formatting = true diff -Nru cargo-0.33.0/vendor/bstr/scripts/generate-unicode-data cargo-0.35.0/vendor/bstr/scripts/generate-unicode-data --- cargo-0.33.0/vendor/bstr/scripts/generate-unicode-data 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/scripts/generate-unicode-data 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,150 @@ +#!/bin/sh + +set -e +D="$(dirname "$0")" + +# Convenience function for checking that a command exists. +requires() { + cmd="$1" + if ! command -v "$cmd" > /dev/null 2>&1; then + echo "DEPENDENCY MISSING: $cmd must be installed" >&2 + exit 1 + fi +} + +# Test if an array ($2) contains a particular element ($1). +array_exists() { + needle="$1" + shift + + for el in "$@"; do + if [ "$el" = "$needle" ]; then + return 0 + fi + done + return 1 +} + +graphemes() { + regex="$(sh "$D/regex/grapheme.sh")" + + echo "generating forward grapheme DFA" + ucd-generate dfa \ + --name GRAPHEME_BREAK_FWD \ + --sparse --minimize --anchored --state-size 2 \ + src/unicode/fsm/ \ + "$regex" + + echo "generating reverse grapheme DFA" + ucd-generate dfa \ + --name GRAPHEME_BREAK_REV \ + --reverse --longest \ + --sparse --minimize --anchored --state-size 2 \ + src/unicode/fsm/ \ + "$regex" +} + +words() { + regex="$(sh "$D/regex/word.sh")" + + echo "generating forward word DFA (this can take a while)" + ucd-generate dfa \ + --name WORD_BREAK_FWD \ + --sparse --minimize --anchored --state-size 4 \ + src/unicode/fsm/ \ + "$regex" +} + +sentences() { + regex="$(sh "$D/regex/sentence.sh")" + + echo "generating forward sentence DFA (this can take a while)" + ucd-generate dfa \ + --name SENTENCE_BREAK_FWD \ + --minimize \ + --sparse --anchored --state-size 4 \ + src/unicode/fsm/ \ + "$regex" +} + +regional_indicator() { + # For finding all occurrences of region indicators. This is used to handle + # regional indicators as a special case for the reverse grapheme iterator + # and the reverse word iterator. + echo "generating regional indicator DFA" + ucd-generate dfa \ + --name REGIONAL_INDICATOR_REV \ + --reverse \ + --classes --minimize --anchored --premultiply --state-size 1 \ + src/unicode/fsm/ \ + "\p{gcb=Regional_Indicator}" +} + +simple_word() { + echo "generating forward simple word DFA" + ucd-generate dfa \ + --name SIMPLE_WORD_FWD \ + --sparse --minimize --state-size 2 \ + src/unicode/fsm/ \ + "\w" +} + +whitespace() { + echo "generating forward whitespace DFA" + ucd-generate dfa \ + --name WHITESPACE_ANCHORED_FWD \ + --anchored --classes --premultiply --minimize --state-size 1 \ + src/unicode/fsm/ \ + "\s+" + + echo "generating reverse whitespace DFA" + ucd-generate dfa \ + --name WHITESPACE_ANCHORED_REV \ + --reverse \ + --anchored --classes --minimize --state-size 1 \ + src/unicode/fsm/ \ + "\s+" +} + +main() { + if array_exists "-h" "$@" || array_exists "--help" "$@"; then + echo "Usage: $(basename "$0") [--list-commands] [] ..." >&2 + exit + fi + + commands=" + graphemes + sentences + words + regional-indicator + simple-word + whitespace + " + if array_exists "--list-commands" "$@"; then + for cmd in $commands; do + echo "$cmd" + done + exit + fi + + # ucd-generate is used to compile regexes into DFAs. + requires ucd-generate + + # For development when ucd-generate needs to be updated. + cargo install -f --path /home/andrew/rust/ucd-generate + + all= + if [ $# -eq 0 ] || array_exists "all" "$@"; then + all=yes + fi + for cmd in "$@"; do + if [ -n "$all" ] || array_exists "$cmd" $commands; then + fun="$(echo "$cmd" | sed 's/-/_/g')" + eval "$fun" + else + echo "unrecognized command: $cmd" >&2 + fi + done +} + +main "$@" diff -Nru cargo-0.33.0/vendor/bstr/scripts/regex/grapheme.sh cargo-0.35.0/vendor/bstr/scripts/regex/grapheme.sh --- cargo-0.33.0/vendor/bstr/scripts/regex/grapheme.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/scripts/regex/grapheme.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,50 @@ +#!/bin/sh + +# vim: indentexpr= nosmartindent autoindent +# vim: tabstop=2 shiftwidth=2 softtabstop=2 + +# This regex was manually written, derived from the rules in UAX #29. +# Particularly, from Table 1c, which lays out a regex for grapheme clusters. + +CR="\p{gcb=CR}" +LF="\p{gcb=LF}" +Control="\p{gcb=Control}" +Prepend="\p{gcb=Prepend}" +L="\p{gcb=L}" +V="\p{gcb=V}" +LV="\p{gcb=LV}" +LVT="\p{gcb=LVT}" +T="\p{gcb=T}" +RI="\p{gcb=RI}" +Extend="\p{gcb=Extend}" +ZWJ="\p{gcb=ZWJ}" +SpacingMark="\p{gcb=SpacingMark}" + +Any="\p{any}" +ExtendPict="\p{Extended_Pictographic}" + +echo "(?x) +$CR $LF +| +$Control +| +$Prepend* +( + ( + ($L* ($V+ | $LV $V* | $LVT) $T*) + | + $L+ + | + $T+ + ) + | + $RI $RI + | + $ExtendPict ($Extend* $ZWJ $ExtendPict)* + | + [^$Control $CR $LF] +) +[$Extend $ZWJ $SpacingMark]* +| +$Any +" diff -Nru cargo-0.33.0/vendor/bstr/scripts/regex/sentence.sh cargo-0.35.0/vendor/bstr/scripts/regex/sentence.sh --- cargo-0.33.0/vendor/bstr/scripts/regex/sentence.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/scripts/regex/sentence.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,176 @@ +#!/bin/sh + +# vim: indentexpr= nosmartindent autoindent +# vim: tabstop=2 shiftwidth=2 softtabstop=2 + +# This is a regex that I reverse engineered from the sentence boundary chain +# rules in UAX #29. Unlike the grapheme regex, which is essentially provided +# for us in UAX #29, no such sentence regex exists. +# +# I looked into how ICU achieves this, since UAX #29 hints that producing +# finite state machines for grapheme/sentence/word/line breaking is possible, +# but only easy to do for graphemes. ICU does this by implementing their own +# DSL for describing the break algorithms in terms of the chaining rules +# directly. You can see an example for sentences in +# icu4c/source/data/brkitr/rules/sent.txt. ICU then builds a finite state +# machine from those rules in a mostly standard way, but implements the +# "chaining" aspect of the rules by connecting overlapping end and start +# states. For example, given SB7: +# +# (Upper | Lower) ATerm x Upper +# +# Then the naive way to convert this into a regex would be something like +# +# [\p{sb=Upper}\p{sb=Lower}]\p{sb=ATerm}\p{sb=Upper} +# +# Unfortunately, this is incorrect. Why? Well, consider an example like so: +# +# U.S.A. +# +# A correct implementation of the sentence breaking algorithm should not insert +# any breaks here, exactly in accordance with repeatedly applying rule SB7 as +# given above. Our regex fails to do this because it will first match `U.S` +# without breaking them---which is correct---but will then start looking for +# its next rule beginning with a full stop (in ATerm) and followed by an +# uppercase letter (A). This will wind up triggering rule SB11 (without +# matching `A`), which inserts a break. +# +# The reason why this happens is because our initial application of rule SB7 +# "consumes" the next uppercase letter (S), which we want to reuse as a prefix +# in the next rule application. A natural way to express this would be with +# look-around, although it's not clear that works in every case since you +# ultimately might want to consume that ending uppercase letter. In any case, +# we can't use look-around in our truly regular regexes, so we must fix this. +# The approach we take is to explicitly repeat rules when a suffix of a rule +# is a prefix of another rule. In the case of SB7, the end of the rule, an +# uppercase letter, also happens to match the beginning of the rule. This can +# in turn be repeated indefinitely. Thus, our actual translation to a regex is: +# +# [\p{sb=Upper}\p{sb=Lower}]\p{sb=ATerm}\p{sb=Upper}(\p{sb=ATerm}\p{sb=Upper}* +# +# It turns out that this is exactly what ICU does, but in their case, they do +# it automatically. In our case, we connect the chaining rules manually. It's +# tedious. With that said, we do no implement Unicode line breaking with this +# approach, which is a far scarier beast. In that case, it would probably be +# worth writing the code to do what ICU does. +# +# In the case of sentence breaks, there aren't *too* many overlaps of this +# nature. We list them out exhaustively to make this clear, because it's +# essentially impossible to easily observe this in the regex. (It took me a +# full day to figure all of this out.) Rules marked with N/A mean that they +# specify a break, and this strategy only really applies to stringing together +# non-breaks. +# +# SB1 - N/A +# SB2 - N/A +# SB3 - None +# SB4 - N/A +# SB5 - None +# SB6 - None +# SB7 - End overlaps with beginning of SB7 +# SB8 - End overlaps with beginning of SB7 +# SB8a - End overlaps with beginning of SB6, SB8, SB8a, SB9, SB10, SB11 +# SB9 - None +# SB10 - None +# SB11 - None +# SB998 - N/A +# +# SB8a is in particular quite tricky to get right without look-ahead, since it +# allows ping-ponging between match rules SB8a and SB9-11, where SB9-11 +# otherwise indicate that a break has been found. In the regex below, we tackle +# this by only permitting part of SB8a to match inside our core non-breaking +# repetition. In particular, we only allow the parts of SB8a to match that +# permit the non-breaking components to continue. If a part of SB8a matches +# that guarantees a pop out to SB9-11, (like `STerm STerm`), then we let it +# happen. This still isn't correct because an SContinue might be seen which +# would allow moving back into SB998 and thus the non-breaking repetition, so +# we handle that case as well. +# +# Finally, the last complication here is the sprinkling of $Ex* everywhere. +# This essentially corresponds to the implementation of SB5 by following +# UAX #29's recommendation in S6.2. Essentially, we use it avoid ever breaking +# in the middle of a grapheme cluster. + +CR="\p{sb=CR}" +LF="\p{sb=LF}" +Sep="\p{sb=Sep}" +Close="\p{sb=Close}" +Sp="\p{sb=Sp}" +STerm="\p{sb=STerm}" +ATerm="\p{sb=ATerm}" +SContinue="\p{sb=SContinue}" +Numeric="\p{sb=Numeric}" +Upper="\p{sb=Upper}" +Lower="\p{sb=Lower}" +OLetter="\p{sb=OLetter}" + +Ex="[\p{sb=Extend}\p{sb=Format}]" +ParaSep="[$Sep $CR $LF]" +SATerm="[$STerm $ATerm]" + +LetterSepTerm="[$OLetter $Upper $Lower $ParaSep $SATerm]" + +echo "(?x) +( + # SB6 + $ATerm $Ex* + $Numeric + | + # SB7 + [$Upper $Lower] $Ex* $ATerm $Ex* + $Upper $Ex* + # overlap with SB7 + ($ATerm $Ex* $Upper $Ex*)* + | + # SB8 + $ATerm $Ex* $Close* $Ex* $Sp* $Ex* + ([^$LetterSepTerm] $Ex*)* $Lower $Ex* + # overlap with SB7 + ($ATerm $Ex* $Upper $Ex*)* + | + # SB8a + $SATerm $Ex* $Close* $Ex* $Sp* $Ex* + ( + $SContinue + | + $ATerm $Ex* + # Permit repetition of SB8a + (($Close $Ex*)* ($Sp $Ex*)* $SATerm)* + # In order to continue non-breaking matching, we now must observe + # a match with a rule that keeps us in SB6-8a. Otherwise, we've entered + # one of SB9-11 and know that a break must follow. + ( + # overlap with SB6 + $Numeric + | + # overlap with SB8 + ($Close $Ex*)* ($Sp $Ex*)* + ([^$LetterSepTerm] $Ex*)* $Lower $Ex* + # overlap with SB7 + ($ATerm $Ex* $Upper $Ex*)* + | + # overlap with SB8a + ($Close $Ex*)* ($Sp $Ex*)* $SContinue + ) + | + $STerm $Ex* + # Permit repetition of SB8a + (($Close $Ex*)* ($Sp $Ex*)* $SATerm)* + # As with ATerm above, in order to continue non-breaking matching, we + # must now observe a match with a rule that keeps us out of SB9-11. + # For STerm, the only such possibility is to see an SContinue. Anything + # else will result in a break. + ($Close $Ex*)* ($Sp $Ex*)* $SContinue + ) + | + # SB998 + # The logic behind this catch-all is that if we get to this point and + # see a Sep, CR, LF, STerm or ATerm, then it has to fall into one of + # SB9, SB10 or SB11. In the cases of SB9-11, we always find a break since + # SB11 acts as a catch-all to induce a break following a SATerm that isn't + # handled by rules SB6-SB8a. + [^$ParaSep $SATerm] +)* +# The following collapses rules SB3, SB4, part of SB8a, SB9, SB10 and SB11. +($SATerm $Ex* ($Close $Ex*)* ($Sp $Ex*)*)* ($CR $LF | $ParaSep)? +" diff -Nru cargo-0.33.0/vendor/bstr/scripts/regex/word.sh cargo-0.35.0/vendor/bstr/scripts/regex/word.sh --- cargo-0.33.0/vendor/bstr/scripts/regex/word.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/scripts/regex/word.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,111 @@ +#!/bin/sh + +# vim: indentexpr= nosmartindent autoindent +# vim: tabstop=2 shiftwidth=2 softtabstop=2 + +# See the comments in regex/sentence.sh for the general approach to how this +# regex was written. +# +# Writing the regex for this was *hard*. It took me two days of hacking to get +# this far, and that was after I had finished the sentence regex, so my brain +# was fully cached on this. Unlike the sentence regex, the rules in the regex +# below don't correspond as nicely to the rules in UAX #29. In particular, the +# UAX #29 rules have a ton of overlap with each other, which requires crazy +# stuff in the regex. I'm not even sure the regex below is 100% correct or even +# minimal, however, I did compare this with the ICU word segmenter on a few +# different corpora, and it produces identical results. (In addition to of +# course passing the UCD tests.) +# +# In general, I consider this approach to be a failure. Firstly, this is +# clearly a write-only regex. Secondly, building the minimized DFA for this is +# incredibly slow. Thirdly, the DFA is itself very large (~240KB). Fourthly, +# reversing this regex (for reverse word iteration) results in a >19MB DFA. +# Yes. That's MB. Wat. And it took 5 minutes to build. +# +# I think we might consider changing our approach to this problem. The normal +# path I've seen, I think, is to decode codepoints one at a time, and then +# thread them through a state machine in the code itself. We could take this +# approach, or possibly combine it with a DFA that tells us which Word_Break +# value a codepoint has. I'd prefer the latter approach, but it requires adding +# RegexSet support to regex-automata. Something that should definitely be done, +# but is a fair amount of work. +# +# Gah. + +CR="\p{wb=CR}" +LF="\p{wb=LF}" +Newline="\p{wb=Newline}" +ZWJ="\p{wb=ZWJ}" +RI="\p{wb=Regional_Indicator}" +Katakana="\p{wb=Katakana}" +HebrewLet="\p{wb=HebrewLetter}" +ALetter="\p{wb=ALetter}" +SingleQuote="\p{wb=SingleQuote}" +DoubleQuote="\p{wb=DoubleQuote}" +MidNumLet="\p{wb=MidNumLet}" +MidLetter="\p{wb=MidLetter}" +MidNum="\p{wb=MidNum}" +Numeric="\p{wb=Numeric}" +ExtendNumLet="\p{wb=ExtendNumLet}" +WSegSpace="\p{wb=WSegSpace}" + +Any="\p{any}" +Ex="[\p{wb=Extend} \p{wb=Format} $ZWJ]" +ExtendPict="\p{Extended_Pictographic}" +AHLetter="[$ALetter $HebrewLet]" +MidNumLetQ="[$MidNumLet $SingleQuote]" + +AHLetterRepeat="$AHLetter $Ex* ([$MidLetter $MidNumLetQ] $Ex* $AHLetter $Ex*)*" +NumericRepeat="$Numeric $Ex* ([$MidNum $MidNumLetQ] $Ex* $Numeric $Ex*)*" + +echo "(?x) +$CR $LF +| +[$Newline $CR $LF] +| +$WSegSpace $WSegSpace+ +| +( + ([^$Newline $CR $LF]? $Ex* $ZWJ $ExtendPict $Ex*)+ + | + ($ExtendNumLet $Ex*)* $AHLetter $Ex* + ( + ( + ($NumericRepeat | $ExtendNumLet $Ex*)* + | + [$MidLetter $MidNumLetQ] $Ex* + ) + $AHLetter $Ex* + )+ + ($NumericRepeat | $ExtendNumLet $Ex*)* + | + ($ExtendNumLet $Ex*)* $AHLetter $Ex* ($NumericRepeat | $ExtendNumLet $Ex*)+ + | + ($ExtendNumLet $Ex*)* $Numeric $Ex* + ( + ( + ($AHLetterRepeat | $ExtendNumLet $Ex*)* + | + [$MidNum $MidNumLetQ] $Ex* + ) + $Numeric $Ex* + )+ + ($AHLetterRepeat | $ExtendNumLet $Ex*)* + | + ($ExtendNumLet $Ex*)* $Numeric $Ex* ($AHLetterRepeat | $ExtendNumLet $Ex*)+ + | + $Katakana $Ex* + (($Katakana | $ExtendNumLet) $Ex*)+ + | + $ExtendNumLet $Ex* + (($ExtendNumLet | $AHLetter | $Numeric | $Katakana) $Ex*)+ +)+ +| +$HebrewLet $Ex* $SingleQuote $Ex* +| +($HebrewLet $Ex* $DoubleQuote $Ex*)+ $HebrewLet $Ex* +| +$RI $Ex* $RI $Ex* +| +$Any $Ex* +" diff -Nru cargo-0.33.0/vendor/bstr/src/ascii.rs cargo-0.35.0/vendor/bstr/src/ascii.rs --- cargo-0.33.0/vendor/bstr/src/ascii.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/ascii.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,322 @@ +use core::mem; + +// The following ~400 lines of code exists for exactly one purpose, which is +// to optimize this code: +// +// byte_slice.iter().position(|&b| b > 0x7F).unwrap_or(byte_slice.len()) +// +// Yes... Overengineered is a word that comes to mind, but this is effectively +// a very similar problem to memchr, and virtually nobody has been able to +// resist optimizing the crap out of that (except for perhaps the BSD and MUSL +// folks). In particular, this routine makes a very common case (ASCII) very +// fast, which seems worth it. We do stop short of adding AVX variants of the +// code below in order to retain our sanity and also to avoid needing to deal +// with runtime target feature detection. RESIST! +// +// In order to understand the SIMD version below, it would be good to read this +// comment describing how my memchr routine works: +// https://github.com/BurntSushi/rust-memchr/blob/b0a29f267f4a7fad8ffcc8fe8377a06498202883/src/x86/sse2.rs#L19-L106 +// +// The primary difference with memchr is that for ASCII, we can do a bit less +// work. In particular, we don't need to detect the presence of a specific +// byte, but rather, whether any byte has its most significant bit set. That +// means we can effectively skip the _mm_cmpeq_epi8 step and jump straight to +// _mm_movemask_epi8. + +#[cfg(any(test, not(target_arch = "x86_64")))] +const USIZE_BYTES: usize = mem::size_of::(); +#[cfg(any(test, not(target_arch = "x86_64")))] +const FALLBACK_LOOP_SIZE: usize = 2 * USIZE_BYTES; + +// This is a mask where the most significant bit of each byte in the usize +// is set. We test this bit to determine whether a character is ASCII or not. +// Namely, a single byte is regarded as an ASCII codepoint if and only if it's +// most significant bit is not set. +#[cfg(any(test, not(target_arch = "x86_64")))] +const ASCII_MASK_U64: u64 = 0x8080808080808080; +#[cfg(any(test, not(target_arch = "x86_64")))] +const ASCII_MASK: usize = ASCII_MASK_U64 as usize; + +/// Returns the index of the first non ASCII byte in the given slice. +/// +/// If slice only contains ASCII bytes, then the length of the slice is +/// returned. +pub fn first_non_ascii_byte(slice: &[u8]) -> usize { + #[cfg(not(target_arch = "x86_64"))] + { + first_non_ascii_byte_fallback(slice) + } + + #[cfg(target_arch = "x86_64")] + { + first_non_ascii_byte_sse2(slice) + } +} + +#[cfg(any(test, not(target_arch = "x86_64")))] +fn first_non_ascii_byte_fallback(slice: &[u8]) -> usize { + let align = USIZE_BYTES - 1; + let start_ptr = slice.as_ptr(); + let end_ptr = slice[slice.len()..].as_ptr(); + let mut ptr = start_ptr; + + unsafe { + if slice.len() < USIZE_BYTES { + return first_non_ascii_byte_slow(start_ptr, end_ptr, ptr); + } + + let chunk = read_unaligned_usize(ptr); + let mask = chunk & ASCII_MASK; + if mask != 0 { + return first_non_ascii_byte_mask(mask); + } + + ptr = ptr_add(ptr, USIZE_BYTES - (start_ptr as usize & align)); + debug_assert!(ptr > start_ptr); + debug_assert!(ptr_sub(end_ptr, USIZE_BYTES) >= start_ptr); + if slice.len() >= FALLBACK_LOOP_SIZE { + while ptr <= ptr_sub(end_ptr, FALLBACK_LOOP_SIZE) { + debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES); + + let a = *(ptr as *const usize); + let b = *(ptr_add(ptr, USIZE_BYTES) as *const usize); + if (a | b) & ASCII_MASK != 0 { + // What a kludge. We wrap the position finding code into + // a non-inlineable function, which makes the codegen in + // the tight loop above a bit better by avoiding a + // couple extra movs. We pay for it by two additional + // stores, but only in the case of finding a non-ASCII + // byte. + #[inline(never)] + unsafe fn findpos( + start_ptr: *const u8, + ptr: *const u8, + ) -> usize { + let a = *(ptr as *const usize); + let b = *(ptr_add(ptr, USIZE_BYTES) as *const usize); + + let mut at = sub(ptr, start_ptr); + let maska = a & ASCII_MASK; + if maska != 0 { + return at + first_non_ascii_byte_mask(maska); + } + + at += USIZE_BYTES; + let maskb = b & ASCII_MASK; + debug_assert!(maskb != 0); + return at + first_non_ascii_byte_mask(maskb); + } + return findpos(start_ptr, ptr); + } + ptr = ptr_add(ptr, FALLBACK_LOOP_SIZE); + } + } + first_non_ascii_byte_slow(start_ptr, end_ptr, ptr) + } +} + +#[cfg(target_arch = "x86_64")] +fn first_non_ascii_byte_sse2(slice: &[u8]) -> usize { + use core::arch::x86_64::*; + + const VECTOR_SIZE: usize = mem::size_of::<__m128i>(); + const VECTOR_ALIGN: usize = VECTOR_SIZE - 1; + const VECTOR_LOOP_SIZE: usize = 4 * VECTOR_SIZE; + + let start_ptr = slice.as_ptr(); + let end_ptr = slice[slice.len()..].as_ptr(); + let mut ptr = start_ptr; + + unsafe { + if slice.len() < VECTOR_SIZE { + return first_non_ascii_byte_slow(start_ptr, end_ptr, ptr); + } + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let mask = _mm_movemask_epi8(chunk); + if mask != 0 { + return mask.trailing_zeros() as usize; + } + + ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN)); + debug_assert!(ptr > start_ptr); + debug_assert!(end_ptr.sub(VECTOR_SIZE) >= start_ptr); + if slice.len() >= VECTOR_LOOP_SIZE { + while ptr <= ptr_sub(end_ptr, VECTOR_LOOP_SIZE) { + debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE); + + let a = _mm_load_si128(ptr as *const __m128i); + let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i); + let c = _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i); + let d = _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i); + + let or1 = _mm_or_si128(a, b); + let or2 = _mm_or_si128(c, d); + let or3 = _mm_or_si128(or1, or2); + if _mm_movemask_epi8(or3) != 0 { + let mut at = sub(ptr, start_ptr); + let mask = _mm_movemask_epi8(a); + if mask != 0 { + return at + mask.trailing_zeros() as usize; + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(b); + if mask != 0 { + return at + mask.trailing_zeros() as usize; + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(c); + if mask != 0 { + return at + mask.trailing_zeros() as usize; + } + + at += VECTOR_SIZE; + let mask = _mm_movemask_epi8(d); + debug_assert!(mask != 0); + return at + mask.trailing_zeros() as usize; + } + ptr = ptr_add(ptr, VECTOR_LOOP_SIZE); + } + } + while ptr <= end_ptr.sub(VECTOR_SIZE) { + debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE); + + let chunk = _mm_loadu_si128(ptr as *const __m128i); + let mask = _mm_movemask_epi8(chunk); + if mask != 0 { + return sub(ptr, start_ptr) + mask.trailing_zeros() as usize; + } + ptr = ptr.add(VECTOR_SIZE); + } + first_non_ascii_byte_slow(start_ptr, end_ptr, ptr) + } +} + +#[inline(always)] +unsafe fn first_non_ascii_byte_slow( + start_ptr: *const u8, + end_ptr: *const u8, + mut ptr: *const u8, +) -> usize { + debug_assert!(start_ptr <= ptr); + debug_assert!(ptr <= end_ptr); + + while ptr < end_ptr { + if *ptr > 0x7F { + return sub(ptr, start_ptr); + } + ptr = ptr.offset(1); + } + sub(end_ptr, start_ptr) +} + +/// Compute the position of the first ASCII byte in the given mask. +/// +/// The mask should be computed by `chunk & ASCII_MASK`, where `chunk` is +/// 8 contiguous bytes of the slice being checked where *at least* one of those +/// bytes is not an ASCII byte. +/// +/// The position returned is always in the inclusive range [0, 7]. +#[cfg(any(test, not(target_arch = "x86_64")))] +fn first_non_ascii_byte_mask(mask: usize) -> usize { + #[cfg(target_endian = "little")] + { mask.trailing_zeros() as usize / 8 } + #[cfg(target_endian = "big")] + { mask.leading_zeros() as usize / 8 } +} + +/// Increment the given pointer by the given amount. +unsafe fn ptr_add(ptr: *const u8, amt: usize) -> *const u8 { + debug_assert!(amt < ::core::isize::MAX as usize); + ptr.offset(amt as isize) +} + +/// Decrement the given pointer by the given amount. +unsafe fn ptr_sub(ptr: *const u8, amt: usize) -> *const u8 { + debug_assert!(amt < ::core::isize::MAX as usize); + ptr.offset((amt as isize).wrapping_neg()) +} + +#[cfg(any(test, not(target_arch = "x86_64")))] +unsafe fn read_unaligned_usize(ptr: *const u8) -> usize { + use core::ptr; + + let mut n: usize = 0; + ptr::copy_nonoverlapping(ptr, &mut n as *mut _ as *mut u8, USIZE_BYTES); + n +} + +/// Subtract `b` from `a` and return the difference. `a` should be greater than +/// or equal to `b`. +fn sub(a: *const u8, b: *const u8) -> usize { + debug_assert!(a >= b); + (a as usize) - (b as usize) +} + +#[cfg(test)] +mod tests { + use super::*; + + // Our testing approach here is to try and exhaustively test every case. + // This includes the position at which a non-ASCII byte occurs in addition + // to the alignment of the slice that we're searching. + + #[test] + fn positive_fallback_forward() { + for i in 0..517 { + let s = "a".repeat(i); + assert_eq!( + i, + first_non_ascii_byte_fallback(s.as_bytes()), + "i: {:?}, len: {:?}, s: {:?}", + i, s.len(), s + ); + } + } + + #[test] + #[cfg(target_arch = "x86_64")] + fn positive_sse2_forward() { + for i in 0..517 { + let b = "a".repeat(i).into_bytes(); + assert_eq!(b.len(), first_non_ascii_byte_sse2(&b)); + } + } + + #[test] + fn negative_fallback_forward() { + for i in 0..517 { + for align in 0..65 { + let mut s = "a".repeat(i); + s.push_str("☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"); + let s = s.get(align..).unwrap_or(""); + assert_eq!( + i.saturating_sub(align), + first_non_ascii_byte_fallback(s.as_bytes()), + "i: {:?}, align: {:?}, len: {:?}, s: {:?}", + i, align, s.len(), s + ); + } + } + } + + #[test] + #[cfg(target_arch = "x86_64")] + fn negative_sse2_forward() { + for i in 0..517 { + for align in 0..65 { + let mut s = "a".repeat(i); + s.push_str("☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"); + let s = s.get(align..).unwrap_or(""); + assert_eq!( + i.saturating_sub(align), + first_non_ascii_byte_sse2(s.as_bytes()), + "i: {:?}, align: {:?}, len: {:?}, s: {:?}", + i, align, s.len(), s + ); + } + } + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/bstring.rs cargo-0.35.0/vendor/bstr/src/bstring.rs --- cargo-0.33.0/vendor/bstr/src/bstring.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/bstring.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1588 @@ +use std::borrow::Cow; +use std::error; +use std::ffi::{OsStr, OsString}; +use std::fmt; +use std::iter; +use std::ops; +use std::path::{Path, PathBuf}; +use std::ptr; +use std::str; +use std::vec; + +use bstr::BStr; +use utf8::{self, Utf8Error}; + +/// Concatenate the elements given by the iterator together into a single +/// `BString`. +/// +/// The elements may be any type that can be cheaply converted into an `&[u8]`. +/// This includes, but is not limited to, `&str`, `&BStr` and `&[u8]` itself. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr; +/// +/// let s = bstr::concat(&["foo", "bar", "baz"]); +/// assert_eq!(s, "foobarbaz"); +/// ``` +#[inline] +pub fn concat( + elements: I, +) -> BString +where T: AsRef<[u8]>, + I: IntoIterator +{ + let mut dest = BString::new(); + for element in elements { + dest.push(element); + } + dest +} + +/// Join the elements given by the iterator with the given separator into a +/// single `BString`. +/// +/// Both the separator and the elements may be any type that can be cheaply +/// converted into an `&[u8]`. This includes, but is not limited to, +/// `&str`, `&BStr` and `&[u8]` itself. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr; +/// +/// let s = bstr::join(",", &["foo", "bar", "baz"]); +/// assert_eq!(s, "foo,bar,baz"); +/// ``` +#[inline] +pub fn join( + separator: B, + elements: I, +) -> BString +where B: AsRef<[u8]>, + T: AsRef<[u8]>, + I: IntoIterator +{ + let mut it = elements.into_iter(); + let mut dest = BString::new(); + match it.next() { + None => return dest, + Some(first) => { + dest.push(first); + } + } + for element in it { + dest.push(&separator); + dest.push(element); + } + dest +} + +/// A growable byte string that is conventionally UTF-8. +/// +/// A `BString` has ownership over its contents and corresponds to +/// a growable or shrinkable buffer. Its borrowed counterpart is a +/// [`BStr`](struct.BStr.html), called a byte string slice. +/// +/// # Examples +/// +/// You can create a new `BString` from a literal Unicode string or a literal +/// byte string with `BString::from`: +/// +/// ``` +/// use bstr::BString; +/// +/// let s = BString::from("Hello, world!"); +/// ``` +/// +/// You can append bytes, characters or other strings to a `BString`: +/// +/// ``` +/// use bstr::BString; +/// +/// let mut s = BString::from("Hello, "); +/// s.push_byte(b'w'); +/// s.push_char('o'); +/// s.push("rl"); +/// s.push(b"d!"); +/// assert_eq!(s, "Hello, world!"); +/// ``` +/// +/// If you have a `String` or a `Vec`, then you can create a `BString` +/// from it with zero cost: +/// +/// ``` +/// use bstr::BString; +/// +/// let s = BString::from(vec![b'f', b'o', b'o']); +/// let s = BString::from("foo".to_string()); +/// ``` +/// +/// A `BString` can be freely converted back to a `Vec`: +/// +/// ``` +/// use bstr::BString; +/// +/// let s = BString::from("foo"); +/// let vector = s.into_vec(); +/// assert_eq!(vector, vec![b'f', b'o', b'o']); +/// ``` +/// +/// However, converting from a `BString` to a `String` requires UTF-8 +/// validation: +/// +/// ``` +/// use bstr::BString; +/// +/// # fn example() -> Result<(), ::bstr::FromUtf8Error> { +/// let bytes = BString::from("hello"); +/// let string = bytes.into_string()?; +/// +/// assert_eq!("hello", string); +/// # Ok(()) }; example().unwrap() +/// ``` +/// +/// # UTF-8 +/// +/// Like byte string slices (`BStr`), a `BString` is only conventionally +/// UTF-8. This is in constrast to the standard library's `String` type, which +/// is guaranteed to be valid UTF-8. +/// +/// Because of this relaxation, types such as `Vec`, `&[u8]`, `String` and +/// `&str` can all be converted to a `BString` (or `BStr`) at zero cost without +/// any validation step. +/// +/// Moreover, this relaxation implies that many of the restrictions around +/// mutating a `String` do not apply to `BString`. Namely, if your `BString` +/// is valid UTF-8, then the various methods that mutate the `BString` do not +/// necessarily prevent you from causing the bytes to become invalid UTF-8. +/// For example: +/// +/// ``` +/// use bstr::{B, BString}; +/// +/// let mut s = BString::from("hello"); +/// s[1] = b'\xFF'; +/// // `s` was valid UTF-8, but now it's now. +/// assert_eq!(s, B(b"h\xFFllo")); +/// ``` +/// +/// # Deref +/// +/// The `BString` type implements `Deref` and `DerefMut`, where the target +/// types are `&BStr` and `&mut BStr`, respectively. `Deref` permits all of the +/// methods defined on `BStr` to be implicitly callable on any `BString`. +/// For example, the `contains` method is defined on `BStr` and not `BString`, +/// but values of type `BString` can still use it directly: +/// +/// ``` +/// use bstr::BString; +/// +/// let s = BString::from("foobarbaz"); +/// assert!(s.contains("bar")); +/// ``` +/// +/// For more information about how deref works, see the documentation for the +/// [`std::ops::Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html) +/// trait. +/// +/// # Representation +/// +/// A `BString` has the same representation as a `Vec` and a `String`. +/// That is, it is made up of three word sized components: a pointer to a +/// region of memory containing the bytes, a length and a capacity. +#[derive(Clone, Hash)] +pub struct BString { + bytes: Vec, +} + +impl BString { + /// Creates a new empty `BString`. + /// + /// Given that the `BString` is empty, this will not allocate any initial + /// buffer. While that means that this initial operation is very + /// inexpensive, it may cause excessive allocation later when you add + /// data. If you have an idea of how much data the `String` will hold, + /// consider the [`with_capacity`] method to prevent excessive + /// re-allocation. + /// + /// [`with_capacity`]: #method.with_capacity + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let s = BString::new(); + /// ``` + #[inline] + pub fn new() -> BString { + BString { bytes: vec![] } + } + + /// Creates a new empty `BString` with a particular capacity. + /// + /// `BString`s have an internal buffer to hold their data. The capacity is + /// the length of that buffer, and can be queried with the [`capacity`] + /// method. This method creates an empty `BString`, but one with an initial + /// buffer that can hold `capacity` bytes. This is useful when you may be + /// appending a bunch of data to the `BString`, reducing the number of + /// reallocations it needs to do. + /// + /// [`capacity`]: #method.capacity + /// + /// If the given capacity is `0`, no allocation will occur, and this method + /// is identical to the [`new`] method. + /// + /// [`new`]: #method.new + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::with_capacity(10); + /// + /// // The String contains no chars, even though it has capacity for more + /// assert_eq!(s.len(), 0); + /// + /// // These are all done without reallocating... + /// let cap = s.capacity(); + /// for i in 0..10 { + /// s.push_char('a'); + /// } + /// + /// assert_eq!(s.capacity(), cap); + /// + /// // ...but this may make the vector reallocate + /// s.push_char('a'); + /// ``` + #[inline] + pub fn with_capacity(capacity: usize) -> BString { + BString { bytes: Vec::with_capacity(capacity) } + } + + /// Create a new byte string from the given bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bytes = vec![b'a', b'b', b'c']; + /// let s = BString::from_vec(bytes); + /// assert_eq!("abc", s); + /// ``` + #[inline] + pub fn from_vec(bytes: Vec) -> BString { + BString { bytes } + } + + /// Create a new byte string by copying the given slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let s = BString::from_slice(b"abc"); + /// assert_eq!("abc", s); + /// ``` + #[inline] + pub fn from_slice>(slice: B) -> BString { + BString::from_vec(slice.as_ref().to_vec()) + } + + /// Create a new byte string from an owned OS string. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns the original OS string if it is not valid UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::ffi::OsString; + /// + /// use bstr::BString; + /// + /// let os_str = OsString::from("foo"); + /// let bs = BString::from_os_string(os_str).expect("must be valid UTF-8"); + /// assert_eq!(bs, "foo"); + /// ``` + #[inline] + pub fn from_os_string(os_str: OsString) -> Result { + BString::from_os_string_imp(os_str) + } + + #[cfg(unix)] + #[inline] + fn from_os_string_imp(os_str: OsString) -> Result { + use std::os::unix::ffi::OsStringExt; + + Ok(BString::from(os_str.into_vec())) + } + + #[cfg(not(unix))] + #[inline] + fn from_os_string_imp(os_str: OsString) -> Result { + os_str.into_string().map(BString::from) + } + + /// Lossily create a new byte string from an OS string slice. + /// + /// On Unix, this always succeeds, is zero cost and always returns a slice. + /// On non-Unix systems, this does a UTF-8 check. If the given OS string + /// slice is not valid UTF-8, then it is lossily decoded into valid UTF-8 + /// (with invalid bytes replaced by the Unicode replacement codepoint). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// use bstr::{B, BString}; + /// + /// let os_str = OsStr::new("foo"); + /// let bs = BString::from_os_str_lossy(os_str); + /// assert_eq!(bs, B("foo")); + /// ``` + #[inline] + pub fn from_os_str_lossy<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> { + BString::from_os_str_lossy_imp(os_str) + } + + #[cfg(unix)] + #[inline] + fn from_os_str_lossy_imp<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> { + use std::os::unix::ffi::OsStrExt; + + Cow::Borrowed(BStr::new(os_str.as_bytes())) + } + + #[cfg(not(unix))] + #[inline] + fn from_os_str_lossy_imp<'a>(os_str: &'a OsStr) -> Cow<'a, BStr> { + match os_str.to_string_lossy() { + Cow::Borrowed(x) => Cow::Borrowed(BStr::new(x)), + Cow::Owned(x) => Cow::Owned(BString::from(x)), + } + } + + /// Create a new byte string from an owned file path. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns the original path if it is not valid UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::path::PathBuf; + /// + /// use bstr::BString; + /// + /// let path = PathBuf::from("foo"); + /// let bs = BString::from_path_buf(path).expect("must be valid UTF-8"); + /// assert_eq!(bs, "foo"); + /// ``` + #[inline] + pub fn from_path_buf(path: PathBuf) -> Result { + BString::from_os_string(path.into_os_string()) + .map_err(PathBuf::from) + } + + /// Lossily create a new byte string from a file path. + /// + /// On Unix, this always succeeds, is zero cost and always returns a slice. + /// On non-Unix systems, this does a UTF-8 check. If the given path is not + /// valid UTF-8, then it is lossily decoded into valid UTF-8 (with invalid + /// bytes replaced by the Unicode replacement codepoint). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::path::Path; + /// + /// use bstr::{B, BString}; + /// + /// let path = Path::new("foo"); + /// let bs = BString::from_path_lossy(path); + /// assert_eq!(bs, B("foo")); + /// ``` + #[inline] + pub fn from_path_lossy<'a>(path: &'a Path) -> Cow<'a, BStr> { + BString::from_os_str_lossy(path.as_os_str()) + } + + /// Appends the given byte to the end of this byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("abc"); + /// s.push_byte(b'\xE2'); + /// s.push_byte(b'\x98'); + /// s.push_byte(b'\x83'); + /// assert_eq!("abc☃", s); + /// ``` + #[inline] + pub fn push_byte(&mut self, byte: u8) { + self.bytes.push(byte); + } + + /// Appends the given `char` to the end of this byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("abc"); + /// s.push_char('1'); + /// s.push_char('2'); + /// s.push_char('3'); + /// assert_eq!("abc123", s); + /// ``` + #[inline] + pub fn push_char(&mut self, ch: char) { + if ch.len_utf8() == 1 { + self.bytes.push(ch as u8); + return; + } + self.bytes.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()); + } + + /// Appends the given slice to the end of this byte string. This accepts + /// any type that be converted to a `&[u8]`. This includes, but is not + /// limited to, `&str`, `&BStr`, and of course, `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("abc"); + /// s.push(b"123"); + /// assert_eq!("abc123", s); + /// ``` + #[inline] + pub fn push>(&mut self, bytes: B) { + self.bytes.extend_from_slice(bytes.as_ref()); + } + + /// Extracts a byte string slice containing the entire `BString`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{BStr, BString}; + /// + /// let s = BString::from("foo"); + /// + /// assert_eq!(BStr::new("foo"), s.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &BStr { + BStr::from_bytes(&self.bytes) + } + + /// Returns this `BString` as a borrowed byte vector. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bs = BString::from("ab"); + /// assert!(bs.as_vec().capacity() >= 2); + /// ``` + #[inline] + pub fn as_vec(&self) -> &Vec { + &self.bytes + } + + /// Converts a `BString` into a mutable string slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// let s_mut_str = s.as_mut_bstr(); + /// + /// s_mut_str[0] = b'F'; + /// + /// assert_eq!("Foobar", s_mut_str); + /// ``` + #[inline] + pub fn as_mut_bstr(&mut self) -> &mut BStr { + BStr::from_bytes_mut(&mut self.bytes) + } + + /// Returns this `BString` as a mutable byte vector. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut bs = BString::from("ab"); + /// bs.as_mut_vec().push(b'c'); + /// assert_eq!("abc", bs); + /// ``` + #[inline] + pub fn as_mut_vec(&mut self) -> &mut Vec { + &mut self.bytes + } + + /// Converts a `BString` into a byte vector. + /// + /// This consumes the `BString`, and thus the contents are not copied. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let s = BString::from("hello"); + /// let bytes = s.into_vec(); + /// + /// assert_eq!(vec![104, 101, 108, 108, 111], &bytes[..]); + /// ``` + #[inline] + pub fn into_vec(self) -> Vec { + self.bytes + } + + /// Converts a `BString` into a `String` if and only if this byte string is + /// valid UTF-8. + /// + /// If it is not valid UTF-8, then the error `std::string::FromUtf8Error` + /// is returned. (This error can be used to examine why UTF-8 validation + /// failed, or to regain the original byte string.) + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// # fn example() -> Result<(), ::bstr::FromUtf8Error> { + /// let bytes = BString::from("hello"); + /// let string = bytes.into_string()?; + /// + /// assert_eq!("hello", string); + /// # Ok(()) }; example().unwrap() + /// ``` + /// + /// If this byte string is not valid UTF-8, then an error will be returned. + /// That error can then be used to inspect the location at which invalid + /// UTF-8 was found, or to regain the original byte string: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let bytes = BString::from_slice(b"foo\xFFbar"); + /// let err = bytes.into_string().unwrap_err(); + /// + /// assert_eq!(err.utf8_error().valid_up_to(), 3); + /// assert_eq!(err.utf8_error().error_len(), Some(1)); + /// + /// // At no point in this example is an allocation performed. + /// let bytes = BString::from(err.into_bstring()); + /// assert_eq!(bytes, B(b"foo\xFFbar")); + /// ``` + #[inline] + pub fn into_string(self) -> Result { + match utf8::validate(self.as_bytes()) { + Err(err) => { + Err(FromUtf8Error { original: self, err: err }) + } + Ok(()) => { + // SAFETY: This is safe because of the guarantees provided by + // utf8::validate. + unsafe { Ok(self.into_string_unchecked()) } + } + } + } + + /// Lossily converts a `BString` into a `String`. If this byte string + /// contains invalid UTF-8, then the invalid bytes are replaced with the + /// Unicode replacement codepoint. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bytes = BString::from_slice(b"foo\xFFbar"); + /// let string = bytes.into_string_lossy(); + /// assert_eq!(string, "foo\u{FFFD}bar"); + /// ``` + #[inline] + pub fn into_string_lossy(self) -> String { + self.to_string() + } + + /// Unsafely convert this byte string into a `String`, without checking for + /// valid UTF-8. + /// + /// # Safety + /// + /// Callers *must* ensure that this byte string is valid UTF-8 before + /// calling this method. Converting a byte string into a `String` that is + /// not valid UTF-8 is considered undefined behavior. + /// + /// This routine is useful in performance sensitive contexts where the + /// UTF-8 validity of the byte string is already known and it is + /// undesirable to pay the cost of an additional UTF-8 validation check + /// that [`into_string`](#method.into_string) performs. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// // SAFETY: This is safe because string literals are guaranteed to be + /// // valid UTF-8 by the Rust compiler. + /// let s = unsafe { BString::from("☃βツ").into_string_unchecked() }; + /// assert_eq!("☃βツ", s); + /// ``` + pub unsafe fn into_string_unchecked(self) -> String { + String::from_utf8_unchecked(self.into_vec()) + } + + /// Converts this byte string into an OS string, in place. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns the original byte string if it is not valid UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// use bstr::BString; + /// + /// let bs = BString::from("foo"); + /// let os_str = bs.into_os_string().expect("should be valid UTF-8"); + /// assert_eq!(os_str, OsStr::new("foo")); + /// ``` + #[inline] + pub fn into_os_string(self) -> Result { + self.into_os_string_imp() + } + + #[cfg(unix)] + #[inline] + fn into_os_string_imp(self) -> Result { + use std::os::unix::ffi::OsStringExt; + + Ok(OsString::from_vec(self.into_vec())) + } + + #[cfg(not(unix))] + #[inline] + fn into_os_string_imp(self) -> Result { + match self.into_string() { + Ok(s) => Ok(OsString::from(s)), + Err(err) => Err(err.into_bstring()), + } + } + + /// Lossily converts this byte string into an OS string, in place. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this will perform a UTF-8 check and lossily convert this byte string + /// into valid UTF-8 using the Unicode replacement codepoint. + /// + /// Note that this can prevent the correct roundtripping of file paths on + /// non-Unix systems such as Windows, where file paths are an arbitrary + /// sequence of 16-bit integers. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bs = BString::from_slice(b"foo\xFFbar"); + /// let os_str = bs.into_os_string_lossy(); + /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar"); + /// ``` + #[inline] + pub fn into_os_string_lossy(self) -> OsString { + self.into_os_string_lossy_imp() + } + + #[cfg(unix)] + #[inline] + fn into_os_string_lossy_imp(self) -> OsString { + use std::os::unix::ffi::OsStringExt; + + OsString::from_vec(self.into_vec()) + } + + #[cfg(not(unix))] + #[inline] + fn into_os_string_lossy_imp(self) -> OsString { + OsString::from(self.into_string_lossy()) + } + + /// Converts this byte string into an owned file path, in place. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns the original byte string if it is not valid UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bs = BString::from("foo"); + /// let path = bs.into_path_buf().expect("should be valid UTF-8"); + /// assert_eq!(path.as_os_str(), "foo"); + /// ``` + #[inline] + pub fn into_path_buf(self) -> Result { + self.into_os_string().map(PathBuf::from) + } + + /// Lossily converts this byte string into an owned file path, in place. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this will perform a UTF-8 check and lossily convert this byte string + /// into valid UTF-8 using the Unicode replacement codepoint. + /// + /// Note that this can prevent the correct roundtripping of file paths on + /// non-Unix systems such as Windows, where file paths are an arbitrary + /// sequence of 16-bit integers. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let bs = BString::from_slice(b"foo\xFFbar"); + /// let path = bs.into_path_buf_lossy(); + /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar"); + /// ``` + #[inline] + pub fn into_path_buf_lossy(self) -> PathBuf { + PathBuf::from(self.into_os_string_lossy()) + } + + /// Converts this `BString` into a `Box`. + /// + /// This will drop any excess capacity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let s = BString::from("foobar"); + /// let b = s.into_boxed_bstr(); + /// assert_eq!(6, b.len()); + /// ``` + #[inline] + pub fn into_boxed_bstr(self) -> Box { + unsafe { + let slice = self.bytes.into_boxed_slice(); + Box::from_raw(Box::into_raw(slice) as *mut BStr) + } + } + + /// Returns this byte string's capacity, in bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let s = BString::with_capacity(10); + /// assert_eq!(10, s.capacity()); + /// ``` + #[inline] + pub fn capacity(&self) -> usize { + self.bytes.capacity() + } + + /// Truncates this byte string, removing all contents. + /// + /// The resulting byte string will always have length `0`, but its capacity + /// remains unchanged. + #[inline] + pub fn clear(&mut self) { + self.bytes.clear(); + } + + /// Ensures that this `BString`'s capacity is at least `additional` + /// bytes larger than its length. + /// + /// The capacity may be increased by more than `additional` bytes if it + /// chooses, to prevent frequent reallocations. + /// + /// If you do not want this "at least" behavior, use the + /// [`reserve_exact`](#method.reserve_exact) method instead. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::new(); + /// s.reserve(10); + /// assert!(s.capacity() >= 10); + /// ``` + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.bytes.reserve(additional); + } + + /// Ensures that this `BString`'s capacity is exactly `additional` + /// bytes larger than its length. + /// + /// Consider using the [`reserve`](#method.reserve) method unless you + /// absolutely know better than the allocator. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::new(); + /// s.reserve_exact(10); + /// assert!(s.capacity() >= 10); + /// ``` + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + self.bytes.reserve_exact(additional); + } + + /// Shrinks the capacity of this `BString` to match its length. + /// + /// Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo"); + /// s.reserve(10); + /// assert!(s.capacity() >= 10); + /// s.shrink_to_fit(); + /// assert_eq!(3, s.capacity()); + /// ``` + #[inline] + pub fn shrink_to_fit(&mut self) { + self.bytes.shrink_to_fit(); + } + + /// Shortens this `BString` to the specified length, in bytes. + /// + /// If `new_len` is greater than or equal to this byte string's current + /// length, then this has no effect. + /// + /// Note that this does _not_ panic if the result is not on a valid + /// `char` boundary. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// s.truncate(3); + /// assert_eq!("foo", s); + /// ``` + #[inline] + pub fn truncate(&mut self, new_len: usize) { + if new_len < self.len() { + self.bytes.truncate(new_len); + } + } + + /// Resizes this byte string in place so that the length of this byte + /// string is equivalent to `new_len`. + /// + /// If `new_len` is greater than the length of this byte string, then + /// the byte string is extended by the difference, which each additional + /// byte filled with the given value. If `new_len` is less than the length + /// of this byte string, then it is simply truncated. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("f"); + /// s.resize(3, b'o'); + /// assert_eq!(s, "foo"); + /// s.resize(1, b'o'); + /// assert_eq!(s, "f"); + /// ``` + #[inline] + pub fn resize(&mut self, new_len: usize, value: u8) { + self.bytes.resize(new_len, value); + } + + /// Removes the last codepoint from this `BString` and returns it. + /// + /// If this byte string is empty, then `None` is returned. If the last + /// bytes of this byte string do not correspond to a valid UTF-8 code unit + /// sequence, then the Unicode replacement codepoint is yielded instead in + /// accordance with the + /// [replacement codepoint substitution policy](index.html#handling-of-invalid-utf8-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo"); + /// assert_eq!(s.pop_char(), Some('o')); + /// assert_eq!(s.pop_char(), Some('o')); + /// assert_eq!(s.pop_char(), Some('f')); + /// assert_eq!(s.pop_char(), None); + /// ``` + /// + /// This shows the replacement codepoint substitution policy. Note that + /// the first pop yields a replacement codepoint but actually removes two + /// bytes. This is in contrast with subsequent pops when encountering + /// `\xFF` since `\xFF` is never a valid prefix for any valid UTF-8 + /// code unit sequence. + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98"); + /// assert_eq!(s.pop_char(), Some('\u{FFFD}')); + /// assert_eq!(s.pop_char(), Some('o')); + /// assert_eq!(s.pop_char(), Some('o')); + /// assert_eq!(s.pop_char(), Some('\u{FFFD}')); + /// assert_eq!(s.pop_char(), Some('\u{FFFD}')); + /// assert_eq!(s.pop_char(), Some('\u{FFFD}')); + /// assert_eq!(s.pop_char(), Some('f')); + /// assert_eq!(s.pop_char(), None); + /// ``` + #[inline] + pub fn pop_char(&mut self) -> Option { + let (ch, size) = utf8::decode_last_lossy(self.as_bytes()); + if size == 0 { + return None; + } + let new_len = self.len() - size; + self.truncate(new_len); + Some(ch) + } + + /// Removes the last byte from this `BString` and returns it. + /// + /// If this byte string is empty, then `None` is returned. + /// + /// Note that if the last codepoint in this byte string is not ASCII, then + /// removing the last byte could make this byte string contain invalid + /// UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo"); + /// assert_eq!(s.pop_byte(), Some(b'o')); + /// assert_eq!(s.pop_byte(), Some(b'o')); + /// assert_eq!(s.pop_byte(), Some(b'f')); + /// assert_eq!(s.pop_byte(), None); + /// ``` + #[inline] + pub fn pop_byte(&mut self) -> Option { + self.bytes.pop() + } + + /// **DEPRECATED**: Use + /// [`pop_char`](struct.BString.html#method.pop_char) + /// or + /// [`pop_byte`](struct.BString.html#method.pop_byte) + /// instead. + /// + /// Removes the last codepoint from this `BString` and returns it. + /// + /// If this byte string is empty, then `None` is returned. If the last + /// bytes of this byte string do not correspond to a valid UTF-8 code unit + /// sequence, then the Unicode replacement codepoint is yielded instead in + /// accordance with the + /// [replacement codepoint substitution policy](index.html#handling-of-invalid-utf8-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo"); + /// assert_eq!(s.pop(), Some('o')); + /// assert_eq!(s.pop(), Some('o')); + /// assert_eq!(s.pop(), Some('f')); + /// assert_eq!(s.pop(), None); + /// ``` + /// + /// This shows the replacement codepoint substitution policy. Note that + /// the first pop yields a replacement codepoint but actually removes two + /// bytes. This is in contrast with subsequent pops when encountering + /// `\xFF` since `\xFF` is never a valid prefix for any valid UTF-8 + /// code unit sequence. + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98"); + /// assert_eq!(s.pop(), Some('\u{FFFD}')); + /// assert_eq!(s.pop(), Some('o')); + /// assert_eq!(s.pop(), Some('o')); + /// assert_eq!(s.pop(), Some('\u{FFFD}')); + /// assert_eq!(s.pop(), Some('\u{FFFD}')); + /// assert_eq!(s.pop(), Some('\u{FFFD}')); + /// assert_eq!(s.pop(), Some('f')); + /// assert_eq!(s.pop(), None); + /// ``` + #[deprecated(since = "0.1.1", note = "use pop_char or pop_byte instead")] + #[inline] + pub fn pop(&mut self) -> Option { + self.pop_char() + } + + /// Removes a `char` from this `BString` at the given byte position and + /// returns it. + /// + /// If the bytes at the given position do not lead to a valid UTF-8 code + /// unit sequence, then a + /// [replacement codepoint is returned instead](index.html#handling-of-invalid-utf8-8). + /// + /// # Panics + /// + /// Panics if `at` is larger than or equal to this byte string's length. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo☃bar"); + /// assert_eq!('☃', s.remove(3)); + /// assert_eq!("foobar", s); + /// ``` + /// + /// This example shows how the Unicode replacement codepoint policy is + /// used: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from_slice(b"foo\xFFbar"); + /// assert_eq!('\u{FFFD}', s.remove(3)); + /// assert_eq!("foobar", s); + /// ``` + #[inline] + pub fn remove(&mut self, at: usize) -> char { + let (ch, size) = utf8::decode_lossy(self[at..].as_bytes()); + assert!(size > 0, "expected {} to be less than {}", at, self.len()); + self.bytes.drain(at..at + size); + ch + } + + /// Inserts the given codepoint into this `BString` at a particular byte + /// position. + /// + /// This is an `O(n)` operation as it may copy a number of elements in this + /// byte string proportional to its length. + /// + /// # Panics + /// + /// Panics if `at` is larger than the byte string's length. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// s.insert_char(3, '☃'); + /// assert_eq!("foo☃bar", s); + /// ``` + #[inline] + pub fn insert_char(&mut self, at: usize, ch: char) { + self.insert(at, ch.encode_utf8(&mut [0; 4]).as_bytes()); + } + + /// Inserts the given byte string into this byte string at a particular + /// byte position. + /// + /// This is an `O(n)` operation as it may copy a number of elements in this + /// byte string proportional to its length. + /// + /// Note that the type parameter `B` on this method means that it can + /// accept anything that can be cheaply converted to a `&[u8]`. This + /// includes, but is not limited to, `&str`, `&BStr` and `&[u8]` itself. + /// + /// # Panics + /// + /// Panics if `at` is larger than the byte string's length. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// s.insert(3, "☃☃☃"); + /// assert_eq!("foo☃☃☃bar", s); + /// ``` + #[inline] + pub fn insert>(&mut self, at: usize, bytes: B) { + assert!(at <= self.len(), "expected {} to be <= {}", at, self.len()); + + let bytes = bytes.as_ref(); + let len = self.len(); + + // SAFETY: We'd like to efficiently splice in the given bytes into + // this byte string. Since we are only working with `u8` elements here, + // we only need to consider whether our bounds are correct and whether + // our byte string has enough space. + self.reserve(bytes.len()); + unsafe { + // Shift bytes after `at` over by the length of `bytes` to make + // room for it. This requires referencing two regions of memory + // that may overlap, so we use ptr::copy. + ptr::copy( + self.bytes.as_ptr().add(at), + self.bytes.as_mut_ptr().add(at + bytes.len()), + len - at, + ); + // Now copy the bytes given into the room we made above. In this + // case, we know that the given bytes cannot possibly overlap + // with this byte string since we have a mutable borrow of the + // latter. Thus, we can use a nonoverlapping copy. + ptr::copy_nonoverlapping( + bytes.as_ptr(), + self.bytes.as_mut_ptr().add(at), + bytes.len(), + ); + self.bytes.set_len(len + bytes.len()); + } + } + + /// Splits this `BString` into two separate byte strings at the given + /// index. + /// + /// This returns a newly allocated `BString`, while `self` retans bytes + /// `[0, at)` and the returned `BString` contains bytes `[at, len)`. + /// + /// The capacity of `self` does not change. + /// + /// # Panics + /// + /// Panics if `at` is beyond the end of this byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// let bar = s.split_off(3); + /// assert_eq!(s, "foo"); + /// assert_eq!(bar, "bar"); + /// ``` + #[inline] + pub fn split_off(&mut self, at: usize) -> BString { + BString::from(self.bytes.split_off(at)) + } + + /// Removes the specified range in this byte string and replaces it with + /// the given bytes. The given bytes do not need to have the same length + /// as the range provided. + /// + /// # Panics + /// + /// Panics if the given range is invalid. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// s.replace_range(2..4, "xxxxx"); + /// assert_eq!(s, "foxxxxxar"); + /// ``` + #[inline] + pub fn replace_range( + &mut self, + range: R, + replace_with: B, + ) where R: ops::RangeBounds, + B: AsRef<[u8]> + { + self.bytes.splice(range, replace_with.as_ref().iter().cloned()); + } + + /// Creates a draining iterator that removes the specified range in this + /// `BString` and yields each of the removed bytes. + /// + /// Note that the elements specified by the given range are removed + /// regardless of whether the returned iterator is fully exhausted. + /// + /// Also note that is is unspecified how many bytes are removed from the + /// `BString` if the `DrainBytes` iterator is leaked. + /// + /// # Panics + /// + /// Panics if the given range is not valid. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foobar"); + /// { + /// let mut drainer = s.drain_bytes(2..4); + /// assert_eq!(drainer.next(), Some(b'o')); + /// assert_eq!(drainer.next(), Some(b'b')); + /// assert_eq!(drainer.next(), None); + /// } + /// assert_eq!(s, "foar"); + /// ``` + #[inline] + pub fn drain_bytes( + &mut self, + range: R, + ) -> DrainBytes + where R: ops::RangeBounds + { + DrainBytes { it: self.bytes.drain(range) } + } +} + +/// A draining byte oriented iterator for `BString`. +/// +/// This iterator is created by +/// [`BString::drain`](struct.BString.html#method.drain). +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr::BString; +/// +/// let mut s = BString::from("foobar"); +/// { +/// let mut drainer = s.drain_bytes(2..4); +/// assert_eq!(drainer.next(), Some(b'o')); +/// assert_eq!(drainer.next(), Some(b'b')); +/// assert_eq!(drainer.next(), None); +/// } +/// assert_eq!(s, "foar"); +/// ``` +#[derive(Debug)] +pub struct DrainBytes<'a> { + it: vec::Drain<'a, u8>, +} + +impl<'a> iter::FusedIterator for DrainBytes<'a> {} + +impl<'a> Iterator for DrainBytes<'a> { + type Item = u8; + + #[inline] + fn next(&mut self) -> Option { + self.it.next() + } +} + +impl<'a> DoubleEndedIterator for DrainBytes<'a> { + #[inline] + fn next_back(&mut self) -> Option { + self.it.next_back() + } +} + +impl<'a> ExactSizeIterator for DrainBytes<'a> { + #[inline] + fn len(&self) -> usize { + self.it.len() + } +} + +/// An error that may occur when converting a `BString` to a `String`. +/// +/// This error includes the original `BString` that failed to convert to a +/// `String`. This permits callers to recover the allocation used even if it +/// it not valid UTF-8. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr::{B, BString}; +/// +/// let bytes = BString::from_slice(b"foo\xFFbar"); +/// let err = bytes.into_string().unwrap_err(); +/// +/// assert_eq!(err.utf8_error().valid_up_to(), 3); +/// assert_eq!(err.utf8_error().error_len(), Some(1)); +/// +/// // At no point in this example is an allocation performed. +/// let bytes = BString::from(err.into_bstring()); +/// assert_eq!(bytes, B(b"foo\xFFbar")); +/// ``` +#[derive(Debug, Eq, PartialEq)] +pub struct FromUtf8Error { + original: BString, + err: Utf8Error, +} + +impl FromUtf8Error { + /// Return the original bytes as a slice that failed to convert to a + /// `String`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let bytes = BString::from_slice(b"foo\xFFbar"); + /// let err = bytes.into_string().unwrap_err(); + /// + /// // At no point in this example is an allocation performed. + /// assert_eq!(err.as_bstr(), B(b"foo\xFFbar")); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &BStr { + &self.original + } + + /// Consume this error and return the original byte string that failed to + /// convert to a `String`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let bytes = BString::from_slice(b"foo\xFFbar"); + /// let err = bytes.into_string().unwrap_err(); + /// let original = err.into_bstring(); + /// + /// // At no point in this example is an allocation performed. + /// assert_eq!(original, B(b"foo\xFFbar")); + /// ``` + #[inline] + pub fn into_bstring(self) -> BString { + self.original + } + + /// Return the underlying UTF-8 error that occurred. This error provides + /// information on the nature and location of the invalid UTF-8 detected. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let bytes = BString::from_slice(b"foo\xFFbar"); + /// let err = bytes.into_string().unwrap_err(); + /// + /// assert_eq!(err.utf8_error().valid_up_to(), 3); + /// assert_eq!(err.utf8_error().error_len(), Some(1)); + /// ``` + #[inline] + pub fn utf8_error(&self) -> &Utf8Error { + &self.err + } +} + +impl error::Error for FromUtf8Error { + #[inline] + fn description(&self) -> &str { "invalid UTF-8 vector" } +} + +impl fmt::Display for FromUtf8Error { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.err) + } +} + +#[cfg(test)] +mod tests { + use bstr::B; + use super::*; + + #[test] + fn insert() { + let mut s = BString::new(); + s.insert(0, "foo"); + assert_eq!("foo", s); + + let mut s = BString::from("a"); + s.insert(0, "foo"); + assert_eq!("fooa", s); + + let mut s = BString::from("a"); + s.insert(1, "foo"); + assert_eq!("afoo", s); + + let mut s = BString::from("foobar"); + s.insert(3, "quux"); + assert_eq!("fooquuxbar", s); + + let mut s = BString::from("foobar"); + s.insert(3, "x"); + assert_eq!("fooxbar", s); + + let mut s = BString::from("foobar"); + s.insert(0, "x"); + assert_eq!("xfoobar", s); + + let mut s = BString::from("foobar"); + s.insert(6, "x"); + assert_eq!("foobarx", s); + + let mut s = BString::from("foobar"); + s.insert(3, "quuxbazquux"); + assert_eq!("fooquuxbazquuxbar", s); + } + + #[test] + #[should_panic] + fn insert_fail1() { + let mut s = BString::new(); + s.insert(1, "foo"); + } + + #[test] + #[should_panic] + fn insert_fail2() { + let mut s = BString::from("a"); + s.insert(2, "foo"); + } + + #[test] + #[should_panic] + fn insert_fail3() { + let mut s = BString::from("foobar"); + s.insert(7, "foo"); + } + + #[test] + fn collect() { + let s: BString = vec!['a', 'b', 'c'].into_iter().collect(); + assert_eq!(s, "abc"); + + let s: BString = vec!["a", "b", "c"].into_iter().collect(); + assert_eq!(s, "abc"); + + let s: BString = vec![B("a"), B("b"), B("c")].into_iter().collect(); + assert_eq!(s, "abc"); + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/bstr.rs cargo-0.35.0/vendor/bstr/src/bstr.rs --- cargo-0.33.0/vendor/bstr/src/bstr.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/bstr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,3991 @@ +#[cfg(feature = "std")] +use std::borrow::Cow; +#[cfg(feature = "std")] +use std::ffi::OsStr; +#[cfg(feature = "std")] +use std::iter; +#[cfg(feature = "std")] +use std::path::Path; + +use core::cmp; +use core::mem; +use core::ops; +use core::ptr; +use core::slice; +use core::str; + +use memchr::{memchr, memrchr}; + +use ascii; +#[cfg(feature = "std")] +use bstring::BString; +use search::{PrefilterState, TwoWay}; +use slice_index::SliceIndex; +#[cfg(feature = "unicode")] +use unicode::{ + Graphemes, GraphemeIndices, + Sentences, SentenceIndices, + Words, WordIndices, WordsWithBreaks, WordsWithBreakIndices, + whitespace_len_fwd, whitespace_len_rev, +}; +use utf8::{self, Chars, CharIndices, Utf8Error}; + +/// A short-hand constructor for building a `&BStr`. +/// +/// This idiosyncratic constructor is useful for concisely building byte string +/// slices. Its primary utility is in conveniently writing byte string literals +/// in a uniform way. For example, consider this code that does not compile: +/// +/// ```ignore +/// let strs = vec![b"a", b"xy"]; +/// ``` +/// +/// The above code doesn't compile because the type of the byte string literal +/// `b"a"` is `&'static [u8; 1]`, and the type of `b"xy"` is +/// `&'static [u8; 2]`. Since their types aren't the same, they can't be stored +/// in the same `Vec`. (This is dissimilar from normal Unicode string slices, +/// where both `"a"` and `"xy"` have the same type of `&'static str`.) +/// +/// One way of getting the above code to compile is to convert byte strings to +/// slices. You might try this: +/// +/// ```ignore +/// let strs = vec![&b"a", &b"xy"]; +/// ``` +/// +/// But this just creates values with type `& &'static [u8; 1]` and +/// `& &'static [u8; 2]`. Instead, you need to force the issue like so: +/// +/// ``` +/// let strs = vec![&b"a"[..], &b"xy"[..]]; +/// // or +/// let strs = vec![b"a".as_ref(), b"xy".as_ref()]; +/// ``` +/// +/// But neither of these are particularly convenient to type, especially when +/// it's something as common as a string literal. Thus, this constructor +/// permits writing the following instead: +/// +/// ``` +/// use bstr::B; +/// +/// let strs = vec![B("a"), B(b"xy")]; +/// ``` +/// +/// Notice that this also lets you mix and match both string literals and byte +/// string literals. This can be quite convenient! +#[allow(non_snake_case)] +#[inline] +pub fn B<'a, B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> &'a BStr { + BStr::new(bytes.as_ref()) +} + +/// A byte string slice that is conventionally UTF-8. +/// +/// A byte string slice is the core string type in this library, and is usually +/// seen in its borrowed form, `&BStr`. The principle difference between a +/// `&BStr` and a `&str` (Rust's standard Unicode string slice) is that a +/// `&BStr` is only *conventionally* UTF-8, where as a `&str` is guaranteed to +/// always be valid UTF-8. +/// +/// If you need ownership or a growable byte string buffer, then use +/// [`BString`](struct.BString.html). +/// +/// # Literals +/// +/// A byte string literal has type `&'static BStr`. The most convenient way to +/// write a byte string literal is by using the short-hand [`B`](fn.B.html) +/// constructor function: +/// +/// ``` +/// use bstr::{B, BStr}; +/// +/// // A byte string literal can be constructed from a normal Unicode string. +/// let s = B("a byte string literal"); +/// // A byte string literal can also be constructed from a Rust byte string. +/// let s = B(b"another byte string literal"); +/// +/// // BStr::new can also be used: +/// let s = BStr::new("a byte string literal"); +/// let s = BStr::new(b"another byte string literal"); +/// ``` +/// +/// # Representation +/// +/// A `&BStr` has the same representation as a `&str`. That is, a `&BStr` is +/// a fat pointer which consists of a pointer to some bytes and a length. +/// +/// # Trait implementations +/// +/// The `BStr` type has a number of trait implementations, and in particular, +/// defines equality and ordinal comparisons between `&BStr`, `&str` and +/// `&[u8]` for convenience. +/// +/// The `Debug` implementation for `BStr` shows its bytes as a normal string. +/// For invalid UTF-8, hex escape sequences are used. +/// +/// The `Display` implementation behaves as if `BStr` were first lossily +/// converted to a `str`. Invalid UTF-8 bytes are substituted with the Unicode +/// replacement codepoint, which looks like this: �. +/// +/// # Indexing and slicing +/// +/// A `BStr` implements indexing and slicing using `[..]` notation. Unlike +/// the standard `str` type, the `BStr` type permits callers to index +/// individual bytes. For example: +/// +/// ``` +/// use bstr::B; +/// +/// let s = B("foo☃bar"); +/// assert_eq!(&s[0..3], "foo"); +/// assert_eq!(s[2], b'o'); +/// assert_eq!(&s[3..6], "☃"); +/// +/// // Nothing stops you from indexing or slicing invalid UTF-8. +/// assert_eq!(s[3], b'\xE2'); +/// assert_eq!(&s[3..5], B(b"\xE2\x98")); +/// ``` +#[derive(Hash)] +pub struct BStr { + bytes: [u8], +} + +impl BStr { + /// Create a byte string slice from anything that can be borrowed as a + /// sequence of bytes. This includes, but is not limited to, `&Vec`, + /// `&[u8]`, `&String` and `&str`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// assert_eq!("abc", BStr::new("abc")); + /// assert_eq!("abc", BStr::new(b"abc")); + /// ``` + #[inline] + pub fn new>(bytes: &B) -> &BStr { + BStr::from_bytes(bytes.as_ref()) + } + + /// Create a mutable byte string slice from anything that can be borrowed + /// as a sequence of bytes. This includes, but is not limited to, `&mut + /// Vec` and `&mut [u8]`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// assert_eq!("abc", BStr::new("abc")); + /// assert_eq!("abc", BStr::new(b"abc")); + /// ``` + #[inline] + pub fn new_mut>(bytes: &mut B) -> &mut BStr { + BStr::from_bytes_mut(bytes.as_mut()) + } + + /// Create an immutable byte string slice from an immutable byte slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// let bytes = &[b'a']; + /// let bs = BStr::from_bytes(bytes); + /// assert_eq!("a", bs); + /// ``` + #[inline] + pub fn from_bytes(slice: &[u8]) -> &BStr { + unsafe { mem::transmute(slice) } + } + + /// Create a mutable byte string slice from a mutable byte slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// let bytes = &mut [b'a']; + /// { + /// let bs = BStr::from_bytes_mut(bytes); + /// bs[0] = b'b'; + /// } + /// assert_eq!(b"b", bytes); + /// ``` + #[inline] + pub fn from_bytes_mut(slice: &mut [u8]) -> &mut BStr { + unsafe { mem::transmute(slice) } + } + + /// Create a byte string from its constituent pointer and length, where + /// the length is the number of bytes in the byte string. + /// + /// # Safety + /// + /// This function is unsafe as there is no guarantee that the given pointer + /// is valid for `len` elements, nor whether the lifetime inferred is a + /// suitable lifetime for the returned slice. + /// + /// `data` must be a non-null pointer, even for a zero length slice. A + /// pointer that is usable for zero-length slices can be obtaining from + /// the standard library's `NonNull::dangling()` constructor. + /// + /// The total size of the given slice must be no larger than `isize::MAX` + /// bytes in memory. + /// + /// # Caveat + /// + /// The lifetime for the returned slice is inferred from its usage. To + /// prevent accidental misuse, it's suggested to tie the lifetime to + /// whichever source lifetime is safe in the context, such as by providing + /// a helper function taking the lifetime of a host value for the slice, or + /// by explicit annotation. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// // manifest a byte string from a single byte + /// let x = b'Z'; + /// let ptr = &x as *const u8; + /// let s = unsafe { BStr::from_raw_parts(ptr, 1) }; + /// assert_eq!(s, "Z"); + /// ``` + pub unsafe fn from_raw_parts<'a>(data: *const u8, len: usize) -> &'a BStr { + BStr::new(slice::from_raw_parts(data, len)) + } + + /// Create a mutable byte string from its constituent pointer and length, + /// where the length is the number of bytes in the byte string. + /// + /// # Safety + /// + /// This function is unsafe as there is no guarantee that the given pointer + /// is valid for `len` elements, nor whether the lifetime inferred is a + /// suitable lifetime for the returned slice. + /// + /// `data` must be a non-null pointer, even for a zero length slice. A + /// pointer that is usable for zero-length slices can be obtaining from + /// the standard library's `NonNull::dangling()` constructor. + /// + /// The total size of the given slice must be no larger than `isize::MAX` + /// bytes in memory. + /// + /// The above reasons are the same as for + /// [`from_raw_parts`](#method.from_raw_parts). In addition, for this + /// constructor, callers must guarantee that the mutable slice returned + /// is not aliased with any other reference. + /// + /// # Caveat + /// + /// The lifetime for the returned slice is inferred from its usage. To + /// prevent accidental misuse, it's suggested to tie the lifetime to + /// whichever source lifetime is safe in the context, such as by providing + /// a helper function taking the lifetime of a host value for the slice, or + /// by explicit annotation. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::mem; + /// use bstr::{BStr, BString}; + /// + /// // For demonstration purposes, get a mutable pointer to a byte string. + /// let mut buf = BString::from("bar"); + /// let ptr = buf.as_mut_ptr(); + /// // Drop buf without deallocating, to avoid &mut aliasing. + /// mem::forget(buf); + /// + /// // Now convert it to a mutable byte string from the raw pointer. + /// let mut s = unsafe { BStr::from_raw_parts_mut(ptr, 3) }; + /// s.make_ascii_uppercase(); + /// assert_eq!(s, "BAR"); + /// ``` + pub unsafe fn from_raw_parts_mut<'a>( + data: *mut u8, + len: usize, + ) -> &'a mut BStr { + BStr::new_mut(slice::from_raw_parts_mut(data, len)) + } + + /// Create an immutable byte string from an OS string slice. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns `None` if the given OS string is not valid UTF-8. (For + /// example, on Windows, file paths are allowed to be a sequence of + /// arbitrary 16-bit integers. Not all such sequences can be transcoded to + /// valid UTF-8.) + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::ffi::OsStr; + /// + /// use bstr::BStr; + /// + /// let os_str = OsStr::new("foo"); + /// let bs = BStr::from_os_str(os_str).expect("should be valid UTF-8"); + /// assert_eq!(bs, "foo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn from_os_str(os_str: &OsStr) -> Option<&BStr> { + BStr::from_os_str_imp(os_str) + } + + #[cfg(feature = "std")] + #[cfg(unix)] + #[inline] + fn from_os_str_imp(os_str: &OsStr) -> Option<&BStr> { + use std::os::unix::ffi::OsStrExt; + + Some(BStr::new(os_str.as_bytes())) + } + + #[cfg(feature = "std")] + #[cfg(not(unix))] + #[inline] + fn from_os_str_imp(os_str: &OsStr) -> Option<&BStr> { + os_str.to_str().map(BStr::new) + } + + /// Create an immutable byte string from a file path. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns `None` if the given path is not valid UTF-8. (For example, + /// on Windows, file paths are allowed to be a sequence of arbitrary 16-bit + /// integers. Not all such sequences can be transcoded to valid UTF-8.) + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::path::Path; + /// + /// use bstr::BStr; + /// + /// let path = Path::new("foo"); + /// let bs = BStr::from_path(path).expect("should be valid UTF-8"); + /// assert_eq!(bs, "foo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn from_path(path: &Path) -> Option<&BStr> { + BStr::from_os_str(path.as_os_str()) + } + + /// Returns the length, in bytes, of this byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// assert_eq!(0, BStr::new("").len()); + /// assert_eq!(3, BStr::new("abc").len()); + /// assert_eq!(8, BStr::new("☃βツ").len()); + /// ``` + #[inline] + pub fn len(&self) -> usize { + self.bytes.len() + } + + /// Returns true if and only if the length of this byte string is zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// assert!(BStr::new("").is_empty()); + /// assert!(!BStr::new("abc").is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.bytes.is_empty() + } + + /// Returns an immutable byte slice of this `BStr`'s contents. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("hello"); + /// + /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes()); + /// ``` + #[inline] + pub fn as_bytes(&self) -> &[u8] { + &self.bytes + } + + /// Returns a mutable byte slice of this `BStr`'s contents. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("hello"); + /// s.as_bytes_mut()[1] = b'a'; + /// + /// assert_eq!(&[104, 97, 108, 108, 111], s.as_bytes()); + /// ``` + #[inline] + pub fn as_bytes_mut(&mut self) -> &mut [u8] { + &mut self.bytes + } + + /// Create a new owned byte string from this byte string slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// let s = BStr::new("abc"); + /// let mut owned = s.to_bstring(); + /// owned.push_char('d'); + /// assert_eq!("abcd", owned); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_bstring(&self) -> BString { + BString::from_vec(self.as_bytes().to_vec()) + } + + /// Safely convert this byte string into a `&str` if it's valid UTF-8. + /// + /// If this byte string is not valid UTF-8, then an error is returned. The + /// error returned indicates the first invalid byte found and the length + /// of the error. + /// + /// In cases where a lossy conversion to `&str` is acceptable, then use one + /// of the [`to_str_lossy`](#method.to_str_lossy) + /// or [`to_str_lossy_into`](#method.to_str_lossy_into) methods. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// # fn example() -> Result<(), bstr::Utf8Error> { + /// let s = B("☃βツ").to_str()?; + /// assert_eq!("☃βツ", s); + /// + /// let mut bstring = BString::from("☃βツ"); + /// bstring.push_byte(b'\xFF'); + /// let err = bstring.to_str().unwrap_err(); + /// assert_eq!(8, err.valid_up_to()); + /// # Ok(()) }; example().unwrap() + /// ``` + #[inline] + pub fn to_str(&self) -> Result<&str, Utf8Error> { + utf8::validate(self.as_bytes()).map(|_| { + // SAFETY: This is safe because of the guarantees provided by + // utf8::validate. + unsafe { + str::from_utf8_unchecked(self.as_bytes()) + } + }) + } + + /// Unsafely convert this byte string into a `&str`, without checking for + /// valid UTF-8. + /// + /// # Safety + /// + /// Callers *must* ensure that this byte string is valid UTF-8 before + /// calling this method. Converting a byte string into a `&str` that is + /// not valid UTF-8 is considered undefined behavior. + /// + /// This routine is useful in performance sensitive contexts where the + /// UTF-8 validity of the byte string is already known and it is + /// undesirable to pay the cost of an additional UTF-8 validation check + /// that [`to_str`](#method.to_str) performs. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// // SAFETY: This is safe because string literals are guaranteed to be + /// // valid UTF-8 by the Rust compiler. + /// let s = unsafe { B("☃βツ").to_str_unchecked() }; + /// assert_eq!("☃βツ", s); + /// ``` + pub unsafe fn to_str_unchecked(&self) -> &str { + str::from_utf8_unchecked(self.as_bytes()) + } + + /// Convert this byte string to a valid UTF-8 string by replacing invalid + /// UTF-8 bytes with the Unicode replacement codepoint (`U+FFFD`). + /// + /// If the byte string is already valid UTF-8, then no copying or + /// allocation is performed and a borrrowed string slice is returned. If + /// the byte string is not valid UTF-8, then an owned string buffer is + /// returned with invalid bytes replaced by the replacement codepoint. + /// + /// This method uses the "substitution of maximal subparts" (Unicode + /// Standard, Chapter 3, Section 9) strategy for inserting the replacement + /// codepoint. Specifically, a replacement codepoint is inserted whenever a + /// byte is found that cannot possibly lead to a valid code unit sequence. + /// If there were previous bytes that represented a prefix of a well-formed + /// code unit sequence, then all of those bytes are substituted with a + /// single replacement codepoint. The "substitution of maximal subparts" + /// strategy is the same strategy used by + /// [W3C's Encoding standard](https://www.w3.org/TR/encoding/). + /// For a more precise description of the maximal subpart strategy, see + /// the Unicode Standard, Chapter 3, Section 9. See also + /// [Public Review Issue #121](http://www.unicode.org/review/pr-121.html). + /// + /// N.B. Rust's standard library also appears to use the same strategy, + /// but it does not appear to be an API guarantee. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::borrow::Cow; + /// use bstr::BString; + /// + /// let mut bstring = BString::from("☃βツ"); + /// assert_eq!(Cow::Borrowed("☃βツ"), bstring.to_str_lossy()); + /// + /// // Add a byte that makes the sequence invalid. + /// bstring.push_byte(b'\xFF'); + /// assert_eq!(Cow::Borrowed("☃βツ\u{FFFD}"), bstring.to_str_lossy()); + /// ``` + /// + /// This demonstrates the "maximal subpart" substitution logic. + /// + /// ``` + /// use bstr::B; + /// + /// // \x61 is the ASCII codepoint for 'a'. + /// // \xF1\x80\x80 is a valid 3-byte code unit prefix. + /// // \xE1\x80 is a valid 2-byte code unit prefix. + /// // \xC2 is a valid 1-byte code unit prefix. + /// // \x62 is the ASCII codepoint for 'b'. + /// // + /// // In sum, each of the prefixes is replaced by a single replacement + /// // codepoint since none of the prefixes are properly completed. This + /// // is in contrast to other strategies that might insert a replacement + /// // codepoint for every single byte. + /// let bs = B(b"\x61\xF1\x80\x80\xE1\x80\xC2\x62"); + /// assert_eq!("a\u{FFFD}\u{FFFD}\u{FFFD}b", bs.to_str_lossy()); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_str_lossy(&self) -> Cow { + match utf8::validate(self.as_bytes()) { + Ok(()) => { + // SAFETY: This is safe because of the guarantees provided by + // utf8::validate. + unsafe { + Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes())) + } + } + Err(err) => { + let mut lossy = String::with_capacity(self.len()); + let (valid, after) = self + .as_bytes() + .split_at(err.valid_up_to()); + // SAFETY: This is safe because utf8::validate guarantees + // that all of `valid` is valid UTF-8. + lossy.push_str(unsafe { str::from_utf8_unchecked(valid) }); + lossy.push_str("\u{FFFD}"); + if let Some(len) = err.error_len() { + B(&after[len..]).to_str_lossy_into(&mut lossy); + } + Cow::Owned(lossy) + } + } + } + + /// Copy the contents of this byte string into the given owned string + /// buffer, while replacing invalid UTF-8 code unit sequences with the + /// Unicode replacement codepoint (`U+FFFD`). + /// + /// This method uses the same "substitution of maximal subparts" strategy + /// for inserting the replacement codepoint as the + /// [`to_str_lossy`](#method.to_str_lossy) method. + /// + /// This routine is useful for amortizing allocation. However, unlike + /// `to_str_lossy`, this routine will _always_ copy the contents of this + /// byte string into the destination buffer, even if this byte string is + /// valid UTF-8. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::borrow::Cow; + /// use bstr::BString; + /// + /// let mut bstring = BString::from("☃βツ"); + /// // Add a byte that makes the sequence invalid. + /// bstring.push_byte(b'\xFF'); + /// + /// let mut dest = String::new(); + /// bstring.to_str_lossy_into(&mut dest); + /// assert_eq!("☃βツ\u{FFFD}", dest); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_str_lossy_into(&self, dest: &mut String) { + dest.reserve(self.len()); + let mut bytes = self.as_bytes(); + loop { + match utf8::validate(bytes) { + Ok(()) => { + // SAFETY: This is safe because utf8::validate guarantees + // that all of `bytes` is valid UTF-8. + dest.push_str(unsafe { str::from_utf8_unchecked(bytes) }); + break; + } + Err(err) => { + let (valid, after) = bytes.split_at(err.valid_up_to()); + // SAFETY: This is safe because utf8::validate guarantees + // that all of `valid` is valid UTF-8. + dest.push_str(unsafe { str::from_utf8_unchecked(valid) }); + dest.push_str("\u{FFFD}"); + match err.error_len() { + None => break, + Some(len) => bytes = &after[len..], + } + } + } + } + } + + /// Create an OS string slice from this byte string. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns a UTF-8 decoding error if this byte string is not valid + /// UTF-8. (For example, on Windows, file paths are allowed to be a + /// sequence of arbitrary 16-bit integers. There is no obvious mapping from + /// an arbitrary sequence of 8-bit integers to an arbitrary sequence of + /// 16-bit integers.) + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("foo"); + /// let os_str = bs.to_os_str().expect("should be valid UTF-8"); + /// assert_eq!(os_str, "foo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_os_str(&self) -> Result<&OsStr, Utf8Error> { + self.to_os_str_imp() + } + + #[cfg(feature = "std")] + #[cfg(unix)] + #[inline] + fn to_os_str_imp(&self) -> Result<&OsStr, Utf8Error> { + use std::os::unix::ffi::OsStrExt; + + Ok(OsStr::from_bytes(self.as_bytes())) + } + + #[cfg(feature = "std")] + #[cfg(not(unix))] + #[inline] + fn to_os_str_imp(&self) -> Result<&OsStr, Utf8Error> { + self.to_str().map(OsStr::new) + } + + /// Lossily create an OS string slice from this byte string. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this will perform a UTF-8 check and lossily convert this byte string + /// into valid UTF-8 using the Unicode replacement codepoint. + /// + /// Note that this can prevent the correct roundtripping of file paths on + /// non-Unix systems such as Windows, where file paths are an arbitrary + /// sequence of 16-bit integers. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"foo\xFFbar"); + /// let os_str = bs.to_os_str_lossy(); + /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_os_str_lossy(&self) -> Cow { + self.to_os_str_lossy_imp() + } + + #[cfg(feature = "std")] + #[cfg(unix)] + #[inline] + fn to_os_str_lossy_imp(&self) -> Cow { + use std::os::unix::ffi::OsStrExt; + + Cow::Borrowed(OsStr::from_bytes(self.as_bytes())) + } + + #[cfg(feature = "std")] + #[cfg(not(unix))] + #[inline] + fn to_os_str_lossy_imp(&self) -> Cow { + use std::ffi::OsString; + + match self.to_str_lossy() { + Cow::Borrowed(x) => Cow::Borrowed(OsStr::new(x)), + Cow::Owned(x) => Cow::Owned(OsString::from(x)), + } + } + + /// Create a path slice from this byte string. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this returns a UTF-8 decoding error if this byte string is not valid + /// UTF-8. (For example, on Windows, file paths are allowed to be a + /// sequence of arbitrary 16-bit integers. There is no obvious mapping from + /// an arbitrary sequence of 8-bit integers to an arbitrary sequence of + /// 16-bit integers.) + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("foo"); + /// let path = bs.to_path().expect("should be valid UTF-8"); + /// assert_eq!(path.as_os_str(), "foo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_path(&self) -> Result<&Path, Utf8Error> { + self.to_os_str().map(Path::new) + } + + /// Lossily create a path slice from this byte string. + /// + /// On Unix, this always succeeds and is zero cost. On non-Unix systems, + /// this will perform a UTF-8 check and lossily convert this byte string + /// into valid UTF-8 using the Unicode replacement codepoint. + /// + /// Note that this can prevent the correct roundtripping of file paths on + /// non-Unix systems such as Windows, where file paths are an arbitrary + /// sequence of 16-bit integers. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"foo\xFFbar"); + /// let path = bs.to_path_lossy(); + /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_path_lossy(&self) -> Cow { + use std::path::PathBuf; + + match self.to_os_str_lossy() { + Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)), + Cow::Owned(x) => Cow::Owned(PathBuf::from(x)), + } + } + + /// Create a new `BString` by repeating this byte string `n` times. + /// + /// # Panics + /// + /// This function panics if the capacity of the new `BString` would + /// overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!("foofoofoofoo", B("foo").repeat(4)); + /// assert_eq!("", B("foo").repeat(0)); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn repeat(&self, n: usize) -> BString { + iter::repeat(self).take(n).collect() + } + + /// Returns true if and only if this byte string contains the given needle. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert!(B("foo bar").contains("foo")); + /// assert!(B("foo bar").contains("bar")); + /// assert!(!B("foo").contains("foobar")); + /// ``` + #[inline] + pub fn contains>(&self, needle: B) -> bool { + self.find(needle).is_some() + } + + /// Returns true if and only if this byte string has the given prefix. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert!(B("foo bar").starts_with("foo")); + /// assert!(!B("foo bar").starts_with("bar")); + /// assert!(!B("foo").starts_with("foobar")); + /// ``` + #[inline] + pub fn starts_with>(&self, prefix: B) -> bool { + let prefix = prefix.as_ref(); + self.get(..prefix.len()).map_or(false, |x| x == prefix) + } + + /// Returns true if and only if this byte string has the given suffix. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert!(B("foo bar").ends_with("bar")); + /// assert!(!B("foo bar").ends_with("foo")); + /// assert!(!B("bar").ends_with("foobar")); + /// ``` + #[inline] + pub fn ends_with>(&self, suffix: B) -> bool { + let suffix = suffix.as_ref(); + self.len() + .checked_sub(suffix.len()) + .map_or(false, |s| &self[s..] == suffix) + } + + /// Returns the index of the first occurrence of the given needle. + /// + /// The needle may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// Note that if you're are searching for the same needle in many + /// different small haystacks, it may be faster to initialize a + /// [`Finder`](struct.Finder.html) once, and reuse it for each search. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo bar baz"); + /// assert_eq!(Some(0), s.find("foo")); + /// assert_eq!(Some(4), s.find("bar")); + /// assert_eq!(None, s.find("quux")); + /// ``` + #[inline] + pub fn find>(&self, needle: B) -> Option { + Finder::new(needle.as_ref()).find(self) + } + + /// Returns the index of the last occurrence of the given needle. + /// + /// The needle may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// Note that if you're are searching for the same needle in many + /// different small haystacks, it may be faster to initialize a + /// [`FinderReverse`](struct.FinderReverse.html) once, and reuse it for + /// each search. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo bar baz"); + /// assert_eq!(Some(0), s.rfind("foo")); + /// assert_eq!(Some(4), s.rfind("bar")); + /// assert_eq!(Some(8), s.rfind("ba")); + /// assert_eq!(None, s.rfind("quux")); + /// ``` + #[inline] + pub fn rfind>(&self, needle: B) -> Option { + FinderReverse::new(needle.as_ref()).rfind(self) + } + + /// Returns an iterator of the non-overlapping occurrences of the given + /// needle. The iterator yields byte offset positions indicating the start + /// of each match. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo bar foo foo quux foo"); + /// let matches: Vec = s.find_iter("foo").collect(); + /// assert_eq!(matches, vec![0, 8, 12, 21]); + /// ``` + /// + /// An empty string matches at every position, including the position + /// immediately following the last byte: + /// + /// ``` + /// use bstr::B; + /// + /// let matches: Vec = B("foo").find_iter("").collect(); + /// assert_eq!(matches, vec![0, 1, 2, 3]); + /// + /// let matches: Vec = B("").find_iter("").collect(); + /// assert_eq!(matches, vec![0]); + /// ``` + #[inline] + pub fn find_iter<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + needle: &'a B, + ) -> Find<'a> { + Find::new(self, BStr::new(needle.as_ref())) + } + + /// Returns an iterator of the non-overlapping occurrences of the given + /// needle in reverse. The iterator yields byte offset positions indicating + /// the start of each match. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo bar foo foo quux foo"); + /// let matches: Vec = s.rfind_iter("foo").collect(); + /// assert_eq!(matches, vec![21, 12, 8, 0]); + /// ``` + /// + /// An empty string matches at every position, including the position + /// immediately following the last byte: + /// + /// ``` + /// use bstr::B; + /// + /// let matches: Vec = B("foo").rfind_iter("").collect(); + /// assert_eq!(matches, vec![3, 2, 1, 0]); + /// + /// let matches: Vec = B("").rfind_iter("").collect(); + /// assert_eq!(matches, vec![0]); + /// ``` + #[inline] + pub fn rfind_iter<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + needle: &'a B, + ) -> FindReverse<'a> { + FindReverse::new(self, BStr::new(needle.as_ref())) + } + + /// Returns the index of the first occurrence of the given byte. If the + /// byte does not occur in this byte string, then `None` is returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(Some(10), B("foo bar baz").find_byte(b'z')); + /// assert_eq!(None, B("foo bar baz").find_byte(b'y')); + /// ``` + #[inline] + pub fn find_byte(&self, byte: u8) -> Option { + memchr(byte, self.as_bytes()) + } + + /// Returns the index of the last occurrence of the given byte. If the + /// byte does not occur in this byte string, then `None` is returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(Some(10), B("foo bar baz").rfind_byte(b'z')); + /// assert_eq!(None, B("foo bar baz").rfind_byte(b'y')); + /// ``` + #[inline] + pub fn rfind_byte(&self, byte: u8) -> Option { + memrchr(byte, self.as_bytes()) + } + + /// Returns the index of the first occurrence of the given codepoint. + /// If the codepoint does not occur in this byte string, then `None` is + /// returned. + /// + /// Note that if one searches for the replacement codepoint, `\u{FFFD}`, + /// then only explicit occurrences of that encoding will be found. Invalid + /// UTF-8 sequences will not be matched. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(Some(10), B("foo bar baz").find_char('z')); + /// assert_eq!(Some(4), B("αβγγδ").find_char('γ')); + /// assert_eq!(None, B("foo bar baz").find_char('y')); + /// ``` + #[inline] + pub fn find_char(&self, ch: char) -> Option { + self.find(ch.encode_utf8(&mut [0; 4])) + } + + /// Returns the index of the last occurrence of the given codepoint. + /// If the codepoint does not occur in this byte string, then `None` is + /// returned. + /// + /// Note that if one searches for the replacement codepoint, `\u{FFFD}`, + /// then only explicit occurrences of that encoding will be found. Invalid + /// UTF-8 sequences will not be matched. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(Some(10), B("foo bar baz").rfind_char('z')); + /// assert_eq!(Some(6), B("αβγγδ").rfind_char('γ')); + /// assert_eq!(None, B("foo bar baz").rfind_char('y')); + /// ``` + #[inline] + pub fn rfind_char(&self, ch: char) -> Option { + self.rfind(ch.encode_utf8(&mut [0; 4])) + } + + /// Returns an iterator over the fields in a byte string, separated by + /// contiguous whitespace. + /// + /// # Example + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let s = B(" foo\tbar\t\u{2003}\nquux \n"); + /// let fields: Vec<&BStr> = s.fields().collect(); + /// assert_eq!(fields, vec!["foo", "bar", "quux"]); + /// ``` + /// + /// A byte string consisting of just whitespace yields no elements: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(0, B(" \n\t\u{2003}\n \t").fields().count()); + /// ``` + #[inline] + pub fn fields(&self) -> Fields { + Fields::new(self) + } + + /// Returns an iterator over the fields in a byte string, separated by + /// contiguous codepoints satisfying the given predicate. + /// + /// If this byte + /// + /// # Example + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let s = B("123foo999999bar1quux123456"); + /// let fields: Vec<&BStr> = s.fields_with(|c| c.is_numeric()).collect(); + /// assert_eq!(fields, vec!["foo", "bar", "quux"]); + /// ``` + /// + /// A byte string consisting of all codepoints satisfying the predicate + /// yields no elements: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(0, B("1911354563").fields_with(|c| c.is_numeric()).count()); + /// ``` + #[inline] + pub fn fields_with bool>(&self, f: F) -> FieldsWith { + FieldsWith::new(self, f) + } + + /// Returns an iterator over substrings of this byte string, separated + /// by the given byte string. Each element yielded is guaranteed not to + /// include the splitter substring. + /// + /// The splitter may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("Mary had a little lamb").split(" ").collect(); + /// assert_eq!(x, vec!["Mary", "had", "a", "little", "lamb"]); + /// + /// let x: Vec<&BStr> = B("").split("X").collect(); + /// assert_eq!(x, vec![""]); + /// + /// let x: Vec<&BStr> = B("lionXXtigerXleopard").split("X").collect(); + /// assert_eq!(x, vec!["lion", "", "tiger", "leopard"]); + /// + /// let x: Vec<&BStr> = B("lion::tiger::leopard").split("::").collect(); + /// assert_eq!(x, vec!["lion", "tiger", "leopard"]); + /// ``` + /// + /// If a string contains multiple contiguous separators, you will end up + /// with empty strings yielded by the iterator: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("||||a||b|c").split("|").collect(); + /// assert_eq!(x, vec!["", "", "", "", "a", "", "b", "c"]); + /// + /// let x: Vec<&BStr> = B("(///)").split("/").collect(); + /// assert_eq!(x, vec!["(", "", "", ")"]); + /// ``` + /// + /// Separators at the start or end of a string are neighbored by empty + /// strings. + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("010").split("0").collect(); + /// assert_eq!(x, vec!["", "1", ""]); + /// ``` + /// + /// When the empty string is used as a separator, it splits every **byte** + /// in the byte string, along with the beginning and end of the byte + /// string. + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("rust").split("").collect(); + /// assert_eq!(x, vec!["", "r", "u", "s", "t", ""]); + /// + /// // Splitting by an empty string is not UTF-8 aware. Elements yielded + /// // may not be valid UTF-8! + /// let x: Vec<&BStr> = B("☃").split("").collect(); + /// assert_eq!(x, vec![B(""), B(b"\xE2"), B(b"\x98"), B(b"\x83"), B("")]); + /// ``` + /// + /// Contiguous separators, especially whitespace, can lead to possibly + /// surprising behavior. For example, this code is correct: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B(" a b c").split(" ").collect(); + /// assert_eq!(x, vec!["", "", "", "", "a", "", "b", "c"]); + /// ``` + /// + /// It does *not* give you `["a", "b", "c"]`. For that behavior, use + /// [`fields`](#method.fields) instead. + #[inline] + pub fn split<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &'a B, + ) -> Split<'a> { + Split::new(self, BStr::new(splitter.as_ref())) + } + + /// Returns an iterator over substrings of this byte string, separated by + /// the given byte string, in reverse. Each element yielded is guaranteed + /// not to include the splitter substring. + /// + /// The splitter may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("Mary had a little lamb").rsplit(" ").collect(); + /// assert_eq!(x, vec!["lamb", "little", "a", "had", "Mary"]); + /// + /// let x: Vec<&BStr> = B("").rsplit("X").collect(); + /// assert_eq!(x, vec![""]); + /// + /// let x: Vec<&BStr> = B("lionXXtigerXleopard").rsplit("X").collect(); + /// assert_eq!(x, vec!["leopard", "tiger", "", "lion"]); + /// + /// let x: Vec<&BStr> = B("lion::tiger::leopard").rsplit("::").collect(); + /// assert_eq!(x, vec!["leopard", "tiger", "lion"]); + /// ``` + /// + /// If a string contains multiple contiguous separators, you will end up + /// with empty strings yielded by the iterator: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("||||a||b|c").rsplit("|").collect(); + /// assert_eq!(x, vec!["c", "b", "", "a", "", "", "", ""]); + /// + /// let x: Vec<&BStr> = B("(///)").rsplit("/").collect(); + /// assert_eq!(x, vec![")", "", "", "("]); + /// ``` + /// + /// Separators at the start or end of a string are neighbored by empty + /// strings. + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("010").rsplit("0").collect(); + /// assert_eq!(x, vec!["", "1", ""]); + /// ``` + /// + /// When the empty string is used as a separator, it splits every **byte** + /// in the byte string, along with the beginning and end of the byte + /// string. + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B("rust").rsplit("").collect(); + /// assert_eq!(x, vec!["", "t", "s", "u", "r", ""]); + /// + /// // Splitting by an empty string is not UTF-8 aware. Elements yielded + /// // may not be valid UTF-8! + /// let x: Vec<&BStr> = B("☃").rsplit("").collect(); + /// assert_eq!(x, vec![B(""), B(b"\x83"), B(b"\x98"), B(b"\xE2"), B("")]); + /// ``` + /// + /// Contiguous separators, especially whitespace, can lead to possibly + /// surprising behavior. For example, this code is correct: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<&BStr> = B(" a b c").rsplit(" ").collect(); + /// assert_eq!(x, vec!["c", "b", "", "a", "", "", "", ""]); + /// ``` + /// + /// It does *not* give you `["a", "b", "c"]`. + #[inline] + pub fn rsplit<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &'a B, + ) -> SplitReverse<'a> { + SplitReverse::new(self, BStr::new(splitter.as_ref())) + } + + /// Returns an iterator of at most `limit` substrings of this byte string, + /// separated by the given byte string. If `limit` substrings are yielded, + /// then the last substring will contain the remainder of this byte string. + /// + /// The splitter may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<_> = B("Mary had a little lamb").splitn(3, " ").collect(); + /// assert_eq!(x, vec!["Mary", "had", "a little lamb"]); + /// + /// let x: Vec<_> = B("").splitn(3, "X").collect(); + /// assert_eq!(x, vec![""]); + /// + /// let x: Vec<_> = B("lionXXtigerXleopard").splitn(3, "X").collect(); + /// assert_eq!(x, vec!["lion", "", "tigerXleopard"]); + /// + /// let x: Vec<_> = B("lion::tiger::leopard").splitn(2, "::").collect(); + /// assert_eq!(x, vec!["lion", "tiger::leopard"]); + /// + /// let x: Vec<_> = B("abcXdef").splitn(1, "X").collect(); + /// assert_eq!(x, vec!["abcXdef"]); + /// + /// let x: Vec<_> = B("abcXdef").splitn(0, "X").collect(); + /// assert!(x.is_empty()); + /// ``` + #[inline] + pub fn splitn<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + limit: usize, + splitter: &'a B, + ) -> SplitN<'a> { + SplitN::new(self, BStr::new(splitter.as_ref()), limit) + } + + /// Returns an iterator of at most `limit` substrings of this byte string, + /// separated by the given byte string, in reverse. If `limit` substrings + /// are yielded, then the last substring will contain the remainder of this + /// byte string. + /// + /// The splitter may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let x: Vec<_> = B("Mary had a little lamb").rsplitn(3, " ").collect(); + /// assert_eq!(x, vec!["lamb", "little", "Mary had a"]); + /// + /// let x: Vec<_> = B("").rsplitn(3, "X").collect(); + /// assert_eq!(x, vec![""]); + /// + /// let x: Vec<_> = B("lionXXtigerXleopard").rsplitn(3, "X").collect(); + /// assert_eq!(x, vec!["leopard", "tiger", "lionX"]); + /// + /// let x: Vec<_> = B("lion::tiger::leopard").rsplitn(2, "::").collect(); + /// assert_eq!(x, vec!["leopard", "lion::tiger"]); + /// + /// let x: Vec<_> = B("abcXdef").rsplitn(1, "X").collect(); + /// assert_eq!(x, vec!["abcXdef"]); + /// + /// let x: Vec<_> = B("abcXdef").rsplitn(0, "X").collect(); + /// assert!(x.is_empty()); + /// ``` + #[inline] + pub fn rsplitn<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + limit: usize, + splitter: &'a B, + ) -> SplitNReverse<'a> { + SplitNReverse::new(self, BStr::new(splitter.as_ref()), limit) + } + + /// Replace all matches of the given needle with the given replacement, and + /// the result as a new `BString`. + /// + /// This routine is useful as a convenience. If you need to reuse an + /// allocation, use [`replace_into`](#method.replace_into) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("this is old").replace("old", "new"); + /// assert_eq!(s, "this is new"); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("this is old").replace("nada nada", "limonada"); + /// assert_eq!(s, "this is old"); + /// ``` + /// + /// When the needle is an empty string: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo").replace("", "Z"); + /// assert_eq!(s, "ZfZoZoZ"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn replace, R: AsRef<[u8]>>( + &self, + needle: N, + replacement: R, + ) -> BString { + let mut dest = BString::with_capacity(self.len()); + self.replace_into(needle, replacement, &mut dest); + dest + } + + /// Replace up to `limit` matches of the given needle with the given + /// replacement, and the result as a new `BString`. + /// + /// This routine is useful as a convenience. If you need to reuse an + /// allocation, use [`replacen_into`](#method.replacen_into) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foofoo").replacen("o", "z", 2); + /// assert_eq!(s, "fzzfoo"); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foofoo").replacen("a", "z", 2); + /// assert_eq!(s, "foofoo"); + /// ``` + /// + /// When the needle is an empty string: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("foo").replacen("", "Z", 2); + /// assert_eq!(s, "ZfZoo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn replacen, R: AsRef<[u8]>>( + &self, + needle: N, + replacement: R, + limit: usize, + ) -> BString { + let mut dest = BString::with_capacity(self.len()); + self.replacen_into(needle, replacement, limit, &mut dest); + dest + } + + /// Replace all matches of the given needle with the given replacement, + /// and write the result into the provided `BString`. + /// + /// This does **not** clear `dest` before writing to it. + /// + /// This routine is useful for reusing allocation. For a more convenient + /// API, use [`replace`](#method.replace) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("this is old"); + /// + /// let mut dest = BString::new(); + /// s.replace_into("old", "new", &mut dest); + /// assert_eq!(dest, "this is new"); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("this is old"); + /// + /// let mut dest = BString::new(); + /// s.replace_into("nada nada", "limonada", &mut dest); + /// assert_eq!(dest, "this is old"); + /// ``` + /// + /// When the needle is an empty string: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("foo"); + /// + /// let mut dest = BString::new(); + /// s.replace_into("", "Z", &mut dest); + /// assert_eq!(dest, "ZfZoZoZ"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn replace_into, R: AsRef<[u8]>>( + &self, + needle: N, + replacement: R, + dest: &mut BString, + ) { + let (needle, replacement) = (needle.as_ref(), replacement.as_ref()); + + let mut last = 0; + for start in self.find_iter(needle) { + dest.push(&self[last..start]); + dest.push(replacement); + last = start + needle.len(); + } + dest.push(&self[last..]); + } + + /// Replace up to `limit` matches of the given needle with the given + /// replacement, and write the result into the provided `BString`. + /// + /// This does **not** clear `dest` before writing to it. + /// + /// This routine is useful for reusing allocation. For a more convenient + /// API, use [`replace`](#method.replacen) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("foofoo"); + /// + /// let mut dest = BString::new(); + /// s.replacen_into("o", "z", 2, &mut dest); + /// assert_eq!(dest, "fzzfoo"); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("foofoo"); + /// + /// let mut dest = BString::new(); + /// s.replacen_into("a", "z", 2, &mut dest); + /// assert_eq!(dest, "foofoo"); + /// ``` + /// + /// When the needle is an empty string: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("foo"); + /// + /// let mut dest = BString::new(); + /// s.replacen_into("", "Z", 2, &mut dest); + /// assert_eq!(dest, "ZfZoo"); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn replacen_into, R: AsRef<[u8]>>( + &self, + needle: N, + replacement: R, + limit: usize, + dest: &mut BString, + ) { + let (needle, replacement) = (needle.as_ref(), replacement.as_ref()); + + let mut last = 0; + for start in self.find_iter(needle).take(limit) { + dest.push(&self[last..start]); + dest.push(replacement); + last = start + needle.len(); + } + dest.push(&self[last..]); + } + + /// Returns an iterator over the bytes in this byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("foobar"); + /// let bytes: Vec = bs.bytes().collect(); + /// assert_eq!(bytes, bs); + /// ``` + #[inline] + pub fn bytes(&self) -> Bytes { + Bytes { it: self.as_bytes().iter() } + } + + /// Returns an iterator over the Unicode scalar values in this byte string. + /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint + /// is yielded instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"); + /// let chars: Vec = bs.chars().collect(); + /// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars); + /// ``` + /// + /// Codepoints can also be iterated over in reverse: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"); + /// let chars: Vec = bs.chars().rev().collect(); + /// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars); + /// ``` + #[inline] + pub fn chars(&self) -> Chars { + Chars::new(self) + } + + /// Returns an iterator over the Unicode scalar values in this byte string + /// along with their starting and ending byte index positions. If invalid + /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded + /// instead. + /// + /// Note that this is slightly different from the `CharIndices` iterator + /// provided by the standard library. Aside from working on possibly + /// invalid UTF-8, this iterator provides both the corresponding starting + /// and ending byte indices of each codepoint yielded. The ending position + /// is necessary to slice the original byte string when invalid UTF-8 bytes + /// are converted into a Unicode replacement codepoint, since a single + /// replacement codepoint can substitute anywhere from 1 to 3 invalid bytes + /// (inclusive). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"); + /// let chars: Vec<(usize, usize, char)> = bs.char_indices().collect(); + /// assert_eq!(chars, vec![ + /// (0, 3, '☃'), + /// (3, 4, '\u{FFFD}'), + /// (4, 8, '𝞃'), + /// (8, 10, '\u{FFFD}'), + /// (10, 11, 'a'), + /// ]); + /// ``` + /// + /// Codepoints can also be iterated over in reverse: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"); + /// let chars: Vec<(usize, usize, char)> = bs + /// .char_indices() + /// .rev() + /// .collect(); + /// assert_eq!(chars, vec![ + /// (10, 11, 'a'), + /// (8, 10, '\u{FFFD}'), + /// (4, 8, '𝞃'), + /// (3, 4, '\u{FFFD}'), + /// (0, 3, '☃'), + /// ]); + /// ``` + #[inline] + pub fn char_indices(&self) -> CharIndices { + CharIndices::new(self) + } + + /// Returns an iterator over the grapheme clusters in this byte string. + /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint + /// is yielded instead. + /// + /// # Examples + /// + /// This example shows how multiple codepoints can combine to form a + /// single grapheme cluster: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}"); + /// let graphemes: Vec<&str> = bs.graphemes().collect(); + /// assert_eq!(vec!["à̖", "🇺🇸"], graphemes); + /// ``` + /// + /// This shows that graphemes can be iterated over in reverse: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}"); + /// let graphemes: Vec<&str> = bs.graphemes().rev().collect(); + /// assert_eq!(vec!["🇺🇸", "à̖"], graphemes); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn graphemes(&self) -> Graphemes { + Graphemes::new(self) + } + + /// Returns an iterator over the grapheme clusters in this byte string + /// along with their starting and ending byte index positions. If invalid + /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded + /// instead. + /// + /// # Examples + /// + /// This example shows how to get the byte offsets of each individual + /// grapheme cluster: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}"); + /// let graphemes: Vec<(usize, usize, &str)> = + /// bs.grapheme_indices().collect(); + /// assert_eq!(vec![(0, 5, "à̖"), (5, 13, "🇺🇸")], graphemes); + /// ``` + /// + /// This example shows what happens when invalid UTF-8 is enountered. Note + /// that the offsets are valid indices into the original string, and do + /// not necessarily correspond to the length of the `&str` returned! + /// + /// ``` + /// use bstr::BString; + /// + /// let mut bytes = BString::new(); + /// bytes.push("a\u{0300}\u{0316}"); + /// bytes.push_byte(b'\xFF'); + /// bytes.push("\u{1F1FA}\u{1F1F8}"); + /// + /// let graphemes: Vec<(usize, usize, &str)> = + /// bytes.grapheme_indices().collect(); + /// assert_eq!( + /// graphemes, + /// vec![(0, 5, "à̖"), (5, 6, "\u{FFFD}"), (6, 14, "🇺🇸")] + /// ); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn grapheme_indices(&self) -> GraphemeIndices { + GraphemeIndices::new(self) + } + + /// Returns an iterator over the words in this byte string. If invalid + /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded + /// instead. + /// + /// This is similar to + /// [`words_with_breaks`](struct.BStr.html#method.words_with_breaks), + /// except it only returns elements that contain a "word" character. A word + /// character is defined by UTS #18 (Annex C) to be the combination of the + /// `Alphabetic` and `Join_Control` properties, along with the + /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general + /// categories. + /// + /// Since words are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(r#"The quick ("brown") fox can't jump 32.3 feet, right?"#); + /// let words: Vec<&str> = bs.words().collect(); + /// assert_eq!(words, vec![ + /// "The", "quick", "brown", "fox", "can't", + /// "jump", "32.3", "feet", "right", + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn words(&self) -> Words { + Words::new(self) + } + + /// Returns an iterator over the words in this byte string along with + /// their starting and ending byte index positions. + /// + /// This is similar to + /// [`words_with_break_indices`](struct.BStr.html#method.words_with_break_indices), + /// except it only returns elements that contain a "word" character. A word + /// character is defined by UTS #18 (Annex C) to be the combination of the + /// `Alphabetic` and `Join_Control` properties, along with the + /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general + /// categories. + /// + /// Since words are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// This example shows how to get the byte offsets of each individual + /// word: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("can't jump 32.3 feet"); + /// let words: Vec<(usize, usize, &str)> = bs.word_indices().collect(); + /// assert_eq!(words, vec![ + /// (0, 5, "can't"), + /// (6, 10, "jump"), + /// (11, 15, "32.3"), + /// (16, 20, "feet"), + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn word_indices(&self) -> WordIndices { + WordIndices::new(self) + } + + /// Returns an iterator over the words in this byte string, along with + /// all breaks between the words. Concatenating all elements yielded by + /// the iterator results in the original string (modulo Unicode replacement + /// codepoint substitutions if invalid UTF-8 is encountered). + /// + /// Since words are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B(r#"The quick ("brown") fox can't jump 32.3 feet, right?"#); + /// let words: Vec<&str> = bs.words_with_breaks().collect(); + /// assert_eq!(words, vec![ + /// "The", " ", "quick", " ", "(", "\"", "brown", "\"", ")", + /// " ", "fox", " ", "can't", " ", "jump", " ", "32.3", " ", "feet", + /// ",", " ", "right", "?", + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn words_with_breaks(&self) -> WordsWithBreaks { + WordsWithBreaks::new(self) + } + + /// Returns an iterator over the words and their byte offsets in this + /// byte string, along with all breaks between the words. Concatenating + /// all elements yielded by the iterator results in the original string + /// (modulo Unicode replacement codepoint substitutions if invalid UTF-8 is + /// encountered). + /// + /// Since words are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// This example shows how to get the byte offsets of each individual + /// word: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("can't jump 32.3 feet"); + /// let words: Vec<(usize, usize, &str)> = + /// bs.words_with_break_indices().collect(); + /// assert_eq!(words, vec![ + /// (0, 5, "can't"), + /// (5, 6, " "), + /// (6, 10, "jump"), + /// (10, 11, " "), + /// (11, 15, "32.3"), + /// (15, 16, " "), + /// (16, 20, "feet"), + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn words_with_break_indices(&self) -> WordsWithBreakIndices { + WordsWithBreakIndices::new(self) + } + + /// Returns an iterator over the sentences in this byte string. + /// + /// Typically, a sentence will include its trailing punctuation and + /// whitespace. Concatenating all elements yielded by the iterator + /// results in the original string (modulo Unicode replacement codepoint + /// substitutions if invalid UTF-8 is encountered). + /// + /// Since sentences are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("I want this. Not that. Right now."); + /// let sentences: Vec<&str> = bs.sentences().collect(); + /// assert_eq!(sentences, vec![ + /// "I want this. ", + /// "Not that. ", + /// "Right now.", + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn sentences(&self) -> Sentences { + Sentences::new(self) + } + + /// Returns an iterator over the sentences in this byte string along with + /// their starting and ending byte index positions. + /// + /// Typically, a sentence will include its trailing punctuation and + /// whitespace. Concatenating all elements yielded by the iterator + /// results in the original string (modulo Unicode replacement codepoint + /// substitutions if invalid UTF-8 is encountered). + /// + /// Since sentences are made up of one or more codepoints, this iterator + /// yields `&str` elements. When invalid UTF-8 is encountered, replacement + /// codepoints are [substituted](index.html#handling-of-invalid-utf-8). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let bs = B("I want this. Not that. Right now."); + /// let sentences: Vec<(usize, usize, &str)> = + /// bs.sentence_indices().collect(); + /// assert_eq!(sentences, vec![ + /// (0, 13, "I want this. "), + /// (13, 23, "Not that. "), + /// (23, 33, "Right now."), + /// ]); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn sentence_indices(&self) -> SentenceIndices { + SentenceIndices::new(self) + } + + /// An iterator over all lines in a byte string, without their + /// terminators. + /// + /// For this iterator, the only line terminators recognized are `\r\n` and + /// `\n`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let s = B("\ + /// foo + /// + /// bar\r + /// baz + /// + /// + /// quux"); + /// let lines: Vec<&BStr> = s.lines().collect(); + /// assert_eq!(lines, vec![ + /// "foo", "", "bar", "baz", "", "", "quux", + /// ]); + /// ``` + #[inline] + pub fn lines(&self) -> Lines { + Lines::new(self) + } + + /// An iterator over all lines in a byte string, including their + /// terminators. + /// + /// For this iterator, the only line terminator recognized is `\n`. (Since + /// line terminators are included, this also handles `\r\n` line endings.) + /// + /// Line terminators are only included if they are present in the original + /// byte string. For example, the last line in a byte string may not end + /// with a line terminator. + /// + /// Concatenating all elements yielded by this iterator is guaranteed to + /// yield the original byte string. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BStr}; + /// + /// let s = B("\ + /// foo + /// + /// bar\r + /// baz + /// + /// + /// quux"); + /// let lines: Vec<&BStr> = s.lines_with_terminator().collect(); + /// assert_eq!(lines, vec![ + /// "foo\n", "\n", "bar\r\n", "baz\n", "\n", "\n", "quux", + /// ]); + /// ``` + #[inline] + pub fn lines_with_terminator(&self) -> LinesWithTerminator { + LinesWithTerminator::new(self) + } + + /// Return a byte string slice with leading and trailing whitespace + /// removed. + /// + /// Whitespace is defined according to the terms of the `White_Space` + /// Unicode property. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B(" foo\tbar\t\u{2003}\n"); + /// assert_eq!(s.trim(), "foo\tbar"); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn trim(&self) -> &BStr { + self.trim_start().trim_end() + } + + /// Return a byte string slice with leading whitespace removed. + /// + /// Whitespace is defined according to the terms of the `White_Space` + /// Unicode property. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B(" foo\tbar\t\u{2003}\n"); + /// assert_eq!(s.trim_start(), "foo\tbar\t\u{2003}\n"); + /// ``` + #[inline] + pub fn trim_start(&self) -> &BStr { + self.trim_start_imp() + } + + #[cfg(feature = "unicode")] + #[inline] + fn trim_start_imp(&self) -> &BStr { + let start = whitespace_len_fwd(self.as_bytes()); + &self[start..] + } + + #[cfg(not(feature = "unicode"))] + #[inline] + fn trim_start_imp(&self) -> &BStr { + self.trim_start_with(|c| c.is_whitespace()) + } + + /// Return a byte string slice with trailing whitespace removed. + /// + /// Whitespace is defined according to the terms of the `White_Space` + /// Unicode property. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B(" foo\tbar\t\u{2003}\n"); + /// assert_eq!(s.trim_end(), " foo\tbar"); + /// ``` + #[inline] + pub fn trim_end(&self) -> &BStr { + self.trim_end_imp() + } + + #[cfg(feature = "unicode")] + #[inline] + fn trim_end_imp(&self) -> &BStr { + let end = whitespace_len_rev(self.as_bytes()); + &self[..end] + } + + #[cfg(not(feature = "unicode"))] + #[inline] + fn trim_end_imp(&self) -> &BStr { + self.trim_end_with(|c| c.is_whitespace()) + } + + /// Return a byte string slice with leading and trailing characters + /// satisfying the given predicate removed. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("123foo5bar789"); + /// assert_eq!(s.trim_with(|c| c.is_numeric()), "foo5bar"); + /// ``` + #[inline] + pub fn trim_with bool>(&self, mut trim: F) -> &BStr { + self.trim_start_with(&mut trim).trim_end_with(&mut trim) + } + + /// Return a byte string slice with leading characters satisfying the given + /// predicate removed. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("123foo5bar789"); + /// assert_eq!(s.trim_start_with(|c| c.is_numeric()), "foo5bar789"); + /// ``` + #[inline] + pub fn trim_start_with bool>( + &self, + mut trim: F, + ) -> &BStr { + for (s, _, ch) in self.char_indices() { + if !trim(ch) { + return &self[s..]; + } + } + B("") + } + + /// Return a byte string slice with trailing characters satisfying the + /// given predicate removed. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("123foo5bar"); + /// assert_eq!(s.trim_end_with(|c| c.is_numeric()), "123foo5bar"); + /// ``` + #[inline] + pub fn trim_end_with bool>( + &self, + mut trim: F, + ) -> &BStr { + for (_, e, ch) in self.char_indices().rev() { + if !trim(ch) { + return &self[..e]; + } + } + B("") + } + + /// Returns a new `BString` containing the lowercase equivalent of this + /// byte string. + /// + /// In this case, lowercase is defined according to the `Lowercase` Unicode + /// property. + /// + /// If invalid UTF-8 is seen, or if a character has no lowercase variant, + /// then it is written to the given buffer unchanged. + /// + /// Note that some characters in this byte string may expand into multiple + /// characters when changing the case, so the number of bytes written to + /// the given byte string may not be equivalent to the number of bytes in + /// this byte string. + /// + /// If you'd like to reuse an allocation for performance reasons, then use + /// [`to_lowercase_into`](#method.to_lowercase_into) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("HELLO Β"); + /// assert_eq!("hello β", s.to_lowercase()); + /// ``` + /// + /// Scripts without case are not changed: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("农历新年"); + /// assert_eq!("农历新年", s.to_lowercase()); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ"); + /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s.to_lowercase()); + /// ``` + #[cfg(all(feature = "std", feature = "unicode"))] + #[inline] + pub fn to_lowercase(&self) -> BString { + let mut buf = BString::new(); + self.to_lowercase_into(&mut buf); + buf + } + + /// Writes the lowercase equivalent of this byte string into the given + /// buffer. The buffer is not cleared before written to. + /// + /// In this case, lowercase is defined according to the `Lowercase` + /// Unicode property. + /// + /// If invalid UTF-8 is seen, or if a character has no lowercase variant, + /// then it is written to the given buffer unchanged. + /// + /// Note that some characters in this byte string may expand into multiple + /// characters when changing the case, so the number of bytes written to + /// the given byte string may not be equivalent to the number of bytes in + /// this byte string. + /// + /// If you don't need to amortize allocation and instead prefer + /// convenience, then use [`to_lowercase`](#method.to_lowercase) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("HELLO Β"); + /// + /// let mut buf = BString::new(); + /// s.to_lowercase_into(&mut buf); + /// assert_eq!("hello β", buf); + /// ``` + /// + /// Scripts without case are not changed: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("农历新年"); + /// + /// let mut buf = BString::new(); + /// s.to_lowercase_into(&mut buf); + /// assert_eq!("农历新年", buf); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ"); + /// + /// let mut buf = BString::new(); + /// s.to_lowercase_into(&mut buf); + /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), buf); + /// ``` + #[cfg(all(feature = "std", feature = "unicode"))] + #[inline] + pub fn to_lowercase_into(&self, buf: &mut BString) { + // TODO: This is the best we can do given what std exposes I think. + // If we roll our own case handling, then we might be able to do this + // a bit faster. We shouldn't roll our own case handling unless we + // need to, e.g., for doing caseless matching or case folding. + + // TODO(BUG): This doesn't handle any special casing rules. + + buf.reserve(self.len()); + for (s, e, ch) in self.char_indices() { + if ch == '\u{FFFD}' { + buf.push(&self[s..e]); + } else { + for upper in ch.to_lowercase() { + buf.push_char(upper); + } + } + } + } + + /// Returns a new `BString` containing the ASCII lowercase equivalent of + /// this byte string. + /// + /// In this case, lowercase is only defined in ASCII letters. Namely, the + /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged. + /// In particular, the length of the byte string returned is always + /// equivalent to the length of this byte string. + /// + /// If you'd like to reuse an allocation for performance reasons, then use + /// [`make_ascii_lowercase`](#method.make_ascii_lowercase) to perform + /// the conversion in place. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("HELLO Β"); + /// assert_eq!("hello Β", s.to_ascii_lowercase()); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ"); + /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s.to_ascii_lowercase()); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_ascii_lowercase(&self) -> BString { + BString::from(self.as_bytes().to_ascii_lowercase()) + } + + /// Convert this byte string to its lowercase ASCII equivalent in place. + /// + /// In this case, lowercase is only defined in ASCII letters. Namely, the + /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged. + /// + /// If you don't need to do the conversion in + /// place and instead prefer convenience, then use + /// [`to_ascii_lowercase`](#method.to_ascii_lowercase) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("HELLO Β"); + /// s.make_ascii_lowercase(); + /// assert_eq!("hello Β", s); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let mut s = BString::from_slice(b"FOO\xFFBAR\xE2\x98BAZ"); + /// s.make_ascii_lowercase(); + /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s); + /// ``` + #[inline] + pub fn make_ascii_lowercase(&mut self) { + self.as_bytes_mut().make_ascii_lowercase(); + } + + /// Returns a new `BString` containing the uppercase equivalent of this + /// byte string. + /// + /// In this case, uppercase is defined according to the `Uppercase` + /// Unicode property. + /// + /// If invalid UTF-8 is seen, or if a character has no uppercase variant, + /// then it is written to the given buffer unchanged. + /// + /// Note that some characters in this byte string may expand into multiple + /// characters when changing the case, so the number of bytes written to + /// the given byte string may not be equivalent to the number of bytes in + /// this byte string. + /// + /// If you'd like to reuse an allocation for performance reasons, then use + /// [`to_uppercase_into`](#method.to_uppercase_into) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("hello β"); + /// assert_eq!("HELLO Β", s.to_uppercase()); + /// ``` + /// + /// Scripts without case are not changed: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("农历新年"); + /// assert_eq!("农历新年", s.to_uppercase()); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"foo\xFFbar\xE2\x98baz"); + /// assert_eq!(B(b"FOO\xFFBAR\xE2\x98BAZ"), s.to_uppercase()); + /// ``` + #[cfg(all(feature = "std", feature = "unicode"))] + #[inline] + pub fn to_uppercase(&self) -> BString { + let mut buf = BString::new(); + self.to_uppercase_into(&mut buf); + buf + } + + /// Writes the uppercase equivalent of this byte string into the given + /// buffer. The buffer is not cleared before written to. + /// + /// In this case, uppercase is defined according to the `Uppercase` + /// Unicode property. + /// + /// If invalid UTF-8 is seen, or if a character has no uppercase variant, + /// then it is written to the given buffer unchanged. + /// + /// Note that some characters in this byte string may expand into multiple + /// characters when changing the case, so the number of bytes written to + /// the given byte string may not be equivalent to the number of bytes in + /// this byte string. + /// + /// If you don't need to amortize allocation and instead prefer + /// convenience, then use [`to_uppercase`](#method.to_uppercase) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("hello β"); + /// + /// let mut buf = BString::new(); + /// s.to_uppercase_into(&mut buf); + /// assert_eq!("HELLO Β", buf); + /// ``` + /// + /// Scripts without case are not changed: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("农历新年"); + /// + /// let mut buf = BString::new(); + /// s.to_uppercase_into(&mut buf); + /// assert_eq!("农历新年", buf); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"foo\xFFbar\xE2\x98baz"); + /// + /// let mut buf = BString::new(); + /// s.to_uppercase_into(&mut buf); + /// assert_eq!(B(b"FOO\xFFBAR\xE2\x98BAZ"), buf); + /// ``` + #[cfg(all(feature = "std", feature = "unicode"))] + #[inline] + pub fn to_uppercase_into(&self, buf: &mut BString) { + // TODO: This is the best we can do given what std exposes I think. + // If we roll our own case handling, then we might be able to do this + // a bit faster. We shouldn't roll our own case handling unless we + // need to, e.g., for doing caseless matching or case folding. + buf.reserve(self.len()); + for (s, e, ch) in self.char_indices() { + if ch == '\u{FFFD}' { + buf.push(&self[s..e]); + } else if ch.is_ascii() { + buf.push_char(ch.to_ascii_uppercase()); + } else { + for upper in ch.to_uppercase() { + buf.push_char(upper); + } + } + } + } + + /// Returns a new `BString` containing the ASCII uppercase equivalent of + /// this byte string. + /// + /// In this case, uppercase is only defined in ASCII letters. Namely, the + /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged. + /// In particular, the length of the byte string returned is always + /// equivalent to the length of this byte string. + /// + /// If you'd like to reuse an allocation for performance reasons, then use + /// [`make_ascii_uppercase`](#method.make_ascii_uppercase) to perform + /// the conversion in place. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B("hello β"); + /// assert_eq!("HELLO β", s.to_ascii_uppercase()); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let s = B(b"foo\xFFbar\xE2\x98baz"); + /// assert_eq!(B(b"FOO\xFFBAR\xE2\x98BAZ"), s.to_ascii_uppercase()); + /// ``` + #[cfg(feature = "std")] + #[inline] + pub fn to_ascii_uppercase(&self) -> BString { + BString::from(self.as_bytes().to_ascii_uppercase()) + } + + /// Convert this byte string to its uppercase ASCII equivalent in place. + /// + /// In this case, uppercase is only defined in ASCII letters. Namely, the + /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged. + /// + /// If you don't need to do the conversion in + /// place and instead prefer convenience, then use + /// [`to_ascii_uppercase`](#method.to_ascii_uppercase) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("hello β"); + /// s.make_ascii_uppercase(); + /// assert_eq!("HELLO β", s); + /// ``` + /// + /// Invalid UTF-8 remains as is: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let mut s = BString::from_slice(b"foo\xFFbar\xE2\x98baz"); + /// s.make_ascii_uppercase(); + /// assert_eq!(B(b"FOO\xFFBAR\xE2\x98BAZ"), s); + /// ``` + #[inline] + pub fn make_ascii_uppercase(&mut self) { + self.as_bytes_mut().make_ascii_uppercase(); + } + + /// Reverse the bytes in this string, in place. + /// + /// Note that this is not necessarily a well formed operation. For example, + /// if this byte string contains valid UTF-8 that isn't ASCII, then + /// reversing the string will likely result in invalid UTF-8 and otherwise + /// non-sensical content. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("hello"); + /// s.reverse_bytes(); + /// assert_eq!(s, "olleh"); + /// ``` + #[inline] + pub fn reverse_bytes(&mut self) { + self.as_bytes_mut().reverse(); + } + + /// Reverse the codepoints in this string, in place. + /// + /// If this byte string is valid UTF-8, then its reversal by codepoint + /// is also guaranteed to be valid UTF-8. + /// + /// This operation is equivalent to the following, but without allocating: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo☃bar"); + /// + /// let mut chars: Vec = s.chars().collect(); + /// chars.reverse(); + /// + /// let reversed: String = chars.into_iter().collect(); + /// assert_eq!(reversed, "rab☃oof"); + /// ``` + /// + /// Note that this is not necessarily a well formed operation. For example, + /// if this byte string contains grapheme clusters with more than one + /// codepoint, then those grapheme clusters will not necessarily be + /// preserved. If you'd like to preserve grapheme clusters, then use + /// [`reverse_graphemes`](#method.reverse_graphemes) instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo☃bar"); + /// s.reverse_chars(); + /// assert_eq!(s, "rab☃oof"); + /// ``` + /// + /// This example shows that not all reversals lead to a well formed string. + /// For example, in this case, combining marks are used to put accents over + /// some letters, and those accent marks must appear after the codepoints + /// they modify. + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let mut s = BString::from("résumé"); + /// s.reverse_chars(); + /// assert_eq!(s, B(b"\xCC\x81emus\xCC\x81er")); + /// ``` + /// + /// A word of warning: the above example relies on the fact that + /// `résumé` is in decomposed normal form, which means there are separate + /// codepoints for the accents above `e`. If it is instead in composed + /// normal form, then the example works: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let mut s = BString::from("résumé"); + /// s.reverse_chars(); + /// assert_eq!(s, "émusér"); + /// ``` + /// + /// The point here is to be cautious and not assume that just because + /// `reverse_chars` works in one case, that it therefore works in all + /// cases. + #[inline] + pub fn reverse_chars(&mut self) { + let mut i = 0; + loop { + let (_, size) = utf8::decode(self[i..].as_bytes()); + if size == 0 { + break; + } + if size > 1 { + self[i..i + size].reverse_bytes(); + } + i += size; + } + self.reverse_bytes(); + } + + /// Reverse the graphemes in this string, in place. + /// + /// If this byte string is valid UTF-8, then its reversal by grapheme + /// is also guaranteed to be valid UTF-8. + /// + /// This operation is equivalent to the following, but without allocating: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo☃bar"); + /// + /// let mut graphemes: Vec<&str> = s.graphemes().collect(); + /// graphemes.reverse(); + /// + /// let reversed = graphemes.concat(); + /// assert_eq!(reversed, "rab☃oof"); + /// ``` + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("foo☃bar"); + /// s.reverse_graphemes(); + /// assert_eq!(s, "rab☃oof"); + /// ``` + /// + /// This example shows how this correctly handles grapheme clusters, + /// unlike `reverse_chars`. + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("résumé"); + /// s.reverse_graphemes(); + /// assert_eq!(s, "émusér"); + /// ``` + #[cfg(feature = "unicode")] + #[inline] + pub fn reverse_graphemes(&mut self) { + use unicode::decode_grapheme; + + let mut i = 0; + loop { + let (_, size) = decode_grapheme(&self[i..]); + if size == 0 { + break; + } + if size > 1 { + self[i..i + size].reverse_bytes(); + } + i += size; + } + self.reverse_bytes(); + } + + /// Returns true if and only if every byte in this byte string is ASCII. + /// + /// ASCII is an encoding that defines 128 codepoints. A byte corresponds to + /// an ASCII codepoint if and only if it is in the inclusive range + /// `[0, 127]`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert!(B("abc").is_ascii()); + /// assert!(!B("☃βツ").is_ascii()); + /// assert!(!B(b"\xFF").is_ascii()); + /// ``` + #[inline] + pub fn is_ascii(&self) -> bool { + ascii::first_non_ascii_byte(&self.bytes) == self.len() + } + + /// Returns true if and only if the entire byte string is valid UTF-8. + /// + /// If you need location information about where a byte string's first + /// invalid UTF-8 byte is, then use the [`to_str`](#method.to_str) method. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert!(B("abc").is_utf8()); + /// assert!(B("☃βツ").is_utf8()); + /// // invalid bytes + /// assert!(!B(b"abc\xFF").is_utf8()); + /// // surrogate encoding + /// assert!(!B(b"\xED\xA0\x80").is_utf8()); + /// // incomplete sequence + /// assert!(!B(b"\xF0\x9D\x9Ca").is_utf8()); + /// // overlong sequence + /// assert!(!B(b"\xF0\x82\x82\xAC").is_utf8()); + /// ``` + #[inline] + pub fn is_utf8(&self) -> bool { + utf8::validate(self.as_bytes()).is_ok() + } + + /// Divides this byte string into two at an index. + /// + /// The first byte string will contain all bytes at indices `[0, at)`, and + /// the second byte string will contain all bytes at indices `[at, len)`. + /// + /// # Panics + /// + /// Panics if `at > len`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(B("foobar").split_at(3), (B("foo"), B("bar"))); + /// assert_eq!(B("foobar").split_at(0), (B(""), B("foobar"))); + /// assert_eq!(B("foobar").split_at(6), (B("foobar"), B(""))); + /// ``` + #[inline] + pub fn split_at(&self, at: usize) -> (&BStr, &BStr) { + let (left, right) = self.as_bytes().split_at(at); + (BStr::new(left), BStr::new(right)) + } + + /// Divides this mutable byte string into two at an index. + /// + /// The first byte string will contain all bytes at indices `[0, at)`, and + /// the second byte string will contain all bytes at indices `[at, len)`. + /// + /// # Panics + /// + /// Panics if `at > len`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::{B, BString}; + /// + /// let mut b = BString::from("foobar"); + /// { + /// let (left, right) = b.split_at_mut(3); + /// left[2] = b'z'; + /// right[2] = b'z'; + /// } + /// assert_eq!(b, B("fozbaz")); + /// ``` + #[inline] + pub fn split_at_mut(&mut self, at: usize) -> (&mut BStr, &mut BStr) { + let (left, right) = self.as_bytes_mut().split_at_mut(at); + (BStr::new_mut(left), BStr::new_mut(right)) + } + + /// Retrieve a reference to a byte or a subslice, depending on the type of + /// the index given. + /// + /// If given a position, this returns a reference to the byte at that + /// position, if it exists. + /// + /// If given a range, this returns the slice of bytes corresponding to that + /// range in this byte string. + /// + /// In the case of invalid indices, this returns `None`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("baz"); + /// assert_eq!(s.get(1), Some(&b'a')); + /// assert_eq!(s.get(0..2), Some(B("ba"))); + /// assert_eq!(s.get(2..), Some(B("z"))); + /// assert_eq!(s.get(1..=2), Some(B("az"))); + /// ``` + #[inline] + pub fn get(&self, at: I) -> Option<&I::Output> { + at.get(self) + } + + /// Retrieve a mutable reference to a byte or a subslice, depending on the + /// type of the index given. + /// + /// If given a position, this returns a reference to the byte at that + /// position, if it exists. + /// + /// If given a range, this returns the slice of bytes corresponding to that + /// range in this byte string. + /// + /// In the case of invalid indices, this returns `None`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("baz"); + /// if let Some(mut slice) = s.get_mut(1..) { + /// slice[0] = b'o'; + /// slice[1] = b'p'; + /// } + /// assert_eq!(s, "bop"); + /// ``` + #[inline] + pub fn get_mut(&mut self, at: I) -> Option<&mut I::Output> { + at.get_mut(self) + } + + /// Retrieve a reference to a byte or a subslice, depending on the type of + /// the index given, while explicitly eliding bounds checks. + /// + /// If given a position, this returns a reference to the byte at that + /// position, if it exists. + /// + /// If given a range, this returns the slice of bytes corresponding to that + /// range in this byte string. + /// + /// In the case of invalid indices, this returns `None`. + /// + /// # Safety + /// + /// Callers must ensure that the supplied bounds are correct. If they + /// are out of bounds, then this results in undefined behavior. For a + /// safe alternative, use [`get`](#method.get). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("baz"); + /// unsafe { + /// assert_eq!(s.get_unchecked(1), &b'a'); + /// assert_eq!(s.get_unchecked(0..2), "ba"); + /// assert_eq!(s.get_unchecked(2..), "z"); + /// assert_eq!(s.get_unchecked(1..=2), "az"); + /// } + /// ``` + pub unsafe fn get_unchecked(&self, at: I) -> &I::Output { + at.get_unchecked(self) + } + + /// Retrieve a mutable reference to a byte or a subslice, depending on the + /// type of the index given, while explicitly eliding bounds checks. + /// + /// If given a position, this returns a reference to the byte at that + /// position, if it exists. + /// + /// If given a range, this returns the slice of bytes corresponding to that + /// range in this byte string. + /// + /// In the case of invalid indices, this returns `None`. + /// + /// # Safety + /// + /// Callers must ensure that the supplied bounds are correct. If they + /// are out of bounds, then this results in undefined behavior. For a + /// safe alternative, use [`get_mut`](#method.get_mut). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BString; + /// + /// let mut s = BString::from("baz"); + /// { + /// let mut slice = unsafe { s.get_unchecked_mut(1..) }; + /// slice[0] = b'o'; + /// slice[1] = b'p'; + /// } + /// assert_eq!(s, "bop"); + /// ``` + pub unsafe fn get_unchecked_mut( + &mut self, + at: I, + ) -> &mut I::Output { + at.get_unchecked_mut(self) + } + + /// Returns the last byte in this byte string, if it's non-empty. If this + /// byte string is empty, this returns `None`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// assert_eq!(Some(b'z'), B("baz").last()); + /// assert_eq!(None, B("").last()); + /// ``` + #[inline] + pub fn last(&self) -> Option { + self.get(self.len().saturating_sub(1)).map(|&b| b) + } + + /// Copies elements from one part of the slice to another part of itself, + /// where the parts may be overlapping. + /// + /// `src` is the range within this byte string to copy from, while `dest` + /// is the starting index of the range within this byte string to copy to. + /// The length indicated by `src` must be less than or equal to the number + /// of bytes from `dest` to the end of the byte string. + /// + /// # Panics + /// + /// Panics if either range is out of bounds, or if `src` is too big to fit + /// into `dest`, or if the end of `src` is before the start. + /// + /// # Examples + /// + /// Copying four bytes within a byte string: + /// + /// ``` + /// use bstr::BStr; + /// + /// let mut buf = *b"Hello, World!"; + /// let s = BStr::new_mut(&mut buf); + /// s.copy_within(1..5, 8); + /// assert_eq!(s, "Hello, Wello!"); + /// ``` + #[inline] + pub fn copy_within( + &mut self, + src: R, + dest: usize, + ) where R: ops::RangeBounds + { + let src_start = match src.start_bound() { + ops::Bound::Included(&n) => n, + ops::Bound::Excluded(&n) => { + n.checked_add(1).expect("attempted to index slice beyond max") + } + ops::Bound::Unbounded => 0, + }; + let src_end = match src.end_bound() { + ops::Bound::Included(&n) => { + n.checked_add(1).expect("attempted to index slice beyond max") + } + ops::Bound::Excluded(&n) => n, + ops::Bound::Unbounded => self.len(), + }; + assert!(src_start <= src_end, "src end is before src start"); + assert!(src_end <= self.len(), "src is out of bounds"); + let count = src_end - src_start; + assert!(dest <= self.len() - count, "dest is out of bounds"); + + // SAFETY: This is safe because we use ptr::copy to handle overlapping + // copies, and is also safe because we've checked all the bounds above. + // Finally, we are only dealing with u8 data, which is Copy, which + // means we can copy without worrying about ownership/destructors. + unsafe { + ptr::copy( + self.get_unchecked(src_start), + self.get_unchecked_mut(dest), + count, + ); + } + } + + /// Returns a raw pointer to this byte string's underlying bytes. + /// + /// # Safety + /// + /// The caller must ensure that the byte string outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// Modifying the container (like a `BString`) referenced by this byte + /// string may cause its buffer to be reallocated, which would also make + /// any pointers to it invalid. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B("hello"); + /// let p = s.as_ptr(); + /// + /// unsafe { + /// assert_eq!(*p.add(2), b'l'); + /// } + /// ``` + #[inline] + pub fn as_ptr(&self) -> *const u8 { + self.as_bytes().as_ptr() + } + + /// Returns a raw mutable pointer to this byte string's underlying bytes. + /// + /// # Safety + /// + /// The caller must ensure that the byte string outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// Modifying the container (like a `BString`) referenced by this byte + /// string may cause its buffer to be reallocated, which would also make + /// any pointers to it invalid. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::BStr; + /// + /// let mut buf = &mut [b'h', b'e', b'l', b'l', b'o']; + /// let mut s = BStr::new_mut(buf); + /// let p = s.as_mut_ptr(); + /// + /// unsafe { + /// *p.add(2) = b'Z'; + /// } + /// assert_eq!("heZlo", s); + /// ``` + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut u8 { + self.as_bytes_mut().as_mut_ptr() + } +} + +/// A single substring searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, using +/// [`BStr::find`](struct.BStr.html#method.find) +/// or +/// [`BStr::find_iter`](struct.BStr.html#method.find_iter) +/// is good enough, but `Finder` is useful when you can meaningfully observe +/// searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `Finder` that is not connected to the +/// lifetime of its needle. +#[derive(Clone, Debug)] +pub struct Finder<'a> { + searcher: TwoWay<'a>, +} + +impl<'a> Finder<'a> { + /// Create a new finder for the given needle. + #[inline] + pub fn new>(needle: &'a B) -> Finder<'a> { + Finder { searcher: TwoWay::forward(BStr::new(needle)) } + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> Finder<'static> { + Finder { searcher: self.searcher.into_owned() } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of the finder, and may be shorter than the `'a` lifetime. Namely, a + /// finder's needle can be either borrowed or owned, so the lifetime of the + /// needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &BStr { + self.searcher.needle() + } + + /// Returns the index of the first occurrence of this needle in the given + /// haystack. + /// + /// The haystack may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::Finder; + /// + /// let haystack = "foo bar baz"; + /// assert_eq!(Some(0), Finder::new("foo").find(haystack)); + /// assert_eq!(Some(4), Finder::new("bar").find(haystack)); + /// assert_eq!(None, Finder::new("quux").find(haystack)); + /// ``` + #[inline] + pub fn find>(&self, haystack: B) -> Option { + self.searcher.find(BStr::new(haystack.as_ref())) + } +} + +/// A single substring reverse searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, using +/// [`BStr::rfind`](struct.BStr.html#method.rfind) +/// or +/// [`BStr::rfind_iter`](struct.BStr.html#method.rfind_iter) +/// is good enough, but `FinderReverse` is useful when you can meaningfully +/// observe searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `FinderReverse` that is not connected to +/// the lifetime of its needle. +#[derive(Clone, Debug)] +pub struct FinderReverse<'a> { + searcher: TwoWay<'a>, +} + +impl<'a> FinderReverse<'a> { + /// Create a new reverse finder for the given needle. + #[inline] + pub fn new>(needle: &'a B) -> FinderReverse<'a> { + FinderReverse { searcher: TwoWay::reverse(BStr::new(needle)) } + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "std")] + #[inline] + pub fn into_owned(self) -> FinderReverse<'static> { + FinderReverse { searcher: self.searcher.into_owned() } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of this finder, and may be shorter than the `'a` lifetime. Namely, + /// a finder's needle can be either borrowed or owned, so the lifetime of + /// the needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &BStr { + self.searcher.needle() + } + + /// Returns the index of the last occurrence of this needle in the given + /// haystack. + /// + /// The haystack may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str`, `&BStr`, and of + /// course, `&[u8]` itself. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bstr::FinderReverse; + /// + /// let haystack = "foo bar baz"; + /// assert_eq!(Some(0), FinderReverse::new("foo").rfind(haystack)); + /// assert_eq!(Some(4), FinderReverse::new("bar").rfind(haystack)); + /// assert_eq!(None, FinderReverse::new("quux").rfind(haystack)); + /// ``` + #[inline] + pub fn rfind>(&self, haystack: B) -> Option { + self.searcher.rfind(BStr::new(haystack.as_ref())) + } +} + +/// An iterator over non-overlapping substring matches. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'a` is the shorter of two lifetimes: the byte string being searched or the +/// byte string being looked for. +#[derive(Debug)] +pub struct Find<'a> { + haystack: &'a BStr, + prestate: PrefilterState, + searcher: TwoWay<'a>, + pos: usize, +} + +impl<'a> Find<'a> { + fn new(haystack: &'a BStr, needle: &'a BStr) -> Find<'a> { + let searcher = TwoWay::forward(needle); + let prestate = searcher.prefilter_state(); + Find { haystack, prestate, searcher, pos: 0 } + } +} + +impl<'a> Iterator for Find<'a> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + if self.pos > self.haystack.len() { + return None; + } + let result = self.searcher.find_with( + &mut self.prestate, + &self.haystack[self.pos..], + ); + match result { + None => None, + Some(i) => { + let pos = self.pos + i; + self.pos = pos + cmp::max(1, self.searcher.needle().len()); + Some(pos) + } + } + } +} + +/// An iterator over non-overlapping substring matches in reverse. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'a` is the shorter of two lifetimes: the byte string being searched or the +/// byte string being looked for. +#[derive(Debug)] +pub struct FindReverse<'a> { + haystack: &'a BStr, + prestate: PrefilterState, + searcher: TwoWay<'a>, + /// When searching with an empty needle, this gets set to `None` after + /// we've yielded the last element at `0`. + pos: Option, +} + +impl<'a> FindReverse<'a> { + fn new(haystack: &'a BStr, needle: &'a BStr) -> FindReverse<'a> { + let searcher = TwoWay::reverse(needle); + let prestate = searcher.prefilter_state(); + let pos = Some(haystack.len()); + FindReverse { haystack, prestate, searcher, pos } + } + + fn haystack(&self) -> &'a BStr { + self.haystack + } + + fn needle(&self) -> &BStr { + self.searcher.needle() + } +} + +impl<'a> Iterator for FindReverse<'a> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + let pos = match self.pos { + None => return None, + Some(pos) => pos, + }; + let result = self.searcher.rfind_with( + &mut self.prestate, + &self.haystack[..pos], + ); + match result { + None => None, + Some(i) => { + if pos == i { + self.pos = pos.checked_sub(1); + } else { + self.pos = Some(i); + } + Some(i) + } + } + } +} + +/// An iterator over the bytes in a byte string. +/// +/// `'a` is the lifetime of the byte string being traversed. +#[derive(Debug)] +pub struct Bytes<'a> { + it: slice::Iter<'a, u8>, +} + +impl<'a> Iterator for Bytes<'a> { + type Item = u8; + + #[inline] + fn next(&mut self) -> Option { + self.it.next().map(|&b| b) + } +} + +impl<'a> DoubleEndedIterator for Bytes<'a> { + #[inline] + fn next_back(&mut self) -> Option { + self.it.next_back().map(|&b| b) + } +} + +impl<'a> ExactSizeIterator for Bytes<'a> { + #[inline] + fn len(&self) -> usize { + self.it.len() + } +} + +/// An iterator over the fields in a byte string, separated by whitespace. +/// +/// This iterator splits on contiguous runs of whitespace, such that the fields +/// in `foo\t\t\n \nbar` are `foo` and `bar`. +/// +/// `'a` is the lifetime of the byte string being split. +#[derive(Debug)] +pub struct Fields<'a> { + it: FieldsWith<'a, fn(char) -> bool>, +} + +impl<'a> Fields<'a> { + fn new(bytes: &'a BStr) -> Fields<'a> { + Fields { it: bytes.fields_with(|ch| ch.is_whitespace()) } + } +} + +impl<'a> Iterator for Fields<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + self.it.next() + } +} + +/// An iterator over fields in the byte string, separated by a predicate over +/// codepoints. +/// +/// This iterator splits a byte string based on its predicate function such +/// that the elements returned are separated by contiguous runs of codepoints +/// for which the predicate returns true. +/// +/// `'a` is the lifetime of the byte string being split, while `F` is the type +/// of the predicate, i.e., `FnMut(char) -> bool`. +#[derive(Debug)] +pub struct FieldsWith<'a, F> { + f: F, + bytes: &'a BStr, + chars: CharIndices<'a>, +} + +impl<'a, F: FnMut(char) -> bool> FieldsWith<'a, F> { + fn new(bytes: &'a BStr, f: F) -> FieldsWith<'a, F> { + FieldsWith { + f: f, + bytes: bytes, + chars: bytes.char_indices(), + } + } +} + +impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + let (start, mut end); + loop { + match self.chars.next() { + None => return None, + Some((s, e, ch)) => { + if !(self.f)(ch) { + start = s; + end = e; + break; + } + } + } + } + while let Some((_, e, ch)) = self.chars.next() { + if (self.f)(ch) { + break; + } + end = e; + } + Some(&self.bytes[start..end]) + } +} + +/// An iterator over substrings in a byte string, split by a separator. +/// +/// `'a` is the lifetime of the byte string being split, while `F` is the type +/// of the predicate, i.e., `FnMut(char) -> bool`. +#[derive(Debug)] +pub struct Split<'a> { + finder: Find<'a>, + /// The end position of the previous match of our splitter. The element + /// we yield corresponds to the substring starting at `last` up to the + /// beginning of the next match of the splitter. + last: usize, + /// Only set when iteration is complete. A corner case here is when a + /// splitter is matched at the end of the haystack. At that point, we still + /// need to yield an empty string following it. + done: bool, +} + +impl<'a> Split<'a> { + fn new(haystack: &'a BStr, splitter: &'a BStr) -> Split<'a> { + let finder = haystack.find_iter(splitter); + Split { finder, last: 0, done: false } + } +} + +impl<'a> Iterator for Split<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + let haystack = self.finder.haystack; + match self.finder.next() { + Some(start) => { + let next = &haystack[self.last..start]; + self.last = start + self.finder.searcher.needle().len(); + Some(next) + } + None => { + if self.last >= haystack.len() { + if !self.done { + self.done = true; + Some(B("")) + } else { + None + } + } else { + let s = &haystack[self.last..]; + self.last = haystack.len(); + self.done = true; + Some(s) + } + } + } + } +} + +/// An iterator over substrings in a byte string, split by a separator, in +/// reverse. +/// +/// `'a` is the lifetime of the byte string being split, while `F` is the type +/// of the predicate, i.e., `FnMut(char) -> bool`. +#[derive(Debug)] +pub struct SplitReverse<'a> { + finder: FindReverse<'a>, + /// The end position of the previous match of our splitter. The element + /// we yield corresponds to the substring starting at `last` up to the + /// beginning of the next match of the splitter. + last: usize, + /// Only set when iteration is complete. A corner case here is when a + /// splitter is matched at the end of the haystack. At that point, we still + /// need to yield an empty string following it. + done: bool, +} + +impl<'a> SplitReverse<'a> { + fn new(haystack: &'a BStr, splitter: &'a BStr) -> SplitReverse<'a> { + let finder = haystack.rfind_iter(splitter); + SplitReverse { finder, last: haystack.len(), done: false } + } +} + +impl<'a> Iterator for SplitReverse<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + let haystack = self.finder.haystack(); + match self.finder.next() { + Some(start) => { + let nlen = self.finder.needle().len(); + let next = &haystack[start + nlen..self.last]; + self.last = start; + Some(next) + } + None => { + if self.last == 0 { + if !self.done { + self.done = true; + Some(B("")) + } else { + None + } + } else { + let s = &haystack[..self.last]; + self.last = 0; + self.done = true; + Some(s) + } + } + } + } +} + +/// An iterator over at most `n` substrings in a byte string, split by a +/// separator. +/// +/// `'a` is the lifetime of the byte string being split, while `F` is the type +/// of the predicate, i.e., `FnMut(char) -> bool`. +#[derive(Debug)] +pub struct SplitN<'a> { + split: Split<'a>, + limit: usize, + count: usize, +} + +impl<'a> SplitN<'a> { + fn new( + haystack: &'a BStr, + splitter: &'a BStr, + limit: usize, + ) -> SplitN<'a> { + let split = haystack.split(splitter); + SplitN { split, limit, count: 0 } + } +} + +impl<'a> Iterator for SplitN<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + self.count += 1; + if self.count > self.limit { + None + } else if self.count == self.limit { + Some(&self.split.finder.haystack[self.split.last..]) + } else { + self.split.next() + } + } +} + + +/// An iterator over at most `n` substrings in a byte string, split by a +/// separator, in reverse. +/// +/// `'a` is the lifetime of the byte string being split, while `F` is the type +/// of the predicate, i.e., `FnMut(char) -> bool`. +#[derive(Debug)] +pub struct SplitNReverse<'a> { + split: SplitReverse<'a>, + limit: usize, + count: usize, +} + +impl<'a> SplitNReverse<'a> { + fn new( + haystack: &'a BStr, + splitter: &'a BStr, + limit: usize, + ) -> SplitNReverse<'a> { + let split = haystack.rsplit(splitter); + SplitNReverse { split, limit, count: 0 } + } +} + +impl<'a> Iterator for SplitNReverse<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + self.count += 1; + if self.count > self.limit { + None + } else if self.count == self.limit { + Some(&self.split.finder.haystack()[..self.split.last]) + } else { + self.split.next() + } + } +} + +/// An iterator over all lines in a byte string, without their terminators. +/// +/// For this iterator, the only line terminators recognized are `\r\n` and +/// `\n`. +/// +/// `'a` is the lifetime of the byte string being iterated over. +pub struct Lines<'a> { + it: LinesWithTerminator<'a>, +} + +impl<'a> Lines<'a> { + fn new(bytes: &'a BStr) -> Lines<'a> { + Lines { it: LinesWithTerminator::new(bytes) } + } +} + +impl<'a> Iterator for Lines<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + let mut line = self.it.next()?; + if line.last() == Some(b'\n') { + line = &line[..line.len() - 1]; + if line.last() == Some(b'\r') { + line = &line[..line.len() - 1]; + } + } + Some(line) + } +} + +/// An iterator over all lines in a byte string, including their terminators. +/// +/// For this iterator, the only line terminator recognized is `\n`. (Since +/// line terminators are included, this also handles `\r\n` line endings.) +/// +/// Line terminators are only included if they are present in the original +/// byte string. For example, the last line in a byte string may not end with +/// a line terminator. +/// +/// Concatenating all elements yielded by this iterator is guaranteed to yield +/// the original byte string. +/// +/// `'a` is the lifetime of the byte string being iterated over. +pub struct LinesWithTerminator<'a> { + bytes: &'a BStr, +} + +impl<'a> LinesWithTerminator<'a> { + fn new(bytes: &'a BStr) -> LinesWithTerminator<'a> { + LinesWithTerminator { bytes } + } +} + +impl<'a> Iterator for LinesWithTerminator<'a> { + type Item = &'a BStr; + + #[inline] + fn next(&mut self) -> Option<&'a BStr> { + match self.bytes.find_byte(b'\n') { + None if self.bytes.is_empty() => None, + None => { + let line = self.bytes; + self.bytes = B(""); + Some(line) + } + Some(end) => { + let line = &self.bytes[..end + 1]; + self.bytes = &self.bytes[end + 1..]; + Some(line) + } + } + } +} + +#[cfg(test)] +mod tests { + use tests::LOSSY_TESTS; + use super::*; + + #[test] + fn to_str_lossy() { + for (i, &(expected, input)) in LOSSY_TESTS.iter().enumerate() { + let got = B(input).to_str_lossy(); + assert_eq!( + expected.as_bytes(), + got.as_bytes(), + "to_str_lossy(ith: {:?}, given: {:?})", + i, input, + ); + + let mut got = String::new(); + B(input).to_str_lossy_into(&mut got); + assert_eq!( + expected.as_bytes(), got.as_bytes(), "to_str_lossy_into", + ); + + let got = String::from_utf8_lossy(input); + assert_eq!(expected.as_bytes(), got.as_bytes(), "std"); + } + } + + #[test] + #[should_panic] + fn copy_within_fail1() { + let mut buf = *b"foobar"; + let s = BStr::new_mut(&mut buf); + s.copy_within(0..2, 5); + } + + #[test] + #[should_panic] + fn copy_within_fail2() { + let mut buf = *b"foobar"; + let s = BStr::new_mut(&mut buf); + s.copy_within(3..2, 0); + } + + #[test] + #[should_panic] + fn copy_within_fail3() { + let mut buf = *b"foobar"; + let s = BStr::new_mut(&mut buf); + s.copy_within(5..7, 0); + } + + #[test] + #[should_panic] + fn copy_within_fail4() { + let mut buf = *b"foobar"; + let s = BStr::new_mut(&mut buf); + s.copy_within(0..1, 6); + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/cow.rs cargo-0.35.0/vendor/bstr/src/cow.rs --- cargo-0.33.0/vendor/bstr/src/cow.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/cow.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,89 @@ +#[cfg(feature = "std")] +use std::borrow::Cow; +use core::ops; + +use bstr::BStr; +#[cfg(feature = "std")] +use bstring::BString; + +/// A specialized copy-on-write BStr. +/// +/// The purpose of this type is to permit usage of a "borrowed or owned byte +/// string" in a way that keeps std/no-std compatibility. That is, in no-std +/// mode, this type devolves into a simple &BStr with no owned variant +/// availble. +#[derive(Clone, Debug)] +pub struct CowBStr<'a>(Imp<'a>); + +#[cfg(feature = "std")] +#[derive(Clone, Debug)] +struct Imp<'a>(Cow<'a, BStr>); + +#[cfg(not(feature = "std"))] +#[derive(Clone, Debug)] +struct Imp<'a>(&'a BStr); + +impl<'a> ops::Deref for CowBStr<'a> { + type Target = BStr; + + fn deref(&self) -> &BStr { + self.as_bstr() + } +} + +impl<'a> CowBStr<'a> { + /// Create a new borrowed CowBStr. + pub fn new>(bytes: &'a B) -> CowBStr<'a> { + CowBStr(Imp::new(BStr::new(bytes))) + } + + /// Create a new owned CowBStr. + #[cfg(feature = "std")] + pub fn new_owned(bytes: BString) -> CowBStr<'static> { + CowBStr(Imp(Cow::Owned(bytes))) + } + + /// Return a borrowed byte string, regardless of whether this is an owned + /// or borrowed byte string internally. + pub fn as_bstr(&self) -> &BStr { + self.0.as_bstr() + } + + /// Return an owned version of this copy-on-write byte string. + /// + /// If this is already an owned byte string internally, then this is a + /// no-op. Otherwise, the internal byte string is copied. + #[cfg(feature = "std")] + pub fn into_owned(self) -> CowBStr<'static> { + match (self.0).0 { + Cow::Borrowed(b) => CowBStr::new_owned(b.to_bstring()), + Cow::Owned(b) => CowBStr::new_owned(b), + } + } +} + +impl<'a> Imp<'a> { + #[cfg(feature = "std")] + pub fn new(bytes: &'a BStr) -> Imp<'a> { + Imp(Cow::Borrowed(bytes)) + } + + #[cfg(not(feature = "std"))] + pub fn new(bytes: &'a BStr) -> Imp<'a> { + Imp(bytes) + } + + #[cfg(feature = "std")] + pub fn as_bstr(&self) -> &BStr { + // &*self.0 + match self.0 { + Cow::Owned(ref x) => x, + Cow::Borrowed(x) => x, + } + } + + #[cfg(not(feature = "std"))] + pub fn as_bstr(&self) -> &BStr { + self.0 + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/freqs.rs cargo-0.35.0/vendor/bstr/src/freqs.rs --- cargo-0.33.0/vendor/bstr/src/freqs.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/freqs.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,258 @@ +pub const BYTE_FREQUENCIES: [u8; 256] = [ + 55, // '\x00' + 52, // '\x01' + 51, // '\x02' + 50, // '\x03' + 49, // '\x04' + 48, // '\x05' + 47, // '\x06' + 46, // '\x07' + 45, // '\x08' + 103, // '\t' + 242, // '\n' + 66, // '\x0b' + 67, // '\x0c' + 229, // '\r' + 44, // '\x0e' + 43, // '\x0f' + 42, // '\x10' + 41, // '\x11' + 40, // '\x12' + 39, // '\x13' + 38, // '\x14' + 37, // '\x15' + 36, // '\x16' + 35, // '\x17' + 34, // '\x18' + 33, // '\x19' + 56, // '\x1a' + 32, // '\x1b' + 31, // '\x1c' + 30, // '\x1d' + 29, // '\x1e' + 28, // '\x1f' + 255, // ' ' + 148, // '!' + 164, // '"' + 149, // '#' + 136, // '$' + 160, // '%' + 155, // '&' + 173, // "'" + 221, // '(' + 222, // ')' + 134, // '*' + 122, // '+' + 232, // ',' + 202, // '-' + 215, // '.' + 224, // '/' + 208, // '0' + 220, // '1' + 204, // '2' + 187, // '3' + 183, // '4' + 179, // '5' + 177, // '6' + 168, // '7' + 178, // '8' + 200, // '9' + 226, // ':' + 195, // ';' + 154, // '<' + 184, // '=' + 174, // '>' + 126, // '?' + 120, // '@' + 191, // 'A' + 157, // 'B' + 194, // 'C' + 170, // 'D' + 189, // 'E' + 162, // 'F' + 161, // 'G' + 150, // 'H' + 193, // 'I' + 142, // 'J' + 137, // 'K' + 171, // 'L' + 176, // 'M' + 185, // 'N' + 167, // 'O' + 186, // 'P' + 112, // 'Q' + 175, // 'R' + 192, // 'S' + 188, // 'T' + 156, // 'U' + 140, // 'V' + 143, // 'W' + 123, // 'X' + 133, // 'Y' + 128, // 'Z' + 147, // '[' + 138, // '\\' + 146, // ']' + 114, // '^' + 223, // '_' + 151, // '`' + 249, // 'a' + 216, // 'b' + 238, // 'c' + 236, // 'd' + 253, // 'e' + 227, // 'f' + 218, // 'g' + 230, // 'h' + 247, // 'i' + 135, // 'j' + 180, // 'k' + 241, // 'l' + 233, // 'm' + 246, // 'n' + 244, // 'o' + 231, // 'p' + 139, // 'q' + 245, // 'r' + 243, // 's' + 251, // 't' + 235, // 'u' + 201, // 'v' + 196, // 'w' + 240, // 'x' + 214, // 'y' + 152, // 'z' + 182, // '{' + 205, // '|' + 181, // '}' + 127, // '~' + 27, // '\x7f' + 212, // '\x80' + 211, // '\x81' + 210, // '\x82' + 213, // '\x83' + 228, // '\x84' + 197, // '\x85' + 169, // '\x86' + 159, // '\x87' + 131, // '\x88' + 172, // '\x89' + 105, // '\x8a' + 80, // '\x8b' + 98, // '\x8c' + 96, // '\x8d' + 97, // '\x8e' + 81, // '\x8f' + 207, // '\x90' + 145, // '\x91' + 116, // '\x92' + 115, // '\x93' + 144, // '\x94' + 130, // '\x95' + 153, // '\x96' + 121, // '\x97' + 107, // '\x98' + 132, // '\x99' + 109, // '\x9a' + 110, // '\x9b' + 124, // '\x9c' + 111, // '\x9d' + 82, // '\x9e' + 108, // '\x9f' + 118, // '\xa0' + 141, // '¡' + 113, // '¢' + 129, // '£' + 119, // '¤' + 125, // '¥' + 165, // '¦' + 117, // '§' + 92, // '¨' + 106, // '©' + 83, // 'ª' + 72, // '«' + 99, // '¬' + 93, // '\xad' + 65, // '®' + 79, // '¯' + 166, // '°' + 237, // '±' + 163, // '²' + 199, // '³' + 190, // '´' + 225, // 'µ' + 209, // '¶' + 203, // '·' + 198, // '¸' + 217, // '¹' + 219, // 'º' + 206, // '»' + 234, // '¼' + 248, // '½' + 158, // '¾' + 239, // '¿' + 255, // 'À' + 255, // 'Á' + 255, // 'Â' + 255, // 'Ã' + 255, // 'Ä' + 255, // 'Å' + 255, // 'Æ' + 255, // 'Ç' + 255, // 'È' + 255, // 'É' + 255, // 'Ê' + 255, // 'Ë' + 255, // 'Ì' + 255, // 'Í' + 255, // 'Î' + 255, // 'Ï' + 255, // 'Ð' + 255, // 'Ñ' + 255, // 'Ò' + 255, // 'Ó' + 255, // 'Ô' + 255, // 'Õ' + 255, // 'Ö' + 255, // '×' + 255, // 'Ø' + 255, // 'Ù' + 255, // 'Ú' + 255, // 'Û' + 255, // 'Ü' + 255, // 'Ý' + 255, // 'Þ' + 255, // 'ß' + 255, // 'à' + 255, // 'á' + 255, // 'â' + 255, // 'ã' + 255, // 'ä' + 255, // 'å' + 255, // 'æ' + 255, // 'ç' + 255, // 'è' + 255, // 'é' + 255, // 'ê' + 255, // 'ë' + 255, // 'ì' + 255, // 'í' + 255, // 'î' + 255, // 'ï' + 255, // 'ð' + 255, // 'ñ' + 255, // 'ò' + 255, // 'ó' + 255, // 'ô' + 255, // 'õ' + 255, // 'ö' + 255, // '÷' + 255, // 'ø' + 255, // 'ù' + 255, // 'ú' + 255, // 'û' + 255, // 'ü' + 255, // 'ý' + 255, // 'þ' + 255, // 'ÿ' +]; diff -Nru cargo-0.33.0/vendor/bstr/src/impls.rs cargo-0.35.0/vendor/bstr/src/impls.rs --- cargo-0.33.0/vendor/bstr/src/impls.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/impls.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,715 @@ +macro_rules! impl_partial_eq { + ($lhs:ty, $rhs:ty) => { + impl<'a, 'b> PartialEq<$rhs> for $lhs { + #[inline] + fn eq(&self, other: &$rhs) -> bool { + let other: &[u8] = other.as_ref(); + PartialEq::eq(self.as_bytes(), other) + } + } + + impl<'a, 'b> PartialEq<$lhs> for $rhs { + #[inline] + fn eq(&self, other: &$lhs) -> bool { + let this: &[u8] = self.as_ref(); + PartialEq::eq(this, other.as_bytes()) + } + } + } +} + +macro_rules! impl_partial_eq_cow { + ($lhs:ty, $rhs:ty) => { + impl<'a, 'b> PartialEq<$rhs> for $lhs { + #[inline] + fn eq(&self, other: &$rhs) -> bool { + let other: &[u8] = (&**other).as_ref(); + PartialEq::eq(self.as_bytes(), other) + } + } + + impl<'a, 'b> PartialEq<$lhs> for $rhs { + #[inline] + fn eq(&self, other: &$lhs) -> bool { + let this: &[u8] = (&**other).as_ref(); + PartialEq::eq(this, other.as_bytes()) + } + } + } +} + +macro_rules! impl_partial_ord { + ($lhs:ty, $rhs:ty) => { + impl<'a, 'b> PartialOrd<$rhs> for $lhs { + #[inline] + fn partial_cmp(&self, other: &$rhs) -> Option { + let other: &[u8] = other.as_ref(); + PartialOrd::partial_cmp(self.as_bytes(), other) + } + } + + impl<'a, 'b> PartialOrd<$lhs> for $rhs { + #[inline] + fn partial_cmp(&self, other: &$lhs) -> Option { + let this: &[u8] = self.as_ref(); + PartialOrd::partial_cmp(this, other.as_bytes()) + } + } + } +} + +#[cfg(feature = "std")] +mod bstring { + use std::borrow::{Borrow, ToOwned}; + use std::cmp::Ordering; + use std::fmt; + use std::iter::FromIterator; + use std::ops; + + use bstr::BStr; + use bstring::BString; + + impl fmt::Display for BString { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_bstr(), f) + } + } + + impl fmt::Debug for BString { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_bstr(), f) + } + } + + impl ops::Deref for BString { + type Target = BStr; + + #[inline] + fn deref(&self) -> &BStr { + self.as_bstr() + } + } + + impl ops::DerefMut for BString { + #[inline] + fn deref_mut(&mut self) -> &mut BStr { + self.as_mut_bstr() + } + } + + impl AsRef<[u8]> for BString { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } + } + + impl AsRef for BString { + #[inline] + fn as_ref(&self) -> &BStr { + self.as_bstr() + } + } + + impl AsMut<[u8]> for BString { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + self.as_bytes_mut() + } + } + + impl AsMut for BString { + #[inline] + fn as_mut(&mut self) -> &mut BStr { + self.as_mut_bstr() + } + } + + impl Borrow for BString { + #[inline] + fn borrow(&self) -> &BStr { + self.as_bstr() + } + } + + impl ToOwned for BStr { + type Owned = BString; + + #[inline] + fn to_owned(&self) -> BString { + self.to_bstring() + } + } + + impl<'a> From<&'a [u8]> for BString { + #[inline] + fn from(s: &'a [u8]) -> BString { + BString::from_vec(s.to_vec()) + } + } + + impl From> for BString { + #[inline] + fn from(s: Vec) -> BString { + BString::from_vec(s) + } + } + + impl From for Vec { + #[inline] + fn from(s: BString) -> Vec { + s.into_vec() + } + } + + impl<'a> From<&'a str> for BString { + #[inline] + fn from(s: &'a str) -> BString { + BString::from_vec(s.as_bytes().to_vec()) + } + } + + impl From for BString { + #[inline] + fn from(s: String) -> BString { + BString::from_vec(s.into_bytes()) + } + } + + impl<'a> From<&'a BStr> for BString { + #[inline] + fn from(s: &'a BStr) -> BString { + s.to_bstring() + } + } + + impl FromIterator for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + BString::from(iter.into_iter().collect::()) + } + } + + impl FromIterator for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + BString::from(iter.into_iter().collect::>()) + } + } + + impl<'a> FromIterator<&'a str> for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + let mut buf = BString::new(); + for b in iter { + buf.push(b); + } + buf + } + } + + impl<'a> FromIterator<&'a [u8]> for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + let mut buf = BString::new(); + for b in iter { + buf.push(b); + } + buf + } + } + + impl<'a> FromIterator<&'a BStr> for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + let mut buf = BString::new(); + for b in iter { + buf.push(b); + } + buf + } + } + + impl FromIterator for BString { + #[inline] + fn from_iter>(iter: T) -> BString { + let mut buf = BString::new(); + for b in iter { + buf.push(b); + } + buf + } + } + + impl Eq for BString {} + + impl PartialEq for BString { + #[inline] + fn eq(&self, other: &BString) -> bool { + &self[..] == &other[..] + } + } + + impl_partial_eq!(BString, Vec); + impl_partial_eq!(BString, [u8]); + impl_partial_eq!(BString, &'a [u8]); + impl_partial_eq!(BString, String); + impl_partial_eq!(BString, str); + impl_partial_eq!(BString, &'a str); + impl_partial_eq!(BString, BStr); + impl_partial_eq!(BString, &'a BStr); + + impl PartialOrd for BString { + #[inline] + fn partial_cmp(&self, other: &BString) -> Option { + PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes()) + } + } + + impl Ord for BString { + #[inline] + fn cmp(&self, other: &BString) -> Ordering { + self.partial_cmp(other).unwrap() + } + } + + impl_partial_ord!(BString, Vec); + impl_partial_ord!(BString, [u8]); + impl_partial_ord!(BString, &'a [u8]); + impl_partial_ord!(BString, String); + impl_partial_ord!(BString, str); + impl_partial_ord!(BString, &'a str); + impl_partial_ord!(BString, BStr); + impl_partial_ord!(BString, &'a BStr); +} + +mod bstr { + #[cfg(feature = "std")] + use std::borrow::Cow; + + use core::cmp::Ordering; + use core::fmt; + use core::ops; + + use bstr::BStr; + + impl fmt::Display for BStr { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Ok(allutf8) = self.to_str() { + return fmt::Display::fmt(allutf8, f); + } + for ch in self.chars() { + write!(f, "{}", ch)?; + } + Ok(()) + } + } + + impl fmt::Debug for BStr { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "\"")?; + for (s, e, ch) in self.char_indices() { + if ch == '\u{FFFD}' { + for &b in self[s..e].as_bytes() { + write!(f, r"\x{:X}", b)?; + } + } else { + write!(f, "{}", ch.escape_debug())?; + } + } + write!(f, "\"")?; + Ok(()) + } + } + + impl ops::Index for BStr { + type Output = u8; + + #[inline] + fn index(&self, idx: usize) -> &u8 { + &self.as_bytes()[idx] + } + } + + impl ops::Index for BStr { + type Output = BStr; + + #[inline] + fn index(&self, _: ops::RangeFull) -> &BStr { + self + } + } + + impl ops::Index> for BStr { + type Output = BStr; + + #[inline] + fn index(&self, r: ops::Range) -> &BStr { + BStr::new(&self.as_bytes()[r.start..r.end]) + } + } + + impl ops::Index> for BStr { + type Output = BStr; + + #[inline] + fn index(&self, r: ops::RangeInclusive) -> &BStr { + BStr::new(&self.as_bytes()[*r.start()..=*r.end()]) + } + } + + impl ops::Index> for BStr { + type Output = BStr; + + #[inline] + fn index(&self, r: ops::RangeFrom) -> &BStr { + BStr::new(&self.as_bytes()[r.start..]) + } + } + + impl ops::Index> for BStr { + type Output = BStr; + + #[inline] + fn index(&self, r: ops::RangeTo) -> &BStr { + BStr::new(&self.as_bytes()[..r.end]) + } + } + + impl ops::Index> for BStr { + type Output = BStr; + + #[inline] + fn index(&self, r: ops::RangeToInclusive) -> &BStr { + BStr::new(&self.as_bytes()[..=r.end]) + } + } + + impl ops::IndexMut for BStr { + #[inline] + fn index_mut(&mut self, idx: usize) -> &mut u8 { + &mut self.as_bytes_mut()[idx] + } + } + + impl ops::IndexMut for BStr { + #[inline] + fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr { + self + } + } + + impl ops::IndexMut> for BStr { + #[inline] + fn index_mut(&mut self, r: ops::Range) -> &mut BStr { + BStr::from_bytes_mut(&mut self.as_bytes_mut()[r.start..r.end]) + } + } + + impl ops::IndexMut> for BStr { + #[inline] + fn index_mut(&mut self, r: ops::RangeInclusive) -> &mut BStr { + BStr::from_bytes_mut(&mut self.as_bytes_mut()[*r.start()..=*r.end()]) + } + } + + impl ops::IndexMut> for BStr { + #[inline] + fn index_mut(&mut self, r: ops::RangeFrom) -> &mut BStr { + BStr::from_bytes_mut(&mut self.as_bytes_mut()[r.start..]) + } + } + + impl ops::IndexMut> for BStr { + #[inline] + fn index_mut(&mut self, r: ops::RangeTo) -> &mut BStr { + BStr::from_bytes_mut(&mut self.as_bytes_mut()[..r.end]) + } + } + + impl ops::IndexMut> for BStr { + #[inline] + fn index_mut(&mut self, r: ops::RangeToInclusive) -> &mut BStr { + BStr::from_bytes_mut(&mut self.as_bytes_mut()[..=r.end]) + } + } + + impl AsRef<[u8]> for BStr { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } + } + + impl AsRef for [u8] { + #[inline] + fn as_ref(&self) -> &BStr { + BStr::new(self) + } + } + + impl AsRef for str { + #[inline] + fn as_ref(&self) -> &BStr { + BStr::new(self) + } + } + + impl AsMut<[u8]> for BStr { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + self.as_bytes_mut() + } + } + + impl AsMut for [u8] { + #[inline] + fn as_mut(&mut self) -> &mut BStr { + BStr::new_mut(self) + } + } + + impl<'a> From<&'a [u8]> for &'a BStr { + #[inline] + fn from(s: &'a [u8]) -> &'a BStr { + BStr::from_bytes(s) + } + } + + impl<'a> From<&'a str> for &'a BStr { + #[inline] + fn from(s: &'a str) -> &'a BStr { + BStr::from_bytes(s.as_bytes()) + } + } + + impl Eq for BStr {} + + impl PartialEq for BStr { + #[inline] + fn eq(&self, other: &BStr) -> bool { + self.as_bytes() == other.as_bytes() + } + } + + impl_partial_eq!(BStr, [u8]); + impl_partial_eq!(BStr, &'a [u8]); + impl_partial_eq!(BStr, str); + impl_partial_eq!(BStr, &'a str); + + #[cfg(feature = "std")] + impl_partial_eq!(BStr, Vec); + #[cfg(feature = "std")] + impl_partial_eq!(&'a BStr, Vec); + #[cfg(feature = "std")] + impl_partial_eq!(BStr, String); + #[cfg(feature = "std")] + impl_partial_eq!(&'a BStr, String); + #[cfg(feature = "std")] + impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>); + #[cfg(feature = "std")] + impl_partial_eq_cow!(&'a BStr, Cow<'a, str>); + #[cfg(feature = "std")] + impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>); + + impl PartialOrd for BStr { + #[inline] + fn partial_cmp(&self, other: &BStr) -> Option { + PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes()) + } + } + + impl Ord for BStr { + #[inline] + fn cmp(&self, other: &BStr) -> Ordering { + self.partial_cmp(other).unwrap() + } + } + + impl_partial_ord!(BStr, [u8]); + impl_partial_ord!(BStr, &'a [u8]); + impl_partial_ord!(BStr, str); + impl_partial_ord!(BStr, &'a str); + + #[cfg(feature = "std")] + impl_partial_ord!(BStr, Vec); + #[cfg(feature = "std")] + impl_partial_ord!(&'a BStr, Vec); + #[cfg(feature = "std")] + impl_partial_ord!(BStr, String); + #[cfg(feature = "std")] + impl_partial_ord!(&'a BStr, String); +} + +#[cfg(feature = "serde1-nostd")] +mod bstr_serde { + use std::fmt; + + use serde::{ + Serialize, Serializer, + Deserialize, Deserializer, de::Error, de::Visitor, + }; + + use bstr::BStr; + + impl Serialize for BStr { + #[inline] + fn serialize( + &self, + serializer: S, + ) -> Result + where S: Serializer + { + serializer.serialize_bytes(self.as_bytes()) + } + } + + impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr { + #[inline] + fn deserialize( + deserializer: D, + ) -> Result<&'a BStr, D::Error> + where D: Deserializer<'de> + { + struct BStrVisitor; + + impl<'de> Visitor<'de> for BStrVisitor { + type Value = &'de BStr; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a borrowed byte string") + } + + #[inline] + fn visit_borrowed_bytes( + self, + value: &'de [u8], + ) -> Result<&'de BStr, E> { + Ok(BStr::new(value)) + } + + #[inline] + fn visit_borrowed_str( + self, + value: &'de str, + ) -> Result<&'de BStr, E> { + Ok(BStr::new(value)) + } + } + + deserializer.deserialize_bytes(BStrVisitor) + } + } +} + +#[cfg(feature = "serde1")] +mod bstring_serde { + use std::cmp; + use std::fmt; + + use serde::{ + Serialize, Serializer, + Deserialize, Deserializer, de::Error, de::SeqAccess, de::Visitor, + }; + + use bstring::BString; + + impl Serialize for BString { + #[inline] + fn serialize( + &self, + serializer: S, + ) -> Result + where S: Serializer + { + serializer.serialize_bytes(self.as_bytes()) + } + } + + impl<'de> Deserialize<'de> for BString { + #[inline] + fn deserialize( + deserializer: D, + ) -> Result + where D: Deserializer<'de> + { + struct BStringVisitor; + + impl<'de> Visitor<'de> for BStringVisitor { + type Value = BString; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("a byte string") + } + + #[inline] + fn visit_seq>( + self, + mut visitor: V, + ) -> Result { + let len = cmp::min(visitor.size_hint().unwrap_or(0), 256); + let mut bytes = BString::with_capacity(len); + while let Some(v) = visitor.next_element()? { + bytes.push_byte(v); + } + Ok(bytes) + } + + #[inline] + fn visit_bytes( + self, + value: &[u8], + ) -> Result { + Ok(BString::from(value)) + } + + #[inline] + fn visit_byte_buf( + self, + value: Vec, + ) -> Result { + Ok(BString::from(value)) + } + + #[inline] + fn visit_str( + self, + value: &str, + ) -> Result { + Ok(BString::from(value)) + } + + #[inline] + fn visit_string( + self, + value: String, + ) -> Result { + Ok(BString::from(value)) + } + } + + deserializer.deserialize_byte_buf(BStringVisitor) + } + } +} + +#[cfg(test)] +mod bstring_arbitrary { + use bstring::BString; + + use quickcheck::{Arbitrary, Gen}; + + impl Arbitrary for BString { + fn arbitrary(g: &mut G) -> BString { + BString::from(Vec::::arbitrary(g)) + } + + fn shrink(&self) -> Box> { + Box::new(self.as_vec().shrink().map(BString::from)) + } + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/io.rs cargo-0.35.0/vendor/bstr/src/io.rs --- cargo-0.33.0/vendor/bstr/src/io.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/io.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,203 @@ +/*! +Utilities for working with I/O using byte strings. + +This module currently only exports a single trait, `BufReadExt`, which provides +facilities for conveniently and efficiently working with lines as byte strings. + +More APIs may be added in the future. +*/ + +use std::io; + +use bstr::BStr; +use bstring::BString; + +/// An extention trait for +/// [`std::io::BufRead`](https://doc.rust-lang.org/std/io/trait.BufRead.html) +/// which provides convenience APIs for dealing with byte strings. +pub trait BufReadExt: io::BufRead { + /// Returns an iterator over the lines of this reader, where each line + /// is represented as a byte string. + /// + /// Each item yielded by this iterator is a `io::Result`, where + /// an error is yielded if there was a problem reading from the underlying + /// reader. + /// + /// On success, the next line in the iterator is returned. The line does + /// *not* contain a trailing `\n` or `\r\n`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::io; + /// + /// use bstr::io::BufReadExt; + /// + /// # fn example() -> Result<(), io::Error> { + /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor"); + /// + /// let mut lines = vec![]; + /// for result in cursor.byte_lines() { + /// let line = result?; + /// lines.push(line); + /// } + /// assert_eq!(lines.len(), 3); + /// assert_eq!(lines[0], "lorem"); + /// assert_eq!(lines[1], "ipsum"); + /// assert_eq!(lines[2], "dolor"); + /// # Ok(()) }; example().unwrap() + /// ``` + fn byte_lines(self) -> ByteLines where Self: Sized { + ByteLines { buf: self } + } + + /// Executes the given closure on each line in the underlying reader. + /// + /// If the closure returns an error (or if the underlying reader returns an + /// error), then iteration is stopped and the error is returned. If false + /// is returned, then iteration is stopped and no error is returned. + /// + /// The closure given is called on exactly the same values as yielded by + /// the [`byte_lines`](trait.BufReadExt.html#method.byte_lines) + /// iterator. Namely, lines do _not_ contain trailing `\n` or `\r\n` bytes. + /// + /// This routine is useful for iterating over lines as quickly as + /// possible. Namely, a single allocation is reused for each line. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::io; + /// + /// use bstr::io::BufReadExt; + /// + /// # fn example() -> Result<(), io::Error> { + /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor"); + /// + /// let mut lines = vec![]; + /// cursor.for_byte_line(|line| { + /// lines.push(line.to_bstring()); + /// Ok(true) + /// })?; + /// assert_eq!(lines.len(), 3); + /// assert_eq!(lines[0], "lorem"); + /// assert_eq!(lines[1], "ipsum"); + /// assert_eq!(lines[2], "dolor"); + /// # Ok(()) }; example().unwrap() + /// ``` + fn for_byte_line( + mut self, + mut for_each_line: F, + ) -> io::Result<()> + where Self: Sized, + F: FnMut(&BStr) -> io::Result + { + let mut bytes = BString::new(); + while self.read_until(b'\n', bytes.as_mut_vec())? > 0 { + trim_line(&mut bytes); + if !for_each_line(&bytes)? { + break; + } + bytes.clear(); + } + Ok(()) + } + + /// Executes the given closure on each line in the underlying reader. + /// + /// If the closure returns an error (or if the underlying reader returns an + /// error), then iteration is stopped and the error is returned. If false + /// is returned, then iteration is stopped and no error is returned. + /// + /// Unlike + /// [`for_byte_line`](trait.BufReadExt.html#method.for_byte_line), + /// the lines given to the closure *do* include the line terminator, if one + /// exists. + /// + /// This routine is useful for iterating over lines as quickly as + /// possible. Namely, a single allocation is reused for each line. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::io; + /// + /// use bstr::io::BufReadExt; + /// + /// # fn example() -> Result<(), io::Error> { + /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor"); + /// + /// let mut lines = vec![]; + /// cursor.for_byte_line_with_terminator(|line| { + /// lines.push(line.to_bstring()); + /// Ok(true) + /// })?; + /// assert_eq!(lines.len(), 3); + /// assert_eq!(lines[0], "lorem\n"); + /// assert_eq!(lines[1], "ipsum\r\n"); + /// assert_eq!(lines[2], "dolor"); + /// # Ok(()) }; example().unwrap() + /// ``` + fn for_byte_line_with_terminator( + mut self, + mut for_each_line: F, + ) -> io::Result<()> + where Self: Sized, + F: FnMut(&BStr) -> io::Result + { + let mut bytes = BString::new(); + while self.read_until(b'\n', bytes.as_mut_vec())? > 0 { + if !for_each_line(&bytes)? { + break; + } + bytes.clear(); + } + Ok(()) + } +} + +impl BufReadExt for B {} + +/// An iterator over lines from an instance of +/// [`std::io::BufRead`](https://doc.rust-lang.org/std/io/trait.BufRead.html). +/// +/// This iterator is generally created by calling the +/// [`byte_lines`](trait.BufReadExt.html#method.byte_lines) +/// method on the +/// [`BufReadExt`](trait.BufReadExt.html) +/// trait. +#[derive(Debug)] +pub struct ByteLines { + buf: B, +} + +impl Iterator for ByteLines { + type Item = io::Result; + + fn next(&mut self) -> Option> { + let mut bytes = BString::new(); + match self.buf.read_until(b'\n', bytes.as_mut_vec()) { + Err(e) => Some(Err(e)), + Ok(0) => None, + Ok(_) => { + trim_line(&mut bytes); + Some(Ok(bytes)) + } + } + } +} + +fn trim_line(line: &mut BString) { + if line.last() == Some(b'\n') { + line.pop_byte(); + if line.last() == Some(b'\r') { + line.pop_byte(); + } + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/lib.rs cargo-0.35.0/vendor/bstr/src/lib.rs --- cargo-0.33.0/vendor/bstr/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,407 @@ +/*! +An experimental byte string library. + +Byte strings are just like standard Unicode strings with one very important +difference: byte strings are only *conventionally* UTF-8 while Rust's standard +Unicode strings are *guaranteed* to be valid UTF-8. The primary motivation for +this type is for handling arbitrary bytes that are mostly UTF-8. + +# Overview + +There are two primary types in this crate: + +* [`BString`](struct.BString.html) is an owned growable byte string buffer, + analogous to `String`. +* [`BStr`](struct.BStr.html) is a byte string slice, analogous to `str`. + +Additionally, the free function [`B`](fn.B.html) serves as a convenient short +hand for writing byte string literals. + +# Quick examples + +Byte strings are effectively the same thing as a `Vec` or a `&[u8]`, except +they provide a string oriented API. Operations such as iterating over +graphemes, searching for substrings, replacing substrings, trimming and case +conversion are examples of things not provided on the standard `&[u8]` APIs +but are provided by this crate. For example, this code iterates over all of +occurrences of a subtring: + +``` +use bstr::B; + +let s = B("foo bar foo foo quux foo"); + +let mut matches = vec![]; +for start in s.find_iter("foo") { + matches.push(start); +} +assert_eq!(matches, [0, 8, 12, 21]); +``` + +Here's another example showing how to do a search and replace: + +``` +use bstr::B; + +let old = B("foo bar foo foo quux foo"); +let new = old.replace("foo", "hello"); +assert_eq!(new, "hello bar hello hello quux hello"); +``` + +And here's an example that shows case conversion, even in the presence of +invalid UTF-8: + +``` +use bstr::{B, BString}; + +let mut lower = BString::from("hello β"); +lower[0] = b'\xFF'; +// lowercase β is uppercased to Β +assert_eq!(lower.to_uppercase(), B(b"\xFFELLO \xCE\x92")); +``` + +# When should I use byte strings? + +This library is somewhat of an experiment that reflects my hypothesis that +UTF-8 by convention is a better trade off in some circumstances than guaranteed +UTF-8. It's possible, perhaps even likely, that this is a niche concern for +folks working closely with core text primitives. + +The first time this idea hit me was in the implementation of Rust's regex +engine. In particular, very little of the internal implementation cares at all +about searching valid UTF-8 encoded strings. Indeed, internally, the +implementation converts `&str` from the API to `&[u8]` fairly quickly and +just deals with raw bytes. UTF-8 match boundaries are then guaranteed by the +finite state machine itself rather than any specific string type. This makes it +possible to not only run regexes on `&str` values, but also on `&[u8]` values. + +Why would you ever want to run a regex on a `&[u8]` though? Well, `&[u8]` is +the fundamental way at which one reads data from all sorts of streams, via the +standard library's [`Read`](https://doc.rust-lang.org/std/io/trait.Read.html) +trait. In particular, there is no platform independent way to determine whether +what you're reading from is some binary file or a human readable text file. +Therefore, if you're writing a program to search files, you probably need to +deal with `&[u8]` directly unless you're okay with first converting it to a +`&str` and dropping any bytes that aren't valid UTF-8. (Or otherwise determine +the encoding---which is often impractical---and perform a transcoding step.) +Often, the simplest and most robust way to approach this is to simply treat the +contents of a file as if it were mostly valid UTF-8 and pass through invalid +UTF-8 untouched. This may not be the most correct approach though! + +One case in particular exacerbates these issues, and that's memory mapping +a file. When you memory map a file, that file may be gigabytes big, but all +you get is a `&[u8]`. Converting that to a `&str` all in one go is generally +not a good idea because of the costs associated with doing so, and also +because it generally causes one to do two passes over the data instead of +one, which is quite undesirable. It is of course usually possible to do it an +incremental way by only parsing chunks at a time, but this is often complex to +do or impractical. For example, many regex engines only accept one contiguous +sequence of bytes at a time with no way to perform incremental matching. + +In summary, the conventional UTF-8 byte strings provided by this library is an +experiment. They are definitely useful in some limited circumstances, but how +useful they are more broadly isn't clear yet. + +# `bstr` in public APIs + +Since this library is still experimental, you should not use it in the public +API of your crates until it hits `1.0` (unless you're OK with with tracking +breaking releases of `bstr`). It is a priority to move this crate to `1.0` +expediently so that `BString` and `BStr` may be used in the public APIs of +other crates. While both `BString` and `BStr` do provide zero cost ways of +converting between `Vec` and `&[u8]`, it is often convenient to provide +trait implementations for `BString` and `BStr`, which requires making `bstr` a +public dependency. + +# Differences with standard strings + +The primary difference between `BStr` and `str` is that the former is +conventionally UTF-8 while the latter is guaranteed to be UTF-8. The phrase +"conventionally UTF-8" means that a `BStr` may contain bytes that do not form +a valid UTF-8 sequence, but operations defined on the type are generally most +useful on valid UTF-8 sequences. For example, iterating over Unicode codepoints +or grapheme clusters is an operation that is only defined on valid UTF-8. +Therefore, when invalid UTF-8 is encountered, the Unicode replacement codepoint +is substituted. Thus, a byte string that is not UTF-8 at all is of limited +utility when using these methods. + +However, not all operations on byte strings are specifically Unicode aware. For +example, substring search has no specific Unicode semantics ascribed to it. It +works just as well for byte strings that are completely valid UTF-8 as for byte +strings that contain no valid UTF-8 at all. Similarly for replacements and +various other operations. + +Aside from the difference in how UTF-8 is handled, the APIs between `BStr` and +`str` (and `BString` and `String`) are intentionally very similar, including +maintaining the same behavior for corner cases in things like substring +splitting. There are, however, some differences: + +* Substring search is not done with `matches`, but instead, `find_iter`. + In general, this crate does not define any generic + [`Pattern`](https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html) + infrastructure, and instead prefers adding new methods for different + argument types. For example, `matches` can search by a `char` or a `&str`, + where as `find_iter` can only search by a byte string. `find_char` can be + used for searching by a `char`. +* Since `SliceConcatExt` in the standard library is unstable, it is not + possible to reuse that to implement `join` and `concat` methods. Instead, + [`join`](fn.join.html) and [`concat`](fn.concat.html) are provided as free + functions that perform a similar task. +* This library bundles in a few more Unicode operations, such as grapheme, + word and sentence iterators. More operations, such as normalization and + case folding, may be provided in the future. +* Some `String`/`str` APIs will panic if a particular index was not on a valid + UTF-8 code unit sequence boundary. Conversely, no such checking is performed + in this crate, as is consistent with treating byte strings as a sequence of + bytes. This means callers are responsible for maintaining a UTF-8 invariant + if that's important. + +Otherwise, you should find most of the APIs between this crate and the standard +library to be very similar, if not identical. + +# Handling of invalid UTF-8 + +Since byte strings are only *conventionally* UTF-8, there is no guarantee +that byte strings contain valid UTF-8. Indeed, it is perfectly legal for a +byte string to contain arbitrary bytes. However, since this library defines +a *string* type, it provides many operations specified by Unicode. These +operations are typically only defined over codepoints, and thus have no real +meaning on bytes that are invalid UTF-8 because they do not map to a particular +codepoint. + +For this reason, whenever operations defined only on codepoints are used, this +library will automatically convert invalid UTF-8 to the Unicode replacement +codepoint, `U+FFFD`, which looks like this: `�`. For example, an +[iterator over codepoints](struct.Chars.html) will yield a Unicode +replacement codepoint whenever it comes across bytes that are not valid UTF-8: + +``` +use bstr::B; + +let bs = B(b"a\xFF\xFFz"); +let chars: Vec = bs.chars().collect(); +assert_eq!(vec!['a', '\u{FFFD}', '\u{FFFD}', 'z'], chars); +``` + +There are a few ways in which invalid bytes can be substituted with a Unicode +replacement codepoint. One way, not used by this crate, is to replace every +individual invalid byte with a single replacement codepoint. In contrast, the +approach this crate uses is called the "substitution of maximal subparts," as +specified by the Unicode Standard (Chapter 3, Section 9). (This approach is +also used by [W3C's Encoding Standard](https://www.w3.org/TR/encoding/).) In +this strategy, a replacement codepoint is inserted whenever a byte is found +that cannot possibly lead to a valid UTF-8 code unit sequence. If there were +previous bytes that represented a *prefix* of a well-formed UTF-8 code unit +sequence, then all of those bytes (up to 3) are substituted with a single +replacement codepoint. For example: + +``` +use bstr::B; + +let bs = B(b"a\xF0\x9F\x87z"); +let chars: Vec = bs.chars().collect(); +// The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of them +// on their own are invalid. Only one replacement codepoint is substituted, +// which demonstrates the "substitution of maximal subparts" strategy. +assert_eq!(vec!['a', '\u{FFFD}', 'z'], chars); +``` + +If you do need to access the raw bytes for some reason in an iterator like +`Chars`, then you should use the iterator's "indices" variant, which gives +the byte offsets containing the invalid UTF-8 bytes that were substituted with +the replacement codepoint. For example: + +``` +use bstr::{B, BStr}; + +let bs = B(b"a\xE2\x98z"); +let chars: Vec<(usize, usize, char)> = bs.char_indices().collect(); +// Even though the replacement codepoint is encoded as 3 bytes itself, the +// byte range given here is only two bytes, corresponding to the original +// raw bytes. +assert_eq!(vec![(0, 1, 'a'), (1, 3, '\u{FFFD}'), (3, 4, 'z')], chars); + +// Thus, getting the original raw bytes is as simple as slicing the original +// byte string: +let chars: Vec<&BStr> = bs.char_indices().map(|(s, e, _)| &bs[s..e]).collect(); +assert_eq!(vec![B("a"), B(b"\xE2\x98"), B("z")], chars); +``` + +# File paths and OS strings + +One of the premiere features of Rust's standard library is how it handles file +paths. In particular, it makes it very hard to write incorrect code while +simultaneously providing a correct cross platform abstraction for manipulating +file paths. The key challenge that one faces with file paths across platforms +is derived from the following observations: + +* On most Unix-like systems, file paths are an arbitrary sequence of bytes. +* On Windows, file paths are an arbitrary sequence of 16-bit integers. + +(In both cases, certain sequences aren't allowed. For example a `NUL` byte is +not allowed in either case. But we can ignore this for the purposes of this +section.) + +Byte strings, like the ones provided in this crate, line up really well with +file paths on Unix like systems, which are themselves just arbitrary sequences +of bytes. It turns out that if you treat them as "mostly UTF-8," then things +work out pretty well. On the contrary, byte strings _don't_ really work +that well on Windows because it's not possible to correctly roundtrip file +paths between 16-bit integers and something that looks like UTF-8 _without_ +explicitly defining an encoding to do this for you, which is anathema to byte +strings, which are just bytes. + +Rust's standard library elegantly solves this problem by specifying an +internal encoding for file paths that's only used on Windows called +[WTF-8](https://simonsapin.github.io/wtf-8/). Its key properties are that they +permit losslessly roundtripping file paths on Windows by extending UTF-8 to +support an encoding of surrogate codepoints, while simultaneously supporting +zero-cost conversion from Rust's Unicode strings to file paths. (Since UTF-8 is +a proper subset of WTF-8.) + +The fundamental point at which the above strategy fails is when you want to +treat file paths as things that look like strings in a zero cost way. In most +cases, this is actually the wrong thing to do, but some cases call for it, +for example, glob or regex matching on file paths. This is because WTF-8 is +treated as an internal implementation detail, and there is no way to access +those bytes via a public API. Therefore, such consumers are limited in what +they can do: + +1. One could re-implement WTF-8 and re-encode file paths on Windows to WTF-8 + by accessing their underlying 16-bit integer representation. Unfortunately, + this isn't zero cost (it introduces a second WTF-8 decoding step) and it's + not clear this is a good thing to do, since WTF-8 should ideally remain an + internal implementation detail. +2. One could instead declare that they will not handle paths on Windows that + are not valid UTF-16, and return an error when one is encountered. +3. Like (2), but instead of returning an error, lossily decode the file path + on Windows that isn't valid UTF-16 into UTF-16 by replacing invalid bytes + with the Unicode replacement codepoint. + +While this library may provide facilities for (1) in the future, currently, +this library only provides facilities for (2) and (3). In particular, a suite +of conversion functions are provided that permit converting between byte +strings, OS strings and file paths. For owned `BString`s, they are: + +* [`BString::from_os_string`](struct.BString.html#method.from_os_string) +* [`BString::from_os_str_lossy`](struct.BString.html#method.from_os_str_lossy) +* [`BString::from_path_buf`](struct.BString.html#method.from_path_buf) +* [`BString::from_path_lossy`](struct.BString.html#method.from_path_lossy) +* [`BString::into_os_string`](struct.BString.html#method.into_os_string) +* [`BString::into_os_string_lossy`](struct.BString.html#method.into_os_string_lossy) +* [`BString::into_path_buf`](struct.BString.html#method.into_path_buf) +* [`BString::into_path_buf_lossy`](struct.BString.html#method.into_path_buf_lossy) + +For byte string slices, they are: + +* [`BStr::from_os_str`](struct.BStr.html#method.from_os_str) +* [`BStr::from_path`](struct.BStr.html#method.from_path) +* [`BStr::to_os_str`](struct.BStr.html#method.to_os_str) +* [`BStr::to_os_str_lossy`](struct.BStr.html#method.to_os_str_lossy) +* [`BStr::to_path`](struct.BStr.html#method.to_path) +* [`BStr::to_path_lossy`](struct.BStr.html#method.to_path_lossy) + +On Unix, all of these conversions are rigorously zero cost, which gives one +a way to ergonomically deal with raw file paths exactly as they are using +normal string-related functions. On Windows, these conversion routines perform +a UTF-8 check and either return an error or lossily decode the file path +into valid UTF-8, depending on which function you use. This means that you +cannot roundtrip all file paths on Windows correctly using these conversion +routines. However, this may be an acceptable downside since such file paths +are exceptionally rare. Moreover, roundtripping isn't always necessary, for +example, if all you're doing is filtering based on file paths. + +The reason why using byte strings for this is potentially superior than the +standard library's approach is that a lot of Rust code is already lossily +converting file paths to Rust's Unicode strings, which are required to be valid +UTF-8, and thus contain latent bugs on Unix where paths with invalid UTF-8 are +not terribly uncommon. If you instead use byte strings, then you're guaranteed +to write correct code for Unix, at the cost of getting a corner case wrong on +Windows. +*/ + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +extern crate core; + +#[cfg(feature = "unicode")] +#[macro_use] +extern crate lazy_static; +extern crate memchr; +#[cfg(test)] +#[macro_use] +extern crate quickcheck; +#[cfg(feature = "unicode")] +extern crate regex_automata; +#[cfg(feature = "serde1-nostd")] +extern crate serde; +#[cfg(test)] +extern crate ucd_parse; + +pub use bstr::{ + B, BStr, + Bytes, + Finder, FinderReverse, Find, FindReverse, + Split, SplitReverse, SplitN, SplitNReverse, + Fields, FieldsWith, + Lines, LinesWithTerminator, +}; +#[cfg(feature = "std")] +pub use bstring::{BString, DrainBytes, FromUtf8Error, concat, join}; +pub use slice_index::SliceIndex; +#[cfg(feature = "unicode")] +pub use unicode::{ + Graphemes, GraphemeIndices, + Sentences, SentenceIndices, + Words, WordIndices, WordsWithBreaks, WordsWithBreakIndices, +}; +pub use utf8::{ + Utf8Error, Chars, CharIndices, + decode as decode_utf8, + decode_last as decode_last_utf8, +}; + +mod ascii; +mod bstr; +#[cfg(feature = "std")] +mod bstring; +mod cow; +mod impls; +#[cfg(feature = "std")] +pub mod io; +mod search; +mod slice_index; +#[cfg(test)] +mod tests; +#[cfg(feature = "unicode")] +mod unicode; +mod utf8; + +#[cfg(test)] +mod apitests { + use super::*; + + #[test] + fn oibits() { + use std::panic::{RefUnwindSafe, UnwindSafe}; + + fn assert_send() {} + fn assert_sync() {} + fn assert_unwind_safe() {} + + assert_send::<&BStr>(); + assert_sync::<&BStr>(); + assert_unwind_safe::<&BStr>(); + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/search/byte_frequencies.rs cargo-0.35.0/vendor/bstr/src/search/byte_frequencies.rs --- cargo-0.33.0/vendor/bstr/src/search/byte_frequencies.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/search/byte_frequencies.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,258 @@ +pub const BYTE_FREQUENCIES: [u8; 256] = [ + 55, // '\x00' + 52, // '\x01' + 51, // '\x02' + 50, // '\x03' + 49, // '\x04' + 48, // '\x05' + 47, // '\x06' + 46, // '\x07' + 45, // '\x08' + 103, // '\t' + 242, // '\n' + 66, // '\x0b' + 67, // '\x0c' + 229, // '\r' + 44, // '\x0e' + 43, // '\x0f' + 42, // '\x10' + 41, // '\x11' + 40, // '\x12' + 39, // '\x13' + 38, // '\x14' + 37, // '\x15' + 36, // '\x16' + 35, // '\x17' + 34, // '\x18' + 33, // '\x19' + 56, // '\x1a' + 32, // '\x1b' + 31, // '\x1c' + 30, // '\x1d' + 29, // '\x1e' + 28, // '\x1f' + 255, // ' ' + 148, // '!' + 164, // '"' + 149, // '#' + 136, // '$' + 160, // '%' + 155, // '&' + 173, // "'" + 221, // '(' + 222, // ')' + 134, // '*' + 122, // '+' + 232, // ',' + 202, // '-' + 215, // '.' + 224, // '/' + 208, // '0' + 220, // '1' + 204, // '2' + 187, // '3' + 183, // '4' + 179, // '5' + 177, // '6' + 168, // '7' + 178, // '8' + 200, // '9' + 226, // ':' + 195, // ';' + 154, // '<' + 184, // '=' + 174, // '>' + 126, // '?' + 120, // '@' + 191, // 'A' + 157, // 'B' + 194, // 'C' + 170, // 'D' + 189, // 'E' + 162, // 'F' + 161, // 'G' + 150, // 'H' + 193, // 'I' + 142, // 'J' + 137, // 'K' + 171, // 'L' + 176, // 'M' + 185, // 'N' + 167, // 'O' + 186, // 'P' + 112, // 'Q' + 175, // 'R' + 192, // 'S' + 188, // 'T' + 156, // 'U' + 140, // 'V' + 143, // 'W' + 123, // 'X' + 133, // 'Y' + 128, // 'Z' + 147, // '[' + 138, // '\\' + 146, // ']' + 114, // '^' + 223, // '_' + 151, // '`' + 249, // 'a' + 216, // 'b' + 238, // 'c' + 236, // 'd' + 253, // 'e' + 227, // 'f' + 218, // 'g' + 230, // 'h' + 247, // 'i' + 135, // 'j' + 180, // 'k' + 241, // 'l' + 233, // 'm' + 246, // 'n' + 244, // 'o' + 231, // 'p' + 139, // 'q' + 245, // 'r' + 243, // 's' + 251, // 't' + 235, // 'u' + 201, // 'v' + 196, // 'w' + 240, // 'x' + 214, // 'y' + 152, // 'z' + 182, // '{' + 205, // '|' + 181, // '}' + 127, // '~' + 27, // '\x7f' + 212, // '\x80' + 211, // '\x81' + 210, // '\x82' + 213, // '\x83' + 228, // '\x84' + 197, // '\x85' + 169, // '\x86' + 159, // '\x87' + 131, // '\x88' + 172, // '\x89' + 105, // '\x8a' + 80, // '\x8b' + 98, // '\x8c' + 96, // '\x8d' + 97, // '\x8e' + 81, // '\x8f' + 207, // '\x90' + 145, // '\x91' + 116, // '\x92' + 115, // '\x93' + 144, // '\x94' + 130, // '\x95' + 153, // '\x96' + 121, // '\x97' + 107, // '\x98' + 132, // '\x99' + 109, // '\x9a' + 110, // '\x9b' + 124, // '\x9c' + 111, // '\x9d' + 82, // '\x9e' + 108, // '\x9f' + 118, // '\xa0' + 141, // '¡' + 113, // '¢' + 129, // '£' + 119, // '¤' + 125, // '¥' + 165, // '¦' + 117, // '§' + 92, // '¨' + 106, // '©' + 83, // 'ª' + 72, // '«' + 99, // '¬' + 93, // '\xad' + 65, // '®' + 79, // '¯' + 166, // '°' + 237, // '±' + 163, // '²' + 199, // '³' + 190, // '´' + 225, // 'µ' + 209, // '¶' + 203, // '·' + 198, // '¸' + 217, // '¹' + 219, // 'º' + 206, // '»' + 234, // '¼' + 248, // '½' + 158, // '¾' + 239, // '¿' + 255, // 'À' + 255, // 'Á' + 255, // 'Â' + 255, // 'Ã' + 255, // 'Ä' + 255, // 'Å' + 255, // 'Æ' + 255, // 'Ç' + 255, // 'È' + 255, // 'É' + 255, // 'Ê' + 255, // 'Ë' + 255, // 'Ì' + 255, // 'Í' + 255, // 'Î' + 255, // 'Ï' + 255, // 'Ð' + 255, // 'Ñ' + 255, // 'Ò' + 255, // 'Ó' + 255, // 'Ô' + 255, // 'Õ' + 255, // 'Ö' + 255, // '×' + 255, // 'Ø' + 255, // 'Ù' + 255, // 'Ú' + 255, // 'Û' + 255, // 'Ü' + 255, // 'Ý' + 255, // 'Þ' + 255, // 'ß' + 255, // 'à' + 255, // 'á' + 255, // 'â' + 255, // 'ã' + 255, // 'ä' + 255, // 'å' + 255, // 'æ' + 255, // 'ç' + 255, // 'è' + 255, // 'é' + 255, // 'ê' + 255, // 'ë' + 255, // 'ì' + 255, // 'í' + 255, // 'î' + 255, // 'ï' + 255, // 'ð' + 255, // 'ñ' + 255, // 'ò' + 255, // 'ó' + 255, // 'ô' + 255, // 'õ' + 255, // 'ö' + 255, // '÷' + 255, // 'ø' + 255, // 'ù' + 255, // 'ú' + 255, // 'û' + 255, // 'ü' + 255, // 'ý' + 255, // 'þ' + 255, // 'ÿ' +]; diff -Nru cargo-0.33.0/vendor/bstr/src/search/mod.rs cargo-0.35.0/vendor/bstr/src/search/mod.rs --- cargo-0.33.0/vendor/bstr/src/search/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/search/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +pub use self::prefilter::PrefilterState; +pub use self::twoway::TwoWay; + +mod byte_frequencies; +mod prefilter; +#[cfg(test)] +mod tests; +mod twoway; diff -Nru cargo-0.33.0/vendor/bstr/src/search/prefilter.rs cargo-0.35.0/vendor/bstr/src/search/prefilter.rs --- cargo-0.33.0/vendor/bstr/src/search/prefilter.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/search/prefilter.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,424 @@ +use core::mem; + +use bstr::BStr; +use search::byte_frequencies::BYTE_FREQUENCIES; + +/// PrefilterState tracks state associated with the effectiveness of a +/// prefilter. It is used to track how many bytes, on average, are skipped by +/// the prefilter. If this average dips below a certain threshold over time, +/// then the state renders the prefilter inert and stops using it. +/// +/// A prefilter state should be created for each search. (Where creating an +/// iterator via, e.g., `find_iter`, is treated as a single search.) +#[derive(Clone, Debug)] +pub struct PrefilterState { + /// The number of skips that has been executed. + skips: usize, + /// The total number of bytes that have been skipped. + skipped: usize, + /// The maximum length of a match. This is used to help determine how many + /// bytes on average should be skipped in order for a prefilter to be + /// effective. + max_match_len: usize, + /// Once this heuristic has been deemed ineffective, it will be inert + /// throughout the rest of its lifetime. This serves as a cheap way to + /// check inertness. + inert: bool, +} + +impl PrefilterState { + /// The minimum number of skip attempts to try before considering whether + /// a prefilter is effective or not. + const MIN_SKIPS: usize = 50; + + /// The minimum amount of bytes that skipping must average. + /// + /// This value was chosen based on varying it and checking the bstr/find/ + /// microbenchmarks. In particular, this can impact the + /// pathological/repeated-{huge,small} benchmarks quite a bit if it's + /// set too low. + const MIN_SKIP_BYTES: usize = 8; + + /// Create a fresh prefilter state. + pub fn new(max_match_len: usize) -> PrefilterState { + if max_match_len == 0 { + return PrefilterState::inert(); + } + PrefilterState { skips: 0, skipped: 0, max_match_len, inert: false } + } + + /// Create a fresh prefilter state that is always inert. + fn inert() -> PrefilterState { + PrefilterState { skips: 0, skipped: 0, max_match_len: 0, inert: true } + } + + /// Update this state with the number of bytes skipped on the last + /// invocation of the prefilter. + #[inline] + pub fn update(&mut self, skipped: usize) { + self.skips += 1; + self.skipped += skipped; + } + + /// Return true if and only if this state indicates that a prefilter is + /// still effective. + #[inline] + pub fn is_effective(&mut self) -> bool { + if self.inert { + return false; + } + if self.skips < PrefilterState::MIN_SKIPS { + return true; + } + if self.skipped >= PrefilterState::MIN_SKIP_BYTES * self.skips { + return true; + } + + // We're inert. + self.inert = true; + false + } +} + +/// A heuristic frequency based prefilter for searching a single needle. +/// +/// This prefilter attempts to pick out the byte in a needle that is predicted +/// to occur least frequently, and search for that using fast vectorized +/// routines. If a rare enough byte could not be found, then this prefilter's +/// constructors will return `None`. +/// +/// This can be combined with `PrefilterState` to dynamically render this +/// prefilter inert if it proves to ineffective. +#[derive(Clone, Debug)] +pub struct Freqy { + /// Whether this prefilter should be used or not. + inert: bool, + /// The length of the needle we're searching for. + needle_len: usize, + /// The rarest byte in the needle, according to pre-computed frequency + /// analysis. + rare1: u8, + /// The leftmost offset of the rarest byte in the needle. + rare1i: usize, + /// The second rarest byte in the needle, according to pre-computed + /// frequency analysis. (This may be equivalent to the rarest byte.) + /// + /// The second rarest byte is used as a type of guard for quickly detecting + /// a mismatch after memchr locates an instance of the rarest byte. This + /// is a hedge against pathological cases where the pre-computed frequency + /// analysis may be off. (But of course, does not prevent *all* + /// pathological cases.) + rare2: u8, + /// The leftmost offset of the second rarest byte in the needle. + rare2i: usize, +} + +impl Freqy { + /// The maximum frequency rank permitted. If the rarest byte in the needle + /// has a frequency rank above this value, then Freqy is not used. + const MAX_RANK: usize = 200; + + /// Return a fresh prefilter state that can be used with this prefilter. A + /// prefilter state is used to track the effectiveness of a prefilter for + /// speeding up searches. Therefore, the prefilter state should generally + /// be reused on subsequent searches (such as in an iterator). For searches + /// on a different haystack, then a new prefilter state should be used. + pub fn prefilter_state(&self) -> PrefilterState { + if self.inert { + PrefilterState::inert() + } else { + PrefilterState::new(self.needle_len) + } + } + + /// Returns a valid but inert prefilter. This is valid for both the forward + /// and reverse direction. + /// + /// It is never correct to use an inert prefilter. The results of finding + /// the next (or previous) candidate are unspecified. + fn inert() -> Freqy { + Freqy { + inert: true, + needle_len: 0, + rare1: 0, + rare1i: 0, + rare2: 0, + rare2i: 0, + } + } + + /// Return search info for the given needle in the forward direction. + pub fn forward(needle: &BStr) -> Freqy { + if needle.is_empty() { + return Freqy::inert(); + } + + // Find the rarest two bytes. Try to make them distinct (but it's not + // required). + let (mut rare1, mut rare1i) = (needle[0], 0); + let (mut rare2, mut rare2i) = (needle[0], 0); + if needle.len() >= 2 { + rare2 = needle[1]; + rare2i = 1; + } + if Freqy::rank(rare2) < Freqy::rank(rare1) { + mem::swap(&mut rare1, &mut rare2); + mem::swap(&mut rare1i, &mut rare2i); + } + for (i, b) in needle.bytes().enumerate().skip(2) { + if Freqy::rank(b) < Freqy::rank(rare1) { + rare2 = rare1; + rare2i = rare1i; + rare1 = b; + rare1i = i; + } else if b != rare1 && Freqy::rank(b) < Freqy::rank(rare2) { + rare2 = b; + rare2i = i; + } + } + if Freqy::rank(rare1) > Freqy::MAX_RANK { + return Freqy::inert(); + } + let needle_len = needle.len(); + Freqy { inert: false, needle_len, rare1, rare1i, rare2, rare2i } + } + + /// Return search info for the given needle in the reverse direction. + pub fn reverse(needle: &BStr) -> Freqy { + if needle.is_empty() { + return Freqy::inert(); + } + + // Find the rarest two bytes. Try to make them distinct (but it's not + // required). In reverse, the offsets correspond to the number of bytes + // from the end of the needle. So `0` is the last byte in the needle. + let (mut rare1i, mut rare2i) = (0, 0); + if needle.len() >= 2 { + rare2i += 1; + } + let mut rare1 = needle[needle.len() - rare1i - 1]; + let mut rare2 = needle[needle.len() - rare2i - 1]; + if Freqy::rank(rare2) < Freqy::rank(rare1) { + mem::swap(&mut rare1, &mut rare2); + mem::swap(&mut rare1i, &mut rare2i); + } + for (i, b) in needle.bytes().rev().enumerate().skip(2) { + if Freqy::rank(b) < Freqy::rank(rare1) { + rare2 = rare1; + rare2i = rare1i; + rare1 = b; + rare1i = i; + } else if b != rare1 && Freqy::rank(b) < Freqy::rank(rare2) { + rare2 = b; + rare2i = i; + } + } + if Freqy::rank(rare1) > Freqy::MAX_RANK { + return Freqy::inert(); + } + let needle_len = needle.len(); + Freqy { inert: false, needle_len, rare1, rare1i, rare2, rare2i } + } + + /// Look for a possible occurrence of needle. The position returned + /// corresponds to the beginning of the occurrence, if one exists. + /// + /// Callers may assume that this never returns false negatives (i.e., it + /// never misses an actual occurrence), but must check that the returned + /// position corresponds to a match. That is, it can return false + /// positives. + /// + /// This should only be used when Freqy is constructed for forward + /// searching. + pub fn find_candidate( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + ) -> Option { + debug_assert!(!self.inert); + + let mut i = 0; + while prestate.is_effective() { + // Use a fast vectorized implementation to skip to the next + // occurrence of the rarest byte (heuristically chosen) in the + // needle. + i += match haystack[i..].find_byte(self.rare1) { + None => return None, + Some(found) => { + prestate.update(found); + found + } + }; + + // If we can't align our first match with the haystack, then a + // match is impossible. + if i < self.rare1i { + i += 1; + continue; + } + + // Align our rare2 byte with the haystack. A mismatch means that + // a match is impossible. + let aligned_rare2i = i - self.rare1i + self.rare2i; + if haystack.get(aligned_rare2i) != Some(&self.rare2) { + i += 1; + continue; + } + + // We've done what we can. There might be a match here. + return Some(i - self.rare1i); + } + // The only way we get here is if we believe our skipping heuristic + // has become ineffective. We're allowed to return false positives, + // so return the position at which we advanced to, aligned to the + // haystack. + Some(i.saturating_sub(self.rare1i)) + } + + /// Look for a possible occurrence of needle, in reverse, starting from the + /// end of the given haystack. The position returned corresponds to the + /// position immediately after the end of the occurrence, if one exists. + /// + /// Callers may assume that this never returns false negatives (i.e., it + /// never misses an actual occurrence), but must check that the returned + /// position corresponds to a match. That is, it can return false + /// positives. + /// + /// This should only be used when Freqy is constructed for reverse + /// searching. + pub fn rfind_candidate( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + ) -> Option { + debug_assert!(!self.inert); + + let mut i = haystack.len(); + while prestate.is_effective() { + // Use a fast vectorized implementation to skip to the next + // occurrence of the rarest byte (heuristically chosen) in the + // needle. + i = match haystack[..i].rfind_byte(self.rare1) { + None => return None, + Some(found) => { + prestate.update(i - found); + found + } + }; + + // If we can't align our first match with the haystack, then a + // match is impossible. + if i + self.rare1i + 1 > haystack.len() { + continue; + } + + // Align our rare2 byte with the haystack. A mismatch means that + // a match is impossible. + let aligned = match (i + self.rare1i).checked_sub(self.rare2i) { + None => continue, + Some(aligned) => aligned, + }; + if haystack.get(aligned) != Some(&self.rare2) { + continue; + } + + // We've done what we can. There might be a match here. + return Some(i + self.rare1i + 1); + } + // The only way we get here is if we believe our skipping heuristic + // has become ineffective. We're allowed to return false positives, + // so return the position at which we advanced to, aligned to the + // haystack. + Some(i + self.rare1i + 1) + } + + /// Return the heuristical frequency rank of the given byte. A lower rank + /// means the byte is believed to occur less frequently. + fn rank(b: u8) -> usize { + BYTE_FREQUENCIES[b as usize] as usize + } +} + +#[cfg(test)] +mod tests { + use bstr::B; + use super::*; + + #[test] + fn freqy_forward() { + // N.B. We sometimes use uppercase here since that mostly ensures freqy + // will be constructable. Lowercase letters may be too common for freqy + // to work. + + let s = Freqy::forward(B("BAR")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(0), s.find_candidate(&mut pre, B("BARFOO"))); + + let s = Freqy::forward(B("BAR")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(3), s.find_candidate(&mut pre, B("FOOBAR"))); + + let s = Freqy::forward(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(0), s.find_candidate(&mut pre, B("zyzz"))); + + let s = Freqy::forward(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(2), s.find_candidate(&mut pre, B("zzzy"))); + + let s = Freqy::forward(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(None, s.find_candidate(&mut pre, B("zazb"))); + + let s = Freqy::forward(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(0), s.find_candidate(&mut pre, B("yzyy"))); + + let s = Freqy::forward(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(2), s.find_candidate(&mut pre, B("yyyz"))); + + let s = Freqy::forward(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(None, s.find_candidate(&mut pre, B("yayb"))); + } + + #[test] + fn freqy_reverse() { + // N.B. We sometimes use uppercase here since that mostly ensures freqy + // will be constructable. Lowercase letters may be too common for freqy + // to work. + + let s = Freqy::reverse(B("BAR")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(3), s.rfind_candidate(&mut pre, B("BARFOO"))); + + let s = Freqy::reverse(B("BAR")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(6), s.rfind_candidate(&mut pre, B("FOOBAR"))); + + let s = Freqy::reverse(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(2), s.rfind_candidate(&mut pre, B("zyzz"))); + + let s = Freqy::reverse(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(4), s.rfind_candidate(&mut pre, B("zzzy"))); + + let s = Freqy::reverse(B("zyzy")); + let mut pre = s.prefilter_state(); + assert_eq!(None, s.rfind_candidate(&mut pre, B("zazb"))); + + let s = Freqy::reverse(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(2), s.rfind_candidate(&mut pre, B("yzyy"))); + + let s = Freqy::reverse(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(Some(4), s.rfind_candidate(&mut pre, B("yyyz"))); + + let s = Freqy::reverse(B("yzyz")); + let mut pre = s.prefilter_state(); + assert_eq!(None, s.rfind_candidate(&mut pre, B("yayb"))); + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/search/tests.rs cargo-0.35.0/vendor/bstr/src/search/tests.rs --- cargo-0.33.0/vendor/bstr/src/search/tests.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/search/tests.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,223 @@ +use bstr::{B, BStr}; +use bstring::BString; +use search::twoway::TwoWay; + +/// Each test is a (needle, haystack, expected_fwd, expected_rev) tuple. +type SearchTest = (&'static str, &'static str, Option, Option); + +const SEARCH_TESTS: &'static [SearchTest] = &[ + ("", "", Some(0), Some(0)), + ("", "a", Some(0), Some(1)), + ("", "ab", Some(0), Some(2)), + ("", "abc", Some(0), Some(3)), + ("a", "", None, None), + ("a", "a", Some(0), Some(0)), + ("a", "aa", Some(0), Some(1)), + ("a", "ba", Some(1), Some(1)), + ("a", "bba", Some(2), Some(2)), + ("a", "bbba", Some(3), Some(3)), + ("a", "bbbab", Some(3), Some(3)), + ("a", "bbbabb", Some(3), Some(3)), + ("a", "bbbabbb", Some(3), Some(3)), + ("a", "bbbbbb", None, None), + ("ab", "", None, None), + ("ab", "a", None, None), + ("ab", "b", None, None), + ("ab", "ab", Some(0), Some(0)), + ("ab", "aab", Some(1), Some(1)), + ("ab", "aaab", Some(2), Some(2)), + ("ab", "abaab", Some(0), Some(3)), + ("ab", "baaab", Some(3), Some(3)), + ("ab", "acb", None, None), + ("ab", "abba", Some(0), Some(0)), + ("abc", "ab", None, None), + ("abc", "abc", Some(0), Some(0)), + ("abc", "abcz", Some(0), Some(0)), + ("abc", "abczz", Some(0), Some(0)), + ("abc", "zabc", Some(1), Some(1)), + ("abc", "zzabc", Some(2), Some(2)), + ("abc", "azbc", None, None), + ("abc", "abzc", None, None), + + ("abczdef", "abczdefzzzzzzzzzzzzzzzzzzzz", Some(0), Some(0)), + ("abczdef", "zzzzzzzzzzzzzzzzzzzzabczdef", Some(20), Some(20)), + + // Failures caught by quickcheck. + ("\u{0}\u{15}", "\u{0}\u{15}\u{15}\u{0}", Some(0), Some(0)), + ("\u{0}\u{1e}", "\u{1e}\u{0}", None, None), +]; + +#[test] +fn unit_twoway_fwd() { + run_search_tests_fwd("TwoWay", |n, h| TwoWay::forward(n).find(h)); +} + +#[test] +fn unit_twoway_rev() { + run_search_tests_rev("TwoWay", |n, h| TwoWay::reverse(n).rfind(h)); +} + +/// Run the substring search tests. `name` should be the type of searcher used, +/// for diagnostics. `search` should be a closure that accepts a needle and a +/// haystack and returns the starting position of the first occurrence of +/// needle in the haystack, or `None` if one doesn't exist. +fn run_search_tests_fwd( + name: &str, + mut search: impl FnMut(&BStr, &BStr) -> Option, +) { + for &(needle, haystack, expected_fwd, _) in SEARCH_TESTS { + let (n, h) = (B(needle), B(haystack)); + assert_eq!( + expected_fwd, + search(n, h), + "{}: needle: {:?}, haystack: {:?}, expected: {:?}", + name, n, h, expected_fwd + ); + } +} + +/// Run the substring search tests. `name` should be the type of searcher used, +/// for diagnostics. `search` should be a closure that accepts a needle and a +/// haystack and returns the starting position of the last occurrence of +/// needle in the haystack, or `None` if one doesn't exist. +fn run_search_tests_rev( + name: &str, + mut search: impl FnMut(&BStr, &BStr) -> Option, +) { + for &(needle, haystack, _, expected_rev) in SEARCH_TESTS { + let (n, h) = (B(needle), B(haystack)); + assert_eq!( + expected_rev, + search(n, h), + "{}: needle: {:?}, haystack: {:?}, expected: {:?}", + name, n, h, expected_rev + ); + } +} + +quickcheck! { + fn qc_twoway_fwd_prefix_is_substring(bs: BString) -> bool { + prop_prefix_is_substring(false, &bs, |n, h| TwoWay::forward(n).find(h)) + } + + fn qc_twoway_fwd_suffix_is_substring(bs: BString) -> bool { + prop_suffix_is_substring(false, &bs, |n, h| TwoWay::forward(n).find(h)) + } + + fn qc_twoway_rev_prefix_is_substring(bs: BString) -> bool { + prop_prefix_is_substring(true, &bs, |n, h| TwoWay::reverse(n).rfind(h)) + } + + fn qc_twoway_rev_suffix_is_substring(bs: BString) -> bool { + prop_suffix_is_substring(true, &bs, |n, h| TwoWay::reverse(n).rfind(h)) + } + + fn qc_twoway_fwd_matches_naive( + needle: BString, + haystack: BString + ) -> bool { + prop_matches_naive( + false, + &needle, + &haystack, + |n, h| TwoWay::forward(n).find(h), + ) + } + + fn qc_twoway_rev_matches_naive( + needle: BString, + haystack: BString + ) -> bool { + prop_matches_naive( + true, + &needle, + &haystack, + |n, h| TwoWay::reverse(n).rfind(h), + ) + } +} + +/// Check that every prefix of the given byte string is a substring. +fn prop_prefix_is_substring( + reverse: bool, + bs: &BStr, + mut search: impl FnMut(&BStr, &BStr) -> Option, +) -> bool { + if bs.is_empty() { + return true; + } + for i in 0..(bs.len() - 1) { + let prefix = &bs[..i]; + if reverse { + assert_eq!(naive_rfind(prefix, bs), search(prefix, bs)); + } else { + assert_eq!(naive_find(prefix, bs), search(prefix, bs)); + } + } + true +} + +/// Check that every suffix of the given byte string is a substring. +fn prop_suffix_is_substring( + reverse: bool, + bs: &BStr, + mut search: impl FnMut(&BStr, &BStr) -> Option, +) -> bool { + if bs.is_empty() { + return true; + } + for i in 0..(bs.len() - 1) { + let suffix = &bs[i..]; + if reverse { + assert_eq!(naive_rfind(suffix, bs), search(suffix, bs)); + } else { + assert_eq!(naive_find(suffix, bs), search(suffix, bs)); + } + } + true +} + +/// Check that naive substring search matches the result of the given search +/// algorithm. +fn prop_matches_naive( + reverse: bool, + needle: &BStr, + haystack: &BStr, + mut search: impl FnMut(&BStr, &BStr) -> Option, +) -> bool { + if reverse { + naive_rfind(needle, haystack) == search(needle, haystack) + } else { + naive_find(needle, haystack) == search(needle, haystack) + } +} + +/// Naively search forwards for the given needle in the given haystack. +fn naive_find(needle: &BStr, haystack: &BStr) -> Option { + if needle.is_empty() { + return Some(0); + } else if haystack.len() < needle.len() { + return None; + } + for i in 0..(haystack.len() - needle.len() + 1) { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None +} + +/// Naively search in reverse for the given needle in the given haystack. +fn naive_rfind(needle: &BStr, haystack: &BStr) -> Option { + if needle.is_empty() { + return Some(haystack.len()); + } else if haystack.len() < needle.len() { + return None; + } + for i in (0..(haystack.len() - needle.len() + 1)).rev() { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None +} diff -Nru cargo-0.33.0/vendor/bstr/src/search/twoway.rs cargo-0.35.0/vendor/bstr/src/search/twoway.rs --- cargo-0.33.0/vendor/bstr/src/search/twoway.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/search/twoway.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,883 @@ +use core::cmp; + +use bstr::BStr; +use cow::CowBStr; +use search::prefilter::{Freqy, PrefilterState}; + +/// An implementation of the TwoWay substring search algorithm, with heuristics +/// for accelerating search based on frequency analysis. +/// +/// This searcher supports forward and reverse search, although not +/// simultaneously. It runs in O(n + m) time and O(1) space, where +/// `n ~ len(needle)` and `m ~ len(haystack)`. +/// +/// The implementation here roughly matches that which was developed by +/// Crochemore and Perrin in their 1991 paper "Two-way string-matching." The +/// only change in this implementation is the use of zero-based indices and +/// the addition of heuristics for a fast skip loop. That is, this will detect +/// bytes that are believed to be rare in the needle and use fast vectorized +/// instructions to find their occurrences quickly. The Two-Way algorithm is +/// then used to confirm whether a match at that location occurred. +/// +/// The heuristic for fast skipping is automatically shut off if it's +/// detected to be ineffective at search time. Generally, this only occurs in +/// pathological cases. But this is generally necessary in order to preserve +/// a `O(n + m)` time bound. +/// +/// The code below is fairly complex and not obviously correct at all. It's +/// likely necessary to read the Two-Way paper cited above in order to fully +/// grok this code. +#[derive(Clone, Debug)] +pub struct TwoWay<'b> { + /// The needle that we're looking for. + needle: CowBStr<'b>, + /// An implementation of a fast skip loop based on hard-coded frequency + /// data. This is only used when conditions are deemed favorable. + freqy: Freqy, + /// A critical position in needle. Specifically, this position corresponds + /// to beginning of either the minimal or maximal suffix in needle. (N.B. + /// See SuffixType below for why "minimal" isn't quite the correct word + /// here.) + /// + /// This is the position at which every search begins. Namely, search + /// starts by scanning text to the right of this position, and only if + /// there's a match does the text to the left of this position get scanned. + critical_pos: usize, + /// The amount we shift by in the Two-Way search algorithm. This + /// corresponds to the "small period" and "large period" cases. + shift: Shift, +} + +impl<'b> TwoWay<'b> { + /// Create a searcher that uses the Two-Way algorithm by searching forwards + /// through any haystack. + pub fn forward(needle: &'b BStr) -> TwoWay<'b> { + let freqy = Freqy::forward(needle); + if needle.is_empty() { + return TwoWay { + needle: CowBStr::new(needle), + freqy, + critical_pos: 0, + shift: Shift::Large { shift: 0 }, + }; + } + + let min_suffix = Suffix::forward(needle, SuffixKind::Minimal); + let max_suffix = Suffix::forward(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos > max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + let shift = Shift::forward(needle, period_lower_bound, critical_pos); + let needle = CowBStr::new(needle); + TwoWay { needle, freqy, critical_pos, shift } + } + + /// Create a searcher that uses the Two-Way algorithm by searching in + /// reverse through any haystack. + pub fn reverse(needle: &'b BStr) -> TwoWay<'b> { + let freqy = Freqy::reverse(needle); + if needle.is_empty() { + return TwoWay { + needle: CowBStr::new(needle), + freqy, + critical_pos: 0, + shift: Shift::Large { shift: 0 }, + }; + } + + let min_suffix = Suffix::reverse(needle, SuffixKind::Minimal); + let max_suffix = Suffix::reverse(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos < max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + let shift = Shift::reverse(needle, period_lower_bound, critical_pos); + let needle = CowBStr::new(needle); + TwoWay { needle, freqy, critical_pos, shift } + } + + /// Return a fresh prefilter state that can be used with this searcher. + /// A prefilter state is used to track the effectiveness of a searcher's + /// prefilter for speeding up searches. Therefore, the prefilter state + /// should generally be reused on subsequent searches (such as in an + /// iterator). For searches on a different haystack, then a new prefilter + /// state should be used. + /// + /// This always initializes a valid prefilter state even if this searcher + /// does not have a prefilter enabled. + pub fn prefilter_state(&self) -> PrefilterState { + self.freqy.prefilter_state() + } + + /// Return the needle used by this searcher. + pub fn needle(&self) -> &BStr { + self.needle.as_bstr() + } + + /// Convert this searched into an owned version, where the needle is + /// copied if it isn't already owned. + #[cfg(feature = "std")] + pub fn into_owned(self) -> TwoWay<'static> { + TwoWay { + needle: self.needle.into_owned(), + freqy: self.freqy, + critical_pos: self.critical_pos, + shift: self.shift, + } + } + + /// Find the position of the first occurrence of this searcher's needle in + /// the given haystack. If one does not exist, then return None. + /// + /// This will automatically initialize prefilter state. This should only + /// be used for one-off searches. + pub fn find(&self, haystack: &BStr) -> Option { + self.find_with(&mut self.prefilter_state(), haystack) + } + + /// Find the position of the last occurrence of this searcher's needle + /// in the given haystack. If one does not exist, then return None. + /// + /// This will automatically initialize prefilter state. This should only + /// be used for one-off searches. + pub fn rfind(&self, haystack: &BStr) -> Option { + self.rfind_with(&mut self.prefilter_state(), haystack) + } + + /// Find the position of the first occurrence of this searcher's needle in + /// the given haystack. If one does not exist, then return None. + /// + /// This accepts prefilter state that is useful when using the same + /// searcher multiple times, such as in an iterator. + pub fn find_with( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + ) -> Option { + if self.needle.is_empty() { + return Some(0); + } else if haystack.len() < self.needle.len() { + return None; + } else if self.needle.len() == 1 { + return haystack.find_byte(self.needle[0]); + } + match self.shift { + Shift::Small { period } => { + self.find_small(prestate, haystack, period) + } + Shift::Large { shift } => { + self.find_large(prestate, haystack, shift) + } + } + } + + /// Find the position of the last occurrence of this searcher's needle + /// in the given haystack. If one does not exist, then return None. + /// + /// This accepts prefilter state that is useful when using the same + /// searcher multiple times, such as in an iterator. + pub fn rfind_with( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + ) -> Option { + if self.needle.is_empty() { + return Some(haystack.len()); + } else if haystack.len() < self.needle.len() { + return None; + } else if self.needle.len() == 1 { + return haystack.rfind_byte(self.needle[0]); + } + match self.shift { + Shift::Small { period } => { + self.rfind_small(prestate, haystack, period) + } + Shift::Large { shift } => { + self.rfind_large(prestate, haystack, shift) + } + } + } + + // Below is the actual implementation of TwoWay searching, including both + // forwards and backwards searching. Each forward and reverse search has + // two fairly similar implementations, each handling the small and large + // period cases, for a total 4 different search routines. + // + // On top of that, each search implementation can be accelerated by a + // Freqy prefilter, but it is not always enabled. To avoid its overhead + // when its disabled, we explicitly inline each search implementation based + // on whether Freqy will be used or not. This brings us up to a total of + // 8 monomorphized versions of the search code. + + #[inline(never)] + fn find_small( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + period: usize, + ) -> Option { + if prestate.is_effective() { + self.find_small_imp(prestate, true, haystack, period) + } else { + self.find_small_imp(prestate, false, haystack, period) + } + } + + #[inline(always)] + fn find_small_imp( + &self, + prestate: &mut PrefilterState, + prefilter: bool, + haystack: &BStr, + period: usize, + ) -> Option { + let needle = self.needle.as_bstr(); + let mut pos = 0; + let mut shift = 0; + while pos + needle.len() <= haystack.len() { + let mut i = cmp::max(self.critical_pos, shift); + if prefilter && prestate.is_effective() { + match self.freqy.find_candidate(prestate, &haystack[pos..]) { + None => return None, + Some(found) => { + shift = 0; + i = self.critical_pos; + pos += found; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + } + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.critical_pos + 1; + shift = 0; + } else { + let mut j = self.critical_pos; + while j > shift && needle[j] == haystack[pos + j] { + j -= 1; + } + if j <= shift && needle[shift] == haystack[pos + shift] { + return Some(pos); + } + pos += period; + shift = needle.len() - period; + } + } + None + } + + #[inline(never)] + fn find_large( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + shift: usize, + ) -> Option { + if prestate.is_effective() { + self.find_large_imp(prestate, true, haystack, shift) + } else { + self.find_large_imp(prestate, false, haystack, shift) + } + } + + #[inline(always)] + fn find_large_imp( + &self, + prestate: &mut PrefilterState, + prefilter: bool, + haystack: &BStr, + shift: usize, + ) -> Option { + let needle = self.needle.as_bstr(); + let mut pos = 0; + while pos + needle.len() <= haystack.len() { + let mut i = self.critical_pos; + if prefilter && prestate.is_effective() { + match self.freqy.find_candidate(prestate, &haystack[pos..]) { + None => return None, + Some(found) => { + pos += found; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + } + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.critical_pos + 1; + } else { + let mut j = self.critical_pos; + while j > 0 && needle[j] == haystack[pos + j] { + j -= 1; + } + if j == 0 && needle[0] == haystack[pos] { + return Some(pos); + } + pos += shift; + } + } + None + } + + #[inline(never)] + fn rfind_small( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + period: usize, + ) -> Option { + if prestate.is_effective() { + self.rfind_small_imp(prestate, true, haystack, period) + } else { + self.rfind_small_imp(prestate, false, haystack, period) + } + } + + #[inline(always)] + fn rfind_small_imp( + &self, + prestate: &mut PrefilterState, + prefilter: bool, + haystack: &BStr, + period: usize, + ) -> Option { + let needle = &*self.needle; + let nlen = needle.len(); + let mut pos = haystack.len(); + let mut shift = nlen; + while pos >= nlen { + let mut i = cmp::min(self.critical_pos, shift); + if prefilter && prestate.is_effective() { + match self.freqy.rfind_candidate(prestate, &haystack[..pos]) { + None => return None, + Some(found) => { + shift = nlen; + i = self.critical_pos; + pos = found; + if pos < nlen { + return None; + } + } + } + } + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || needle[0] != haystack[pos - nlen] { + pos -= self.critical_pos - i + 1; + shift = nlen; + } else { + let mut j = self.critical_pos; + while j < shift && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j == shift { + return Some(pos - nlen); + } + pos -= period; + shift = period; + } + } + None + } + + #[inline(never)] + fn rfind_large( + &self, + prestate: &mut PrefilterState, + haystack: &BStr, + shift: usize, + ) -> Option { + if prestate.is_effective() { + self.rfind_large_imp(prestate, true, haystack, shift) + } else { + self.rfind_large_imp(prestate, false, haystack, shift) + } + } + + #[inline(always)] + fn rfind_large_imp( + &self, + prestate: &mut PrefilterState, + prefilter: bool, + haystack: &BStr, + shift: usize, + ) -> Option { + let needle = &*self.needle; + let nlen = needle.len(); + let mut pos = haystack.len(); + while pos >= nlen { + if prefilter && prestate.is_effective() { + match self.freqy.rfind_candidate(prestate, &haystack[..pos]) { + None => return None, + Some(found) => { + pos = found; + if pos < nlen { + return None; + } + } + } + } + + let mut i = self.critical_pos; + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || needle[0] != haystack[pos - nlen] { + pos -= self.critical_pos - i + 1; + } else { + let mut j = self.critical_pos; + while j < nlen && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j == nlen { + return Some(pos - nlen); + } + pos -= shift; + } + } + None + } +} + +/// A representation of the amount we're allowed to shift by during Two-Way +/// search. +/// +/// When computing a critical factorization of the needle, we find the position +/// of the critical factorization by finding the needle's maximal (or minimal) +/// suffix, along with the period of that suffix. It turns out that the period +/// of that suffix is a lower bound on the period of the needle itself. +/// +/// This lower bound is equivalent to the actual period of the needle in +/// some cases. To describe that case, we denote the needle as `x` where +/// `x = uv` and `v` is the lexicographic maximal suffix of `v`. The lower +/// bound given here is always the period of `v`, which is `<= period(x)`. The +/// case where `period(v) == period(x)` occurs when `len(u) < (len(x) / 2)` and +/// where `u` is a suffix of `v[0..period(v)]`. +/// +/// This case is important because the search algorithm for when the +/// periods are equivalent is slightly different than the search algorithm +/// for when the periods are not equivalent. In particular, when they aren't +/// equivalent, we know that the period of the needle is no less than half its +/// length. In this case, we shift by an amount less than or equal to the +/// period of the needle (determined by the maximum length of the components +/// of the critical factorization of `x`, i.e., `max(len(u), len(v))`).. +/// +/// The above two cases are represented by the variants below. Each entails +/// a different instantiation of the Two-Way search algorithm. +/// +/// N.B. If we could find a way to compute the exact period in all cases, +/// then we could collapse this case analysis and simplify the algorithm. The +/// Two-Way paper suggests this is possible, but more reading is required to +/// grok why the authors didn't pursue that path. +#[derive(Clone, Debug)] +enum Shift { + Small { period: usize }, + Large { shift: usize }, +} + +impl Shift { + /// Compute the shift for a given needle in the forward direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the right-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn forward( + needle: &BStr, + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if critical_pos * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (u, v) = needle.split_at(critical_pos); + if !v[..period_lower_bound].ends_with(u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } + + /// Compute the shift for a given needle in the reverse direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the left-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn reverse( + needle: &BStr, + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if (needle.len() - critical_pos) * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (v, u) = needle.split_at(critical_pos); + if !v[v.len() - period_lower_bound..].starts_with(u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } +} + +/// A suffix extracted from a needle along with its period. +#[derive(Debug)] +struct Suffix { + /// The starting position of this suffix. + /// + /// If this is a forward suffix, then `&bytes[pos..]` can be used. If this + /// is a reverse suffix, then `&bytes[..pos]` can be used. That is, for + /// forward suffixes, this is an inclusive starting position, where as for + /// reverse suffixes, this is an exclusive ending position. + pos: usize, + /// The period of this suffix. + /// + /// Note that this is NOT necessarily the period of the string from which + /// this suffix comes from. (It is always less than or equal to the period + /// of the original string.) + period: usize, +} + +impl Suffix { + fn forward(needle: &BStr, kind: SuffixKind) -> Suffix { + debug_assert!(!needle.is_empty()); + + // suffix represents our maximal (or minimal) suffix, along with + // its period. + let mut suffix = Suffix { pos: 0, period: 1 }; + // The start of a suffix in `needle` that we are considering as a + // more maximal (or minimal) suffix than what's in `suffix`. + let mut candidate_start = 1; + // The current offset of our suffixes that we're comparing. + // + // When the characters at this offset are the same, then we mush on + // to the next position since no decision is possible. When the + // candidate's character is greater (or lesser) than the corresponding + // character than our current maximal (or minimal) suffix, then the + // current suffix is changed over to the candidate and we restart our + // search. Otherwise, the candidate suffix is no good and we restart + // our search on the next candidate. + // + // The three cases above correspond to the three cases in the loop + // below. + let mut offset = 0; + + while candidate_start + offset < needle.len() { + let current = needle[suffix.pos + offset]; + let candidate = needle[candidate_start + offset]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start += 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start += offset + 1; + offset = 0; + suffix.period = candidate_start - suffix.pos; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start += suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } + + fn reverse(needle: &BStr, kind: SuffixKind) -> Suffix { + debug_assert!(!needle.is_empty()); + + // See the comments in `forward` for how this works. + let mut suffix = Suffix { pos: needle.len(), period: 1 }; + if needle.len() == 1 { + return suffix; + } + let mut candidate_start = needle.len() - 1; + let mut offset = 0; + + while offset < candidate_start { + let current = needle[suffix.pos - offset - 1]; + let candidate = needle[candidate_start - offset - 1]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start -= 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start -= offset + 1; + offset = 0; + suffix.period = suffix.pos - candidate_start; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start -= suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } +} + +/// The kind of suffix to extract. +#[derive(Clone, Copy, Debug)] +enum SuffixKind { + /// Extract the smallest lexicographic suffix from a string. + /// + /// Technically, this doesn't actually pick the smallest lexicographic + /// suffix. e.g., Given the choice between `a` and `aa`, this will choose + /// the latter over the former, even though `a < aa`. The reasoning for + /// this isn't clear from the paper, but it still smells like a minimal + /// suffix. + Minimal, + /// Extract the largest lexicographic suffix from a string. + /// + /// Unlike `Minimal`, this really does pick the maximum suffix. e.g., Given + /// the choice between `z` and `zz`, this will choose the latter over the + /// former. + Maximal, +} + +/// The result of comparing corresponding bytes between two suffixes. +#[derive(Clone, Copy, Debug)] +enum SuffixOrdering { + /// This occurs when the given candidate byte indicates that the candidate + /// suffix is better than the current maximal (or minimal) suffix. That is, + /// the current candidate suffix should supplant the current maximal (or + /// minimal) suffix. + Accept, + /// This occurs when the given candidate byte excludes the candidate suffix + /// from being better than the current maximal (or minimal) suffix. That + /// is, the current candidate suffix should be dropped and the next one + /// should be considered. + Skip, + /// This occurs when no decision to accept or skip the candidate suffix + /// can be made, e.g., when corresponding bytes are equivalent. In this + /// case, the next corresponding bytes should be compared. + Push, +} + +impl SuffixKind { + /// Returns true if and only if the given candidate byte indicates that + /// it should replace the current suffix as the maximal (or minimal) + /// suffix. + fn cmp(self, current: u8, candidate: u8) -> SuffixOrdering { + use self::SuffixOrdering::*; + + match self { + SuffixKind::Minimal if candidate < current => Accept, + SuffixKind::Minimal if candidate > current => Skip, + SuffixKind::Minimal => Push, + SuffixKind::Maximal if candidate > current => Accept, + SuffixKind::Maximal if candidate < current => Skip, + SuffixKind::Maximal => Push, + } + } +} + +// N.B. There are more holistic tests in src/search/tests.rs. +#[cfg(test)] +mod tests { + use bstr::{B, BStr}; + use bstring::BString; + + use super::*; + + /// Convenience wrapper for computing the suffix as a byte string. + fn get_suffix_forward(needle: &BStr, kind: SuffixKind) -> (&BStr, usize) { + let s = Suffix::forward(needle, kind); + (&needle[s.pos..], s.period) + } + + /// Convenience wrapper for computing the reverse suffix as a byte string. + fn get_suffix_reverse(needle: &BStr, kind: SuffixKind) -> (&BStr, usize) { + let s = Suffix::reverse(needle, kind); + (&needle[..s.pos], s.period) + } + + /// Return all of the non-empty suffixes in the given byte string. + fn suffixes(bytes: &BStr) -> Vec<&BStr> { + (0..bytes.len()).map(|i| &bytes[i..]).collect() + } + + /// Return the lexicographically maximal suffix of the given byte string. + fn naive_maximal_suffix_forward(needle: &BStr) -> &BStr { + let mut sufs = suffixes(needle); + sufs.sort(); + sufs.pop().unwrap() + } + + /// Return the lexicographically maximal suffix of the reverse of the given + /// byte string. + fn naive_maximal_suffix_reverse(needle: &BStr) -> BString { + let mut reversed = needle.to_bstring(); + reversed.reverse_bytes(); + let mut got = naive_maximal_suffix_forward(&reversed).to_bstring(); + got.reverse_bytes(); + got + } + + #[test] + fn suffix_forward() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = get_suffix_forward( + B($given), + SuffixKind::Minimal, + ); + assert_eq!((B($expected), $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = get_suffix_forward( + B($given), + SuffixKind::Maximal, + ); + assert_eq!((B($expected), $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "ab", 2); + assert_suffix_max!("ab", "b", 1); + + assert_suffix_min!("ba", "a", 1); + assert_suffix_max!("ba", "ba", 2); + + assert_suffix_min!("abc", "abc", 3); + assert_suffix_max!("abc", "c", 1); + + assert_suffix_min!("acb", "acb", 3); + assert_suffix_max!("acb", "cb", 2); + + assert_suffix_min!("cba", "a", 1); + assert_suffix_max!("cba", "cba", 3); + + assert_suffix_min!("abcabc", "abcabc", 3); + assert_suffix_max!("abcabc", "cabc", 3); + + assert_suffix_min!("abcabcabc", "abcabcabc", 3); + assert_suffix_max!("abcabcabc", "cabcabc", 3); + + assert_suffix_min!("abczz", "abczz", 5); + assert_suffix_max!("abczz", "zz", 1); + + assert_suffix_min!("zzabc", "abc", 3); + assert_suffix_max!("zzabc", "zzabc", 5); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + + assert_suffix_min!("foobar", "ar", 2); + assert_suffix_max!("foobar", "r", 1); + } + + #[test] + fn suffix_reverse() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = get_suffix_reverse( + B($given), + SuffixKind::Minimal, + ); + assert_eq!((B($expected), $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = get_suffix_reverse( + B($given), + SuffixKind::Maximal, + ); + assert_eq!((B($expected), $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "a", 1); + assert_suffix_max!("ab", "ab", 2); + + assert_suffix_min!("ba", "ba", 2); + assert_suffix_max!("ba", "b", 1); + + assert_suffix_min!("abc", "a", 1); + assert_suffix_max!("abc", "abc", 3); + + assert_suffix_min!("acb", "a", 1); + assert_suffix_max!("acb", "ac", 2); + + assert_suffix_min!("cba", "cba", 3); + assert_suffix_max!("cba", "c", 1); + + assert_suffix_min!("abcabc", "abca", 3); + assert_suffix_max!("abcabc", "abcabc", 3); + + assert_suffix_min!("abcabcabc", "abcabca", 3); + assert_suffix_max!("abcabcabc", "abcabcabc", 3); + + assert_suffix_min!("abczz", "a", 1); + assert_suffix_max!("abczz", "abczz", 5); + + assert_suffix_min!("zzabc", "zza", 3); + assert_suffix_max!("zzabc", "zz", 1); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + } + + quickcheck! { + fn qc_suffix_forward_maximal(bytes: Vec) -> bool { + let bytes = BString::from(bytes); + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_forward(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_forward(&bytes); + got == expected + } + + fn qc_suffix_reverse_maximal(bytes: Vec) -> bool { + let bytes = BString::from(bytes); + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_reverse(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_reverse(&bytes); + got == expected + } + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/slice_index.rs cargo-0.35.0/vendor/bstr/src/slice_index.rs --- cargo-0.33.0/vendor/bstr/src/slice_index.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/slice_index.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,292 @@ +use core::ops; + +use bstr::BStr; + +/// Ensure that callers cannot implement `SliceIndex` by making an +/// umplementable trait its super trait. +pub trait Sealed {} +impl Sealed for usize {} +impl Sealed for ops::Range {} +impl Sealed for ops::RangeTo {} +impl Sealed for ops::RangeFrom {} +impl Sealed for ops::RangeFull {} +impl Sealed for ops::RangeInclusive {} +impl Sealed for ops::RangeToInclusive {} + +/// A trait that parameterizes the different types of indexing a byte string. +/// +/// In general, this trait makes it possible to define generic routines like +/// `get` that can accept either single positions or ranges, and return single +/// bytes or slices, respectively. +/// +/// This trait is sealed such that callers cannot implement it. In general, +/// callers should not need to interact with this trait directly unless you're +/// defining generic functions that index or slice a byte string. +pub trait SliceIndex: Sealed { + /// The output type returned by methods. For indexing by position, this + /// is always a single byte (`u8`). For ranges, this is always a slice + /// (`BStr`). + type Output: ?Sized; + + /// Returns a shared reference to the output at this location, if in + /// bounds. + fn get(self, slice: &BStr) -> Option<&Self::Output>; + + /// Returns a mutable reference to the output at this location, if in + /// bounds. + fn get_mut(self, slice: &mut BStr) -> Option<&mut Self::Output>; + + /// Returns a shared reference to the output at this location, without + /// performing any bounds checking. + unsafe fn get_unchecked(self, slice: &BStr) -> &Self::Output; + + /// Returns a mutable reference to the output at this location, without + /// performing any bounds checking. + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut Self::Output; + + /// Returns a shared reference to the output at this location, panicking + /// if out of bounds. + fn index(self, slice: &BStr) -> &Self::Output; + + /// Returns a mutable reference to the output at this location, panicking + /// if out of bounds. + fn index_mut(self, slice: &mut BStr) -> &mut Self::Output; +} + +impl SliceIndex for usize { + type Output = u8; + + #[inline] + fn get(self, slice: &BStr) -> Option<&u8> { + slice.as_bytes().get(self) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut u8> { + slice.as_bytes_mut().get_mut(self) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &u8 { + slice.as_bytes().get_unchecked(self) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut u8 { + slice.as_bytes_mut().get_unchecked_mut(self) + } + + #[inline] + fn index(self, slice: &BStr) -> &u8 { + &slice.as_bytes()[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut u8 { + &mut slice.as_bytes_mut()[self] + } +} + +impl SliceIndex for ops::Range { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} + +impl SliceIndex for ops::RangeTo { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} + +impl SliceIndex for ops::RangeFrom { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} + +impl SliceIndex for ops::RangeFull { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} + +impl SliceIndex for ops::RangeInclusive { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} + +impl SliceIndex for ops::RangeToInclusive { + type Output = BStr; + + #[inline] + fn get(self, slice: &BStr) -> Option<&BStr> { + slice.as_bytes().get(self).map(BStr::new) + } + + #[inline] + fn get_mut(self, slice: &mut BStr) -> Option<&mut BStr> { + slice.as_bytes_mut().get_mut(self).map(BStr::new_mut) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &BStr) -> &BStr { + BStr::new(slice.as_bytes().get_unchecked(self)) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut BStr) -> &mut BStr { + BStr::new_mut(slice.as_bytes_mut().get_unchecked_mut(self)) + } + + #[inline] + fn index(self, slice: &BStr) -> &BStr { + &slice[self] + } + + #[inline] + fn index_mut(self, slice: &mut BStr) -> &mut BStr { + &mut slice[self] + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/tests.rs cargo-0.35.0/vendor/bstr/src/tests.rs --- cargo-0.33.0/vendor/bstr/src/tests.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/tests.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,32 @@ +/// A sequence of tests for checking whether lossy decoding uses the maximal +/// subpart strategy correctly. Namely, if a sequence of otherwise invalid +/// UTF-8 bytes is a valid prefix of a valid UTF-8 sequence, then the entire +/// prefix is replaced by a single replacement codepoint. In all other cases, +/// each invalid byte is replaced by a single replacement codepoint. +/// +/// The first element in each tuple is the expected result of lossy decoding, +/// while the second element is the input given. +pub const LOSSY_TESTS: &[(&str, &[u8])] = &[ + ("a", b"a"), + ("\u{FFFD}", b"\xFF"), + ("\u{FFFD}\u{FFFD}", b"\xFF\xFF"), + ("β\u{FFFD}", b"\xCE\xB2\xFF"), + ("☃\u{FFFD}", b"\xE2\x98\x83\xFF"), + ("𝝱\u{FFFD}", b"\xF0\x9D\x9D\xB1\xFF"), + ("\u{FFFD}\u{FFFD}", b"\xCE\xF0"), + ("\u{FFFD}\u{FFFD}", b"\xCE\xFF"), + ("\u{FFFD}\u{FFFD}", b"\xE2\x98\xF0"), + ("\u{FFFD}\u{FFFD}", b"\xE2\x98\xFF"), + ("\u{FFFD}", b"\xF0\x9D\x9D"), + ("\u{FFFD}\u{FFFD}", b"\xF0\x9D\x9D\xF0"), + ("\u{FFFD}\u{FFFD}", b"\xF0\x9D\x9D\xFF"), + ("\u{FFFD}", b"\xCE"), + ("a\u{FFFD}", b"a\xCE"), + ("\u{FFFD}", b"\xE2\x98"), + ("a\u{FFFD}", b"a\xE2\x98"), + ("\u{FFFD}", b"\xF0\x9D\x9C"), + ("a\u{FFFD}", b"a\xF0\x9D\x9C"), + ("a\u{FFFD}\u{FFFD}\u{FFFD}z", b"a\xED\xA0\x80z"), + ("☃βツ\u{FFFD}", b"\xe2\x98\x83\xce\xb2\xe3\x83\x84\xFF"), + ("a\u{FFFD}\u{FFFD}\u{FFFD}b", b"\x61\xF1\x80\x80\xE1\x80\xC2\x62"), +]; diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/data/GraphemeBreakTest.txt cargo-0.35.0/vendor/bstr/src/unicode/data/GraphemeBreakTest.txt --- cargo-0.33.0/vendor/bstr/src/unicode/data/GraphemeBreakTest.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/data/GraphemeBreakTest.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,700 @@ +# GraphemeBreakTest-11.0.0.txt +# Date: 2018-03-18, 13:30:33 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Default Grapheme_Cluster_Break Test +# +# Format: +# (# )? +# contains hex Unicode code points, with +# ÷ wherever there is a break opportunity, and +# × wherever there is not. +# the format can change, but currently it shows: +# - the sample character name +# - (x) the Grapheme_Cluster_Break property value for the sample character +# - [x] the rule that determines whether there is a break or not, +# as listed in the Rules section of GraphemeBreakTest.html +# +# These samples may be extended or changed in the future. +# +÷ 0020 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] (CR) ÷ [0.3] +÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] (LF) ÷ [0.3] +÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] (Control) ÷ [0.3] +÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0020 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0020 × 0308 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0020 × 0308 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0020 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0020 × 0308 ÷ 1100 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0020 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0020 × 0308 ÷ 1160 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0020 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0020 × 0308 ÷ 11A8 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0020 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0020 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] (Other) ÷ [0.3] +÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0020 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] (Control) ÷ [0.3] +÷ 0020 × 0308 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 000D ÷ 0020 ÷ # ÷ [0.2] (CR) ÷ [4.0] SPACE (Other) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 000D ÷ 000D ÷ # ÷ [0.2] (CR) ÷ [4.0] (CR) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 000D × 000A ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 000D ÷ 0001 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Control) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 000D ÷ 034F ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000D ÷ 0308 × 034F ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000D ÷ 0600 ÷ # ÷ [0.2] (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 000D ÷ 0903 ÷ # ÷ [0.2] (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 000D ÷ 1100 ÷ # ÷ [0.2] (CR) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 000D ÷ 1160 ÷ # ÷ [0.2] (CR) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 000D ÷ 11A8 ÷ # ÷ [0.2] (CR) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 000D ÷ AC00 ÷ # ÷ [0.2] (CR) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 000D ÷ AC01 ÷ # ÷ [0.2] (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 000D ÷ 231A ÷ # ÷ [0.2] (CR) ÷ [4.0] WATCH (ExtPict) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 000D ÷ 0300 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 200D ÷ # ÷ [0.2] (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 0378 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Other) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 000D ÷ D800 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Control) ÷ [0.3] +÷ 000D ÷ 0308 ÷ D800 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 000A ÷ 0020 ÷ # ÷ [0.2] (LF) ÷ [4.0] SPACE (Other) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 000A ÷ 000D ÷ # ÷ [0.2] (LF) ÷ [4.0] (CR) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 000A ÷ 000A ÷ # ÷ [0.2] (LF) ÷ [4.0] (LF) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 000A ÷ 0001 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Control) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 000A ÷ 034F ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000A ÷ 0308 × 034F ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000A ÷ 0600 ÷ # ÷ [0.2] (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 000A ÷ 0903 ÷ # ÷ [0.2] (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 000A ÷ 1100 ÷ # ÷ [0.2] (LF) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 000A ÷ 1160 ÷ # ÷ [0.2] (LF) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 000A ÷ 11A8 ÷ # ÷ [0.2] (LF) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 000A ÷ AC00 ÷ # ÷ [0.2] (LF) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 000A ÷ AC01 ÷ # ÷ [0.2] (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 000A ÷ 231A ÷ # ÷ [0.2] (LF) ÷ [4.0] WATCH (ExtPict) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 000A ÷ 0300 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 200D ÷ # ÷ [0.2] (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 0378 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Other) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 000A ÷ D800 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Control) ÷ [0.3] +÷ 000A ÷ 0308 ÷ D800 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0001 ÷ 0020 ÷ # ÷ [0.2] (Control) ÷ [4.0] SPACE (Other) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0001 ÷ 000D ÷ # ÷ [0.2] (Control) ÷ [4.0] (CR) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0001 ÷ 000A ÷ # ÷ [0.2] (Control) ÷ [4.0] (LF) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0001 ÷ 0001 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Control) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0001 ÷ 034F ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0001 ÷ 0308 × 034F ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0001 ÷ 0600 ÷ # ÷ [0.2] (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0001 ÷ 0903 ÷ # ÷ [0.2] (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0001 ÷ 1100 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0001 ÷ 1160 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0001 ÷ 11A8 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0001 ÷ AC00 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0001 ÷ AC01 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0001 ÷ 231A ÷ # ÷ [0.2] (Control) ÷ [4.0] WATCH (ExtPict) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0001 ÷ 0300 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 200D ÷ # ÷ [0.2] (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 0378 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Other) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0001 ÷ D800 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Control) ÷ [0.3] +÷ 0001 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 034F ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 034F × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 034F ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] (CR) ÷ [0.3] +÷ 034F × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 034F ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] (LF) ÷ [0.3] +÷ 034F × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 034F ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] (Control) ÷ [0.3] +÷ 034F × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 034F × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 034F × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 034F ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 034F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 034F ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 034F × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 034F × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 034F × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 034F ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 034F × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 034F ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 034F × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 034F ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 034F × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 034F ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 034F × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 034F ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 034F × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 034F ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 034F × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 034F × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 034F × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 034F × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 034F × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 034F ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] (Other) ÷ [0.3] +÷ 034F × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 034F ÷ D800 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] (Control) ÷ [0.3] +÷ 034F × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] (CR) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] (LF) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] (Control) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1F1E6 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1F1E6 × 0308 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1F1E6 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 1100 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1F1E6 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 1160 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1F1E6 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 11A8 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1F1E6 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1F1E6 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] (Other) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 1F1E6 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] (Control) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3] +÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] (CR) ÷ [0.3] +÷ 0600 × 0308 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0600 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] (LF) ÷ [0.3] +÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] (Control) ÷ [0.3] +÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0600 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0600 × 0308 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0600 × 0308 ÷ 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0600 × 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0600 × 0308 ÷ 1100 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0600 × 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0600 × 0308 ÷ 1160 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0600 × 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0600 × 0308 ÷ 11A8 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0600 × AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0600 × 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] WATCH (ExtPict) ÷ [0.3] +÷ 0600 × 0308 ÷ 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] (Other) ÷ [0.3] +÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0600 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] (Control) ÷ [0.3] +÷ 0600 × 0308 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] (CR) ÷ [0.3] +÷ 0903 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0903 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] (LF) ÷ [0.3] +÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] (Control) ÷ [0.3] +÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0903 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0903 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0903 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0903 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0903 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0903 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0903 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0903 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0903 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0903 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0903 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0903 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] (Other) ÷ [0.3] +÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0903 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] (Control) ÷ [0.3] +÷ 0903 × 0308 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] (CR) ÷ [0.3] +÷ 1100 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 1100 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] (LF) ÷ [0.3] +÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] (Control) ÷ [0.3] +÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1100 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1100 × 0308 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1100 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1100 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1100 × 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1100 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1100 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1100 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1100 × AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1100 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1100 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] (Other) ÷ [0.3] +÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 1100 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] (Control) ÷ [0.3] +÷ 1100 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] (CR) ÷ [0.3] +÷ 1160 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 1160 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] (LF) ÷ [0.3] +÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] (Control) ÷ [0.3] +÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 1160 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1160 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1160 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 1160 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1160 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1160 × 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1160 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 1160 × 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1160 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 1160 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 1160 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1160 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] (Other) ÷ [0.3] +÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 1160 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] (Control) ÷ [0.3] +÷ 1160 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] (CR) ÷ [0.3] +÷ 11A8 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 11A8 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] (LF) ÷ [0.3] +÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] (Control) ÷ [0.3] +÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 11A8 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 11A8 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 11A8 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 11A8 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 11A8 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 11A8 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 11A8 × 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 11A8 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 11A8 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 11A8 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 11A8 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] (Other) ÷ [0.3] +÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 11A8 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] (Control) ÷ [0.3] +÷ 11A8 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] (CR) ÷ [0.3] +÷ AC00 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ AC00 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] (LF) ÷ [0.3] +÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] (Control) ÷ [0.3] +÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ AC00 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC00 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ AC00 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ AC00 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC00 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC00 × 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ AC00 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ AC00 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ AC00 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ AC00 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ AC00 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ AC00 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] (Other) ÷ [0.3] +÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ AC00 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] (Control) ÷ [0.3] +÷ AC00 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] (CR) ÷ [0.3] +÷ AC01 × 0308 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ AC01 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] (LF) ÷ [0.3] +÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] (Control) ÷ [0.3] +÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ AC01 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC01 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ AC01 × 0308 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ AC01 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC01 × 0308 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC01 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ AC01 × 0308 ÷ 1160 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ AC01 × 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ AC01 × 0308 ÷ 11A8 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ AC01 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ AC01 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ AC01 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] (Other) ÷ [0.3] +÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ AC01 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] (Control) ÷ [0.3] +÷ AC01 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] (CR) ÷ [0.3] +÷ 231A × 0308 ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 231A ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] (LF) ÷ [0.3] +÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] (Control) ÷ [0.3] +÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 231A × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 231A × 0308 × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 231A ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 231A × 0308 ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 231A × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 231A × 0308 × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 231A ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 231A × 0308 ÷ 1100 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 231A ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 231A × 0308 ÷ 1160 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 231A ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 231A × 0308 ÷ 11A8 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 231A ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 231A × 0308 ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 231A ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 231A × 0308 ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 231A ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 231A ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] (Other) ÷ [0.3] +÷ 231A × 0308 ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 231A ÷ D800 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] (Control) ÷ [0.3] +÷ 231A × 0308 ÷ D800 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0300 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0300 × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0300 × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0300 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0300 × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0300 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0300 × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0300 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0300 × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0300 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0300 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0300 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0300 × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 200D × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 200D × 0308 × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 200D × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 200D ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 200D × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 200D ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 200D × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 200D ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 200D × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 200D ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 200D ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 200D ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 200D × 0308 ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0378 ÷ 0020 ÷ # ÷ [0.2] (Other) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0378 ÷ 000D ÷ # ÷ [0.2] (Other) ÷ [5.0] (CR) ÷ [0.3] +÷ 0378 × 0308 ÷ 000D ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ 0378 ÷ 000A ÷ # ÷ [0.2] (Other) ÷ [5.0] (LF) ÷ [0.3] +÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ 0378 ÷ 0001 ÷ # ÷ [0.2] (Other) ÷ [5.0] (Control) ÷ [0.3] +÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 0378 × 034F ÷ # ÷ [0.2] (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0378 × 0308 × 034F ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0378 ÷ 0600 ÷ # ÷ [0.2] (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0378 × 0308 ÷ 0600 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0378 × 0903 ÷ # ÷ [0.2] (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0378 ÷ 1100 ÷ # ÷ [0.2] (Other) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0378 × 0308 ÷ 1100 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0378 ÷ 1160 ÷ # ÷ [0.2] (Other) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0378 × 0308 ÷ 1160 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0378 ÷ 11A8 ÷ # ÷ [0.2] (Other) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0378 × 0308 ÷ 11A8 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0378 ÷ AC00 ÷ # ÷ [0.2] (Other) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0378 ÷ AC01 ÷ # ÷ [0.2] (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0378 ÷ 231A ÷ # ÷ [0.2] (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0378 × 0308 ÷ 231A ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0378 × 0300 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0378 × 200D ÷ # ÷ [0.2] (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0378 ÷ 0378 ÷ # ÷ [0.2] (Other) ÷ [999.0] (Other) ÷ [0.3] +÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ 0378 ÷ D800 ÷ # ÷ [0.2] (Other) ÷ [5.0] (Control) ÷ [0.3] +÷ 0378 × 0308 ÷ D800 ÷ # ÷ [0.2] (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ D800 ÷ 0020 ÷ # ÷ [0.2] (Control) ÷ [4.0] SPACE (Other) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ D800 ÷ 000D ÷ # ÷ [0.2] (Control) ÷ [4.0] (CR) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (CR) ÷ [0.3] +÷ D800 ÷ 000A ÷ # ÷ [0.2] (Control) ÷ [4.0] (LF) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (LF) ÷ [0.3] +÷ D800 ÷ 0001 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Control) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ D800 ÷ 034F ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ D800 ÷ 0308 × 034F ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ D800 ÷ 1F1E6 ÷ # ÷ [0.2] (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ D800 ÷ 0600 ÷ # ÷ [0.2] (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ D800 ÷ 0903 ÷ # ÷ [0.2] (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ D800 ÷ 0308 × 0903 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ D800 ÷ 1100 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ D800 ÷ 1160 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ D800 ÷ 11A8 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ D800 ÷ AC00 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ D800 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ D800 ÷ AC01 ÷ # ÷ [0.2] (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ D800 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ D800 ÷ 231A ÷ # ÷ [0.2] (Control) ÷ [4.0] WATCH (ExtPict) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ D800 ÷ 0300 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ D800 ÷ 0308 × 0300 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ D800 ÷ 200D ÷ # ÷ [0.2] (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ D800 ÷ 0308 × 200D ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ D800 ÷ 0378 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Other) ÷ [0.3] +÷ D800 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] (Other) ÷ [0.3] +÷ D800 ÷ D800 ÷ # ÷ [0.2] (Control) ÷ [4.0] (Control) ÷ [0.3] +÷ D800 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] (Control) ÷ [0.3] +÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3] +÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3] +÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3] +÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 1100 × 1100 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC00 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [7.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ AC01 × 11A8 ÷ 1100 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [8.0] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 200D ÷ 1F1E7 × 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [13.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3] +÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3] +÷ 0061 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3] +÷ 0061 × 1F3FF ÷ 1F476 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [0.3] +÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 0061 × 200D ÷ 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] UPPER BLADE SCISSORS (Other) ÷ [0.3] +÷ 0061 × 200D ÷ 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] UPPER BLADE SCISSORS (Other) ÷ [0.3] +# +# Lines: 672 +# +# EOF diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/data/SentenceBreakTest.txt cargo-0.35.0/vendor/bstr/src/unicode/data/SentenceBreakTest.txt --- cargo-0.33.0/vendor/bstr/src/unicode/data/SentenceBreakTest.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/data/SentenceBreakTest.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,530 @@ +# SentenceBreakTest-11.0.0.txt +# Date: 2018-01-31, 08:20:29 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Default Sentence_Break Test +# +# Format: +# (# )? +# contains hex Unicode code points, with +# ÷ wherever there is a break opportunity, and +# × wherever there is not. +# the format can change, but currently it shows: +# - the sample character name +# - (x) the Sentence_Break property value for the sample character +# - [x] the rule that determines whether there is a break or not, +# as listed in the Rules section of SentenceBreakTest.html +# +# These samples may be extended or changed in the future. +# +÷ 0001 × 0001 ÷ # ÷ [0.2] (Other) × [998.0] (Other) ÷ [0.3] +÷ 0001 × 0308 × 0001 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0001 × 000D ÷ # ÷ [0.2] (Other) × [998.0] (CR) ÷ [0.3] +÷ 0001 × 0308 × 000D ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0001 × 000A ÷ # ÷ [0.2] (Other) × [998.0] (LF) ÷ [0.3] +÷ 0001 × 0308 × 000A ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0001 × 0085 ÷ # ÷ [0.2] (Other) × [998.0] (Sep) ÷ [0.3] +÷ 0001 × 0308 × 0085 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0001 × 0009 ÷ # ÷ [0.2] (Other) × [998.0] (Sp) ÷ [0.3] +÷ 0001 × 0308 × 0009 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0001 × 0061 ÷ # ÷ [0.2] (Other) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0001 × 0308 × 0061 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0001 × 0041 ÷ # ÷ [0.2] (Other) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0001 × 0308 × 0041 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0001 × 01BB ÷ # ÷ [0.2] (Other) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0001 × 0308 × 01BB ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0001 × 0030 ÷ # ÷ [0.2] (Other) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0001 × 0308 × 0030 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0001 × 002E ÷ # ÷ [0.2] (Other) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0001 × 0308 × 002E ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0001 × 0021 ÷ # ÷ [0.2] (Other) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0001 × 0308 × 0021 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0001 × 0022 ÷ # ÷ [0.2] (Other) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0001 × 0308 × 0022 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0001 × 002C ÷ # ÷ [0.2] (Other) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0001 × 0308 × 002C ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0001 × 00AD ÷ # ÷ [0.2] (Other) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0001 × 0300 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] (Other) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000D ÷ 0001 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Other) ÷ [0.3] +÷ 000D ÷ 0308 × 0001 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 000D ÷ 000D ÷ # ÷ [0.2] (CR) ÷ [4.0] (CR) ÷ [0.3] +÷ 000D ÷ 0308 × 000D ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 000D × 000A ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [0.3] +÷ 000D ÷ 0308 × 000A ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 000D ÷ 0085 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Sep) ÷ [0.3] +÷ 000D ÷ 0308 × 0085 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 000D ÷ 0009 ÷ # ÷ [0.2] (CR) ÷ [4.0] (Sp) ÷ [0.3] +÷ 000D ÷ 0308 × 0009 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 000D ÷ 0061 ÷ # ÷ [0.2] (CR) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 000D ÷ 0308 × 0061 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 000D ÷ 0041 ÷ # ÷ [0.2] (CR) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 000D ÷ 0308 × 0041 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 000D ÷ 01BB ÷ # ÷ [0.2] (CR) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 000D ÷ 0308 × 01BB ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 000D ÷ 0030 ÷ # ÷ [0.2] (CR) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000D ÷ 0308 × 0030 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000D ÷ 002E ÷ # ÷ [0.2] (CR) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3] +÷ 000D ÷ 0308 × 002E ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 000D ÷ 0021 ÷ # ÷ [0.2] (CR) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 000D ÷ 0308 × 0021 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 000D ÷ 0022 ÷ # ÷ [0.2] (CR) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 000D ÷ 0308 × 0022 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 000D ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [4.0] COMMA (SContinue) ÷ [0.3] +÷ 000D ÷ 0308 × 002C ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 000D ÷ 00AD ÷ # ÷ [0.2] (CR) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000D ÷ 0300 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000A ÷ 0001 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Other) ÷ [0.3] +÷ 000A ÷ 0308 × 0001 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 000A ÷ 000D ÷ # ÷ [0.2] (LF) ÷ [4.0] (CR) ÷ [0.3] +÷ 000A ÷ 0308 × 000D ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 000A ÷ 000A ÷ # ÷ [0.2] (LF) ÷ [4.0] (LF) ÷ [0.3] +÷ 000A ÷ 0308 × 000A ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 000A ÷ 0085 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Sep) ÷ [0.3] +÷ 000A ÷ 0308 × 0085 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 000A ÷ 0009 ÷ # ÷ [0.2] (LF) ÷ [4.0] (Sp) ÷ [0.3] +÷ 000A ÷ 0308 × 0009 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 000A ÷ 0061 ÷ # ÷ [0.2] (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 000A ÷ 0308 × 0061 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 000A ÷ 0041 ÷ # ÷ [0.2] (LF) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 000A ÷ 0308 × 0041 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 000A ÷ 01BB ÷ # ÷ [0.2] (LF) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 000A ÷ 0308 × 01BB ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 000A ÷ 0030 ÷ # ÷ [0.2] (LF) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000A ÷ 0308 × 0030 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000A ÷ 002E ÷ # ÷ [0.2] (LF) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3] +÷ 000A ÷ 0308 × 002E ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 000A ÷ 0021 ÷ # ÷ [0.2] (LF) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 000A ÷ 0308 × 0021 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 000A ÷ 0022 ÷ # ÷ [0.2] (LF) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 000A ÷ 0308 × 0022 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 000A ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [4.0] COMMA (SContinue) ÷ [0.3] +÷ 000A ÷ 0308 × 002C ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 000A ÷ 00AD ÷ # ÷ [0.2] (LF) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000A ÷ 0300 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0085 ÷ 0001 ÷ # ÷ [0.2] (Sep) ÷ [4.0] (Other) ÷ [0.3] +÷ 0085 ÷ 0308 × 0001 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0085 ÷ 000D ÷ # ÷ [0.2] (Sep) ÷ [4.0] (CR) ÷ [0.3] +÷ 0085 ÷ 0308 × 000D ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0085 ÷ 000A ÷ # ÷ [0.2] (Sep) ÷ [4.0] (LF) ÷ [0.3] +÷ 0085 ÷ 0308 × 000A ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0085 ÷ 0085 ÷ # ÷ [0.2] (Sep) ÷ [4.0] (Sep) ÷ [0.3] +÷ 0085 ÷ 0308 × 0085 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0085 ÷ 0009 ÷ # ÷ [0.2] (Sep) ÷ [4.0] (Sp) ÷ [0.3] +÷ 0085 ÷ 0308 × 0009 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0085 ÷ 0061 ÷ # ÷ [0.2] (Sep) ÷ [4.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0085 ÷ 0308 × 0061 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0085 ÷ 0041 ÷ # ÷ [0.2] (Sep) ÷ [4.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0085 ÷ 0308 × 0041 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0085 ÷ 01BB ÷ # ÷ [0.2] (Sep) ÷ [4.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0085 ÷ 0308 × 01BB ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0085 ÷ 0030 ÷ # ÷ [0.2] (Sep) ÷ [4.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0085 ÷ 0308 × 0030 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0085 ÷ 002E ÷ # ÷ [0.2] (Sep) ÷ [4.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0085 ÷ 0308 × 002E ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0085 ÷ 0021 ÷ # ÷ [0.2] (Sep) ÷ [4.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0085 ÷ 0308 × 0021 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0085 ÷ 0022 ÷ # ÷ [0.2] (Sep) ÷ [4.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0085 ÷ 0308 × 0022 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0085 ÷ 002C ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMMA (SContinue) ÷ [0.3] +÷ 0085 ÷ 0308 × 002C ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0085 ÷ 00AD ÷ # ÷ [0.2] (Sep) ÷ [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0085 ÷ 0308 × 00AD ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0085 ÷ 0300 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0085 ÷ 0308 × 0300 ÷ # ÷ [0.2] (Sep) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0009 × 0001 ÷ # ÷ [0.2] (Sp) × [998.0] (Other) ÷ [0.3] +÷ 0009 × 0308 × 0001 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0009 × 000D ÷ # ÷ [0.2] (Sp) × [998.0] (CR) ÷ [0.3] +÷ 0009 × 0308 × 000D ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0009 × 000A ÷ # ÷ [0.2] (Sp) × [998.0] (LF) ÷ [0.3] +÷ 0009 × 0308 × 000A ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0009 × 0085 ÷ # ÷ [0.2] (Sp) × [998.0] (Sep) ÷ [0.3] +÷ 0009 × 0308 × 0085 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0009 × 0009 ÷ # ÷ [0.2] (Sp) × [998.0] (Sp) ÷ [0.3] +÷ 0009 × 0308 × 0009 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0009 × 0061 ÷ # ÷ [0.2] (Sp) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0009 × 0308 × 0061 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0009 × 0041 ÷ # ÷ [0.2] (Sp) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0009 × 0308 × 0041 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0009 × 01BB ÷ # ÷ [0.2] (Sp) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0009 × 0308 × 01BB ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0009 × 0030 ÷ # ÷ [0.2] (Sp) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0009 × 0308 × 0030 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0009 × 002E ÷ # ÷ [0.2] (Sp) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0009 × 0308 × 002E ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0009 × 0021 ÷ # ÷ [0.2] (Sp) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0009 × 0308 × 0021 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0009 × 0022 ÷ # ÷ [0.2] (Sp) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0009 × 0308 × 0022 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0009 × 002C ÷ # ÷ [0.2] (Sp) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0009 × 0308 × 002C ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0009 × 00AD ÷ # ÷ [0.2] (Sp) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0009 × 0308 × 00AD ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0009 × 0300 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0009 × 0308 × 0300 ÷ # ÷ [0.2] (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] (Other) ÷ [0.3] +÷ 0061 × 0308 × 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0061 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] (CR) ÷ [0.3] +÷ 0061 × 0308 × 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0061 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] (LF) ÷ [0.3] +÷ 0061 × 0308 × 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0061 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] (Sep) ÷ [0.3] +÷ 0061 × 0308 × 0085 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0061 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] (Sp) ÷ [0.3] +÷ 0061 × 0308 × 0009 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0061 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0061 × 0308 × 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0061 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0061 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0061 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0061 × 0308 × 01BB ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0061 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0061 × 0308 × 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0061 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0061 × 0308 × 0021 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0061 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0061 × 0308 × 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0061 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0061 × 0308 × 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0061 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0041 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] (Other) ÷ [0.3] +÷ 0041 × 0308 × 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0041 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] (CR) ÷ [0.3] +÷ 0041 × 0308 × 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0041 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] (LF) ÷ [0.3] +÷ 0041 × 0308 × 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0041 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] (Sep) ÷ [0.3] +÷ 0041 × 0308 × 0085 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0041 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] (Sp) ÷ [0.3] +÷ 0041 × 0308 × 0009 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0041 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0041 × 0308 × 0061 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0041 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0041 × 0308 × 01BB ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0041 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0041 × 0308 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0041 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0041 × 0308 × 0021 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0041 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0041 × 0308 × 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0041 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0041 × 0308 × 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 01BB × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] (Other) ÷ [0.3] +÷ 01BB × 0308 × 0001 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 01BB × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] (CR) ÷ [0.3] +÷ 01BB × 0308 × 000D ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 01BB × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] (LF) ÷ [0.3] +÷ 01BB × 0308 × 000A ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 01BB × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] (Sep) ÷ [0.3] +÷ 01BB × 0308 × 0085 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 01BB × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] (Sp) ÷ [0.3] +÷ 01BB × 0308 × 0009 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 01BB × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 01BB × 0308 × 0061 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 01BB × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 01BB × 0308 × 0041 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 01BB × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 01BB × 0308 × 01BB ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 01BB × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 01BB × 0308 × 0030 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 01BB × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 01BB × 0308 × 002E ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 01BB × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 01BB × 0308 × 0021 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 01BB × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 01BB × 0308 × 0022 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 01BB × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 01BB × 0308 × 002C ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 01BB × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 01BB × 0308 × 00AD ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 01BB × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 01BB × 0308 × 0300 ÷ # ÷ [0.2] LATIN LETTER TWO WITH STROKE (OLetter) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0030 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] (Other) ÷ [0.3] +÷ 0030 × 0308 × 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0030 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] (CR) ÷ [0.3] +÷ 0030 × 0308 × 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0030 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] (LF) ÷ [0.3] +÷ 0030 × 0308 × 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0030 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] (Sep) ÷ [0.3] +÷ 0030 × 0308 × 0085 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0030 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] (Sp) ÷ [0.3] +÷ 0030 × 0308 × 0009 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0030 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0030 × 0308 × 0061 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0030 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0030 × 0308 × 01BB ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0030 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0030 × 0308 × 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0030 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0030 × 0308 × 0021 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0030 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0030 × 0308 × 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0030 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0030 × 0308 × 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] (Other) ÷ [0.3] +÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] (Other) ÷ [0.3] +÷ 002E × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] (CR) ÷ [0.3] +÷ 002E × 0308 × 000D ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (CR) ÷ [0.3] +÷ 002E × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] (LF) ÷ [0.3] +÷ 002E × 0308 × 000A ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (LF) ÷ [0.3] +÷ 002E × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] (Sep) ÷ [0.3] +÷ 002E × 0308 × 0085 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (Sep) ÷ [0.3] +÷ 002E × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] (Sp) ÷ [0.3] +÷ 002E × 0308 × 0009 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (Sp) ÷ [0.3] +÷ 002E × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 002E × 0308 × 0061 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 002E ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 002E × 0308 ÷ 01BB ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 002E × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002E × 0308 × 0030 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [6.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002E × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] FULL STOP (ATerm) ÷ [0.3] +÷ 002E × 0308 × 002E ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3] +÷ 002E × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 002E × 0308 × 0021 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 002E × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 002E × 0308 × 0022 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 002E × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [8.1] COMMA (SContinue) ÷ [0.3] +÷ 002E × 0308 × 002C ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3] +÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (ATerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0021 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] (Other) ÷ [0.3] +÷ 0021 × 0308 ÷ 0001 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] (Other) ÷ [0.3] +÷ 0021 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] (CR) ÷ [0.3] +÷ 0021 × 0308 × 000D ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (CR) ÷ [0.3] +÷ 0021 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] (LF) ÷ [0.3] +÷ 0021 × 0308 × 000A ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (LF) ÷ [0.3] +÷ 0021 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] (Sep) ÷ [0.3] +÷ 0021 × 0308 × 0085 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (Sep) ÷ [0.3] +÷ 0021 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] (Sp) ÷ [0.3] +÷ 0021 × 0308 × 0009 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] (Sp) ÷ [0.3] +÷ 0021 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0021 × 0308 ÷ 0061 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0021 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0021 × 0308 ÷ 0041 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0021 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0021 × 0308 ÷ 01BB ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0021 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0021 × 0308 ÷ 0030 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0021 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] FULL STOP (ATerm) ÷ [0.3] +÷ 0021 × 0308 × 002E ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] FULL STOP (ATerm) ÷ [0.3] +÷ 0021 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0021 × 0308 × 0021 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0021 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0021 × 0308 × 0022 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [9.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0021 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [8.1] COMMA (SContinue) ÷ [0.3] +÷ 0021 × 0308 × 002C ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.1] COMMA (SContinue) ÷ [0.3] +÷ 0021 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0021 × 0308 × 00AD ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0021 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0021 × 0308 × 0300 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0022 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] (Other) ÷ [0.3] +÷ 0022 × 0308 × 0001 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0022 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] (CR) ÷ [0.3] +÷ 0022 × 0308 × 000D ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0022 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] (LF) ÷ [0.3] +÷ 0022 × 0308 × 000A ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0022 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] (Sep) ÷ [0.3] +÷ 0022 × 0308 × 0085 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0022 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] (Sp) ÷ [0.3] +÷ 0022 × 0308 × 0009 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0022 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0022 × 0308 × 0061 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0022 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0022 × 0308 × 0041 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0022 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0022 × 0308 × 01BB ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0022 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0022 × 0308 × 0030 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0022 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0022 × 0308 × 002E ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0022 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0022 × 0308 × 0021 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0022 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0022 × 0308 × 0022 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0022 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0022 × 0308 × 002C ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002C × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] (Other) ÷ [0.3] +÷ 002C × 0308 × 0001 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 002C × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] (CR) ÷ [0.3] +÷ 002C × 0308 × 000D ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 002C × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] (LF) ÷ [0.3] +÷ 002C × 0308 × 000A ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 002C × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] (Sep) ÷ [0.3] +÷ 002C × 0308 × 0085 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 002C × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] (Sp) ÷ [0.3] +÷ 002C × 0308 × 0009 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 002C × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 002C × 0308 × 0061 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 002C × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 002C × 0308 × 0041 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 002C × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 002C × 0308 × 01BB ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 002C × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002C × 0308 × 0030 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002C × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 002C × 0308 × 002E ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 002C × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 002C × 0308 × 0021 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 002C × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 002C × 0308 × 0022 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 002C × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 002C × 0308 × 002C ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (SContinue) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 00AD × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] (Other) ÷ [0.3] +÷ 00AD × 0308 × 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 00AD × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] (CR) ÷ [0.3] +÷ 00AD × 0308 × 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 00AD × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] (LF) ÷ [0.3] +÷ 00AD × 0308 × 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 00AD × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] (Sep) ÷ [0.3] +÷ 00AD × 0308 × 0085 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 00AD × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] (Sp) ÷ [0.3] +÷ 00AD × 0308 × 0009 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 00AD × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 00AD × 0308 × 0061 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 00AD × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 00AD × 0308 × 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 00AD × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 00AD × 0308 × 01BB ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 00AD × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 00AD × 0308 × 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 00AD × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 00AD × 0308 × 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 00AD × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 00AD × 0308 × 0021 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 00AD × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 00AD × 0308 × 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 00AD × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 00AD × 0308 × 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0300 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0300 × 0308 × 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Other) ÷ [0.3] +÷ 0300 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0300 × 0308 × 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (CR) ÷ [0.3] +÷ 0300 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0300 × 0308 × 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (LF) ÷ [0.3] +÷ 0300 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0300 × 0308 × 0085 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sep) ÷ [0.3] +÷ 0300 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0300 × 0308 × 0009 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] (Sp) ÷ [0.3] +÷ 0300 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0300 × 0308 × 0061 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN SMALL LETTER A (Lower) ÷ [0.3] +÷ 0300 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0300 × 0308 × 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER A (Upper) ÷ [0.3] +÷ 0300 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0300 × 0308 × 01BB ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN LETTER TWO WITH STROKE (OLetter) ÷ [0.3] +÷ 0300 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0300 × 0308 × 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0300 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0300 × 0308 × 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0300 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0300 × 0308 × 0021 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] EXCLAMATION MARK (STerm) ÷ [0.3] +÷ 0300 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0300 × 0308 × 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] QUOTATION MARK (Close) ÷ [0.3] +÷ 0300 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0300 × 0308 × 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [998.0] COMMA (SContinue) ÷ [0.3] +÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000D × 000A ÷ 0061 × 000A ÷ 0308 ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [4.0] LATIN SMALL LETTER A (Lower) × [998.0] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3] +÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Lower) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3] +÷ 0020 × 200D × 0646 ÷ # ÷ [0.2] SPACE (Sp) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] ARABIC LETTER NOON (OLetter) ÷ [0.3] +÷ 0646 × 200D × 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (OLetter) × [5.0] ZERO WIDTH JOINER (Extend_FE) × [998.0] SPACE (Sp) ÷ [0.3] +÷ 0028 × 0022 × 0047 × 006F × 002E × 0022 × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] FULL STOP (ATerm) × [9.0] QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3] +÷ 0028 × 201C × 0047 × 006F × 003F × 201D × 0029 × 0020 ÷ 0028 × 0048 × 0065 × 0020 × 0064 × 0069 × 0064 × 002E × 0029 ÷ # ÷ [0.2] LEFT PARENTHESIS (Close) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [998.0] LATIN CAPITAL LETTER G (Upper) × [998.0] LATIN SMALL LETTER O (Lower) × [998.0] QUESTION MARK (STerm) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] SPACE (Sp) ÷ [11.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) ÷ [0.3] +÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E × 0020 × 0069 × 0073 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER I (Lower) × [998.0] LATIN SMALL LETTER S (Lower) ÷ [0.3] +÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 003F × 0020 ÷ 0048 × 0065 ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [9.0] SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0055 × 002E × 0053 × 002E × 0041 × 0300 × 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER U (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER S (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) ÷ [0.3] +÷ 0033 × 002E × 0034 ÷ # ÷ [0.2] DIGIT THREE (Numeric) × [998.0] FULL STOP (ATerm) × [6.0] DIGIT FOUR (Numeric) ÷ [0.3] +÷ 0063 × 002E × 0064 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3] +÷ 0043 × 002E × 0064 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [8.0] LATIN SMALL LETTER D (Lower) ÷ [0.3] +÷ 0063 × 002E × 0044 ÷ # ÷ [0.2] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3] +÷ 0043 × 002E × 0044 ÷ # ÷ [0.2] LATIN CAPITAL LETTER C (Upper) × [998.0] FULL STOP (ATerm) × [7.0] LATIN CAPITAL LETTER D (Upper) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 2018 × 0028 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 ÷ 2018 × 0028 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [998.0] LEFT PARENTHESIS (Close) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 × 0074 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.0] RIGHT PARENTHESIS (Close) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [8.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 00A0 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [9.0] NO-BREAK SPACE (Sp) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 2019 × 0308 ÷ 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 0029 × 000A ÷ 0308 × 0054 × 0068 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [9.0] RIGHT PARENTHESIS (Close) × [9.0] (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 0074 × 0068 × 0065 × 0020 × 0072 × 0065 × 0073 × 0070 × 002E × 0020 × 006C × 0065 × 0061 × 0064 × 0065 × 0072 × 0073 × 0020 × 0061 × 0072 × 0065 ÷ # ÷ [0.2] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER H (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] LATIN SMALL LETTER P (Lower) × [998.0] FULL STOP (ATerm) × [8.0] SPACE (Sp) × [8.0] LATIN SMALL LETTER L (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER D (Lower) × [998.0] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER S (Lower) × [998.0] SPACE (Sp) × [998.0] LATIN SMALL LETTER A (Lower) × [998.0] LATIN SMALL LETTER R (Lower) × [998.0] LATIN SMALL LETTER E (Lower) ÷ [0.3] +÷ 5B57 × 002E ÷ 5B57 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E ÷ 5B83 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3] +÷ 0065 × 0074 × 0063 × 002E × 3002 ÷ # ÷ [0.2] LATIN SMALL LETTER E (Lower) × [998.0] LATIN SMALL LETTER T (Lower) × [998.0] LATIN SMALL LETTER C (Lower) × [998.0] FULL STOP (ATerm) × [8.1] IDEOGRAPHIC FULL STOP (STerm) ÷ [0.3] +÷ 5B57 × 3002 ÷ 5B83 ÷ # ÷ [0.2] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [998.0] IDEOGRAPHIC FULL STOP (STerm) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) ÷ [0.3] +÷ 0021 × 0020 × 0020 ÷ # ÷ [0.2] EXCLAMATION MARK (STerm) × [9.0] SPACE (Sp) × [10.0] SPACE (Sp) ÷ [0.3] +÷ 2060 × 0028 × 2060 × 0022 × 2060 × 0047 × 2060 × 006F × 2060 × 002E × 2060 × 0022 × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0028 × 2060 × 201C × 2060 × 0047 × 2060 × 006F × 2060 × 003F × 2060 × 201D × 2060 × 0029 × 2060 × 0020 × 2060 ÷ 0028 × 2060 × 0048 × 2060 × 0065 × 2060 × 0020 × 2060 × 0064 × 2060 × 0069 × 2060 × 0064 × 2060 × 002E × 2060 × 0029 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER G (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER O (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT DOUBLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 0020 × 2060 × 0069 × 2060 × 0073 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER I (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 003F × 2060 × 0020 × 2060 ÷ 0048 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] QUESTION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER H (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0055 × 2060 × 002E × 2060 × 0053 × 2060 × 002E × 2060 × 0041 × 2060 × 0300 × 002E × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER U (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER S (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING GRAVE ACCENT (Extend_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0033 × 2060 × 002E × 2060 × 0034 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] DIGIT THREE (Numeric) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [6.0] DIGIT FOUR (Numeric) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0063 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0043 × 2060 × 002E × 2060 × 0064 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0063 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0043 × 2060 × 002E × 2060 × 0044 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER C (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER D (Upper) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 2018 × 2060 × 0028 × 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 ÷ 2018 × 2060 × 0028 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] LEFT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LEFT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [8.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [8.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 00A0 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] NO-BREAK SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 2019 × 2060 × 0308 ÷ 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT SINGLE QUOTATION MARK (Close) × [5.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) ÷ [11.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 0029 × 2060 × 000A ÷ 2060 × 0308 × 2060 × 0054 × 2060 × 0068 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [9.0] RIGHT PARENTHESIS (Close) × [5.0] WORD JOINER (Format_FE) × [9.0] (LF) ÷ [4.0] WORD JOINER (Format_FE) × [5.0] COMBINING DIAERESIS (Extend_FE) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN CAPITAL LETTER T (Upper) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0074 × 2060 × 0068 × 2060 × 0065 × 2060 × 0020 × 2060 × 0072 × 2060 × 0065 × 2060 × 0073 × 2060 × 0070 × 2060 × 002E × 2060 × 0020 × 2060 × 006C × 2060 × 0065 × 2060 × 0061 × 2060 × 0064 × 2060 × 0065 × 2060 × 0072 × 2060 × 0073 × 2060 × 0020 × 2060 × 0061 × 2060 × 0072 × 2060 × 0065 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER H (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER P (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [8.0] LATIN SMALL LETTER L (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER D (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER S (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER A (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER R (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 5B57 × 2060 × 002E × 2060 ÷ 5B57 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0065 × 2060 × 0074 × 2060 × 0063 × 2060 × 002E × 2060 × 3002 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER E (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER T (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] LATIN SMALL LETTER C (Lower) × [5.0] WORD JOINER (Format_FE) × [998.0] FULL STOP (ATerm) × [5.0] WORD JOINER (Format_FE) × [8.1] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 5B57 × 2060 × 3002 × 2060 ÷ 5B83 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] CJK UNIFIED IDEOGRAPH-5B57 (OLetter) × [5.0] WORD JOINER (Format_FE) × [998.0] IDEOGRAPHIC FULL STOP (STerm) × [5.0] WORD JOINER (Format_FE) ÷ [11.0] CJK UNIFIED IDEOGRAPH-5B83 (OLetter) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 2060 × 0021 × 2060 × 0020 × 2060 × 0020 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) × [998.0] EXCLAMATION MARK (STerm) × [5.0] WORD JOINER (Format_FE) × [9.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [10.0] SPACE (Sp) × [5.0] WORD JOINER (Format_FE) × [5.0] WORD JOINER (Format_FE) ÷ [0.3] +# +# Lines: 502 +# +# EOF diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/data/WordBreakTest.txt cargo-0.35.0/vendor/bstr/src/unicode/data/WordBreakTest.txt --- cargo-0.33.0/vendor/bstr/src/unicode/data/WordBreakTest.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/data/WordBreakTest.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1851 @@ +# WordBreakTest-11.0.0.txt +# Date: 2018-03-16, 20:34:16 GMT +# © 2018 Unicode®, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see http://www.unicode.org/reports/tr44/ +# +# Default Word_Break Test +# +# Format: +# (# )? +# contains hex Unicode code points, with +# ÷ wherever there is a break opportunity, and +# × wherever there is not. +# the format can change, but currently it shows: +# - the sample character name +# - (x) the Word_Break property value for the sample character +# - [x] the rule that determines whether there is a break or not, +# as listed in the Rules section of WordBreakTest.html +# +# These samples may be extended or changed in the future. +# +÷ 0001 ÷ 0001 ÷ # ÷ [0.2] (Other) ÷ [999.0] (Other) ÷ [0.3] +÷ 0001 × 0308 ÷ 0001 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0001 ÷ 000D ÷ # ÷ [0.2] (Other) ÷ [3.2] (CR) ÷ [0.3] +÷ 0001 × 0308 ÷ 000D ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0001 ÷ 000A ÷ # ÷ [0.2] (Other) ÷ [3.2] (LF) ÷ [0.3] +÷ 0001 × 0308 ÷ 000A ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0001 ÷ 000B ÷ # ÷ [0.2] (Other) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0001 × 0308 ÷ 000B ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0001 ÷ 3031 ÷ # ÷ [0.2] (Other) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0001 × 0308 ÷ 3031 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0001 ÷ 0041 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0001 × 0308 ÷ 0041 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0001 ÷ 003A ÷ # ÷ [0.2] (Other) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 × 0308 ÷ 003A ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 ÷ 002C ÷ # ÷ [0.2] (Other) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 × 0308 ÷ 002C ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 ÷ 002E ÷ # ÷ [0.2] (Other) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0001 × 0308 ÷ 002E ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0001 ÷ 0030 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0001 × 0308 ÷ 0030 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0001 ÷ 005F ÷ # ÷ [0.2] (Other) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0001 × 0308 ÷ 005F ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0001 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0001 ÷ 05D0 ÷ # ÷ [0.2] (Other) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0001 × 0308 ÷ 05D0 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0001 ÷ 0022 ÷ # ÷ [0.2] (Other) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0001 × 0308 ÷ 0022 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0001 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 ÷ 231A ÷ # ÷ [0.2] (Other) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0001 × 0308 ÷ 231A ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0001 ÷ 0020 ÷ # ÷ [0.2] (Other) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0001 × 0308 ÷ 0020 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0001 × 00AD ÷ # ÷ [0.2] (Other) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0001 × 0300 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0001 × 0308 × 0300 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0001 × 200D ÷ # ÷ [0.2] (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0001 × 0308 × 200D ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0001 ÷ 0061 × 2060 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0001 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0001 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0001 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0001 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0001 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0001 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0001 ÷ # ÷ [0.2] (CR) ÷ [3.1] (Other) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 000D ÷ 000D ÷ # ÷ [0.2] (CR) ÷ [3.1] (CR) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 000D × 000A ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 000D ÷ 000B ÷ # ÷ [0.2] (CR) ÷ [3.1] (Newline) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 000B ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 000D ÷ 3031 ÷ # ÷ [0.2] (CR) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000D ÷ 0041 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000D ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 002E ÷ # ÷ [0.2] (CR) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000D ÷ 0030 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000D ÷ 005F ÷ # ÷ [0.2] (CR) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 005F ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000D ÷ 05D0 ÷ # ÷ [0.2] (CR) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000D ÷ 0022 ÷ # ÷ [0.2] (CR) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000D ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 231A ÷ # ÷ [0.2] (CR) ÷ [3.1] WATCH (ExtPict) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 000D ÷ 0020 ÷ # ÷ [0.2] (CR) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 000D ÷ 00AD ÷ # ÷ [0.2] (CR) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000D ÷ 0300 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000D ÷ 200D ÷ # ÷ [0.2] (CR) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000D ÷ 0061 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0001 ÷ # ÷ [0.2] (LF) ÷ [3.1] (Other) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 000A ÷ 000D ÷ # ÷ [0.2] (LF) ÷ [3.1] (CR) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 000A ÷ 000A ÷ # ÷ [0.2] (LF) ÷ [3.1] (LF) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 000A ÷ 000B ÷ # ÷ [0.2] (LF) ÷ [3.1] (Newline) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 000B ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 000A ÷ 3031 ÷ # ÷ [0.2] (LF) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000A ÷ 0041 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000A ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 002E ÷ # ÷ [0.2] (LF) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000A ÷ 0030 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000A ÷ 005F ÷ # ÷ [0.2] (LF) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 005F ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000A ÷ 05D0 ÷ # ÷ [0.2] (LF) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000A ÷ 0022 ÷ # ÷ [0.2] (LF) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000A ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 231A ÷ # ÷ [0.2] (LF) ÷ [3.1] WATCH (ExtPict) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 000A ÷ 0020 ÷ # ÷ [0.2] (LF) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 000A ÷ 00AD ÷ # ÷ [0.2] (LF) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000A ÷ 0300 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000A ÷ 200D ÷ # ÷ [0.2] (LF) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000A ÷ 0061 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000A ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0001 ÷ # ÷ [0.2] (Newline) ÷ [3.1] (Other) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 000B ÷ 000D ÷ # ÷ [0.2] (Newline) ÷ [3.1] (CR) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 000D ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 000B ÷ 000A ÷ # ÷ [0.2] (Newline) ÷ [3.1] (LF) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 000A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 000B ÷ 000B ÷ # ÷ [0.2] (Newline) ÷ [3.1] (Newline) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 000B ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 000B ÷ 3031 ÷ # ÷ [0.2] (Newline) ÷ [3.1] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 3031 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 000B ÷ 0041 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0041 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 000B ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 002E ÷ # ÷ [0.2] (Newline) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 002E ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 000B ÷ 0030 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 000B ÷ 005F ÷ # ÷ [0.2] (Newline) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 005F ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 000B ÷ 1F1E6 ÷ # ÷ [0.2] (Newline) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 000B ÷ 05D0 ÷ # ÷ [0.2] (Newline) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 000B ÷ 0022 ÷ # ÷ [0.2] (Newline) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 000B ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 231A ÷ # ÷ [0.2] (Newline) ÷ [3.1] WATCH (ExtPict) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 231A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 000B ÷ 0020 ÷ # ÷ [0.2] (Newline) ÷ [3.1] SPACE (WSegSpace) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 000B ÷ 00AD ÷ # ÷ [0.2] (Newline) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000B ÷ 0308 × 00AD ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 000B ÷ 0300 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000B ÷ 0308 × 0300 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 000B ÷ 200D ÷ # ÷ [0.2] (Newline) ÷ [3.1] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000B ÷ 0308 × 200D ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 000B ÷ 0061 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 000B ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 000B ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000B ÷ 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] (Other) ÷ [0.3] +÷ 3031 × 0308 ÷ 0001 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 3031 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] (CR) ÷ [0.3] +÷ 3031 × 0308 ÷ 000D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 3031 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] (LF) ÷ [0.3] +÷ 3031 × 0308 ÷ 000A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 3031 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [3.2] (Newline) ÷ [0.3] +÷ 3031 × 0308 ÷ 000B ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 3031 × 0308 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 3031 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 3031 × 0308 ÷ 0041 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 3031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 × 0308 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 × 0308 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 3031 × 0308 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 3031 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 3031 × 0308 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 3031 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 3031 × 0308 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 3031 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 3031 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 3031 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 3031 × 0308 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 3031 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 3031 × 0308 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 ÷ 231A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 3031 × 0308 ÷ 231A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 3031 ÷ 0020 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 3031 × 0308 ÷ 0020 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 3031 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 3031 × 0308 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 3031 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 3031 × 0308 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 3031 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 3031 × 0308 × 200D ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 3031 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 3031 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 3031 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 3031 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] (Other) ÷ [0.3] +÷ 0041 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0041 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] (CR) ÷ [0.3] +÷ 0041 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0041 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] (LF) ÷ [0.3] +÷ 0041 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0041 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0041 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0041 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0041 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0041 × 0308 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0041 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0041 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0041 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0041 × 0308 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0041 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0041 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0041 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0041 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0041 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0041 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 ÷ 231A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0041 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0041 ÷ 0020 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0041 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0041 × 0308 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0041 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0041 × 0308 × 200D ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0041 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0041 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0041 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0041 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] (Other) ÷ [0.3] +÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 003A ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] (CR) ÷ [0.3] +÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 003A ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] (LF) ÷ [0.3] +÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 003A ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) ÷ [3.2] (Newline) ÷ [0.3] +÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 003A ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 003A ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 003A ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 003A ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 003A ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 003A ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 003A ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A ÷ 231A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 003A ÷ 0020 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 003A × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 003A × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 003A × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 003A × 0308 × 200D ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] (Other) ÷ [0.3] +÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 002C ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] (CR) ÷ [0.3] +÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 002C ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] (LF) ÷ [0.3] +÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 002C ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) ÷ [3.2] (Newline) ÷ [0.3] +÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 002C ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 002C ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 002C ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 002C ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002C ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 002C ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 002C ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C ÷ 231A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 002C ÷ 0020 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002C × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 002C × 0308 × 200D ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] (Other) ÷ [0.3] +÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 002E ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (CR) ÷ [0.3] +÷ 002E × 0308 ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 002E ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (LF) ÷ [0.3] +÷ 002E × 0308 ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 002E ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] (Newline) ÷ [0.3] +÷ 002E × 0308 ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 002E ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 002E × 0308 ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 002E ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E × 0308 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E × 0308 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 002E × 0308 ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 002E ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002E × 0308 ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 002E ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 002E × 0308 ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 002E ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 002E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 002E ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 002E × 0308 ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 002E ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 002E × 0308 ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 002E ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E × 0308 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E ÷ 231A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 002E × 0308 ÷ 231A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 002E ÷ 0020 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 002E × 0308 ÷ 0020 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 002E × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 002E × 0308 × 200D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 002E ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 002E ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 002E ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 002E ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 002E × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] (Other) ÷ [0.3] +÷ 0030 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0030 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] (CR) ÷ [0.3] +÷ 0030 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0030 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] (LF) ÷ [0.3] +÷ 0030 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0030 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0030 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0030 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0030 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0030 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0030 × 0308 × 0041 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0030 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0030 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0030 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0030 × 0308 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0030 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0030 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0030 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0030 × 0308 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0030 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0030 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 ÷ 231A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0030 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0030 ÷ 0020 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0030 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0030 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0030 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0030 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0030 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0030 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0030 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0030 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] (Other) ÷ [0.3] +÷ 005F × 0308 ÷ 0001 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 005F ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] (CR) ÷ [0.3] +÷ 005F × 0308 ÷ 000D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 005F ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] (LF) ÷ [0.3] +÷ 005F × 0308 ÷ 000A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 005F ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [3.2] (Newline) ÷ [0.3] +÷ 005F × 0308 ÷ 000B ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 005F × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 005F × 0308 × 3031 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 005F × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 005F × 0308 × 0041 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 005F ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F × 0308 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F × 0308 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 005F × 0308 ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 005F × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 005F × 0308 × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 005F × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 005F × 0308 × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 005F ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 005F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 005F × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 005F × 0308 × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 005F ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 005F × 0308 ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F ÷ 231A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 005F × 0308 ÷ 231A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 005F ÷ 0020 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 005F × 0308 ÷ 0020 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 005F × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 005F × 0308 × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 005F × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 005F × 0308 × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 005F × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 005F × 0308 × 200D ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 005F × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 005F × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 005F × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 005F × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] (Other) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] (CR) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 1F1E6 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] (LF) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 1F1E6 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [3.2] (Newline) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 000B ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 1F1E6 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 3031 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 1F1E6 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0041 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 1F1E6 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 1F1E6 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 1F1E6 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1F1E6 × 0308 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [15.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 1F1E6 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 1F1E6 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 1F1E6 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 1F1E6 × 0308 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 1F1E6 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 1F1E6 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 1F1E6 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 1F1E6 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] (Other) ÷ [0.3] +÷ 05D0 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 05D0 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (CR) ÷ [0.3] +÷ 05D0 × 0308 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 05D0 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (LF) ÷ [0.3] +÷ 05D0 × 0308 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 05D0 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] (Newline) ÷ [0.3] +÷ 05D0 × 0308 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 05D0 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 05D0 × 0308 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 05D0 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 05D0 × 0308 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 05D0 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 × 0308 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 × 0308 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 05D0 × 0308 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 05D0 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 05D0 × 0308 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 05D0 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 05D0 × 0308 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 05D0 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 05D0 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 05D0 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 05D0 × 0308 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 05D0 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 05D0 × 0308 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0308 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 ÷ 231A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 05D0 × 0308 ÷ 231A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 05D0 ÷ 0020 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 05D0 × 0308 ÷ 0020 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 05D0 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 05D0 × 0308 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 05D0 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 05D0 × 0308 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 05D0 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 05D0 × 0308 × 200D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 05D0 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 05D0 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 05D0 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 05D0 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] (Other) ÷ [0.3] +÷ 0022 × 0308 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0022 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (CR) ÷ [0.3] +÷ 0022 × 0308 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0022 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (LF) ÷ [0.3] +÷ 0022 × 0308 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0022 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0022 × 0308 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0022 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0022 × 0308 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0022 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0022 × 0308 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0022 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 × 0308 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 × 0308 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0022 × 0308 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0022 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0022 × 0308 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0022 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0022 × 0308 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0022 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0022 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0022 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0022 × 0308 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0022 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0022 × 0308 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0022 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 × 0308 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 ÷ 231A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0022 × 0308 ÷ 231A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0022 ÷ 0020 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0022 × 0308 ÷ 0020 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0022 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0022 × 0308 × 200D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0022 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0022 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0022 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0022 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0022 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] +÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] +÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] +÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0027 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 ÷ 231A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0027 ÷ 0020 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0027 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] (Other) ÷ [0.3] +÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] (CR) ÷ [0.3] +÷ 231A × 0308 ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 231A ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] (LF) ÷ [0.3] +÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 231A ÷ 000B ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [3.2] (Newline) ÷ [0.3] +÷ 231A × 0308 ÷ 000B ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 231A ÷ 3031 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 231A × 0308 ÷ 3031 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 231A ÷ 0041 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 231A × 0308 ÷ 0041 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 231A ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A × 0308 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A × 0308 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A ÷ 002E ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 231A × 0308 ÷ 002E ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 231A ÷ 0030 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 231A × 0308 ÷ 0030 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 231A ÷ 005F ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 231A × 0308 ÷ 005F ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 231A ÷ 05D0 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 231A × 0308 ÷ 05D0 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 231A ÷ 0022 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 231A × 0308 ÷ 0022 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 231A ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A × 0308 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 231A × 00AD ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 231A × 0308 × 00AD ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 231A ÷ 0061 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 231A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 231A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 231A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 231A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] WATCH (ExtPict) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] (Other) ÷ [0.3] +÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0020 ÷ 000D ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] (CR) ÷ [0.3] +÷ 0020 × 0308 ÷ 000D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0020 ÷ 000A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] (LF) ÷ [0.3] +÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0020 ÷ 000B ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0020 × 0308 ÷ 000B ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0020 ÷ 3031 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0020 × 0308 ÷ 3031 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0020 ÷ 0041 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0020 × 0308 ÷ 0041 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0020 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 × 0308 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 × 0308 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 ÷ 002E ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0020 × 0308 ÷ 002E ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0020 ÷ 0030 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0020 × 0308 ÷ 0030 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0020 ÷ 005F ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0020 × 0308 ÷ 005F ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0020 ÷ 05D0 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0020 × 0308 ÷ 05D0 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0020 ÷ 0022 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0020 × 0308 ÷ 0022 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0020 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 × 0308 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 ÷ 231A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0020 × 0020 ÷ # ÷ [0.2] SPACE (WSegSpace) × [3.4] SPACE (WSegSpace) ÷ [0.3] +÷ 0020 × 0308 ÷ 0020 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0020 × 00AD ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0020 × 0308 × 00AD ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0020 ÷ 0061 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0020 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0020 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0020 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0020 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 00AD × 0308 ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 00AD ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 00AD × 0308 ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 00AD ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 00AD × 0308 ÷ 000A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 00AD ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 00AD × 0308 ÷ 000B ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 00AD ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 00AD × 0308 ÷ 3031 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 00AD ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 00AD × 0308 ÷ 0041 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 00AD ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD × 0308 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD × 0308 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 00AD × 0308 ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 00AD ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 00AD × 0308 ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 00AD ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 00AD × 0308 ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 00AD ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 00AD × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 00AD ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 00AD × 0308 ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 00AD ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 00AD × 0308 ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD ÷ 231A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 00AD × 0308 ÷ 231A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 00AD ÷ 0020 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 00AD × 0308 ÷ 0020 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 00AD × 0308 × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 00AD × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 00AD × 0308 × 200D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 00AD ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 00AD ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 00AD ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 00AD × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0300 × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0300 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0300 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0300 × 0308 ÷ 000B ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0300 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0300 × 0308 ÷ 3031 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0300 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0300 × 0308 ÷ 0041 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0300 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 × 0308 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 × 0308 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0300 × 0308 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0300 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0300 × 0308 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0300 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0300 × 0308 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0300 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0300 × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0300 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0300 × 0308 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0300 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0300 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0300 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0300 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 200D × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 200D ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 200D ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 200D × 0308 ÷ 000B ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 200D ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 200D × 0308 ÷ 3031 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 200D ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 200D × 0308 ÷ 0041 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 200D ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D × 0308 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D × 0308 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 200D × 0308 ÷ 002E ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 200D ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 200D × 0308 ÷ 0030 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 200D ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 200D × 0308 ÷ 005F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200D ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 200D × 0308 ÷ 05D0 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 200D ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 200D × 0308 ÷ 0022 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 200D ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D × 0308 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D × 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] WATCH (ExtPict) ÷ [0.3] +÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 200D × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 200D × 0308 × 00AD ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 200D ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 200D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 200D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 200D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 200D × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 × 2060 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 × 2060 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 × 2060 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 × 003A × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 × 003A × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 × 003A × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 003A × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 × 003A × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 003A × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 003A × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 003A × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 × 0027 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0061 ÷ 002C × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 003A × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 × 002C × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 002C × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002C × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 002C × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 002C × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002C × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002C × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 × 002C × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] (Other) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (CR) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (LF) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] (Newline) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 231A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0020 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 × 200D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3] +÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] (CR) × [3.0] (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [3.2] (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [0.3] +÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [0.3] +÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (WSegSpace) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] ARABIC LETTER NOON (ALetter) ÷ [0.3] +÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] SPACE (WSegSpace) ÷ [0.3] +÷ 0041 × 0041 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0041 × 003A × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0041 ÷ 003A ÷ 003A ÷ 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3] +÷ 05D0 × 0022 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.2] QUOTATION MARK (Double_Quote) × [7.3] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3] +÷ 0041 × 0030 × 0030 × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) × [10.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 0030 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 0030 ÷ 002C ÷ 002C ÷ 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3] +÷ 3031 × 3031 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3] +÷ 0041 × 005F × 0030 × 005F × 3031 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3] +÷ 0041 × 005F × 005F × 0041 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3] +÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [15.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 × 200D ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 200D × 1F1E7 ÷ 1F1E8 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0061 ÷ 1F1E6 × 1F1E7 ÷ 1F1E8 × 1F1E9 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER B (RI) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER C (RI) × [16.0] REGIONAL INDICATOR SYMBOL LETTER D (RI) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [999.0] BABY (ExtPict) ÷ [0.3] +÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 0061 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] UPPER BLADE SCISSORS (Other) ÷ [0.3] +÷ 0061 × 200D × 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] UPPER BLADE SCISSORS (Other) ÷ [0.3] +÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] BABY (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3] +÷ 1F6D1 × 1F3FF ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3] +÷ 200D × 1F6D1 × 1F3FF ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) × [4.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_FE) ÷ [0.3] +÷ 200D × 1F6D1 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 200D × 1F6D1 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_FE) × [3.3] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 1F6D1 ÷ 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 0061 × 0308 × 200D × 0308 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] ZERO WIDTH JOINER (ZWJ_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0061 ÷ 0020 × 0020 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] SPACE (WSegSpace) × [3.4] SPACE (WSegSpace) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0031 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 003A ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002E ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 003A ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 002E ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [0.3] +÷ 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0031 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +÷ 0061 × 005F × 0061 ÷ 002C ÷ 002C ÷ 0061 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3] +# +# Lines: 1823 +# +# EOF Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_fwd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name GRAPHEME_BREAK_FWD --sparse --minimize --anchored --state-size 2 src/unicode/fsm/ [snip (arg too long)] +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref GRAPHEME_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("grapheme_break_fwd.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref GRAPHEME_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("grapheme_break_fwd.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/grapheme_break_rev.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name GRAPHEME_BREAK_REV --reverse --longest --sparse --minimize --anchored --state-size 2 src/unicode/fsm/ [snip (arg too long)] +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref GRAPHEME_BREAK_REV: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("grapheme_break_rev.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref GRAPHEME_BREAK_REV: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("grapheme_break_rev.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/mod.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/mod.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +pub mod grapheme_break_fwd; +pub mod grapheme_break_rev; +pub mod regional_indicator_rev; +pub mod sentence_break_fwd; +pub mod simple_word_fwd; +pub mod whitespace_anchored_fwd; +pub mod whitespace_anchored_rev; +pub mod word_break_fwd; Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/regional_indicator_rev.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name REGIONAL_INDICATOR_REV --reverse --classes --minimize --anchored --premultiply --state-size 1 src/unicode/fsm/ \p{gcb=Regional_Indicator} +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref REGIONAL_INDICATOR_REV: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("regional_indicator_rev.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref REGIONAL_INDICATOR_REV: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("regional_indicator_rev.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/sentence_break_fwd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name SENTENCE_BREAK_FWD --minimize --sparse --anchored --state-size 4 src/unicode/fsm/ [snip (arg too long)] +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref SENTENCE_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u32> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("sentence_break_fwd.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref SENTENCE_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u32> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("sentence_break_fwd.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/simple_word_fwd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name SIMPLE_WORD_FWD --sparse --minimize --state-size 2 src/unicode/fsm/ \w +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref SIMPLE_WORD_FWD: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("simple_word_fwd.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref SIMPLE_WORD_FWD: ::regex_automata::SparseDFA<&'static [u8], u16> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("simple_word_fwd.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_fwd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name WHITESPACE_ANCHORED_FWD --anchored --classes --premultiply --minimize --state-size 1 src/unicode/fsm/ \s+ +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref WHITESPACE_ANCHORED_FWD: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("whitespace_anchored_fwd.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref WHITESPACE_ANCHORED_FWD: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("whitespace_anchored_fwd.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/whitespace_anchored_rev.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name WHITESPACE_ANCHORED_REV --reverse --anchored --classes --minimize --state-size 1 src/unicode/fsm/ \s+ +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref WHITESPACE_ANCHORED_REV: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("whitespace_anchored_rev.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref WHITESPACE_ANCHORED_REV: ::regex_automata::DenseDFA<&'static [u8], u8> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("whitespace_anchored_rev.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::DenseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/word_break_fwd.bigendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/word_break_fwd.bigendian.dfa differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/bstr/src/unicode/fsm/word_break_fwd.littleendian.dfa and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/bstr/src/unicode/fsm/word_break_fwd.littleendian.dfa differ diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/fsm/word_break_fwd.rs cargo-0.35.0/vendor/bstr/src/unicode/fsm/word_break_fwd.rs --- cargo-0.33.0/vendor/bstr/src/unicode/fsm/word_break_fwd.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/fsm/word_break_fwd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY: +// +// ucd-generate dfa --name WORD_BREAK_FWD --sparse --minimize --anchored --state-size 4 src/unicode/fsm/ [snip (arg too long)] +// +// ucd-generate is available on crates.io. + +#[cfg(target_endian = "big")] +lazy_static! { + pub static ref WORD_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u32> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("word_break_fwd.bigendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} + +#[cfg(target_endian = "little")] +lazy_static! { + pub static ref WORD_BREAK_FWD: ::regex_automata::SparseDFA<&'static [u8], u32> = { + #[repr(C)] + struct Aligned { + _align: [u8; 0], + bytes: B, + } + + static ALIGNED: &'static Aligned<[u8]> = &Aligned { + _align: [], + bytes: *include_bytes!("word_break_fwd.littleendian.dfa"), + }; + + unsafe { + ::regex_automata::SparseDFA::from_bytes(&ALIGNED.bytes) + } + }; +} diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/grapheme.rs cargo-0.35.0/vendor/bstr/src/unicode/grapheme.rs --- cargo-0.33.0/vendor/bstr/src/unicode/grapheme.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/grapheme.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,357 @@ +use regex_automata::DFA; + +use bstr::BStr; +use unicode::fsm::grapheme_break_fwd::GRAPHEME_BREAK_FWD; +use unicode::fsm::grapheme_break_rev::GRAPHEME_BREAK_REV; +use unicode::fsm::regional_indicator_rev::REGIONAL_INDICATOR_REV; +use utf8; + +/// An iterator over grapheme clusters in a byte string. +/// +/// This iterator is typically constructed by +/// [`bstr::graphemes`](struct.BStr.html#method.graphemes). +/// +/// Unicode defines a grapheme cluster as an *approximation* to a single user +/// visible character. A grapheme cluster, or just "grapheme," is made up of +/// one or more codepoints. For end user oriented tasks, one should generally +/// prefer using graphemes instead of [`Chars`](struct.Chars.html), which +/// always yields one codepoint at a time. +/// +/// Since graphemes are made up of one or more codepoints, this iterator yields +/// `&str` elements. When invalid UTF-8 is encountered, replacement codepoints +/// are [substituted](index.html#handling-of-invalid-utf-8). +/// +/// This iterator can be used in reverse. When reversed, exactly the same +/// set of grapheme clusters are yielded, but in reverse order. +/// +/// This iterator only yields *extended* grapheme clusters, in accordance with +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Grapheme_Cluster_Boundaries). +#[derive(Clone, Debug)] +pub struct Graphemes<'a> { + bs: &'a BStr, +} + +impl<'a> Graphemes<'a> { + pub(crate) fn new(bs: &'a BStr) -> Graphemes<'a> { + Graphemes { bs } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("abc").graphemes(); + /// + /// assert_eq!("abc", it.as_bstr()); + /// it.next(); + /// assert_eq!("bc", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for Graphemes<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + let (grapheme, size) = decode_grapheme(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + Some(grapheme) + } +} + +impl<'a> DoubleEndedIterator for Graphemes<'a> { + #[inline] + fn next_back(&mut self) -> Option<&'a str> { + let (grapheme, size) = decode_last_grapheme(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[..self.bs.len()-size]; + Some(grapheme) + } +} + +/// An iterator over grapheme clusters in a byte string and their byte index +/// positions. +/// +/// This iterator is typically constructed by +/// [`bstr::grapheme_indices`](struct.BStr.html#method.grapheme_indices). +/// +/// Unicode defines a grapheme cluster as an *approximation* to a single user +/// visible character. A grapheme cluster, or just "grapheme," is made up of +/// one or more codepoints. For end user oriented tasks, one should generally +/// prefer using graphemes instead of [`Chars`](struct.Chars.html), which +/// always yields one codepoint at a time. +/// +/// Since graphemes are made up of one or more codepoints, this iterator +/// yields `&str` elements (along with their start and end byte offsets). +/// When invalid UTF-8 is encountered, replacement codepoints are +/// [substituted](index.html#handling-of-invalid-utf-8). Because of this, the +/// indices yielded by this iterator may not correspond to the length of the +/// grapheme cluster yielded with those indices. For example, when this +/// iterator encounters `\xFF` in the byte string, then it will yield a pair +/// of indices ranging over a single byte, but will provide an `&str` +/// equivalent to `"\u{FFFD}"`, which is three bytes in length. However, when +/// given only valid UTF-8, then all indices are in exact correspondence with +/// their paired grapheme cluster. +/// +/// This iterator can be used in reverse. When reversed, exactly the same +/// set of grapheme clusters are yielded, but in reverse order. +/// +/// This iterator only yields *extended* grapheme clusters, in accordance with +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Grapheme_Cluster_Boundaries). +#[derive(Clone, Debug)] +pub struct GraphemeIndices<'a> { + bs: &'a BStr, + forward_index: usize, + reverse_index: usize, +} + +impl<'a> GraphemeIndices<'a> { + pub(crate) fn new(bs: &'a BStr) -> GraphemeIndices<'a> { + GraphemeIndices { bs: bs, forward_index: 0, reverse_index: bs.len() } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("abc").grapheme_indices(); + /// + /// assert_eq!("abc", it.as_bstr()); + /// it.next(); + /// assert_eq!("bc", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for GraphemeIndices<'a> { + type Item = (usize, usize, &'a str); + + #[inline] + fn next(&mut self) -> Option<(usize, usize, &'a str)> { + let index = self.forward_index; + let (grapheme, size) = decode_grapheme(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + self.forward_index += size; + Some((index, index + size, grapheme)) + } +} + +impl<'a> DoubleEndedIterator for GraphemeIndices<'a> { + #[inline] + fn next_back(&mut self) -> Option<(usize, usize, &'a str)> { + let (grapheme, size) = decode_last_grapheme(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[..self.bs.len()-size]; + self.reverse_index -= size; + Some((self.reverse_index, self.reverse_index + size, grapheme)) + } +} + +/// Decode a grapheme from the given byte string. +/// +/// This returns the resulting grapheme (which may be a Unicode replacement +/// codepoint if invalid UTF-8 was found), along with the number of bytes +/// decoded in the byte string. The number of bytes decoded may not be the +/// same as the length of grapheme in the case where invalid UTF-8 is found. +pub fn decode_grapheme(bs: &BStr) -> (&str, usize) { + if bs.is_empty() { + ("", 0) + } else if let Some(end) = GRAPHEME_BREAK_FWD.find(bs.as_bytes()) { + // Safe because a match can only occur for valid UTF-8. + let grapheme = unsafe { bs[..end].to_str_unchecked() }; + (grapheme, grapheme.len()) + } else { + const INVALID: &'static str = "\u{FFFD}"; + // No match on non-empty bytes implies we found invalid UTF-8. + let (_, size) = utf8::decode_lossy(bs.as_bytes()); + (INVALID, size) + } +} + +fn decode_last_grapheme(bs: &BStr) -> (&str, usize) { + if bs.is_empty() { + ("", 0) + } else if let Some(mut start) = GRAPHEME_BREAK_REV.rfind(bs.as_bytes()) { + start = adjust_rev_for_regional_indicator(bs, start); + // Safe because a match can only occur for valid UTF-8. + let grapheme = unsafe { bs[start..].to_str_unchecked() }; + (grapheme, grapheme.len()) + } else { + const INVALID: &'static str = "\u{FFFD}"; + // No match on non-empty bytes implies we found invalid UTF-8. + let (_, size) = utf8::decode_last_lossy(bs.as_bytes()); + (INVALID, size) + } +} + +/// Return the correct offset for the next grapheme decoded at the end of the +/// given byte string, where `i` is the initial guess. In particular, +/// `&bs[i..]` represents the candidate grapheme. +/// +/// `i` is returned by this function in all cases except when `&bs[i..]` is +/// a pair of regional indicator codepoints. In that case, if an odd number of +/// additional regional indicator codepoints precedes `i`, then `i` is +/// adjusted such that it points to only a single regional indicator. +/// +/// This "fixing" is necessary to handle the requirement that a break cannot +/// occur between regional indicators where it would cause an odd number of +/// regional indicators to exist before the break from the *start* of the +/// string. A reverse regex cannot detect this case easily without look-around. +fn adjust_rev_for_regional_indicator(mut bs: &BStr, i: usize) -> usize { + // All regional indicators use a 4 byte encoding, and we only care about + // the case where we found a pair of regional indicators. + if bs.len() - i != 8 { + return i; + } + // Count all contiguous occurrences of regional indicators. If there's an + // even number of them, then we can accept the pair we found. Otherwise, + // we can only take one of them. + // + // FIXME: This is quadratic in the worst case, e.g., a string of just + // regional indicator codepoints. A fix probably requires refactoring this + // code a bit such that we don't rescan regional indicators. + let mut count = 0; + while let Some(start) = REGIONAL_INDICATOR_REV.rfind(bs.as_bytes()) { + bs = &bs[..start]; + count += 1; + } + if count % 2 == 0 { + i + } else { + i + 4 + } +} + +#[cfg(test)] +mod tests { + use ucd_parse::GraphemeClusterBreakTest; + + use bstr::B; + use tests::LOSSY_TESTS; + use super::*; + + #[test] + fn forward_ucd() { + for (i, test) in ucdtests().into_iter().enumerate() { + let given = test.grapheme_clusters.concat(); + let got: Vec = Graphemes::new(B(&given)) + .map(|cluster| cluster.to_string()) + .collect(); + assert_eq!( + test.grapheme_clusters, + got, + "\ngrapheme forward break test {} failed:\n\ + given: {:?}\n\ + expected: {:?}\n\ + got: {:?}\n", + i, + uniescape(&given), + uniescape_vec(&test.grapheme_clusters), + uniescape_vec(&got), + ); + } + } + + #[test] + fn reverse_ucd() { + for (i, test) in ucdtests().into_iter().enumerate() { + let given = test.grapheme_clusters.concat(); + let mut got: Vec = Graphemes::new(B(&given)) + .rev() + .map(|cluster| cluster.to_string()) + .collect(); + got.reverse(); + assert_eq!( + test.grapheme_clusters, + got, + "\n\ngrapheme reverse break test {} failed:\n\ + given: {:?}\n\ + expected: {:?}\n\ + got: {:?}\n", + i, + uniescape(&given), + uniescape_vec(&test.grapheme_clusters), + uniescape_vec(&got), + ); + } + } + + #[test] + fn forward_lossy() { + for &(expected, input) in LOSSY_TESTS { + let got = Graphemes::new(B(input)).collect::(); + assert_eq!(expected, got); + } + } + + #[test] + fn reverse_lossy() { + for &(expected, input) in LOSSY_TESTS { + let expected: String = expected.chars().rev().collect(); + let got = Graphemes::new(B(input)) + .rev() + .collect::(); + assert_eq!(expected, got); + } + } + + fn uniescape(s: &str) -> String { + s.chars().flat_map(|c| c.escape_unicode()).collect::() + } + + fn uniescape_vec(strs: &[String]) -> Vec { + strs.iter().map(|s| uniescape(s)).collect() + } + + /// Return all of the UCD for grapheme breaks. + fn ucdtests() -> Vec { + const TESTDATA: &'static str = include_str!( + "data/GraphemeBreakTest.txt" + ); + + let mut tests = vec![]; + for mut line in TESTDATA.lines() { + line = line.trim(); + if line.starts_with("#") || line.contains("surrogate") { + continue; + } + tests.push(line.parse().unwrap()); + } + tests + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/mod.rs cargo-0.35.0/vendor/bstr/src/unicode/mod.rs --- cargo-0.33.0/vendor/bstr/src/unicode/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,12 @@ +pub use self::grapheme::{Graphemes, GraphemeIndices, decode_grapheme}; +pub use self::sentence::{Sentences, SentenceIndices}; +pub use self::whitespace::{whitespace_len_fwd, whitespace_len_rev}; +pub use self::word::{ + Words, WordIndices, WordsWithBreaks, WordsWithBreakIndices, +}; + +mod fsm; +mod grapheme; +mod sentence; +mod whitespace; +mod word; diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/sentence.rs cargo-0.35.0/vendor/bstr/src/unicode/sentence.rs --- cargo-0.33.0/vendor/bstr/src/unicode/sentence.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/sentence.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,221 @@ +use regex_automata::DFA; + +use bstr::BStr; +use unicode::fsm::sentence_break_fwd::SENTENCE_BREAK_FWD; +use utf8; + +/// An iterator over sentences in a byte string. +/// +/// This iterator is typically constructed by +/// [`bstr::sentences`](struct.BStr.html#method.sentences). +/// +/// Sentences typically include their trailing punctuation and whitespace. +/// +/// Since sentences are made up of one or more codepoints, this iterator yields +/// `&str` elements. When invalid UTF-8 is encountered, replacement codepoints +/// are [substituted](index.html#handling-of-invalid-utf-8). +/// +/// This iterator yields words in accordance with the default sentence boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Sentence_Boundaries). +#[derive(Clone, Debug)] +pub struct Sentences<'a> { + bs: &'a BStr, +} + +impl<'a> Sentences<'a> { + pub(crate) fn new(bs: &'a BStr) -> Sentences<'a> { + Sentences { bs } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("I want this. Not that. Right now.").sentences(); + /// + /// assert_eq!("I want this. Not that. Right now.", it.as_bstr()); + /// it.next(); + /// assert_eq!("Not that. Right now.", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for Sentences<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + let (sentence, size) = decode_sentence(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + Some(sentence) + } +} + +/// An iterator over sentences in a byte string, along with their byte offsets. +/// +/// This iterator is typically constructed by +/// [`bstr::sentence_indices`](struct.BStr.html#method.sentence_indices). +/// +/// Sentences typically include their trailing punctuation and whitespace. +/// +/// Since sentences are made up of one or more codepoints, this iterator +/// yields `&str` elements (along with their start and end byte offsets). +/// When invalid UTF-8 is encountered, replacement codepoints are +/// [substituted](index.html#handling-of-invalid-utf-8). Because of this, the +/// indices yielded by this iterator may not correspond to the length of the +/// sentence yielded with those indices. For example, when this iterator +/// encounters `\xFF` in the byte string, then it will yield a pair of indices +/// ranging over a single byte, but will provide an `&str` equivalent to +/// `"\u{FFFD}"`, which is three bytes in length. However, when given only +/// valid UTF-8, then all indices are in exact correspondence with their paired +/// word. +/// +/// This iterator yields words in accordance with the default sentence boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Sentence_Boundaries). +#[derive(Clone, Debug)] +pub struct SentenceIndices<'a> { + bs: &'a BStr, + forward_index: usize, +} + +impl<'a> SentenceIndices<'a> { + pub(crate) fn new(bs: &'a BStr) -> SentenceIndices<'a> { + SentenceIndices { bs: bs, forward_index: 0 } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("I want this. Not that. Right now.").sentence_indices(); + /// + /// assert_eq!("I want this. Not that. Right now.", it.as_bstr()); + /// it.next(); + /// assert_eq!("Not that. Right now.", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for SentenceIndices<'a> { + type Item = (usize, usize, &'a str); + + #[inline] + fn next(&mut self) -> Option<(usize, usize, &'a str)> { + let index = self.forward_index; + let (word, size) = decode_sentence(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + self.forward_index += size; + Some((index, index + size, word)) + } +} + +fn decode_sentence(bs: &BStr) -> (&str, usize) { + if bs.is_empty() { + ("", 0) + } else if let Some(end) = SENTENCE_BREAK_FWD.find(bs.as_bytes()) { + // Safe because a match can only occur for valid UTF-8. + let sentence = unsafe { bs[..end].to_str_unchecked() }; + (sentence, sentence.len()) + } else { + const INVALID: &'static str = "\u{FFFD}"; + // No match on non-empty bytes implies we found invalid UTF-8. + let (_, size) = utf8::decode_lossy(bs.as_bytes()); + (INVALID, size) + } +} + +#[cfg(test)] +mod tests { + use ucd_parse::SentenceBreakTest; + + use bstr::{B, BStr}; + + #[test] + fn forward_ucd() { + for (i, test) in ucdtests().into_iter().enumerate() { + let given = test.sentences.concat(); + let got = sentences(given.as_bytes()); + assert_eq!( + test.sentences, + got, + "\n\nsentence forward break test {} failed:\n\ + given: {:?}\n\ + expected: {:?}\n\ + got: {:?}\n", + i, + BStr::new(&given), + strs_to_bstrs(&test.sentences), + strs_to_bstrs(&got), + ); + } + } + + // Some additional tests that don't seem to be covered by the UCD tests. + #[test] + fn forward_additional() { + assert_eq!(vec!["a.. ", "A"], sentences(b"a.. A")); + assert_eq!(vec!["a.. a"], sentences(b"a.. a")); + + assert_eq!(vec!["a... ", "A"], sentences(b"a... A")); + assert_eq!(vec!["a... a"], sentences(b"a... a")); + + assert_eq!(vec!["a...,..., a"], sentences(b"a...,..., a")); + } + + fn sentences(bytes: &[u8]) -> Vec<&str> { + BStr::new(bytes).sentences().collect() + } + + fn strs_to_bstrs>(strs: &[S]) -> Vec<&BStr> { + strs.iter().map(|s| B(s.as_ref())).collect() + } + + /// Return all of the UCD for sentence breaks. + fn ucdtests() -> Vec { + const TESTDATA: &'static str = include_str!( + "data/SentenceBreakTest.txt" + ); + + let mut tests = vec![]; + for mut line in TESTDATA.lines() { + line = line.trim(); + if line.starts_with("#") || line.contains("surrogate") { + continue; + } + tests.push(line.parse().unwrap()); + } + tests + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/whitespace.rs cargo-0.35.0/vendor/bstr/src/unicode/whitespace.rs --- cargo-0.33.0/vendor/bstr/src/unicode/whitespace.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/whitespace.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,14 @@ +use regex_automata::DFA; + +use unicode::fsm::whitespace_anchored_fwd::WHITESPACE_ANCHORED_FWD; +use unicode::fsm::whitespace_anchored_rev::WHITESPACE_ANCHORED_REV; + +/// Return the first position of a non-whitespace character. +pub fn whitespace_len_fwd(slice: &[u8]) -> usize { + WHITESPACE_ANCHORED_FWD.find(slice).unwrap_or(0) +} + +/// Return the last position of a non-whitespace character. +pub fn whitespace_len_rev(slice: &[u8]) -> usize { + WHITESPACE_ANCHORED_REV.rfind(slice).unwrap_or(slice.len()) +} diff -Nru cargo-0.33.0/vendor/bstr/src/unicode/word.rs cargo-0.35.0/vendor/bstr/src/unicode/word.rs --- cargo-0.33.0/vendor/bstr/src/unicode/word.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/unicode/word.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,447 @@ +use regex_automata::DFA; + +use bstr::BStr; +use unicode::fsm::simple_word_fwd::SIMPLE_WORD_FWD; +use unicode::fsm::word_break_fwd::WORD_BREAK_FWD; +use utf8; + +/// An iterator over words in a byte string. +/// +/// This iterator is typically constructed by +/// [`bstr::words`](struct.BStr.html#method.words). +/// +/// This is similar to the [`WordsWithBreaks`](struct.WordsWithBreaks.html) +/// iterator, except it only returns elements that contain a "word" character. +/// A word character is defined by UTS #18 (Annex C) to be the combination +/// of the `Alphabetic` and `Join_Control` properties, along with the +/// `Decimal_Number`, `Mark` and `Connector_Punctuation` general categories. +/// +/// Since words are made up of one or more codepoints, this iterator yields +/// `&str` elements. When invalid UTF-8 is encountered, replacement codepoints +/// are [substituted](index.html#handling-of-invalid-utf-8). +/// +/// This iterator yields words in accordance with the default word boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Word_Boundaries). +/// In particular, this may not be suitable for Japanese and Chinese scripts +/// that do not use spaces between words. +#[derive(Clone, Debug)] +pub struct Words<'a>(WordsWithBreaks<'a>); + +impl<'a> Words<'a> { + pub(crate) fn new(bs: &'a BStr) -> Words<'a> { + Words(WordsWithBreaks::new(bs)) + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("foo bar baz").words(); + /// + /// assert_eq!("foo bar baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!(" baz", it.as_bstr()); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.0.as_bstr() + } +} + +impl<'a> Iterator for Words<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + while let Some(word) = self.0.next() { + if SIMPLE_WORD_FWD.is_match(word.as_bytes()) { + return Some(word); + } + } + None + } +} + +/// An iterator over words in a byte string and their byte index positions. +/// +/// This iterator is typically constructed by +/// [`bstr::word_indices`](struct.BStr.html#method.word_indices). +/// +/// This is similar to the +/// [`WordsWithBreakIndices`](struct.WordsWithBreakIndices.html) iterator, +/// except it only returns elements that contain a "word" character. A +/// word character is defined by UTS #18 (Annex C) to be the combination +/// of the `Alphabetic` and `Join_Control` properties, along with the +/// `Decimal_Number`, `Mark` and `Connector_Punctuation` general categories. +/// +/// Since words are made up of one or more codepoints, this iterator +/// yields `&str` elements (along with their start and end byte offsets). +/// When invalid UTF-8 is encountered, replacement codepoints are +/// [substituted](index.html#handling-of-invalid-utf-8). Because of this, the +/// indices yielded by this iterator may not correspond to the length of the +/// word yielded with those indices. For example, when this iterator encounters +/// `\xFF` in the byte string, then it will yield a pair of indices ranging +/// over a single byte, but will provide an `&str` equivalent to `"\u{FFFD}"`, +/// which is three bytes in length. However, when given only valid UTF-8, then +/// all indices are in exact correspondence with their paired word. +/// +/// This iterator yields words in accordance with the default word boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Word_Boundaries). +/// In particular, this may not be suitable for Japanese and Chinese scripts +/// that do not use spaces between words. +#[derive(Clone, Debug)] +pub struct WordIndices<'a>(WordsWithBreakIndices<'a>); + +impl<'a> WordIndices<'a> { + pub(crate) fn new(bs: &'a BStr) -> WordIndices<'a> { + WordIndices(WordsWithBreakIndices::new(bs)) + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("foo bar baz").word_indices(); + /// + /// assert_eq!("foo bar baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!(" baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.0.as_bstr() + } +} + +impl<'a> Iterator for WordIndices<'a> { + type Item = (usize, usize, &'a str); + + #[inline] + fn next(&mut self) -> Option<(usize, usize, &'a str)> { + while let Some((start, end, word)) = self.0.next() { + if SIMPLE_WORD_FWD.is_match(word.as_bytes()) { + return Some((start, end, word)); + } + } + None + } +} + +/// An iterator over all word breaks in a byte string. +/// +/// This iterator is typically constructed by +/// [`bstr::words_with_breaks`](struct.BStr.html#method.words_with_breaks). +/// +/// This iterator yields not only all words, but the content that comes between +/// words. In particular, if all elements yielded by this iterator are +/// concatenated, then the result is the original string (subject to Unicode +/// replacement codepoint substitutions). +/// +/// Since words are made up of one or more codepoints, this iterator yields +/// `&str` elements. When invalid UTF-8 is encountered, replacement codepoints +/// are [substituted](index.html#handling-of-invalid-utf-8). +/// +/// This iterator yields words in accordance with the default word boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Word_Boundaries). +/// In particular, this may not be suitable for Japanese and Chinese scripts +/// that do not use spaces between words. +#[derive(Clone, Debug)] +pub struct WordsWithBreaks<'a> { + bs: &'a BStr, +} + +impl<'a> WordsWithBreaks<'a> { + pub(crate) fn new(bs: &'a BStr) -> WordsWithBreaks<'a> { + WordsWithBreaks { bs } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("foo bar baz").words_with_breaks(); + /// + /// assert_eq!("foo bar baz", it.as_bstr()); + /// it.next(); + /// assert_eq!(" bar baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!(" baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for WordsWithBreaks<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + let (word, size) = decode_word(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + Some(word) + } +} + +/// An iterator over all word breaks in a byte string, along with their byte +/// index positions. +/// +/// This iterator is typically constructed by +/// [`bstr::words_with_break_indices`](struct.BStr.html#method.words_with_break_indices). +/// +/// This iterator yields not only all words, but the content that comes between +/// words. In particular, if all elements yielded by this iterator are +/// concatenated, then the result is the original string (subject to Unicode +/// replacement codepoint substitutions). +/// +/// Since words are made up of one or more codepoints, this iterator +/// yields `&str` elements (along with their start and end byte offsets). +/// When invalid UTF-8 is encountered, replacement codepoints are +/// [substituted](index.html#handling-of-invalid-utf-8). Because of this, the +/// indices yielded by this iterator may not correspond to the length of the +/// word yielded with those indices. For example, when this iterator encounters +/// `\xFF` in the byte string, then it will yield a pair of indices ranging +/// over a single byte, but will provide an `&str` equivalent to `"\u{FFFD}"`, +/// which is three bytes in length. However, when given only valid UTF-8, then +/// all indices are in exact correspondence with their paired word. +/// +/// This iterator yields words in accordance with the default word boundary +/// rules specified in +/// [UAX #29](https://www.unicode.org/reports/tr29/tr29-33.html#Word_Boundaries). +/// In particular, this may not be suitable for Japanese and Chinese scripts +/// that do not use spaces between words. +#[derive(Clone, Debug)] +pub struct WordsWithBreakIndices<'a> { + bs: &'a BStr, + forward_index: usize, +} + +impl<'a> WordsWithBreakIndices<'a> { + pub(crate) fn new(bs: &'a BStr) -> WordsWithBreakIndices<'a> { + WordsWithBreakIndices { bs: bs, forward_index: 0 } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("foo bar baz").words_with_break_indices(); + /// + /// assert_eq!("foo bar baz", it.as_bstr()); + /// it.next(); + /// assert_eq!(" bar baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!(" baz", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for WordsWithBreakIndices<'a> { + type Item = (usize, usize, &'a str); + + #[inline] + fn next(&mut self) -> Option<(usize, usize, &'a str)> { + let index = self.forward_index; + let (word, size) = decode_word(self.bs); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + self.forward_index += size; + Some((index, index + size, word)) + } +} + +fn decode_word(bs: &BStr) -> (&str, usize) { + if bs.is_empty() { + ("", 0) + } else if let Some(end) = WORD_BREAK_FWD.find(bs.as_bytes()) { + // Safe because a match can only occur for valid UTF-8. + let word = unsafe { bs[..end].to_str_unchecked() }; + (word, word.len()) + } else { + const INVALID: &'static str = "\u{FFFD}"; + // No match on non-empty bytes implies we found invalid UTF-8. + let (_, size) = utf8::decode_lossy(bs.as_bytes()); + (INVALID, size) + } +} + +#[cfg(test)] +mod tests { + use ucd_parse::WordBreakTest; + + use bstr::BStr; + + #[test] + fn forward_ucd() { + for (i, test) in ucdtests().into_iter().enumerate() { + let given = test.words.concat(); + let got = words(given.as_bytes()); + assert_eq!( + test.words, + got, + "\n\nword forward break test {} failed:\n\ + given: {:?}\n\ + expected: {:?}\n\ + got: {:?}\n", + i, + BStr::new(&given), + strs_to_bstrs(&test.words), + strs_to_bstrs(&got), + ); + } + } + + // Some additional tests that don't seem to be covered by the UCD tests. + // + // It's pretty amazing that the UCD tests miss these cases. I only found + // them by running this crate's segmenter and ICU's segmenter on the same + // text and comparing the output. + #[test] + fn forward_additional() { + assert_eq!(vec!["a", ".", " ", "Y"], words(b"a. Y")); + assert_eq!( + vec!["r", ".", " ", "Yo"], + words(b"r. Yo") + ); + assert_eq!( + vec!["whatsoever", ".", " ", "You", " ", "may"], + words(b"whatsoever. You may") + ); + assert_eq!( + vec!["21stcentury'syesterday"], + words(b"21stcentury'syesterday") + ); + + assert_eq!( + vec!["Bonta_", "'", "s"], + words(b"Bonta_'s") + ); + assert_eq!( + vec!["_vhat's"], + words(b"_vhat's") + ); + assert_eq!( + vec!["__on'anima"], + words(b"__on'anima") + ); + assert_eq!( + vec!["123_", "'", "4"], + words(b"123_'4") + ); + assert_eq!( + vec!["_123'4"], + words(b"_123'4") + ); + assert_eq!( + vec!["__12'345"], + words(b"__12'345") + ); + + assert_eq!( + vec!["tomorrowat4", ":", "00", ","], + words(b"tomorrowat4:00,") + ); + assert_eq!( + vec!["RS1", "'", "s"], + words(b"RS1's") + ); + assert_eq!( + vec!["X38"], + words(b"X38") + ); + + assert_eq!( + vec!["4abc", ":", "00", ","], + words(b"4abc:00,") + ); + assert_eq!( + vec!["12S", "'", "1"], + words(b"12S'1") + ); + assert_eq!( + vec!["1XY"], + words(b"1XY") + ); + + assert_eq!( + vec!["\u{FEFF}", "Ты"], + words("\u{FEFF}Ты".as_bytes()) + ); + } + + fn words(bytes: &[u8]) -> Vec<&str> { + BStr::new(bytes).words_with_breaks().collect() + } + + fn strs_to_bstrs>(strs: &[S]) -> Vec<&BStr> { + strs.iter().map(|s| BStr::new(s.as_ref())).collect() + } + + /// Return all of the UCD for word breaks. + fn ucdtests() -> Vec { + const TESTDATA: &'static str = include_str!( + "data/WordBreakTest.txt" + ); + + let mut tests = vec![]; + for mut line in TESTDATA.lines() { + line = line.trim(); + if line.starts_with("#") || line.contains("surrogate") { + continue; + } + tests.push(line.parse().unwrap()); + } + tests + } +} diff -Nru cargo-0.33.0/vendor/bstr/src/utf8.rs cargo-0.35.0/vendor/bstr/src/utf8.rs --- cargo-0.33.0/vendor/bstr/src/utf8.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bstr/src/utf8.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1108 @@ +use core::char; +use core::cmp; +#[cfg(feature = "std")] +use std::error; +use core::fmt; + +use ascii; +use bstr::BStr; + +// The UTF-8 decoder provided here is based on the one presented here: +// https://bjoern.hoehrmann.de/utf-8/decoder/dfa/ +// +// We *could* have done UTF-8 decoding by using a DFA generated by `\p{any}` +// using regex-automata that is roughly the same size. The real benefit of +// Hoehrmann's formulation is that the byte class mapping below is manually +// tailored such that each byte's class doubles as a shift to mask out the +// bits necessary for constructing the leading bits of each codepoint value +// from the initial byte. +// +// There are some minor differences between this implementation and Hoehrmann's +// formulation. +// +// Firstly, we make REJECT have state ID 0, since it makes the state table +// itself a little easier to read and is consistent with the notion that 0 +// means "false" or "bad." +// +// Secondly, when doing bulk decoding, we add a SIMD accelerated ASCII fast +// path. +// +// Thirdly, we pre-multiply the state IDs to avoid a multiplication instruction +// in the core decoding loop. (Which is what regex-automata would do by +// default.) +// +// Fourthly, we split the byte class mapping and transition table into two +// arrays because it's clearer. +// +// It is unlikely that this is the fastest way to do UTF-8 decoding, however, +// it is fairly simple. + +const ACCEPT: usize = 12; +const REJECT: usize = 0; + +static CLASSES: [u8; 256] = [ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, +]; + +static STATES_FORWARD: &'static [u8] = &[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 24, 36, 60, 96, 84, 0, 0, 0, 48, 72, + 0, 12, 0, 0, 0, 0, 0, 12, 0, 12, 0, 0, + 0, 24, 0, 0, 0, 0, 0, 24, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 36, 0, 36, 0, 0, + 0, 36, 0, 0, 0, 0, 0, 36, 0, 36, 0, 0, + 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +]; + +/// An iterator over Unicode scalar values in a byte string. +/// +/// When invalid UTF-8 byte sequences are found, they are substituted with the +/// Unicode replacement codepoint (`U+FFFD`) using the +/// ["maximal subpart" strategy](http://www.unicode.org/review/pr-121.html). +/// +/// This iterator is created by the +/// [`chars`](struct.BStr.html#method.chars) method on +/// [`BStr`](struct.BStr.html). +#[derive(Clone, Debug)] +pub struct Chars<'a> { + bs: &'a BStr, +} + +impl<'a> Chars<'a> { + pub(crate) fn new(bs: &'a BStr) -> Chars<'a> { + Chars { bs } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::BStr; + /// + /// let mut chars = BStr::new("abc").chars(); + /// + /// assert_eq!("abc", chars.as_bstr()); + /// chars.next(); + /// assert_eq!("bc", chars.as_bstr()); + /// chars.next(); + /// chars.next(); + /// assert_eq!("", chars.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for Chars<'a> { + type Item = char; + + #[inline] + fn next(&mut self) -> Option { + let (ch, size) = decode_lossy(self.bs.as_bytes()); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + Some(ch) + } +} + +impl<'a> DoubleEndedIterator for Chars<'a> { + #[inline] + fn next_back(&mut self) -> Option { + let (ch, size) = decode_last_lossy(self.bs.as_bytes()); + if size == 0 { + return None; + } + self.bs = &self.bs[..self.bs.len()-size]; + Some(ch) + } +} + +/// An iterator over Unicode scalar values in a byte string and their +/// byte index positions. +/// +/// When invalid UTF-8 byte sequences are found, they are substituted with the +/// Unicode replacement codepoint (`U+FFFD`) using the +/// ["maximal subpart" strategy](http://www.unicode.org/review/pr-121.html). +/// +/// Note that this is slightly different from the `CharIndices` iterator +/// provided by the standard library. Aside from working on possibly invalid +/// UTF-8, this iterator provides both the corresponding starting and ending +/// byte indices of each codepoint yielded. The ending position is necessary to +/// slice the original byte string when invalid UTF-8 bytes are converted into +/// a Unicode replacement codepoint, since a single replacement codepoint can +/// substitute anywhere from 1 to 3 invalid bytes (inclusive). +/// +/// This iterator is created by the +/// [`char_indices`](struct.BStr.html#method.char_indices) method on +/// [`BStr`](struct.BStr.html). +#[derive(Clone, Debug)] +pub struct CharIndices<'a> { + bs: &'a BStr, + forward_index: usize, + reverse_index: usize, +} + +impl<'a> CharIndices<'a> { + pub(crate) fn new(bs: &'a BStr) -> CharIndices<'a> { + CharIndices { bs: bs, forward_index: 0, reverse_index: bs.len() } + } + + /// View the underlying data as a subslice of the original data. + /// + /// The slice returned has the same lifetime as the original slice, and so + /// the iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// ``` + /// use bstr::B; + /// + /// let mut it = B("abc").char_indices(); + /// + /// assert_eq!("abc", it.as_bstr()); + /// it.next(); + /// assert_eq!("bc", it.as_bstr()); + /// it.next(); + /// it.next(); + /// assert_eq!("", it.as_bstr()); + /// ``` + #[inline] + pub fn as_bstr(&self) -> &'a BStr { + self.bs + } +} + +impl<'a> Iterator for CharIndices<'a> { + type Item = (usize, usize, char); + + #[inline] + fn next(&mut self) -> Option<(usize, usize, char)> { + let index = self.forward_index; + let (ch, size) = decode_lossy(self.bs.as_bytes()); + if size == 0 { + return None; + } + self.bs = &self.bs[size..]; + self.forward_index += size; + Some((index, index + size, ch)) + } +} + +impl<'a> DoubleEndedIterator for CharIndices<'a> { + #[inline] + fn next_back(&mut self) -> Option<(usize, usize, char)> { + let (ch, size) = decode_last_lossy(self.bs.as_bytes()); + if size == 0 { + return None; + } + self.bs = &self.bs[..self.bs.len()-size]; + self.reverse_index -= size; + Some((self.reverse_index, self.reverse_index + size, ch)) + } +} + +/// An error that occurs when UTF-8 decoding fails. +/// +/// This error occurs when attempting to convert a non-UTF-8 byte +/// string to a Rust string that must be valid UTF-8. For example, +/// [`to_str`](struct.BStr.html#method.to_str) is one such method. +/// +/// # Example +/// +/// This example shows what happens when a given byte sequence is invalid, +/// but ends with a sequence that is a possible prefix of valid UTF-8. +/// +/// ``` +/// use bstr::B; +/// +/// let s = B(b"foobar\xF1\x80\x80"); +/// let err = s.to_str().unwrap_err(); +/// assert_eq!(err.valid_up_to(), 6); +/// assert_eq!(err.error_len(), None); +/// ``` +/// +/// This example shows what happens when a given byte sequence contains +/// invalid UTF-8. +/// +/// ``` +/// use bstr::B; +/// +/// let s = B(b"foobar\xF1\x80\x80quux"); +/// let err = s.to_str().unwrap_err(); +/// assert_eq!(err.valid_up_to(), 6); +/// // The error length reports the maximum number of bytes that correspond to +/// // a valid prefix of a UTF-8 encoded codepoint. +/// assert_eq!(err.error_len(), Some(3)); +/// +/// // In contrast to the above which contains a single invalid prefix, +/// // consider the case of multiple individal bytes that are never valid +/// // prefixes. Note how the value of error_len changes! +/// let s = B(b"foobar\xFF\xFFquux"); +/// let err = s.to_str().unwrap_err(); +/// assert_eq!(err.valid_up_to(), 6); +/// assert_eq!(err.error_len(), Some(1)); +/// +/// // The fact that it's an invalid prefix does not change error_len even +/// // when it immediately precedes the end of the string. +/// let s = B(b"foobar\xFF"); +/// let err = s.to_str().unwrap_err(); +/// assert_eq!(err.valid_up_to(), 6); +/// assert_eq!(err.error_len(), Some(1)); +/// ``` +#[derive(Debug, Eq, PartialEq)] +pub struct Utf8Error { + valid_up_to: usize, + error_len: Option, +} + +impl Utf8Error { + /// Returns the byte index of the position immediately following the last + /// valid UTF-8 byte. + /// + /// # Example + /// + /// This examples shows how `valid_up_to` can be used to retrieve a + /// possibly empty prefix that is guaranteed to be valid UTF-8: + /// + /// ``` + /// use bstr::B; + /// + /// let s = B(b"foobar\xF1\x80\x80quux"); + /// let err = s.to_str().unwrap_err(); + /// + /// // This is guaranteed to never panic. + /// let string = s[..err.valid_up_to()].to_str().unwrap(); + /// assert_eq!(string, "foobar"); + /// ``` + #[inline] + pub fn valid_up_to(&self) -> usize { + self.valid_up_to + } + + /// Returns the total number of invalid UTF-8 bytes immediately following + /// the position returned by `valid_up_to`. This value is always at least + /// `1`, but can be up to `3` if bytes form a valid prefix of some UTF-8 + /// encoded codepoint. + /// + /// If the end of the original input was found before a valid UTF-8 encoded + /// codepoint could be completed, then this returns `None`. This is useful + /// when processing streams, where a `None` value signals that more input + /// might be needed. + #[inline] + pub fn error_len(&self) -> Option { + self.error_len + } +} + +#[cfg(feature = "std")] +impl error::Error for Utf8Error { + fn description(&self) -> &str { "invalid UTF-8" } +} + +impl fmt::Display for Utf8Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "invalid UTF-8 found at byte offset {}", self.valid_up_to) + } +} + +/// Returns OK if and only if the given slice is completely valid UTF-8. +/// +/// If the slice isn't valid UTF-8, then an error is returned that explains +/// the first location at which invalid UTF-89 was detected. +pub fn validate(slice: &[u8]) -> Result<(), Utf8Error> { + // The fast path for validating UTF-8. It steps through a UTF-8 automaton + // and uses a SIMD accelerated ASCII fast path on x86_64. If an error is + // detected, it backs up and runs the slower version of the UTF-8 automaton + // to determine correct error information. + fn fast(slice: &[u8]) -> Result<(), Utf8Error> { + let mut state = ACCEPT; + let mut i = 0; + + while i < slice.len() { + let b = slice[i]; + + // ASCII fast path. If we see two consecutive ASCII bytes, then try + // to validate as much ASCII as possible very quickly. + if state == ACCEPT + && b <= 0x7F + && slice.get(i+1).map_or(false, |&b| b <= 0x7F) + { + i += ascii::first_non_ascii_byte(&slice[i..]); + continue; + } + + state = step(state, b); + if state == REJECT { + return Err(find_valid_up_to(slice, i)); + } + i += 1; + } + if state != ACCEPT { + Err(find_valid_up_to(slice, slice.len())) + } else { + Ok(()) + } + } + + // Given the first position at which a UTF-8 sequence was determined to be + // invalid, return an error that correctly reports the position at which + // the last complete UTF-8 sequence ends. + #[inline(never)] + fn find_valid_up_to(slice: &[u8], rejected_at: usize) -> Utf8Error { + // In order to find the last valid byte, we need to back up an amount + // that guarantees every preceding byte is part of a valid UTF-8 + // code unit sequence. To do this, we simply locate the last leading + // byte that occurs before rejected_at. + let mut backup = rejected_at.saturating_sub(1); + while backup > 0 && !is_leading_utf8_byte(slice[backup]) { + backup -= 1; + } + let upto = cmp::min(slice.len(), rejected_at.saturating_add(1)); + let mut err = slow(&slice[backup..upto]).unwrap_err(); + err.valid_up_to += backup; + err + } + + // Like top-level UTF-8 decoding, except it correctly reports a UTF-8 error + // when an invalid sequence is found. This is split out from validate so + // that the fast path doesn't need to keep track of the position of the + // last valid UTF-8 byte. In particular, tracking this requires checking + // for an ACCEPT state on each byte, which degrades throughput pretty + // badly. + fn slow(slice: &[u8]) -> Result<(), Utf8Error> { + let mut state = ACCEPT; + let mut valid_up_to = 0; + for (i, &b) in slice.iter().enumerate() { + state = step(state, b); + if state == ACCEPT { + valid_up_to = i + 1; + } else if state == REJECT { + // Our error length must always be at least 1. + let error_len = Some(cmp::max(1, i - valid_up_to)); + return Err(Utf8Error { valid_up_to, error_len }); + } + } + if state != ACCEPT { + Err(Utf8Error { valid_up_to, error_len: None }) + } else { + Ok(()) + } + } + + // Advance to the next state given the current state and current byte. + fn step(state: usize, b: u8) -> usize { + let class = CLASSES[b as usize]; + // SAFETY: This is safe because 'class' is always <=11 and 'state' is + // always <=96. Therefore, the maximal index is 96+11 = 107, where + // STATES_FORWARD.len() = 108 such that every index is guaranteed to be + // valid by construction of the state machine and the byte equivalence + // classes. + unsafe { + *STATES_FORWARD.get_unchecked(state + class as usize) as usize + } + } + + fast(slice) +} + +/// UTF-8 decode a single Unicode scalar value from the beginning of a slice. +/// +/// When successful, the corresponding Unicode scalar value is returned along +/// with the number of bytes it was encoded with. The number of bytes consumed +/// for a successful decode is always between 1 and 4, inclusive. +/// +/// When unsuccessful, `None` is returned along with the number of bytes that +/// make up a maximal prefix of a valid UTF-8 code unit sequence. In this case, +/// the number of bytes consumed is always between 0 and 3, inclusive, where +/// 0 is only returned when `slice` is empty. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr::decode_utf8; +/// +/// // Decoding a valid codepoint. +/// let (ch, size) = decode_utf8(b"\xE2\x98\x83"); +/// assert_eq!(Some('☃'), ch); +/// assert_eq!(3, size); +/// +/// // Decoding an incomplete codepoint. +/// let (ch, size) = decode_utf8(b"\xE2\x98"); +/// assert_eq!(None, ch); +/// assert_eq!(2, size); +/// ``` +/// +/// This example shows how to iterate over all codepoints in UTF-8 encoded +/// bytes, while replacing invalid UTF-8 sequences with the replacement +/// codepoint: +/// +/// ``` +/// use bstr::decode_utf8; +/// +/// let mut bytes = &b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"[..]; +/// let mut chars = vec![]; +/// while !bytes.is_empty() { +/// let (ch, size) = decode_utf8(bytes); +/// bytes = &bytes[size..]; +/// chars.push(ch.unwrap_or('\u{FFFD}')); +/// } +/// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars); +/// ``` +#[inline] +pub fn decode>(slice: B) -> (Option, usize) { + let slice = slice.as_ref(); + match slice.get(0) { + None => return (None, 0), + Some(&b) if b <= 0x7F => return (Some(b as char), 1), + _ => {} + } + + let (mut state, mut cp, mut i) = (ACCEPT, 0, 0); + while i < slice.len() { + decode_step(&mut state, &mut cp, slice[i]); + i += 1; + + if state == ACCEPT { + // SAFETY: This is safe because `decode_step` guarantees that + // `cp` is a valid Unicode scalar value in an ACCEPT state. + let ch = unsafe { char::from_u32_unchecked(cp) }; + return (Some(ch), i); + } else if state == REJECT { + // At this point, we always want to advance at least one byte. + return (None, cmp::max(1, i.saturating_sub(1))); + } + } + (None, i) +} + +/// Lossily UTF-8 decode a single Unicode scalar value from the beginning of a +/// slice. +/// +/// When successful, the corresponding Unicode scalar value is returned along +/// with the number of bytes it was encoded with. The number of bytes consumed +/// for a successful decode is always between 1 and 4, inclusive. +/// +/// When unsuccessful, the Unicode replacement codepoint (`U+FFFD`) is returned +/// along with the number of bytes that make up a maximal prefix of a valid +/// UTF-8 code unit sequence. In this case, the number of bytes consumed is +/// always between 0 and 3, inclusive, where 0 is only returned when `slice` is +/// empty. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ```ignore +/// use bstr::decode_utf8_lossy; +/// +/// // Decoding a valid codepoint. +/// let (ch, size) = decode_utf8_lossy(b"\xE2\x98\x83"); +/// assert_eq!('☃', ch); +/// assert_eq!(3, size); +/// +/// // Decoding an incomplete codepoint. +/// let (ch, size) = decode_utf8_lossy(b"\xE2\x98"); +/// assert_eq!('\u{FFFD}', ch); +/// assert_eq!(2, size); +/// ``` +/// +/// This example shows how to iterate over all codepoints in UTF-8 encoded +/// bytes, while replacing invalid UTF-8 sequences with the replacement +/// codepoint: +/// +/// ```ignore +/// use bstr::decode_utf8_lossy; +/// +/// let mut bytes = &b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"[..]; +/// let mut chars = vec![]; +/// while !bytes.is_empty() { +/// let (ch, size) = decode_utf8_lossy(bytes); +/// bytes = &bytes[size..]; +/// chars.push(ch); +/// } +/// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars); +/// ``` +#[inline] +pub fn decode_lossy>(slice: B) -> (char, usize) { + match decode(slice) { + (Some(ch), size) => (ch, size), + (None, size) => ('\u{FFFD}', size), + } +} + +/// UTF-8 decode a single Unicode scalar value from the end of a slice. +/// +/// When successful, the corresponding Unicode scalar value is returned along +/// with the number of bytes it was encoded with. The number of bytes consumed +/// for a successful decode is always between 1 and 4, inclusive. +/// +/// When unsuccessful, `None` is returned along with the number of bytes that +/// make up a maximal prefix of a valid UTF-8 code unit sequence. In this case, +/// the number of bytes consumed is always between 0 and 3, inclusive, where +/// 0 is only returned when `slice` is empty. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bstr::decode_last_utf8; +/// +/// // Decoding a valid codepoint. +/// let (ch, size) = decode_last_utf8(b"\xE2\x98\x83"); +/// assert_eq!(Some('☃'), ch); +/// assert_eq!(3, size); +/// +/// // Decoding an incomplete codepoint. +/// let (ch, size) = decode_last_utf8(b"\xE2\x98"); +/// assert_eq!(None, ch); +/// assert_eq!(2, size); +/// ``` +/// +/// This example shows how to iterate over all codepoints in UTF-8 encoded +/// bytes in reverse, while replacing invalid UTF-8 sequences with the +/// replacement codepoint: +/// +/// ``` +/// use bstr::decode_last_utf8; +/// +/// let mut bytes = &b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"[..]; +/// let mut chars = vec![]; +/// while !bytes.is_empty() { +/// let (ch, size) = decode_last_utf8(bytes); +/// bytes = &bytes[..bytes.len()-size]; +/// chars.push(ch.unwrap_or('\u{FFFD}')); +/// } +/// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars); +/// ``` +#[inline] +pub fn decode_last>(slice: B) -> (Option, usize) { + // TODO: We could implement this by reversing the UTF-8 automaton, but for + // now, we do it the slow way by using the forward automaton. + + let slice = slice.as_ref(); + if slice.is_empty() { + return (None, 0); + } + let mut start = slice.len() - 1; + let limit = slice.len().saturating_sub(4); + while start > limit && !is_leading_utf8_byte(slice[start]) { + start -= 1; + } + let (ch, size) = decode(&slice[start..]); + // If we didn't consume all of the bytes, then that means there's at least + // one stray byte that never occurs in a valid code unit prefix, so we can + // advance by one byte. + if start + size != slice.len() { + (None, 1) + } else { + (ch, size) + } +} + +/// Lossily UTF-8 decode a single Unicode scalar value from the end of a slice. +/// +/// When successful, the corresponding Unicode scalar value is returned along +/// with the number of bytes it was encoded with. The number of bytes consumed +/// for a successful decode is always between 1 and 4, inclusive. +/// +/// When unsuccessful, the Unicode replacement codepoint (`U+FFFD`) is returned +/// along with the number of bytes that make up a maximal prefix of a valid +/// UTF-8 code unit sequence. In this case, the number of bytes consumed is +/// always between 0 and 3, inclusive, where 0 is only returned when `slice` is +/// empty. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ```ignore +/// use bstr::decode_last_utf8_lossy; +/// +/// // Decoding a valid codepoint. +/// let (ch, size) = decode_last_utf8_lossy(b"\xE2\x98\x83"); +/// assert_eq!('☃', ch); +/// assert_eq!(3, size); +/// +/// // Decoding an incomplete codepoint. +/// let (ch, size) = decode_last_utf8_lossy(b"\xE2\x98"); +/// assert_eq!('\u{FFFD}', ch); +/// assert_eq!(2, size); +/// ``` +/// +/// This example shows how to iterate over all codepoints in UTF-8 encoded +/// bytes in reverse, while replacing invalid UTF-8 sequences with the +/// replacement codepoint: +/// +/// ```ignore +/// use bstr::decode_last_utf8_lossy; +/// +/// let mut bytes = &b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61"[..]; +/// let mut chars = vec![]; +/// while !bytes.is_empty() { +/// let (ch, size) = decode_last_utf8_lossy(bytes); +/// bytes = &bytes[..bytes.len()-size]; +/// chars.push(ch); +/// } +/// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars); +/// ``` +#[inline] +pub fn decode_last_lossy>(slice: B) -> (char, usize) { + match decode_last(slice) { + (Some(ch), size) => (ch, size), + (None, size) => ('\u{FFFD}', size), + } +} + +#[inline] +pub fn decode_step(state: &mut usize, cp: &mut u32, b: u8) { + let class = CLASSES[b as usize]; + if *state == ACCEPT { + *cp = (0xFF >> class) & (b as u32); + } else { + *cp = (b as u32 & 0b111111) | (*cp << 6); + } + *state = STATES_FORWARD[*state + class as usize] as usize; +} + +fn is_leading_utf8_byte(b: u8) -> bool { + // In the ASCII case, the most significant bit is never set. The leading + // byte of a 2/3/4-byte sequence always has the top two most significant + // bigs set. + (b & 0b1100_0000) != 0b1000_0000 +} + +#[cfg(test)] +mod tests { + use std::char; + + use bstr::B; + use tests::LOSSY_TESTS; + use utf8::{self, Utf8Error}; + + fn utf8e(valid_up_to: usize) -> Utf8Error { + Utf8Error { valid_up_to, error_len: None } + } + + fn utf8e2(valid_up_to: usize, error_len: usize) -> Utf8Error { + Utf8Error { valid_up_to, error_len: Some(error_len) } + } + + #[test] + fn validate_all_codepoints() { + for i in 0..(0x10FFFF + 1) { + let cp = match char::from_u32(i) { + None => continue, + Some(cp) => cp, + }; + let mut buf = [0; 4]; + let s = cp.encode_utf8(&mut buf); + assert_eq!(Ok(()), utf8::validate(s.as_bytes())); + } + } + + #[test] + fn validate_multiple_codepoints() { + assert_eq!(Ok(()), utf8::validate(b"abc")); + assert_eq!(Ok(()), utf8::validate(b"a\xE2\x98\x83a")); + assert_eq!(Ok(()), utf8::validate(b"a\xF0\x9D\x9C\xB7a")); + assert_eq!(Ok(()), utf8::validate( + b"\xE2\x98\x83\xF0\x9D\x9C\xB7", + )); + assert_eq!(Ok(()), utf8::validate( + b"a\xE2\x98\x83a\xF0\x9D\x9C\xB7a", + )); + assert_eq!(Ok(()), utf8::validate( + b"\xEF\xBF\xBD\xE2\x98\x83\xEF\xBF\xBD", + )); + } + + #[test] + fn validate_errors() { + // single invalid byte + assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xFF")); + // single invalid byte after ASCII + assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xFF")); + // single invalid byte after 2 byte sequence + assert_eq!(Err(utf8e2(2, 1)), utf8::validate(b"\xCE\xB2\xFF")); + // single invalid byte after 3 byte sequence + assert_eq!(Err(utf8e2(3, 1)), utf8::validate(b"\xE2\x98\x83\xFF")); + // single invalid byte after 4 byte sequence + assert_eq!(Err(utf8e2(4, 1)), utf8::validate(b"\xF0\x9D\x9D\xB1\xFF")); + + // An invalid 2-byte sequence with a valid 1-byte prefix. + assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xCE\xF0")); + // An invalid 3-byte sequence with a valid 2-byte prefix. + assert_eq!(Err(utf8e2(0, 2)), utf8::validate(b"\xE2\x98\xF0")); + // An invalid 4-byte sequence with a valid 3-byte prefix. + assert_eq!(Err(utf8e2(0, 3)), utf8::validate(b"\xF0\x9D\x9D\xF0")); + + // An overlong sequence. Should be \xE2\x82\xAC, but we encode the + // same codepoint value in 4 bytes. This not only tests that we reject + // overlong sequences, but that we get valid_up_to correct. + assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xF0\x82\x82\xAC")); + assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xF0\x82\x82\xAC")); + assert_eq!(Err(utf8e2(3, 1)), utf8::validate( + b"\xE2\x98\x83\xF0\x82\x82\xAC", + )); + + // Check that encoding a surrogate codepoint using the UTF-8 scheme + // fails validation. + assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xED\xA0\x80")); + assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xED\xA0\x80")); + assert_eq!(Err(utf8e2(3, 1)), utf8::validate( + b"\xE2\x98\x83\xED\xA0\x80", + )); + + // Check that an incomplete 2-byte sequence fails. + assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xCEa")); + assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xCEa")); + assert_eq!(Err(utf8e2(3, 1)), utf8::validate( + b"\xE2\x98\x83\xCE\xE2\x98\x83", + )); + // Check that an incomplete 3-byte sequence fails. + assert_eq!(Err(utf8e2(0, 2)), utf8::validate(b"\xE2\x98a")); + assert_eq!(Err(utf8e2(1, 2)), utf8::validate(b"a\xE2\x98a")); + assert_eq!(Err(utf8e2(3, 2)), utf8::validate( + b"\xE2\x98\x83\xE2\x98\xE2\x98\x83", + )); + // Check that an incomplete 4-byte sequence fails. + assert_eq!(Err(utf8e2(0, 3)), utf8::validate(b"\xF0\x9D\x9Ca")); + assert_eq!(Err(utf8e2(1, 3)), utf8::validate(b"a\xF0\x9D\x9Ca")); + assert_eq!(Err(utf8e2(4, 3)), utf8::validate( + b"\xF0\x9D\x9C\xB1\xF0\x9D\x9C\xE2\x98\x83", + )); + assert_eq!(Err(utf8e2(6, 3)), utf8::validate( + b"foobar\xF1\x80\x80quux", + )); + + // Check that an incomplete (EOF) 2-byte sequence fails. + assert_eq!(Err(utf8e(0)), utf8::validate(b"\xCE")); + assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xCE")); + assert_eq!(Err(utf8e(3)), utf8::validate(b"\xE2\x98\x83\xCE")); + // Check that an incomplete (EOF) 3-byte sequence fails. + assert_eq!(Err(utf8e(0)), utf8::validate(b"\xE2\x98")); + assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xE2\x98")); + assert_eq!(Err(utf8e(3)), utf8::validate(b"\xE2\x98\x83\xE2\x98")); + // Check that an incomplete (EOF) 4-byte sequence fails. + assert_eq!(Err(utf8e(0)), utf8::validate(b"\xF0\x9D\x9C")); + assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xF0\x9D\x9C")); + assert_eq!(Err(utf8e(4)), utf8::validate( + b"\xF0\x9D\x9C\xB1\xF0\x9D\x9C", + )); + + // Test that we errors correct even after long valid sequences. This + // checks that our "backup" logic for detecting errors is correct. + assert_eq!(Err(utf8e2(8, 1)), utf8::validate( + b"\xe2\x98\x83\xce\xb2\xe3\x83\x84\xFF", + )); + } + + #[test] + fn decode_valid() { + fn d(mut s: &str) -> Vec { + let mut chars = vec![]; + while !s.is_empty() { + let (ch, size) = utf8::decode(s.as_bytes()); + s = &s[size..]; + chars.push(ch.unwrap()); + } + chars + } + + assert_eq!(vec!['☃'], d("☃")); + assert_eq!(vec!['☃', '☃'], d("☃☃")); + assert_eq!(vec!['α', 'β', 'γ', 'δ', 'ε'], d("αβγδε")); + assert_eq!(vec!['☃', '⛄', '⛇'], d("☃⛄⛇")); + assert_eq!(vec!['𝗮', '𝗯', '𝗰', '𝗱', '𝗲'], d("𝗮𝗯𝗰𝗱𝗲")); + } + + #[test] + fn decode_invalid() { + let (ch, size) = utf8::decode(b""); + assert_eq!(None, ch); + assert_eq!(0, size); + + let (ch, size) = utf8::decode(b"\xFF"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode(b"\xCE\xF0"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode(b"\xE2\x98\xF0"); + assert_eq!(None, ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode(b"\xF0\x9D\x9D"); + assert_eq!(None, ch); + assert_eq!(3, size); + + let (ch, size) = utf8::decode(b"\xF0\x9D\x9D\xF0"); + assert_eq!(None, ch); + assert_eq!(3, size); + + let (ch, size) = utf8::decode(b"\xF0\x82\x82\xAC"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode(b"\xED\xA0\x80"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode(b"\xCEa"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode(b"\xE2\x98a"); + assert_eq!(None, ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode(b"\xF0\x9D\x9Ca"); + assert_eq!(None, ch); + assert_eq!(3, size); + } + + #[test] + fn decode_lossy() { + let (ch, size) = utf8::decode_lossy(b""); + assert_eq!('\u{FFFD}', ch); + assert_eq!(0, size); + + let (ch, size) = utf8::decode_lossy(b"\xFF"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_lossy(b"\xCE\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_lossy(b"\xE2\x98\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_lossy(b"\xF0\x9D\x9D\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(3, size); + + let (ch, size) = utf8::decode_lossy(b"\xF0\x82\x82\xAC"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_lossy(b"\xED\xA0\x80"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_lossy(b"\xCEa"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_lossy(b"\xE2\x98a"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_lossy(b"\xF0\x9D\x9Ca"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(3, size); + } + + #[test] + fn decode_last_valid() { + fn d(mut s: &str) -> Vec { + let mut chars = vec![]; + while !s.is_empty() { + let (ch, size) = utf8::decode_last(s.as_bytes()); + s = &s[..s.len()-size]; + chars.push(ch.unwrap()); + } + chars + } + + assert_eq!(vec!['☃'], d("☃")); + assert_eq!(vec!['☃', '☃'], d("☃☃")); + assert_eq!(vec!['ε', 'δ', 'γ', 'β', 'α'], d("αβγδε")); + assert_eq!(vec!['⛇', '⛄', '☃'], d("☃⛄⛇")); + assert_eq!(vec!['𝗲', '𝗱', '𝗰', '𝗯', '𝗮'], d("𝗮𝗯𝗰𝗱𝗲")); + } + + #[test] + fn decode_last_invalid() { + let (ch, size) = utf8::decode_last(b""); + assert_eq!(None, ch); + assert_eq!(0, size); + + let (ch, size) = utf8::decode_last(b"\xFF"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xCE\xF0"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xCE"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xE2\x98\xF0"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xE2\x98"); + assert_eq!(None, ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_last(b"\xF0\x9D\x9D\xF0"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xF0\x9D\x9D"); + assert_eq!(None, ch); + assert_eq!(3, size); + + let (ch, size) = utf8::decode_last(b"\xF0\x82\x82\xAC"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xED\xA0\x80"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xED\xA0"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"\xED"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"a\xCE"); + assert_eq!(None, ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last(b"a\xE2\x98"); + assert_eq!(None, ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_last(b"a\xF0\x9D\x9C"); + assert_eq!(None, ch); + assert_eq!(3, size); + } + + #[test] + fn decode_last_lossy() { + let (ch, size) = utf8::decode_last_lossy(b""); + assert_eq!('\u{FFFD}', ch); + assert_eq!(0, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xFF"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xCE\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xCE"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xE2\x98\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xE2\x98"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xF0\x9D\x9D\xF0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xF0\x9D\x9D"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(3, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xF0\x82\x82\xAC"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xED\xA0\x80"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xED\xA0"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"\xED"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"a\xCE"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(1, size); + + let (ch, size) = utf8::decode_last_lossy(b"a\xE2\x98"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(2, size); + + let (ch, size) = utf8::decode_last_lossy(b"a\xF0\x9D\x9C"); + assert_eq!('\u{FFFD}', ch); + assert_eq!(3, size); + } + + #[test] + fn chars() { + for (i, &(expected, input)) in LOSSY_TESTS.iter().enumerate() { + let got: String = B(input).chars().collect(); + assert_eq!( + expected, got, + "chars(ith: {:?}, given: {:?})", i, input, + ); + let got: String = B(input) + .char_indices() + .map(|(_, _, ch)| ch) + .collect(); + assert_eq!( + expected, got, + "char_indices(ith: {:?}, given: {:?})", i, input, + ); + + let expected: String = expected.chars().rev().collect(); + + let got: String = B(input).chars().rev().collect(); + assert_eq!( + expected, got, + "chars.rev(ith: {:?}, given: {:?})", i, input, + ); + let got: String = B(input) + .char_indices() + .rev() + .map(|(_, _, ch)| ch) + .collect(); + assert_eq!( + expected, got, + "char_indices.rev(ith: {:?}, given: {:?})", i, input, + ); + } + } +} diff -Nru cargo-0.33.0/vendor/bytes/benches/bytes.rs cargo-0.35.0/vendor/bytes/benches/bytes.rs --- cargo-0.33.0/vendor/bytes/benches/bytes.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/benches/bytes.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,250 @@ +#![feature(test)] + +extern crate bytes; +extern crate test; + +use test::Bencher; +use bytes::{Bytes, BytesMut, BufMut}; + +#[bench] +fn alloc_small(b: &mut Bencher) { + b.iter(|| { + for _ in 0..1024 { + test::black_box(BytesMut::with_capacity(12)); + } + }) +} + +#[bench] +fn alloc_mid(b: &mut Bencher) { + b.iter(|| { + test::black_box(BytesMut::with_capacity(128)); + }) +} + +#[bench] +fn alloc_big(b: &mut Bencher) { + b.iter(|| { + test::black_box(BytesMut::with_capacity(4096)); + }) +} + +#[bench] +fn split_off_and_drop(b: &mut Bencher) { + b.iter(|| { + for _ in 0..1024 { + let v = vec![10; 200]; + let mut b = Bytes::from(v); + test::black_box(b.split_off(100)); + test::black_box(b); + } + }) +} + +#[bench] +fn deref_unique(b: &mut Bencher) { + let mut buf = BytesMut::with_capacity(4096); + buf.put(&[0u8; 1024][..]); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&buf[..]); + } + }) +} + +#[bench] +fn deref_unique_unroll(b: &mut Bencher) { + let mut buf = BytesMut::with_capacity(4096); + buf.put(&[0u8; 1024][..]); + + b.iter(|| { + for _ in 0..128 { + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + test::black_box(&buf[..]); + } + }) +} + +#[bench] +fn deref_shared(b: &mut Bencher) { + let mut buf = BytesMut::with_capacity(4096); + buf.put(&[0u8; 1024][..]); + let _b2 = buf.split_off(1024); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&buf[..]); + } + }) +} + +#[bench] +fn deref_inline(b: &mut Bencher) { + let mut buf = BytesMut::with_capacity(8); + buf.put(&[0u8; 8][..]); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&buf[..]); + } + }) +} + +#[bench] +fn deref_two(b: &mut Bencher) { + let mut buf1 = BytesMut::with_capacity(8); + buf1.put(&[0u8; 8][..]); + + let mut buf2 = BytesMut::with_capacity(4096); + buf2.put(&[0u8; 1024][..]); + + b.iter(|| { + for _ in 0..512 { + test::black_box(&buf1[..]); + test::black_box(&buf2[..]); + } + }) +} + +#[bench] +fn clone_inline(b: &mut Bencher) { + let bytes = Bytes::from_static(b"hello world"); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&bytes.clone()); + } + }) +} + +#[bench] +fn clone_static(b: &mut Bencher) { + let bytes = Bytes::from_static("hello world 1234567890 and have a good byte 0987654321".as_bytes()); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&bytes.clone()); + } + }) +} + +#[bench] +fn clone_arc(b: &mut Bencher) { + let bytes = Bytes::from("hello world 1234567890 and have a good byte 0987654321".as_bytes()); + + b.iter(|| { + for _ in 0..1024 { + test::black_box(&bytes.clone()); + } + }) +} + +#[bench] +fn alloc_write_split_to_mid(b: &mut Bencher) { + b.iter(|| { + let mut buf = BytesMut::with_capacity(128); + buf.put_slice(&[0u8; 64]); + test::black_box(buf.split_to(64)); + }) +} + +#[bench] +fn drain_write_drain(b: &mut Bencher) { + let data = [0u8; 128]; + + b.iter(|| { + let mut buf = BytesMut::with_capacity(1024); + let mut parts = Vec::with_capacity(8); + + for _ in 0..8 { + buf.put(&data[..]); + parts.push(buf.split_to(128)); + } + + test::black_box(parts); + }) +} + +#[bench] +fn fmt_write(b: &mut Bencher) { + use std::fmt::Write; + let mut buf = BytesMut::with_capacity(128); + let s = "foo bar baz quux lorem ipsum dolor et"; + + b.bytes = s.len() as u64; + b.iter(|| { + let _ = write!(buf, "{}", s); + test::black_box(&buf); + unsafe { buf.set_len(0); } + }) +} + +#[bench] +fn from_long_slice(b: &mut Bencher) { + let data = [0u8; 128]; + b.bytes = data.len() as u64; + b.iter(|| { + let buf = BytesMut::from(&data[..]); + test::black_box(buf); + }) +} + +#[bench] +fn slice_empty(b: &mut Bencher) { + b.iter(|| { + let b = Bytes::from(vec![17; 1024]).clone(); + for i in 0..1000 { + test::black_box(b.slice(i % 100, i % 100)); + } + }) +} + +#[bench] +fn slice_short_from_arc(b: &mut Bencher) { + b.iter(|| { + // `clone` is to convert to ARC + let b = Bytes::from(vec![17; 1024]).clone(); + for i in 0..1000 { + test::black_box(b.slice(1, 2 + i % 10)); + } + }) +} + +// Keep in sync with bytes.rs +#[cfg(target_pointer_width = "64")] +const INLINE_CAP: usize = 4 * 8 - 1; +#[cfg(target_pointer_width = "32")] +const INLINE_CAP: usize = 4 * 4 - 1; + +#[bench] +fn slice_avg_le_inline_from_arc(b: &mut Bencher) { + b.iter(|| { + // `clone` is to convert to ARC + let b = Bytes::from(vec![17; 1024]).clone(); + for i in 0..1000 { + // [1, INLINE_CAP] + let len = 1 + i % (INLINE_CAP - 1); + test::black_box(b.slice(i % 10, i % 10 + len)); + } + }) +} + +#[bench] +fn slice_large_le_inline_from_arc(b: &mut Bencher) { + b.iter(|| { + // `clone` is to convert to ARC + let b = Bytes::from(vec![17; 1024]).clone(); + for i in 0..1000 { + // [INLINE_CAP - 10, INLINE_CAP] + let len = INLINE_CAP - 9 + i % 10; + test::black_box(b.slice(i % 10, i % 10 + len)); + } + }) +} diff -Nru cargo-0.33.0/vendor/bytes/.cargo-checksum.json cargo-0.35.0/vendor/bytes/.cargo-checksum.json --- cargo-0.33.0/vendor/bytes/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/bytes/Cargo.toml cargo-0.35.0/vendor/bytes/Cargo.toml --- cargo-0.33.0/vendor/bytes/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,46 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "bytes" +version = "0.4.12" +authors = ["Carl Lerche "] +exclude = [".gitignore", ".travis.yml", "deploy.sh", "bench/**/*", "test/**/*"] +description = "Types and traits for working with bytes" +homepage = "https://github.com/carllerche/bytes" +documentation = "https://docs.rs/bytes/0.4.12/bytes" +readme = "README.md" +keywords = ["buffers", "zero-copy", "io"] +categories = ["network-programming", "data-structures"] +license = "MIT" +repository = "https://github.com/carllerche/bytes" +[package.metadata.docs.rs] +features = ["i128"] +[dependencies.byteorder] +version = "1.1.0" + +[dependencies.either] +version = "1.5" +optional = true +default-features = false + +[dependencies.iovec] +version = "0.1" + +[dependencies.serde] +version = "1.0" +optional = true +[dev-dependencies.serde_test] +version = "1.0" + +[features] +i128 = ["byteorder/i128"] diff -Nru cargo-0.33.0/vendor/bytes/CHANGELOG.md cargo-0.35.0/vendor/bytes/CHANGELOG.md --- cargo-0.33.0/vendor/bytes/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,86 @@ +# 0.4.12 (March 6, 2018) + +### Added +- Implement `FromIterator<&'a u8>` for `BytesMut`/`Bytes` (#244). +- Implement `Buf` for `VecDeque` (#249). + +# 0.4.11 (November 17, 2018) + +* Use raw pointers for potentially racy loads (#233). +* Implement `BufRead` for `buf::Reader` (#232). +* Documentation tweaks (#234). + +# 0.4.10 (September 4, 2018) + +* impl `Buf` and `BufMut` for `Either` (#225). +* Add `Bytes::slice_ref` (#208). + +# 0.4.9 (July 12, 2018) + +* Add 128 bit number support behind a feature flag (#209). +* Implement `IntoBuf` for `&mut [u8]` + +# 0.4.8 (May 25, 2018) + +* Fix panic in `BytesMut` `FromIterator` implementation. +* Bytes: Recycle space when reserving space in vec mode (#197). +* Bytes: Add resize fn (#203). + +# 0.4.7 (April 27, 2018) + +* Make `Buf` and `BufMut` usable as trait objects (#186). +* impl BorrowMut for BytesMut (#185). +* Improve accessor performance (#195). + +# 0.4.6 (Janary 8, 2018) + +* Implement FromIterator for Bytes/BytesMut (#148). +* Add `advance` fn to Bytes/BytesMut (#166). +* Add `unsplit` fn to `BytesMut` (#162, #173). +* Improvements to Bytes split fns (#92). + +# 0.4.5 (August 12, 2017) + +* Fix range bug in `Take::bytes` +* Misc performance improvements +* Add extra `PartialEq` implementations. +* Add `Bytes::with_capacity` +* Implement `AsMut[u8]` for `BytesMut` + +# 0.4.4 (May 26, 2017) + +* Add serde support behind feature flag +* Add `extend_from_slice` on `Bytes` and `BytesMut` +* Add `truncate` and `clear` on `Bytes` +* Misc additional std trait implementations +* Misc performance improvements + +# 0.4.3 (April 30, 2017) + +* Fix Vec::advance_mut bug +* Bump minimum Rust version to 1.15 +* Misc performance tweaks + +# 0.4.2 (April 5, 2017) + +* Misc performance tweaks +* Improved `Debug` implementation for `Bytes` +* Avoid some incorrect assert panics + +# 0.4.1 (March 15, 2017) + +* Expose `buf` module and have most types available from there vs. root. +* Implement `IntoBuf` for `T: Buf`. +* Add `FromBuf` and `Buf::collect`. +* Add iterator adapter for `Buf`. +* Add scatter/gather support to `Buf` and `BufMut`. +* Add `Buf::chain`. +* Reduce allocations on repeated calls to `BytesMut::reserve`. +* Implement `Debug` for more types. +* Remove `Source` in favor of `IntoBuf`. +* Implement `Extend` for `BytesMut`. + + +# 0.4.0 (February 24, 2017) + +* Initial release diff -Nru cargo-0.33.0/vendor/bytes/ci/before_deploy.ps1 cargo-0.35.0/vendor/bytes/ci/before_deploy.ps1 --- cargo-0.33.0/vendor/bytes/ci/before_deploy.ps1 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/ci/before_deploy.ps1 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,23 @@ +# This script takes care of packaging the build artifacts that will go in the +# release zipfile + +$SRC_DIR = $PWD.Path +$STAGE = [System.Guid]::NewGuid().ToString() + +Set-Location $ENV:Temp +New-Item -Type Directory -Name $STAGE +Set-Location $STAGE + +$ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip" + +# TODO Update this to package the right artifacts +Copy-Item "$SRC_DIR\target\$($Env:TARGET)\release\hello.exe" '.\' + +7z a "$ZIP" * + +Push-AppveyorArtifact "$ZIP" + +Remove-Item *.* -Force +Set-Location .. +Remove-Item $STAGE +Set-Location $SRC_DIR diff -Nru cargo-0.33.0/vendor/bytes/ci/before_deploy.sh cargo-0.35.0/vendor/bytes/ci/before_deploy.sh --- cargo-0.33.0/vendor/bytes/ci/before_deploy.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/ci/before_deploy.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,33 @@ +# This script takes care of building your crate and packaging it for release + +set -ex + +main() { + local src=$(pwd) \ + stage= + + case $TRAVIS_OS_NAME in + linux) + stage=$(mktemp -d) + ;; + osx) + stage=$(mktemp -d -t tmp) + ;; + esac + + test -f Cargo.lock || cargo generate-lockfile + + # TODO Update this to build the artifacts that matter to you + cross rustc --bin hello --target $TARGET --release -- -C lto + + # TODO Update this to package the right artifacts + cp target/$TARGET/release/hello $stage/ + + cd $stage + tar czf $src/$CRATE_NAME-$TRAVIS_TAG-$TARGET.tar.gz * + cd $src + + rm -rf $stage +} + +main diff -Nru cargo-0.33.0/vendor/bytes/ci/install.sh cargo-0.35.0/vendor/bytes/ci/install.sh --- cargo-0.33.0/vendor/bytes/ci/install.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/ci/install.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,31 @@ +set -ex + +main() { + curl https://sh.rustup.rs -sSf | \ + sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION + + local target= + if [ $TRAVIS_OS_NAME = linux ]; then + target=x86_64-unknown-linux-gnu + sort=sort + else + target=x86_64-apple-darwin + sort=gsort # for `sort --sort-version`, from brew's coreutils. + fi + + # This fetches latest stable release + local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \ + | cut -d/ -f3 \ + | grep -E '^v[0-9.]+$' \ + | $sort --version-sort \ + | tail -n1) + echo cross version: $tag + curl -LSfs https://japaric.github.io/trust/install.sh | \ + sh -s -- \ + --force \ + --git japaric/cross \ + --tag $tag \ + --target $target +} + +main diff -Nru cargo-0.33.0/vendor/bytes/ci/script.sh cargo-0.35.0/vendor/bytes/ci/script.sh --- cargo-0.33.0/vendor/bytes/ci/script.sh 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/ci/script.sh 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,18 @@ +# This script takes care of testing your crate + +set -ex + +main() { + cross build --target $TARGET $EXTRA_ARGS + + if [ ! -z $DISABLE_TESTS ]; then + return + fi + + cross test --target $TARGET $EXTRA_ARGS +} + +# we don't run the "test phase" when doing deploys +if [ -z $TRAVIS_TAG ]; then + main +fi diff -Nru cargo-0.33.0/vendor/bytes/ci/tsan cargo-0.35.0/vendor/bytes/ci/tsan --- cargo-0.33.0/vendor/bytes/ci/tsan 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/ci/tsan 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,28 @@ +# TSAN suppressions file for `bytes` + +# TSAN does not understand fences and `Arc::drop` is implemented using a fence. +# This causes many false positives. +race:Arc*drop +race:arc*Weak*drop + +# `std` mpsc is not used in any Bytes code base. This race is triggered by some +# rust runtime logic. +race:std*mpsc_queue + +# Some test runtime races. Allocation should be race free +race:alloc::alloc + +# Not sure why this is warning, but it is in the test harness and not the library. +race:TestEvent*clone +race:test::run_tests_console::*closure + +# Probably more fences in std. +race:__call_tls_dtors + +# `is_inline_or_static` is explicitly called concurrently without synchronization. +# The safety explanation can be found in a comment. +race:Inner::is_inline_or_static + +# This ignores a false positive caused by `thread::park()`/`thread::unpark()`. +# See: https://github.com/rust-lang/rust/pull/54806#issuecomment-436193353 +race:pthread_cond_destroy diff -Nru cargo-0.33.0/vendor/bytes/LICENSE cargo-0.35.0/vendor/bytes/LICENSE --- cargo-0.33.0/vendor/bytes/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/LICENSE 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,25 @@ +Copyright (c) 2018 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff -Nru cargo-0.33.0/vendor/bytes/README.md cargo-0.35.0/vendor/bytes/README.md --- cargo-0.33.0/vendor/bytes/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,45 @@ +# Bytes + +A utility library for working with bytes. + +[![Crates.io](https://img.shields.io/crates/v/bytes.svg?maxAge=2592000)](https://crates.io/crates/bytes) +[![Build Status](https://travis-ci.org/carllerche/bytes.svg?branch=master)](https://travis-ci.org/carllerche/bytes) + +[Documentation](https://docs.rs/bytes/0.4.12/bytes/) + +## Usage + +To use `bytes`, first add this to your `Cargo.toml`: + +```toml +[dependencies] +bytes = "0.4.12" +``` + +Next, add this to your crate: + +```rust +extern crate bytes; + +use bytes::{Bytes, BytesMut, Buf, BufMut}; +``` + +## Serde support + +Serde support is optional and disabled by default. To enable use the feature `serde`. + +```toml +[dependencies] +bytes = { version = "0.4.12", features = ["serde"] } +``` + +## License + +This project is licensed under the [MIT license](LICENSE). + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `bytes` by you, shall be licensed as MIT, without any additional +terms or conditions. + diff -Nru cargo-0.33.0/vendor/bytes/src/buf/buf_mut.rs cargo-0.35.0/vendor/bytes/src/buf/buf_mut.rs --- cargo-0.33.0/vendor/bytes/src/buf/buf_mut.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/buf_mut.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1167 @@ +use super::{IntoBuf, Writer}; +use byteorder::{LittleEndian, ByteOrder, BigEndian}; +use iovec::IoVec; + +use std::{cmp, io, ptr, usize}; + +/// A trait for values that provide sequential write access to bytes. +/// +/// Write bytes to a buffer +/// +/// A buffer stores bytes in memory such that write operations are infallible. +/// The underlying storage may or may not be in contiguous memory. A `BufMut` +/// value is a cursor into the buffer. Writing to `BufMut` advances the cursor +/// position. +/// +/// The simplest `BufMut` is a `Vec`. +/// +/// ``` +/// use bytes::BufMut; +/// +/// let mut buf = vec![]; +/// +/// buf.put("hello world"); +/// +/// assert_eq!(buf, b"hello world"); +/// ``` +pub trait BufMut { + /// Returns the number of bytes that can be written from the current + /// position until the end of the buffer is reached. + /// + /// This value is greater than or equal to the length of the slice returned + /// by `bytes_mut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Cursor; + /// + /// let mut dst = [0; 10]; + /// let mut buf = Cursor::new(&mut dst[..]); + /// + /// assert_eq!(10, buf.remaining_mut()); + /// buf.put("hello"); + /// + /// assert_eq!(5, buf.remaining_mut()); + /// ``` + /// + /// # Implementer notes + /// + /// Implementations of `remaining_mut` should ensure that the return value + /// does not change unless a call is made to `advance_mut` or any other + /// function that is documented to change the `BufMut`'s current position. + fn remaining_mut(&self) -> usize; + + /// Advance the internal cursor of the BufMut + /// + /// The next call to `bytes_mut` will return a slice starting `cnt` bytes + /// further into the underlying buffer. + /// + /// This function is unsafe because there is no guarantee that the bytes + /// being advanced past have been initialized. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = Vec::with_capacity(16); + /// + /// unsafe { + /// buf.bytes_mut()[0] = b'h'; + /// buf.bytes_mut()[1] = b'e'; + /// + /// buf.advance_mut(2); + /// + /// buf.bytes_mut()[0] = b'l'; + /// buf.bytes_mut()[1..3].copy_from_slice(b"lo"); + /// + /// buf.advance_mut(3); + /// } + /// + /// assert_eq!(5, buf.len()); + /// assert_eq!(buf, b"hello"); + /// ``` + /// + /// # Panics + /// + /// This function **may** panic if `cnt > self.remaining_mut()`. + /// + /// # Implementer notes + /// + /// It is recommended for implementations of `advance_mut` to panic if + /// `cnt > self.remaining_mut()`. If the implementation does not panic, + /// the call must behave as if `cnt == self.remaining_mut()`. + /// + /// A call with `cnt == 0` should never panic and be a no-op. + unsafe fn advance_mut(&mut self, cnt: usize); + + /// Returns true if there is space in `self` for more bytes. + /// + /// This is equivalent to `self.remaining_mut() != 0`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Cursor; + /// + /// let mut dst = [0; 5]; + /// let mut buf = Cursor::new(&mut dst); + /// + /// assert!(buf.has_remaining_mut()); + /// + /// buf.put("hello"); + /// + /// assert!(!buf.has_remaining_mut()); + /// ``` + fn has_remaining_mut(&self) -> bool { + self.remaining_mut() > 0 + } + + /// Returns a mutable slice starting at the current BufMut position and of + /// length between 0 and `BufMut::remaining_mut()`. Note that this *can* be shorter than the + /// whole remainder of the buffer (this allows non-continuous implementation). + /// + /// This is a lower level function. Most operations are done with other + /// functions. + /// + /// The returned byte slice may represent uninitialized memory. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = Vec::with_capacity(16); + /// + /// unsafe { + /// buf.bytes_mut()[0] = b'h'; + /// buf.bytes_mut()[1] = b'e'; + /// + /// buf.advance_mut(2); + /// + /// buf.bytes_mut()[0] = b'l'; + /// buf.bytes_mut()[1..3].copy_from_slice(b"lo"); + /// + /// buf.advance_mut(3); + /// } + /// + /// assert_eq!(5, buf.len()); + /// assert_eq!(buf, b"hello"); + /// ``` + /// + /// # Implementer notes + /// + /// This function should never panic. `bytes_mut` should return an empty + /// slice **if and only if** `remaining_mut` returns 0. In other words, + /// `bytes_mut` returning an empty slice implies that `remaining_mut` will + /// return 0 and `remaining_mut` returning 0 implies that `bytes_mut` will + /// return an empty slice. + unsafe fn bytes_mut(&mut self) -> &mut [u8]; + + /// Fills `dst` with potentially multiple mutable slices starting at `self`'s + /// current position. + /// + /// If the `BufMut` is backed by disjoint slices of bytes, `bytes_vec_mut` + /// enables fetching more than one slice at once. `dst` is a slice of + /// mutable `IoVec` references, enabling the slice to be directly used with + /// [`readv`] without any further conversion. The sum of the lengths of all + /// the buffers in `dst` will be less than or equal to + /// `Buf::remaining_mut()`. + /// + /// The entries in `dst` will be overwritten, but the data **contained** by + /// the slices **will not** be modified. If `bytes_vec_mut` does not fill every + /// entry in `dst`, then `dst` is guaranteed to contain all remaining slices + /// in `self. + /// + /// This is a lower level function. Most operations are done with other + /// functions. + /// + /// # Implementer notes + /// + /// This function should never panic. Once the end of the buffer is reached, + /// i.e., `BufMut::remaining_mut` returns 0, calls to `bytes_vec_mut` must + /// return 0 without mutating `dst`. + /// + /// Implementations should also take care to properly handle being called + /// with `dst` being a zero length slice. + /// + /// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html + unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { + if dst.is_empty() { + return 0; + } + + if self.has_remaining_mut() { + dst[0] = self.bytes_mut().into(); + 1 + } else { + 0 + } + } + + /// Transfer bytes into `self` from `src` and advance the cursor by the + /// number of bytes written. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// + /// buf.put(b'h'); + /// buf.put(&b"ello"[..]); + /// buf.put(" world"); + /// + /// assert_eq!(buf, b"hello world"); + /// ``` + /// + /// # Panics + /// + /// Panics if `self` does not have enough capacity to contain `src`. + fn put(&mut self, src: T) where Self: Sized { + use super::Buf; + + let mut src = src.into_buf(); + + assert!(self.remaining_mut() >= src.remaining()); + + while src.has_remaining() { + let l; + + unsafe { + let s = src.bytes(); + let d = self.bytes_mut(); + l = cmp::min(s.len(), d.len()); + + ptr::copy_nonoverlapping( + s.as_ptr(), + d.as_mut_ptr(), + l); + } + + src.advance(l); + unsafe { self.advance_mut(l); } + } + } + + /// Transfer bytes into `self` from `src` and advance the cursor by the + /// number of bytes written. + /// + /// `self` must have enough remaining capacity to contain all of `src`. + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Cursor; + /// + /// let mut dst = [0; 6]; + /// + /// { + /// let mut buf = Cursor::new(&mut dst); + /// buf.put_slice(b"hello"); + /// + /// assert_eq!(1, buf.remaining_mut()); + /// } + /// + /// assert_eq!(b"hello\0", &dst); + /// ``` + fn put_slice(&mut self, src: &[u8]) { + let mut off = 0; + + assert!(self.remaining_mut() >= src.len(), "buffer overflow"); + + while off < src.len() { + let cnt; + + unsafe { + let dst = self.bytes_mut(); + cnt = cmp::min(dst.len(), src.len() - off); + + ptr::copy_nonoverlapping( + src[off..].as_ptr(), + dst.as_mut_ptr(), + cnt); + + off += cnt; + + } + + unsafe { self.advance_mut(cnt); } + } + } + + /// Writes an unsigned 8 bit integer to `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u8(0x01); + /// assert_eq!(buf, b"\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u8(&mut self, n: u8) { + let src = [n]; + self.put_slice(&src); + } + + /// Writes a signed 8 bit integer to `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i8(0x01); + /// assert_eq!(buf, b"\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i8(&mut self, n: i8) { + let src = [n as u8]; + self.put_slice(&src) + } + + #[doc(hidden)] + #[deprecated(note="use put_u16_be or put_u16_le")] + fn put_u16(&mut self, n: u16) where Self: Sized { + let mut buf = [0; 2]; + T::write_u16(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 16 bit integer to `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u16_be(0x0809); + /// assert_eq!(buf, b"\x08\x09"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u16_be(&mut self, n: u16) { + let mut buf = [0; 2]; + BigEndian::write_u16(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 16 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u16_le(0x0809); + /// assert_eq!(buf, b"\x09\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u16_le(&mut self, n: u16) { + let mut buf = [0; 2]; + LittleEndian::write_u16(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_i16_be or put_i16_le")] + fn put_i16(&mut self, n: i16) where Self: Sized { + let mut buf = [0; 2]; + T::write_i16(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 16 bit integer to `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i16_be(0x0809); + /// assert_eq!(buf, b"\x08\x09"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i16_be(&mut self, n: i16) { + let mut buf = [0; 2]; + BigEndian::write_i16(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 16 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i16_le(0x0809); + /// assert_eq!(buf, b"\x09\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i16_le(&mut self, n: i16) { + let mut buf = [0; 2]; + LittleEndian::write_i16(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_u32_be or put_u32_le")] + fn put_u32(&mut self, n: u32) where Self: Sized { + let mut buf = [0; 4]; + T::write_u32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 32 bit integer to `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u32_be(0x0809A0A1); + /// assert_eq!(buf, b"\x08\x09\xA0\xA1"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u32_be(&mut self, n: u32) { + let mut buf = [0; 4]; + BigEndian::write_u32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 32 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u32_le(0x0809A0A1); + /// assert_eq!(buf, b"\xA1\xA0\x09\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u32_le(&mut self, n: u32) { + let mut buf = [0; 4]; + LittleEndian::write_u32(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_i32_be or put_i32_le")] + fn put_i32(&mut self, n: i32) where Self: Sized { + let mut buf = [0; 4]; + T::write_i32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 32 bit integer to `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i32_be(0x0809A0A1); + /// assert_eq!(buf, b"\x08\x09\xA0\xA1"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i32_be(&mut self, n: i32) { + let mut buf = [0; 4]; + BigEndian::write_i32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 32 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i32_le(0x0809A0A1); + /// assert_eq!(buf, b"\xA1\xA0\x09\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i32_le(&mut self, n: i32) { + let mut buf = [0; 4]; + LittleEndian::write_i32(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_u64_be or put_u64_le")] + fn put_u64(&mut self, n: u64) where Self: Sized { + let mut buf = [0; 8]; + T::write_u64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 64 bit integer to `self` in the big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u64_be(0x0102030405060708); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u64_be(&mut self, n: u64) { + let mut buf = [0; 8]; + BigEndian::write_u64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 64 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u64_le(0x0102030405060708); + /// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_u64_le(&mut self, n: u64) { + let mut buf = [0; 8]; + LittleEndian::write_u64(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_i64_be or put_i64_le")] + fn put_i64(&mut self, n: i64) where Self: Sized { + let mut buf = [0; 8]; + T::write_i64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 64 bit integer to `self` in the big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i64_be(0x0102030405060708); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i64_be(&mut self, n: i64) { + let mut buf = [0; 8]; + BigEndian::write_i64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 64 bit integer to `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i64_le(0x0102030405060708); + /// assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_i64_le(&mut self, n: i64) { + let mut buf = [0; 8]; + LittleEndian::write_i64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 128 bit integer to `self` in the big-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u128_be(0x01020304050607080910111213141516); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + #[cfg(feature = "i128")] + fn put_u128_be(&mut self, n: u128) { + let mut buf = [0; 16]; + BigEndian::write_u128(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an unsigned 128 bit integer to `self` in little-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_u128_le(0x01020304050607080910111213141516); + /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + #[cfg(feature = "i128")] + fn put_u128_le(&mut self, n: u128) { + let mut buf = [0; 16]; + LittleEndian::write_u128(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 128 bit integer to `self` in the big-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i128_be(0x01020304050607080910111213141516); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + #[cfg(feature = "i128")] + fn put_i128_be(&mut self, n: i128) { + let mut buf = [0; 16]; + BigEndian::write_i128(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes a signed 128 bit integer to `self` in little-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_i128_le(0x01020304050607080910111213141516); + /// assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + #[cfg(feature = "i128")] + fn put_i128_le(&mut self, n: i128) { + let mut buf = [0; 16]; + LittleEndian::write_i128(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_uint_be or put_uint_le")] + fn put_uint(&mut self, n: u64, nbytes: usize) where Self: Sized { + let mut buf = [0; 8]; + T::write_uint(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + /// Writes an unsigned n-byte integer to `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_uint_be(0x010203, 3); + /// assert_eq!(buf, b"\x01\x02\x03"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_uint_be(&mut self, n: u64, nbytes: usize) { + let mut buf = [0; 8]; + BigEndian::write_uint(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + /// Writes an unsigned n-byte integer to `self` in the little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_uint_le(0x010203, 3); + /// assert_eq!(buf, b"\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_uint_le(&mut self, n: u64, nbytes: usize) { + let mut buf = [0; 8]; + LittleEndian::write_uint(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + #[doc(hidden)] + #[deprecated(note="use put_int_be or put_int_le")] + fn put_int(&mut self, n: i64, nbytes: usize) where Self: Sized { + let mut buf = [0; 8]; + T::write_int(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + /// Writes a signed n-byte integer to `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_int_be(0x010203, 3); + /// assert_eq!(buf, b"\x01\x02\x03"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_int_be(&mut self, n: i64, nbytes: usize) { + let mut buf = [0; 8]; + BigEndian::write_int(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + /// Writes a signed n-byte integer to `self` in little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_int_le(0x010203, 3); + /// assert_eq!(buf, b"\x03\x02\x01"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_int_le(&mut self, n: i64, nbytes: usize) { + let mut buf = [0; 8]; + LittleEndian::write_int(&mut buf, n, nbytes); + self.put_slice(&buf[0..nbytes]) + } + + #[doc(hidden)] + #[deprecated(note="use put_f32_be or put_f32_le")] + fn put_f32(&mut self, n: f32) where Self: Sized { + let mut buf = [0; 4]; + T::write_f32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an IEEE754 single-precision (4 bytes) floating point number to + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_f32_be(1.2f32); + /// assert_eq!(buf, b"\x3F\x99\x99\x9A"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_f32_be(&mut self, n: f32) { + let mut buf = [0; 4]; + BigEndian::write_f32(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an IEEE754 single-precision (4 bytes) floating point number to + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_f32_le(1.2f32); + /// assert_eq!(buf, b"\x9A\x99\x99\x3F"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_f32_le(&mut self, n: f32) { + let mut buf = [0; 4]; + LittleEndian::write_f32(&mut buf, n); + self.put_slice(&buf) + } + + #[doc(hidden)] + #[deprecated(note="use put_f64_be or put_f64_le")] + fn put_f64(&mut self, n: f64) where Self: Sized { + let mut buf = [0; 8]; + T::write_f64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an IEEE754 double-precision (8 bytes) floating point number to + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_f64_be(1.2f64); + /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_f64_be(&mut self, n: f64) { + let mut buf = [0; 8]; + BigEndian::write_f64(&mut buf, n); + self.put_slice(&buf) + } + + /// Writes an IEEE754 double-precision (8 bytes) floating point number to + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// buf.put_f64_le(1.2f64); + /// assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. + fn put_f64_le(&mut self, n: f64) { + let mut buf = [0; 8]; + LittleEndian::write_f64(&mut buf, n); + self.put_slice(&buf) + } + + /// Creates a "by reference" adaptor for this instance of `BufMut`. + /// + /// The returned adapter also implements `BufMut` and will simply borrow + /// `self`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io; + /// + /// let mut buf = vec![]; + /// + /// { + /// let mut reference = buf.by_ref(); + /// + /// // Adapt reference to `std::io::Write`. + /// let mut writer = reference.writer(); + /// + /// // Use the buffer as a writter + /// io::Write::write(&mut writer, &b"hello world"[..]).unwrap(); + /// } // drop our &mut reference so that we can use `buf` again + /// + /// assert_eq!(buf, &b"hello world"[..]); + /// ``` + fn by_ref(&mut self) -> &mut Self where Self: Sized { + self + } + + /// Creates an adaptor which implements the `Write` trait for `self`. + /// + /// This function returns a new value which implements `Write` by adapting + /// the `Write` trait functions to the `BufMut` trait functions. Given that + /// `BufMut` operations are infallible, none of the `Write` functions will + /// return with `Err`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Write; + /// + /// let mut buf = vec![].writer(); + /// + /// let num = buf.write(&b"hello world"[..]).unwrap(); + /// assert_eq!(11, num); + /// + /// let buf = buf.into_inner(); + /// + /// assert_eq!(*buf, b"hello world"[..]); + /// ``` + fn writer(self) -> Writer where Self: Sized { + super::writer::new(self) + } +} + +impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T { + fn remaining_mut(&self) -> usize { + (**self).remaining_mut() + } + + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + (**self).bytes_mut() + } + + unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize { + (**self).bytes_vec_mut(dst) + } + + unsafe fn advance_mut(&mut self, cnt: usize) { + (**self).advance_mut(cnt) + } +} + +impl BufMut for Box { + fn remaining_mut(&self) -> usize { + (**self).remaining_mut() + } + + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + (**self).bytes_mut() + } + + unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize { + (**self).bytes_vec_mut(dst) + } + + unsafe fn advance_mut(&mut self, cnt: usize) { + (**self).advance_mut(cnt) + } +} + +impl + AsRef<[u8]>> BufMut for io::Cursor { + fn remaining_mut(&self) -> usize { + use Buf; + self.remaining() + } + + /// Advance the internal cursor of the BufMut + unsafe fn advance_mut(&mut self, cnt: usize) { + use Buf; + self.advance(cnt); + } + + /// Returns a mutable slice starting at the current BufMut position and of + /// length between 0 and `BufMut::remaining()`. + /// + /// The returned byte slice may represent uninitialized memory. + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + let len = self.get_ref().as_ref().len(); + let pos = self.position() as usize; + + if pos >= len { + return Default::default(); + } + + &mut (self.get_mut().as_mut())[pos..] + } +} + +impl BufMut for Vec { + #[inline] + fn remaining_mut(&self) -> usize { + usize::MAX - self.len() + } + + #[inline] + unsafe fn advance_mut(&mut self, cnt: usize) { + let len = self.len(); + let remaining = self.capacity() - len; + if cnt > remaining { + // Reserve additional capacity, and ensure that the total length + // will not overflow usize. + self.reserve(cnt); + } + + self.set_len(len + cnt); + } + + #[inline] + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + use std::slice; + + if self.capacity() == self.len() { + self.reserve(64); // Grow the vec + } + + let cap = self.capacity(); + let len = self.len(); + + let ptr = self.as_mut_ptr(); + &mut slice::from_raw_parts_mut(ptr, cap)[len..] + } +} + +// The existance of this function makes the compiler catch if the BufMut +// trait is "object-safe" or not. +fn _assert_trait_object(_b: &BufMut) {} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/buf.rs cargo-0.35.0/vendor/bytes/src/buf/buf.rs --- cargo-0.33.0/vendor/bytes/src/buf/buf.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/buf.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1154 @@ +use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain}; +use byteorder::{BigEndian, ByteOrder, LittleEndian}; +use iovec::IoVec; + +use std::{cmp, io, ptr}; + +macro_rules! buf_get_impl { + ($this:ident, $size:expr, $conv:path) => ({ + // try to convert directly from the bytes + let ret = { + // this Option trick is to avoid keeping a borrow on self + // when advance() is called (mut borrow) and to call bytes() only once + if let Some(src) = $this.bytes().get(..($size)) { + Some($conv(src)) + } else { + None + } + }; + if let Some(ret) = ret { + // if the direct convertion was possible, advance and return + $this.advance($size); + return ret; + } else { + // if not we copy the bytes in a temp buffer then convert + let mut buf = [0; ($size)]; + $this.copy_to_slice(&mut buf); // (do the advance) + return $conv(&buf); + } + }); + ($this:ident, $buf_size:expr, $conv:path, $len_to_read:expr) => ({ + // The same trick as above does not improve the best case speed. + // It seems to be linked to the way the method is optimised by the compiler + let mut buf = [0; ($buf_size)]; + $this.copy_to_slice(&mut buf[..($len_to_read)]); + return $conv(&buf[..($len_to_read)], $len_to_read); + }); +} + +/// Read bytes from a buffer. +/// +/// A buffer stores bytes in memory such that read operations are infallible. +/// The underlying storage may or may not be in contiguous memory. A `Buf` value +/// is a cursor into the buffer. Reading from `Buf` advances the cursor +/// position. It can be thought of as an efficient `Iterator` for collections of +/// bytes. +/// +/// The simplest `Buf` is a `Cursor` wrapping a `[u8]`. +/// +/// ``` +/// use bytes::Buf; +/// use std::io::Cursor; +/// +/// let mut buf = Cursor::new(b"hello world"); +/// +/// assert_eq!(b'h', buf.get_u8()); +/// assert_eq!(b'e', buf.get_u8()); +/// assert_eq!(b'l', buf.get_u8()); +/// +/// let mut rest = [0; 8]; +/// buf.copy_to_slice(&mut rest); +/// +/// assert_eq!(&rest[..], b"lo world"); +/// ``` +pub trait Buf { + /// Returns the number of bytes between the current position and the end of + /// the buffer. + /// + /// This value is greater than or equal to the length of the slice returned + /// by `bytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world"); + /// + /// assert_eq!(buf.remaining(), 11); + /// + /// buf.get_u8(); + /// + /// assert_eq!(buf.remaining(), 10); + /// ``` + /// + /// # Implementer notes + /// + /// Implementations of `remaining` should ensure that the return value does + /// not change unless a call is made to `advance` or any other function that + /// is documented to change the `Buf`'s current position. + fn remaining(&self) -> usize; + + /// Returns a slice starting at the current position and of length between 0 + /// and `Buf::remaining()`. Note that this *can* return shorter slice (this allows + /// non-continuous internal representation). + /// + /// This is a lower level function. Most operations are done with other + /// functions. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world"); + /// + /// assert_eq!(buf.bytes(), b"hello world"); + /// + /// buf.advance(6); + /// + /// assert_eq!(buf.bytes(), b"world"); + /// ``` + /// + /// # Implementer notes + /// + /// This function should never panic. Once the end of the buffer is reached, + /// i.e., `Buf::remaining` returns 0, calls to `bytes` should return an + /// empty slice. + fn bytes(&self) -> &[u8]; + + /// Fills `dst` with potentially multiple slices starting at `self`'s + /// current position. + /// + /// If the `Buf` is backed by disjoint slices of bytes, `bytes_vec` enables + /// fetching more than one slice at once. `dst` is a slice of `IoVec` + /// references, enabling the slice to be directly used with [`writev`] + /// without any further conversion. The sum of the lengths of all the + /// buffers in `dst` will be less than or equal to `Buf::remaining()`. + /// + /// The entries in `dst` will be overwritten, but the data **contained** by + /// the slices **will not** be modified. If `bytes_vec` does not fill every + /// entry in `dst`, then `dst` is guaranteed to contain all remaining slices + /// in `self. + /// + /// This is a lower level function. Most operations are done with other + /// functions. + /// + /// # Implementer notes + /// + /// This function should never panic. Once the end of the buffer is reached, + /// i.e., `Buf::remaining` returns 0, calls to `bytes_vec` must return 0 + /// without mutating `dst`. + /// + /// Implementations should also take care to properly handle being called + /// with `dst` being a zero length slice. + /// + /// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { + if dst.is_empty() { + return 0; + } + + if self.has_remaining() { + dst[0] = self.bytes().into(); + 1 + } else { + 0 + } + } + + /// Advance the internal cursor of the Buf + /// + /// The next call to `bytes` will return a slice starting `cnt` bytes + /// further into the underlying buffer. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world"); + /// + /// assert_eq!(buf.bytes(), b"hello world"); + /// + /// buf.advance(6); + /// + /// assert_eq!(buf.bytes(), b"world"); + /// ``` + /// + /// # Panics + /// + /// This function **may** panic if `cnt > self.remaining()`. + /// + /// # Implementer notes + /// + /// It is recommended for implementations of `advance` to panic if `cnt > + /// self.remaining()`. If the implementation does not panic, the call must + /// behave as if `cnt == self.remaining()`. + /// + /// A call with `cnt == 0` should never panic and be a no-op. + fn advance(&mut self, cnt: usize); + + /// Returns true if there are any more bytes to consume + /// + /// This is equivalent to `self.remaining() != 0`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"a"); + /// + /// assert!(buf.has_remaining()); + /// + /// buf.get_u8(); + /// + /// assert!(!buf.has_remaining()); + /// ``` + fn has_remaining(&self) -> bool { + self.remaining() > 0 + } + + /// Copies bytes from `self` into `dst`. + /// + /// The cursor is advanced by the number of bytes copied. `self` must have + /// enough remaining bytes to fill `dst`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world"); + /// let mut dst = [0; 5]; + /// + /// buf.copy_to_slice(&mut dst); + /// assert_eq!(b"hello", &dst); + /// assert_eq!(6, buf.remaining()); + /// ``` + /// + /// # Panics + /// + /// This function panics if `self.remaining() < dst.len()` + fn copy_to_slice(&mut self, dst: &mut [u8]) { + let mut off = 0; + + assert!(self.remaining() >= dst.len()); + + while off < dst.len() { + let cnt; + + unsafe { + let src = self.bytes(); + cnt = cmp::min(src.len(), dst.len() - off); + + ptr::copy_nonoverlapping( + src.as_ptr(), dst[off..].as_mut_ptr(), cnt); + + off += src.len(); + } + + self.advance(cnt); + } + } + + /// Gets an unsigned 8 bit integer from `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08 hello"); + /// assert_eq!(8, buf.get_u8()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is no more remaining data in `self`. + fn get_u8(&mut self) -> u8 { + assert!(self.remaining() >= 1); + let ret = self.bytes()[0]; + self.advance(1); + ret + } + + /// Gets a signed 8 bit integer from `self`. + /// + /// The current position is advanced by 1. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08 hello"); + /// assert_eq!(8, buf.get_i8()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is no more remaining data in `self`. + fn get_i8(&mut self) -> i8 { + assert!(self.remaining() >= 1); + let ret = self.bytes()[0] as i8; + self.advance(1); + ret + } + + #[doc(hidden)] + #[deprecated(note="use get_u16_be or get_u16_le")] + fn get_u16(&mut self) -> u16 where Self: Sized { + let mut buf = [0; 2]; + self.copy_to_slice(&mut buf); + T::read_u16(&buf) + } + + /// Gets an unsigned 16 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x09 hello"); + /// assert_eq!(0x0809, buf.get_u16_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u16_be(&mut self) -> u16 { + buf_get_impl!(self, 2, BigEndian::read_u16); + } + + /// Gets an unsigned 16 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x09\x08 hello"); + /// assert_eq!(0x0809, buf.get_u16_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u16_le(&mut self) -> u16 { + buf_get_impl!(self, 2, LittleEndian::read_u16); + } + + #[doc(hidden)] + #[deprecated(note="use get_i16_be or get_i16_le")] + fn get_i16(&mut self) -> i16 where Self: Sized { + let mut buf = [0; 2]; + self.copy_to_slice(&mut buf); + T::read_i16(&buf) + } + + /// Gets a signed 16 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x09 hello"); + /// assert_eq!(0x0809, buf.get_i16_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i16_be(&mut self) -> i16 { + buf_get_impl!(self, 2, BigEndian::read_i16); + } + + /// Gets a signed 16 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x09\x08 hello"); + /// assert_eq!(0x0809, buf.get_i16_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i16_le(&mut self) -> i16 { + buf_get_impl!(self, 2, LittleEndian::read_i16); + } + + #[doc(hidden)] + #[deprecated(note="use get_u32_be or get_u32_le")] + fn get_u32(&mut self) -> u32 where Self: Sized { + let mut buf = [0; 4]; + self.copy_to_slice(&mut buf); + T::read_u32(&buf) + } + + /// Gets an unsigned 32 bit integer from `self` in the big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello"); + /// assert_eq!(0x0809A0A1, buf.get_u32_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u32_be(&mut self) -> u32 { + buf_get_impl!(self, 4, BigEndian::read_u32); + } + + /// Gets an unsigned 32 bit integer from `self` in the little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello"); + /// assert_eq!(0x0809A0A1, buf.get_u32_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u32_le(&mut self) -> u32 { + buf_get_impl!(self, 4, LittleEndian::read_u32); + } + + #[doc(hidden)] + #[deprecated(note="use get_i32_be or get_i32_le")] + fn get_i32(&mut self) -> i32 where Self: Sized { + let mut buf = [0; 4]; + self.copy_to_slice(&mut buf); + T::read_i32(&buf) + } + + /// Gets a signed 32 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x09\xA0\xA1 hello"); + /// assert_eq!(0x0809A0A1, buf.get_i32_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i32_be(&mut self) -> i32 { + buf_get_impl!(self, 4, BigEndian::read_i32); + } + + /// Gets a signed 32 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\xA1\xA0\x09\x08 hello"); + /// assert_eq!(0x0809A0A1, buf.get_i32_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i32_le(&mut self) -> i32 { + buf_get_impl!(self, 4, LittleEndian::read_i32); + } + + #[doc(hidden)] + #[deprecated(note="use get_u64_be or get_u64_le")] + fn get_u64(&mut self) -> u64 where Self: Sized { + let mut buf = [0; 8]; + self.copy_to_slice(&mut buf); + T::read_u64(&buf) + } + + /// Gets an unsigned 64 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"); + /// assert_eq!(0x0102030405060708, buf.get_u64_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u64_be(&mut self) -> u64 { + buf_get_impl!(self, 8, BigEndian::read_u64); + } + + /// Gets an unsigned 64 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"); + /// assert_eq!(0x0102030405060708, buf.get_u64_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_u64_le(&mut self) -> u64 { + buf_get_impl!(self, 8, LittleEndian::read_u64); + } + + #[doc(hidden)] + #[deprecated(note="use get_i64_be or get_i64_le")] + fn get_i64(&mut self) -> i64 where Self: Sized { + let mut buf = [0; 8]; + self.copy_to_slice(&mut buf); + T::read_i64(&buf) + } + + /// Gets a signed 64 bit integer from `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"); + /// assert_eq!(0x0102030405060708, buf.get_i64_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i64_be(&mut self) -> i64 { + buf_get_impl!(self, 8, BigEndian::read_i64); + } + + /// Gets a signed 64 bit integer from `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"); + /// assert_eq!(0x0102030405060708, buf.get_i64_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_i64_le(&mut self) -> i64 { + buf_get_impl!(self, 8, LittleEndian::read_i64); + } + + /// Gets an unsigned 128 bit integer from `self` in big-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"); + /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + #[cfg(feature = "i128")] + fn get_u128_be(&mut self) -> u128 { + buf_get_impl!(self, 16, BigEndian::read_u128); + } + + /// Gets an unsigned 128 bit integer from `self` in little-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"); + /// assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + #[cfg(feature = "i128")] + fn get_u128_le(&mut self) -> u128 { + buf_get_impl!(self, 16, LittleEndian::read_u128); + } + + /// Gets a signed 128 bit integer from `self` in big-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"); + /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + #[cfg(feature = "i128")] + fn get_i128_be(&mut self) -> i128 { + buf_get_impl!(self, 16, BigEndian::read_i128); + } + + /// Gets a signed 128 bit integer from `self` in little-endian byte order. + /// + /// **NOTE:** This method requires the `i128` feature. + /// The current position is advanced by 16. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"); + /// assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + #[cfg(feature = "i128")] + fn get_i128_le(&mut self) -> i128 { + buf_get_impl!(self, 16, LittleEndian::read_i128); + } + + #[doc(hidden)] + #[deprecated(note="use get_uint_be or get_uint_le")] + fn get_uint(&mut self, nbytes: usize) -> u64 where Self: Sized { + let mut buf = [0; 8]; + self.copy_to_slice(&mut buf[..nbytes]); + T::read_uint(&buf[..nbytes], nbytes) + } + + /// Gets an unsigned n-byte integer from `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, BigEndian}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03 hello"); + /// assert_eq!(0x010203, buf.get_uint_be(3)); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_uint_be(&mut self, nbytes: usize) -> u64 { + buf_get_impl!(self, 8, BigEndian::read_uint, nbytes); + } + + /// Gets an unsigned n-byte integer from `self` in little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x03\x02\x01 hello"); + /// assert_eq!(0x010203, buf.get_uint_le(3)); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_uint_le(&mut self, nbytes: usize) -> u64 { + buf_get_impl!(self, 8, LittleEndian::read_uint, nbytes); + } + + #[doc(hidden)] + #[deprecated(note="use get_int_be or get_int_le")] + fn get_int(&mut self, nbytes: usize) -> i64 where Self: Sized { + let mut buf = [0; 8]; + self.copy_to_slice(&mut buf[..nbytes]); + T::read_int(&buf[..nbytes], nbytes) + } + + /// Gets a signed n-byte integer from `self` in big-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x01\x02\x03 hello"); + /// assert_eq!(0x010203, buf.get_int_be(3)); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_int_be(&mut self, nbytes: usize) -> i64 { + buf_get_impl!(self, 8, BigEndian::read_int, nbytes); + } + + /// Gets a signed n-byte integer from `self` in little-endian byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x03\x02\x01 hello"); + /// assert_eq!(0x010203, buf.get_int_le(3)); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_int_le(&mut self, nbytes: usize) -> i64 { + buf_get_impl!(self, 8, LittleEndian::read_int, nbytes); + } + + #[doc(hidden)] + #[deprecated(note="use get_f32_be or get_f32_le")] + fn get_f32(&mut self) -> f32 where Self: Sized { + let mut buf = [0; 4]; + self.copy_to_slice(&mut buf); + T::read_f32(&buf) + } + + /// Gets an IEEE754 single-precision (4 bytes) floating point number from + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x3F\x99\x99\x9A hello"); + /// assert_eq!(1.2f32, buf.get_f32_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_f32_be(&mut self) -> f32 { + buf_get_impl!(self, 4, BigEndian::read_f32); + } + + /// Gets an IEEE754 single-precision (4 bytes) floating point number from + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x9A\x99\x99\x3F hello"); + /// assert_eq!(1.2f32, buf.get_f32_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_f32_le(&mut self) -> f32 { + buf_get_impl!(self, 4, LittleEndian::read_f32); + } + + #[doc(hidden)] + #[deprecated(note="use get_f64_be or get_f64_le")] + fn get_f64(&mut self) -> f64 where Self: Sized { + let mut buf = [0; 8]; + self.copy_to_slice(&mut buf); + T::read_f64(&buf) + } + + /// Gets an IEEE754 double-precision (8 bytes) floating point number from + /// `self` in big-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"); + /// assert_eq!(1.2f64, buf.get_f64_be()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_f64_be(&mut self) -> f64 { + buf_get_impl!(self, 8, BigEndian::read_f64); + } + + /// Gets an IEEE754 double-precision (8 bytes) floating point number from + /// `self` in little-endian byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"); + /// assert_eq!(1.2f64, buf.get_f64_le()); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining data in `self`. + fn get_f64_le(&mut self) -> f64 { + buf_get_impl!(self, 8, LittleEndian::read_f64); + } + + /// Transforms a `Buf` into a concrete buffer. + /// + /// `collect()` can operate on any value that implements `Buf`, and turn it + /// into the relevent concrete buffer type. + /// + /// # Examples + /// + /// Collecting a buffer and loading the contents into a `Vec`. + /// + /// ``` + /// use bytes::{Buf, Bytes, IntoBuf}; + /// + /// let buf = Bytes::from(&b"hello world"[..]).into_buf(); + /// let vec: Vec = buf.collect(); + /// + /// assert_eq!(vec, &b"hello world"[..]); + /// ``` + fn collect(self) -> B + where Self: Sized, + B: FromBuf, + { + B::from_buf(self) + } + + /// Creates an adaptor which will read at most `limit` bytes from `self`. + /// + /// This function returns a new instance of `Buf` which will read at most + /// `limit` bytes. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new("hello world").take(5); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(dst, b"hello"); + /// + /// let mut buf = buf.into_inner(); + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(dst, b" world"); + /// ``` + fn take(self, limit: usize) -> Take + where Self: Sized + { + super::take::new(self, limit) + } + + /// Creates an adaptor which will chain this buffer with another. + /// + /// The returned `Buf` instance will first consume all bytes from `self`. + /// Afterwards the output is equivalent to the output of next. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// use bytes::buf::Chain; + /// + /// let buf = Bytes::from(&b"hello "[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// let full: Bytes = buf.collect(); + /// assert_eq!(full[..], b"hello world"[..]); + /// ``` + fn chain(self, next: U) -> Chain + where U: IntoBuf, + Self: Sized, + { + Chain::new(self, next.into_buf()) + } + + /// Creates a "by reference" adaptor for this instance of `Buf`. + /// + /// The returned adaptor also implements `Buf` and will simply borrow `self`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new("hello world"); + /// let mut dst = vec![]; + /// + /// { + /// let mut reference = buf.by_ref(); + /// dst.put(&mut reference.take(5)); + /// assert_eq!(dst, b"hello"); + /// } // drop our &mut reference so we can use `buf` again + /// + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(dst, b" world"); + /// ``` + fn by_ref(&mut self) -> &mut Self where Self: Sized { + self + } + + /// Creates an adaptor which implements the `Read` trait for `self`. + /// + /// This function returns a new value which implements `Read` by adapting + /// the `Read` trait functions to the `Buf` trait functions. Given that + /// `Buf` operations are infallible, none of the `Read` functions will + /// return with `Err`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, IntoBuf, Bytes}; + /// use std::io::Read; + /// + /// let buf = Bytes::from("hello world").into_buf(); + /// + /// let mut reader = buf.reader(); + /// let mut dst = [0; 1024]; + /// + /// let num = reader.read(&mut dst).unwrap(); + /// + /// assert_eq!(11, num); + /// assert_eq!(&dst[..11], b"hello world"); + /// ``` + fn reader(self) -> Reader where Self: Sized { + super::reader::new(self) + } + + /// Returns an iterator over the bytes contained by the buffer. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, IntoBuf, Bytes}; + /// + /// let buf = Bytes::from(&b"abc"[..]).into_buf(); + /// let mut iter = buf.iter(); + /// + /// assert_eq!(iter.next(), Some(b'a')); + /// assert_eq!(iter.next(), Some(b'b')); + /// assert_eq!(iter.next(), Some(b'c')); + /// assert_eq!(iter.next(), None); + /// ``` + fn iter(self) -> Iter where Self: Sized { + super::iter::new(self) + } +} + +impl<'a, T: Buf + ?Sized> Buf for &'a mut T { + fn remaining(&self) -> usize { + (**self).remaining() + } + + fn bytes(&self) -> &[u8] { + (**self).bytes() + } + + fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { + (**self).bytes_vec(dst) + } + + fn advance(&mut self, cnt: usize) { + (**self).advance(cnt) + } +} + +impl Buf for Box { + fn remaining(&self) -> usize { + (**self).remaining() + } + + fn bytes(&self) -> &[u8] { + (**self).bytes() + } + + fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { + (**self).bytes_vec(dst) + } + + fn advance(&mut self, cnt: usize) { + (**self).advance(cnt) + } +} + +impl> Buf for io::Cursor { + fn remaining(&self) -> usize { + let len = self.get_ref().as_ref().len(); + let pos = self.position(); + + if pos >= len as u64 { + return 0; + } + + len - pos as usize + } + + fn bytes(&self) -> &[u8] { + let len = self.get_ref().as_ref().len(); + let pos = self.position() as usize; + + if pos >= len { + return Default::default(); + } + + &(self.get_ref().as_ref())[pos..] + } + + fn advance(&mut self, cnt: usize) { + let pos = (self.position() as usize) + .checked_add(cnt).expect("overflow"); + + assert!(pos <= self.get_ref().as_ref().len()); + + self.set_position(pos as u64); + } +} + +impl Buf for Option<[u8; 1]> { + fn remaining(&self) -> usize { + if self.is_some() { + 1 + } else { + 0 + } + } + + fn bytes(&self) -> &[u8] { + self.as_ref().map(AsRef::as_ref) + .unwrap_or(Default::default()) + } + + fn advance(&mut self, cnt: usize) { + if cnt == 0 { + return; + } + + if self.is_none() { + panic!("overflow"); + } else { + assert_eq!(1, cnt); + *self = None; + } + } +} + +// The existance of this function makes the compiler catch if the Buf +// trait is "object-safe" or not. +fn _assert_trait_object(_b: &Buf) {} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/chain.rs cargo-0.35.0/vendor/bytes/src/buf/chain.rs --- cargo-0.33.0/vendor/bytes/src/buf/chain.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/chain.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,226 @@ +use {Buf, BufMut}; +use iovec::IoVec; + +/// A `Chain` sequences two buffers. +/// +/// `Chain` is an adapter that links two underlying buffers and provides a +/// continous view across both buffers. It is able to sequence either immutable +/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values). +/// +/// This struct is generally created by calling [`Buf::chain`]. Please see that +/// function's documentation for more detail. +/// +/// # Examples +/// +/// ``` +/// use bytes::{Bytes, Buf, IntoBuf}; +/// use bytes::buf::Chain; +/// +/// let buf = Bytes::from(&b"hello "[..]).into_buf() +/// .chain(Bytes::from(&b"world"[..])); +/// +/// let full: Bytes = buf.collect(); +/// assert_eq!(full[..], b"hello world"[..]); +/// ``` +/// +/// [`Buf::chain`]: trait.Buf.html#method.chain +/// [`Buf`]: trait.Buf.html +/// [`BufMut`]: trait.BufMut.html +#[derive(Debug)] +pub struct Chain { + a: T, + b: U, +} + +impl Chain { + /// Creates a new `Chain` sequencing the provided values. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// use bytes::buf::Chain; + /// + /// let buf = Chain::new( + /// BytesMut::with_capacity(1024), + /// BytesMut::with_capacity(1024)); + /// + /// // Use the chained buffer + /// ``` + pub fn new(a: T, b: U) -> Chain { + Chain { + a: a, + b: b, + } + } + + /// Gets a reference to the first underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// + /// let buf = Bytes::from(&b"hello"[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// assert_eq!(buf.first_ref().get_ref()[..], b"hello"[..]); + /// ``` + pub fn first_ref(&self) -> &T { + &self.a + } + + /// Gets a mutable reference to the first underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// + /// let mut buf = Bytes::from(&b"hello "[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// buf.first_mut().set_position(1); + /// + /// let full: Bytes = buf.collect(); + /// assert_eq!(full[..], b"ello world"[..]); + /// ``` + pub fn first_mut(&mut self) -> &mut T { + &mut self.a + } + + /// Gets a reference to the last underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// + /// let buf = Bytes::from(&b"hello"[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// assert_eq!(buf.last_ref().get_ref()[..], b"world"[..]); + /// ``` + pub fn last_ref(&self) -> &U { + &self.b + } + + /// Gets a mutable reference to the last underlying `Buf`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// + /// let mut buf = Bytes::from(&b"hello "[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// buf.last_mut().set_position(1); + /// + /// let full: Bytes = buf.collect(); + /// assert_eq!(full[..], b"hello orld"[..]); + /// ``` + pub fn last_mut(&mut self) -> &mut U { + &mut self.b + } + + /// Consumes this `Chain`, returning the underlying values. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Bytes, Buf, IntoBuf}; + /// + /// let buf = Bytes::from(&b"hello"[..]).into_buf() + /// .chain(Bytes::from(&b"world"[..])); + /// + /// let (first, last) = buf.into_inner(); + /// assert_eq!(first.get_ref()[..], b"hello"[..]); + /// assert_eq!(last.get_ref()[..], b"world"[..]); + /// ``` + pub fn into_inner(self) -> (T, U) { + (self.a, self.b) + } +} + +impl Buf for Chain + where T: Buf, + U: Buf, +{ + fn remaining(&self) -> usize { + self.a.remaining() + self.b.remaining() + } + + fn bytes(&self) -> &[u8] { + if self.a.has_remaining() { + self.a.bytes() + } else { + self.b.bytes() + } + } + + fn advance(&mut self, mut cnt: usize) { + let a_rem = self.a.remaining(); + + if a_rem != 0 { + if a_rem >= cnt { + self.a.advance(cnt); + return; + } + + // Consume what is left of a + self.a.advance(a_rem); + + cnt -= a_rem; + } + + self.b.advance(cnt); + } + + fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { + let mut n = self.a.bytes_vec(dst); + n += self.b.bytes_vec(&mut dst[n..]); + n + } +} + +impl BufMut for Chain + where T: BufMut, + U: BufMut, +{ + fn remaining_mut(&self) -> usize { + self.a.remaining_mut() + self.b.remaining_mut() + } + + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + if self.a.has_remaining_mut() { + self.a.bytes_mut() + } else { + self.b.bytes_mut() + } + } + + unsafe fn advance_mut(&mut self, mut cnt: usize) { + let a_rem = self.a.remaining_mut(); + + if a_rem != 0 { + if a_rem >= cnt { + self.a.advance_mut(cnt); + return; + } + + // Consume what is left of a + self.a.advance_mut(a_rem); + + cnt -= a_rem; + } + + self.b.advance_mut(cnt); + } + + unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { + let mut n = self.a.bytes_vec_mut(dst); + n += self.b.bytes_vec_mut(&mut dst[n..]); + n + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/from_buf.rs cargo-0.35.0/vendor/bytes/src/buf/from_buf.rs --- cargo-0.33.0/vendor/bytes/src/buf/from_buf.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/from_buf.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,117 @@ +use {Buf, BufMut, IntoBuf, Bytes, BytesMut}; + +/// Conversion from a [`Buf`] +/// +/// Implementing `FromBuf` for a type defines how it is created from a buffer. +/// This is common for types which represent byte storage of some kind. +/// +/// [`FromBuf::from_buf`] is rarely called explicitly, and it is instead used +/// through [`Buf::collect`]. See [`Buf::collect`] documentation for more examples. +/// +/// See also [`IntoBuf`]. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bytes::{Bytes, IntoBuf}; +/// use bytes::buf::FromBuf; +/// +/// let buf = Bytes::from(&b"hello world"[..]).into_buf(); +/// let vec = Vec::from_buf(buf); +/// +/// assert_eq!(vec, &b"hello world"[..]); +/// ``` +/// +/// Using [`Buf::collect`] to implicitly use `FromBuf`: +/// +/// ``` +/// use bytes::{Buf, Bytes, IntoBuf}; +/// +/// let buf = Bytes::from(&b"hello world"[..]).into_buf(); +/// let vec: Vec = buf.collect(); +/// +/// assert_eq!(vec, &b"hello world"[..]); +/// ``` +/// +/// Implementing `FromBuf` for your type: +/// +/// ``` +/// use bytes::{BufMut, Bytes}; +/// use bytes::buf::{IntoBuf, FromBuf}; +/// +/// // A sample buffer, that's just a wrapper over Vec +/// struct MyBuffer(Vec); +/// +/// impl FromBuf for MyBuffer { +/// fn from_buf(buf: B) -> Self where B: IntoBuf { +/// let mut v = Vec::new(); +/// v.put(buf.into_buf()); +/// MyBuffer(v) +/// } +/// } +/// +/// // Now we can make a new buf +/// let buf = Bytes::from(&b"hello world"[..]); +/// +/// // And make a MyBuffer out of it +/// let my_buf = MyBuffer::from_buf(buf); +/// +/// assert_eq!(my_buf.0, &b"hello world"[..]); +/// ``` +/// +/// [`Buf`]: trait.Buf.html +/// [`FromBuf::from_buf`]: #method.from_buf +/// [`Buf::collect`]: trait.Buf.html#method.collect +/// [`IntoBuf`]: trait.IntoBuf.html +pub trait FromBuf { + /// Creates a value from a buffer. + /// + /// See the [type-level documentation](#) for more details. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bytes::{Bytes, IntoBuf}; + /// use bytes::buf::FromBuf; + /// + /// let buf = Bytes::from(&b"hello world"[..]).into_buf(); + /// let vec = Vec::from_buf(buf); + /// + /// assert_eq!(vec, &b"hello world"[..]); + /// ``` + fn from_buf(buf: T) -> Self where T: IntoBuf; +} + +impl FromBuf for Vec { + fn from_buf(buf: T) -> Self + where T: IntoBuf + { + let buf = buf.into_buf(); + let mut ret = Vec::with_capacity(buf.remaining()); + ret.put(buf); + ret + } +} + +impl FromBuf for Bytes { + fn from_buf(buf: T) -> Self + where T: IntoBuf + { + BytesMut::from_buf(buf).freeze() + } +} + +impl FromBuf for BytesMut { + fn from_buf(buf: T) -> Self + where T: IntoBuf + { + let buf = buf.into_buf(); + let mut ret = BytesMut::with_capacity(buf.remaining()); + ret.put(buf); + ret + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/into_buf.rs cargo-0.35.0/vendor/bytes/src/buf/into_buf.rs --- cargo-0.33.0/vendor/bytes/src/buf/into_buf.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/into_buf.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,146 @@ +use super::{Buf}; + +use std::io; + +/// Conversion into a `Buf` +/// +/// An `IntoBuf` implementation defines how to convert a value into a `Buf`. +/// This is common for types that represent byte storage of some kind. `IntoBuf` +/// may be implemented directly for types or on references for those types. +/// +/// # Examples +/// +/// ``` +/// use bytes::{Buf, IntoBuf, BigEndian}; +/// +/// let bytes = b"\x00\x01hello world"; +/// let mut buf = bytes.into_buf(); +/// +/// assert_eq!(1, buf.get_u16::()); +/// +/// let mut rest = [0; 11]; +/// buf.copy_to_slice(&mut rest); +/// +/// assert_eq!(b"hello world", &rest); +/// ``` +pub trait IntoBuf { + /// The `Buf` type that `self` is being converted into + type Buf: Buf; + + /// Creates a `Buf` from a value. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, IntoBuf, BigEndian}; + /// + /// let bytes = b"\x00\x01hello world"; + /// let mut buf = bytes.into_buf(); + /// + /// assert_eq!(1, buf.get_u16::()); + /// + /// let mut rest = [0; 11]; + /// buf.copy_to_slice(&mut rest); + /// + /// assert_eq!(b"hello world", &rest); + /// ``` + fn into_buf(self) -> Self::Buf; +} + +impl IntoBuf for T { + type Buf = Self; + + fn into_buf(self) -> Self { + self + } +} + +impl<'a> IntoBuf for &'a [u8] { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a mut [u8] { + type Buf = io::Cursor<&'a mut [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a str { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + self.as_bytes().into_buf() + } +} + +impl IntoBuf for Vec { + type Buf = io::Cursor>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a Vec { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(&self[..]) + } +} + +// Kind of annoying... but this impl is required to allow passing `&'static +// [u8]` where for<'a> &'a T: IntoBuf is required. +impl<'a> IntoBuf for &'a &'static [u8] { + type Buf = io::Cursor<&'static [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a &'static str { + type Buf = io::Cursor<&'static [u8]>; + + fn into_buf(self) -> Self::Buf { + self.as_bytes().into_buf() + } +} + +impl IntoBuf for String { + type Buf = io::Cursor>; + + fn into_buf(self) -> Self::Buf { + self.into_bytes().into_buf() + } +} + +impl<'a> IntoBuf for &'a String { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + self.as_bytes().into_buf() + } +} + +impl IntoBuf for u8 { + type Buf = Option<[u8; 1]>; + + fn into_buf(self) -> Self::Buf { + Some([self]) + } +} + +impl IntoBuf for i8 { + type Buf = Option<[u8; 1]>; + + fn into_buf(self) -> Self::Buf { + Some([self as u8; 1]) + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/iter.rs cargo-0.35.0/vendor/bytes/src/buf/iter.rs --- cargo-0.33.0/vendor/bytes/src/buf/iter.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/iter.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,116 @@ +use Buf; + +/// Iterator over the bytes contained by the buffer. +/// +/// This struct is created by the [`iter`] method on [`Buf`]. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use bytes::{Buf, IntoBuf, Bytes}; +/// +/// let buf = Bytes::from(&b"abc"[..]).into_buf(); +/// let mut iter = buf.iter(); +/// +/// assert_eq!(iter.next(), Some(b'a')); +/// assert_eq!(iter.next(), Some(b'b')); +/// assert_eq!(iter.next(), Some(b'c')); +/// assert_eq!(iter.next(), None); +/// ``` +/// +/// [`iter`]: trait.Buf.html#method.iter +/// [`Buf`]: trait.Buf.html +#[derive(Debug)] +pub struct Iter { + inner: T, +} + +impl Iter { + /// Consumes this `Iter`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, IntoBuf, Bytes}; + /// + /// let buf = Bytes::from(&b"abc"[..]).into_buf(); + /// let mut iter = buf.iter(); + /// + /// assert_eq!(iter.next(), Some(b'a')); + /// + /// let buf = iter.into_inner(); + /// assert_eq!(2, buf.remaining()); + /// ``` + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, IntoBuf, Bytes}; + /// + /// let buf = Bytes::from(&b"abc"[..]).into_buf(); + /// let mut iter = buf.iter(); + /// + /// assert_eq!(iter.next(), Some(b'a')); + /// + /// assert_eq!(2, iter.get_ref().remaining()); + /// ``` + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, IntoBuf, BytesMut}; + /// + /// let buf = BytesMut::from(&b"abc"[..]).into_buf(); + /// let mut iter = buf.iter(); + /// + /// assert_eq!(iter.next(), Some(b'a')); + /// + /// iter.get_mut().set_position(0); + /// + /// assert_eq!(iter.next(), Some(b'a')); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } +} + +pub fn new(inner: T) -> Iter { + Iter { inner: inner } +} + +impl Iterator for Iter { + type Item = u8; + + fn next(&mut self) -> Option { + if !self.inner.has_remaining() { + return None; + } + + let b = self.inner.bytes()[0]; + self.inner.advance(1); + Some(b) + } + + fn size_hint(&self) -> (usize, Option) { + let rem = self.inner.remaining(); + (rem, Some(rem)) + } +} + +impl ExactSizeIterator for Iter { } diff -Nru cargo-0.33.0/vendor/bytes/src/buf/mod.rs cargo-0.35.0/vendor/bytes/src/buf/mod.rs --- cargo-0.33.0/vendor/bytes/src/buf/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,38 @@ +//! Utilities for working with buffers. +//! +//! A buffer is any structure that contains a sequence of bytes. The bytes may +//! or may not be stored in contiguous memory. This module contains traits used +//! to abstract over buffers as well as utilities for working with buffer types. +//! +//! # `Buf`, `BufMut` +//! +//! These are the two foundational traits for abstractly working with buffers. +//! They can be thought as iterators for byte structures. They offer additional +//! performance over `Iterator` by providing an API optimized for byte slices. +//! +//! See [`Buf`] and [`BufMut`] for more details. +//! +//! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure) +//! [`Buf`]: trait.Buf.html +//! [`BufMut`]: trait.BufMut.html + +mod buf; +mod buf_mut; +mod from_buf; +mod chain; +mod into_buf; +mod iter; +mod reader; +mod take; +mod vec_deque; +mod writer; + +pub use self::buf::Buf; +pub use self::buf_mut::BufMut; +pub use self::from_buf::FromBuf; +pub use self::chain::Chain; +pub use self::into_buf::IntoBuf; +pub use self::iter::Iter; +pub use self::reader::Reader; +pub use self::take::Take; +pub use self::writer::Writer; diff -Nru cargo-0.33.0/vendor/bytes/src/buf/reader.rs cargo-0.35.0/vendor/bytes/src/buf/reader.rs --- cargo-0.33.0/vendor/bytes/src/buf/reader.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/reader.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,97 @@ +use {Buf}; + +use std::{cmp, io}; + +/// A `Buf` adapter which implements `io::Read` for the inner value. +/// +/// This struct is generally created by calling `reader()` on `Buf`. See +/// documentation of [`reader()`](trait.Buf.html#method.reader) for more +/// details. +#[derive(Debug)] +pub struct Reader { + buf: B, +} + +pub fn new(buf: B) -> Reader { + Reader { buf: buf } +} + +impl Reader { + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::Buf; + /// use std::io::{self, Cursor}; + /// + /// let mut buf = Cursor::new(b"hello world").reader(); + /// + /// assert_eq!(0, buf.get_ref().position()); + /// ``` + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::Buf; + /// use std::io::{self, Cursor}; + /// + /// let mut buf = Cursor::new(b"hello world").reader(); + /// let mut dst = vec![]; + /// + /// buf.get_mut().set_position(2); + /// io::copy(&mut buf, &mut dst).unwrap(); + /// + /// assert_eq!(*dst, b"llo world"[..]); + /// ``` + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Consumes this `Reader`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::Buf; + /// use std::io::{self, Cursor}; + /// + /// let mut buf = Cursor::new(b"hello world").reader(); + /// let mut dst = vec![]; + /// + /// io::copy(&mut buf, &mut dst).unwrap(); + /// + /// let buf = buf.into_inner(); + /// assert_eq!(0, buf.remaining()); + /// ``` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl io::Read for Reader { + fn read(&mut self, dst: &mut [u8]) -> io::Result { + let len = cmp::min(self.buf.remaining(), dst.len()); + + Buf::copy_to_slice(&mut self.buf, &mut dst[0..len]); + Ok(len) + } +} + +impl io::BufRead for Reader { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + Ok(self.buf.bytes()) + } + fn consume(&mut self, amt: usize) { + self.buf.advance(amt) + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/take.rs cargo-0.35.0/vendor/bytes/src/buf/take.rs --- cargo-0.33.0/vendor/bytes/src/buf/take.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/take.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,155 @@ +use {Buf}; + +use std::cmp; + +/// A `Buf` adapter which limits the bytes read from an underlying buffer. +/// +/// This struct is generally created by calling `take()` on `Buf`. See +/// documentation of [`take()`](trait.Buf.html#method.take) for more details. +#[derive(Debug)] +pub struct Take { + inner: T, + limit: usize, +} + +pub fn new(inner: T, limit: usize) -> Take { + Take { + inner: inner, + limit: limit, + } +} + +impl Take { + /// Consumes this `Take`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// let mut buf = buf.into_inner(); + /// + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo world"[..]); + /// ``` + pub fn into_inner(self) -> T { + self.inner + } + + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// + /// assert_eq!(0, buf.get_ref().position()); + /// ``` + pub fn get_ref(&self) -> &T { + &self.inner + } + + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying `Buf`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// buf.get_mut().set_position(2); + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"ll"[..]); + /// ``` + pub fn get_mut(&mut self) -> &mut T { + &mut self.inner + } + + /// Returns the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than indicated by this method then + /// that is the actual number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// + /// assert_eq!(2, buf.limit()); + /// assert_eq!(b'h', buf.get_u8()); + /// assert_eq!(1, buf.limit()); + /// ``` + pub fn limit(&self) -> usize { + self.limit + } + + /// Sets the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than `lim` then that is the actual + /// number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// dst.clear(); + /// + /// buf.set_limit(3); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo"[..]); + /// ``` + pub fn set_limit(&mut self, lim: usize) { + self.limit = lim + } +} + +impl Buf for Take { + fn remaining(&self) -> usize { + cmp::min(self.inner.remaining(), self.limit) + } + + fn bytes(&self) -> &[u8] { + let bytes = self.inner.bytes(); + &bytes[..cmp::min(bytes.len(), self.limit)] + } + + fn advance(&mut self, cnt: usize) { + assert!(cnt <= self.limit); + self.inner.advance(cnt); + self.limit -= cnt; + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/vec_deque.rs cargo-0.35.0/vendor/bytes/src/buf/vec_deque.rs --- cargo-0.33.0/vendor/bytes/src/buf/vec_deque.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/vec_deque.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,39 @@ +use std::collections::VecDeque; + +use super::Buf; + +impl Buf for VecDeque { + fn remaining(&self) -> usize { + self.len() + } + + fn bytes(&self) -> &[u8] { + let (s1, s2) = self.as_slices(); + if s1.is_empty() { + s2 + } else { + s1 + } + } + + fn advance(&mut self, cnt: usize) { + self.drain(..cnt); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn hello_world() { + let mut buffer: VecDeque = VecDeque::new(); + buffer.extend(b"hello world"); + assert_eq!(11, buffer.remaining()); + assert_eq!(b"hello world", buffer.bytes()); + buffer.advance(6); + assert_eq!(b"world", buffer.bytes()); + buffer.extend(b" piece"); + assert_eq!(b"world piece" as &[u8], &buffer.collect::>()[..]); + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/buf/writer.rs cargo-0.35.0/vendor/bytes/src/buf/writer.rs --- cargo-0.33.0/vendor/bytes/src/buf/writer.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/buf/writer.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,88 @@ +use BufMut; + +use std::{cmp, io}; + +/// A `BufMut` adapter which implements `io::Write` for the inner value. +/// +/// This struct is generally created by calling `writer()` on `BufMut`. See +/// documentation of [`writer()`](trait.BufMut.html#method.writer) for more +/// details. +#[derive(Debug)] +pub struct Writer { + buf: B, +} + +pub fn new(buf: B) -> Writer { + Writer { buf: buf } +} + +impl Writer { + /// Gets a reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::BufMut; + /// + /// let mut buf = Vec::with_capacity(1024).writer(); + /// + /// assert_eq!(1024, buf.get_ref().capacity()); + /// ``` + pub fn get_ref(&self) -> &B { + &self.buf + } + + /// Gets a mutable reference to the underlying `BufMut`. + /// + /// It is inadvisable to directly write to the underlying `BufMut`. + /// + /// # Examples + /// + /// ```rust + /// use bytes::BufMut; + /// + /// let mut buf = vec![].writer(); + /// + /// buf.get_mut().reserve(1024); + /// + /// assert_eq!(1024, buf.get_ref().capacity()); + /// ``` + pub fn get_mut(&mut self) -> &mut B { + &mut self.buf + } + + /// Consumes this `Writer`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::BufMut; + /// use std::io::{self, Cursor}; + /// + /// let mut buf = vec![].writer(); + /// let mut src = Cursor::new(b"hello world"); + /// + /// io::copy(&mut src, &mut buf).unwrap(); + /// + /// let buf = buf.into_inner(); + /// assert_eq!(*buf, b"hello world"[..]); + /// ``` + pub fn into_inner(self) -> B { + self.buf + } +} + +impl io::Write for Writer { + fn write(&mut self, src: &[u8]) -> io::Result { + let n = cmp::min(self.buf.remaining_mut(), src.len()); + + self.buf.put(&src[0..n]); + Ok(n) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/bytes.rs cargo-0.35.0/vendor/bytes/src/bytes.rs --- cargo-0.33.0/vendor/bytes/src/bytes.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/bytes.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2947 @@ +use {IntoBuf, Buf, BufMut}; +use buf::Iter; +use debug; + +use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize}; +use std::borrow::{Borrow, BorrowMut}; +use std::io::Cursor; +use std::sync::atomic::{self, AtomicUsize, AtomicPtr}; +use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel}; +use std::iter::{FromIterator, Iterator}; + +/// A reference counted contiguous slice of memory. +/// +/// `Bytes` is an efficient container for storing and operating on contiguous +/// slices of memory. It is intended for use primarily in networking code, but +/// could have applications elsewhere as well. +/// +/// `Bytes` values facilitate zero-copy network programming by allowing multiple +/// `Bytes` objects to point to the same underlying memory. This is managed by +/// using a reference count to track when the memory is no longer needed and can +/// be freed. +/// +/// ``` +/// use bytes::Bytes; +/// +/// let mut mem = Bytes::from(&b"Hello world"[..]); +/// let a = mem.slice(0, 5); +/// +/// assert_eq!(&a[..], b"Hello"); +/// +/// let b = mem.split_to(6); +/// +/// assert_eq!(&mem[..], b"world"); +/// assert_eq!(&b[..], b"Hello "); +/// ``` +/// +/// # Memory layout +/// +/// The `Bytes` struct itself is fairly small, limited to a pointer to the +/// memory and 4 `usize` fields used to track information about which segment of +/// the underlying memory the `Bytes` handle has access to. +/// +/// The memory layout looks like this: +/// +/// ```text +/// +-------+ +/// | Bytes | +/// +-------+ +/// / \_____ +/// | \ +/// v v +/// +-----+------------------------------------+ +/// | Arc | | Data | | +/// +-----+------------------------------------+ +/// ``` +/// +/// `Bytes` keeps both a pointer to the shared `Arc` containing the full memory +/// slice and a pointer to the start of the region visible by the handle. +/// `Bytes` also tracks the length of its view into the memory. +/// +/// # Sharing +/// +/// The memory itself is reference counted, and multiple `Bytes` objects may +/// point to the same region. Each `Bytes` handle point to different sections within +/// the memory region, and `Bytes` handle may or may not have overlapping views +/// into the memory. +/// +/// +/// ```text +/// +/// Arc ptrs +---------+ +/// ________________________ / | Bytes 2 | +/// / +---------+ +/// / +-----------+ | | +/// |_________/ | Bytes 1 | | | +/// | +-----------+ | | +/// | | | ___/ data | tail +/// | data | tail |/ | +/// v v v v +/// +-----+---------------------------------+-----+ +/// | Arc | | | | | +/// +-----+---------------------------------+-----+ +/// ``` +/// +/// # Mutating +/// +/// While `Bytes` handles may potentially represent overlapping views of the +/// underlying memory slice and may not be mutated, `BytesMut` handles are +/// guaranteed to be the only handle able to view that slice of memory. As such, +/// `BytesMut` handles are able to mutate the underlying memory. Note that +/// holding a unique view to a region of memory does not mean that there are no +/// other `Bytes` and `BytesMut` handles with disjoint views of the underlying +/// memory. +/// +/// # Inline bytes +/// +/// As an optimization, when the slice referenced by a `Bytes` or `BytesMut` +/// handle is small enough [^1], `with_capacity` will avoid the allocation by +/// inlining the slice directly in the handle. In this case, a clone is no +/// longer "shallow" and the data will be copied. Converting from a `Vec` will +/// never use inlining. +/// +/// [^1]: Small enough: 31 bytes on 64 bit systems, 15 on 32 bit systems. +/// +pub struct Bytes { + inner: Inner, +} + +/// A unique reference to a contiguous slice of memory. +/// +/// `BytesMut` represents a unique view into a potentially shared memory region. +/// Given the uniqueness guarantee, owners of `BytesMut` handles are able to +/// mutate the memory. It is similar to a `Vec` but with less copies and +/// allocations. +/// +/// For more detail, see [Bytes](struct.Bytes.html). +/// +/// # Growth +/// +/// One key difference from `Vec` is that most operations **do not +/// implicitly grow the buffer**. This means that calling `my_bytes.put("hello +/// world");` could panic if `my_bytes` does not have enough capacity. Before +/// writing to the buffer, ensure that there is enough remaining capacity by +/// calling `my_bytes.remaining_mut()`. In general, avoiding calls to `reserve` +/// is preferable. +/// +/// The only exception is `extend` which implicitly reserves required capacity. +/// +/// # Examples +/// +/// ``` +/// use bytes::{BytesMut, BufMut}; +/// +/// let mut buf = BytesMut::with_capacity(64); +/// +/// buf.put(b'h'); +/// buf.put(b'e'); +/// buf.put("llo"); +/// +/// assert_eq!(&buf[..], b"hello"); +/// +/// // Freeze the buffer so that it can be shared +/// let a = buf.freeze(); +/// +/// // This does not allocate, instead `b` points to the same memory. +/// let b = a.clone(); +/// +/// assert_eq!(&a[..], b"hello"); +/// assert_eq!(&b[..], b"hello"); +/// ``` +pub struct BytesMut { + inner: Inner, +} + +// Both `Bytes` and `BytesMut` are backed by `Inner` and functions are delegated +// to `Inner` functions. The `Bytes` and `BytesMut` shims ensure that functions +// that mutate the underlying buffer are only performed when the data range +// being mutated is only available via a single `BytesMut` handle. +// +// # Data storage modes +// +// The goal of `bytes` is to be as efficient as possible across a wide range of +// potential usage patterns. As such, `bytes` needs to be able to handle buffers +// that are never shared, shared on a single thread, and shared across many +// threads. `bytes` also needs to handle both tiny buffers as well as very large +// buffers. For example, [Cassandra](http://cassandra.apache.org) values have +// been known to be in the hundreds of megabyte, and HTTP header values can be a +// few characters in size. +// +// To achieve high performance in these various situations, `Bytes` and +// `BytesMut` use different strategies for storing the buffer depending on the +// usage pattern. +// +// ## Delayed `Arc` allocation +// +// When a `Bytes` or `BytesMut` is first created, there is only one outstanding +// handle referencing the buffer. Since sharing is not yet required, an `Arc`* is +// not used and the buffer is backed by a `Vec` directly. Using an +// `Arc>` requires two allocations, so if the buffer ends up never being +// shared, that allocation is avoided. +// +// When sharing does become necessary (`clone`, `split_to`, `split_off`), that +// is when the buffer is promoted to being shareable. The `Vec` is moved +// into an `Arc` and both the original handle and the new handle use the same +// buffer via the `Arc`. +// +// * `Arc` is being used to signify an atomically reference counted cell. We +// don't use the `Arc` implementation provided by `std` and instead use our own. +// This ends up simplifying a number of the `unsafe` code snippets. +// +// ## Inlining small buffers +// +// The `Bytes` / `BytesMut` structs require 4 pointer sized fields. On 64 bit +// systems, this ends up being 32 bytes, which is actually a lot of storage for +// cases where `Bytes` is being used to represent small byte strings, such as +// HTTP header names and values. +// +// To avoid any allocation at all in these cases, `Bytes` will use the struct +// itself for storing the buffer, reserving 1 byte for meta data. This means +// that, on 64 bit systems, 31 byte buffers require no allocation at all. +// +// The byte used for metadata stores a 2 bits flag used to indicate that the +// buffer is stored inline as well as 6 bits for tracking the buffer length (the +// return value of `Bytes::len`). +// +// ## Static buffers +// +// `Bytes` can also represent a static buffer, which is created with +// `Bytes::from_static`. No copying or allocations are required for tracking +// static buffers. The pointer to the `&'static [u8]`, the length, and a flag +// tracking that the `Bytes` instance represents a static buffer is stored in +// the `Bytes` struct. +// +// # Struct layout +// +// Both `Bytes` and `BytesMut` are wrappers around `Inner`, which provides the +// data fields as well as all of the function implementations. +// +// The `Inner` struct is carefully laid out in order to support the +// functionality described above as well as being as small as possible. Size is +// important as growing the size of the `Bytes` struct from 32 bytes to 40 bytes +// added as much as 15% overhead in benchmarks using `Bytes` in an HTTP header +// map structure. +// +// The `Inner` struct contains the following fields: +// +// * `ptr: *mut u8` +// * `len: usize` +// * `cap: usize` +// * `arc: AtomicPtr` +// +// ## `ptr: *mut u8` +// +// A pointer to start of the handle's buffer view. When backed by a `Vec`, +// this is always the `Vec`'s pointer. When backed by an `Arc>`, `ptr` +// may have been shifted to point somewhere inside the buffer. +// +// When in "inlined" mode, `ptr` is used as part of the inlined buffer. +// +// ## `len: usize` +// +// The length of the handle's buffer view. When backed by a `Vec`, this is +// always the `Vec`'s length. The slice represented by `ptr` and `len` should +// (ideally) always be initialized memory. +// +// When in "inlined" mode, `len` is used as part of the inlined buffer. +// +// ## `cap: usize` +// +// The capacity of the handle's buffer view. When backed by a `Vec`, this is +// always the `Vec`'s capacity. The slice represented by `ptr+len` and `cap-len` +// may or may not be initialized memory. +// +// When in "inlined" mode, `cap` is used as part of the inlined buffer. +// +// ## `arc: AtomicPtr` +// +// When `Inner` is in allocated mode (backed by Vec or Arc>), this +// will be the pointer to the `Arc` structure tracking the ref count for the +// underlying buffer. When the pointer is null, then the `Arc` has not been +// allocated yet and `self` is the only outstanding handle for the underlying +// buffer. +// +// The lower two bits of `arc` are used to track the storage mode of `Inner`. +// `0b01` indicates inline storage, `0b10` indicates static storage, and `0b11` +// indicates vector storage, not yet promoted to Arc. Since pointers to +// allocated structures are aligned, the lower two bits of a pointer will always +// be 0. This allows disambiguating between a pointer and the two flags. +// +// When in "inlined" mode, the least significant byte of `arc` is also used to +// store the length of the buffer view (vs. the capacity, which is a constant). +// +// The rest of `arc`'s bytes are used as part of the inline buffer, which means +// that those bytes need to be located next to the `ptr`, `len`, and `cap` +// fields, which make up the rest of the inline buffer. This requires special +// casing the layout of `Inner` depending on if the target platform is big or +// little endian. +// +// On little endian platforms, the `arc` field must be the first field in the +// struct. On big endian platforms, the `arc` field must be the last field in +// the struct. Since a deterministic struct layout is required, `Inner` is +// annotated with `#[repr(C)]`. +// +// # Thread safety +// +// `Bytes::clone()` returns a new `Bytes` handle with no copying. This is done +// by bumping the buffer ref count and returning a new struct pointing to the +// same buffer. However, the `Arc` structure is lazily allocated. This means +// that if `Bytes` is stored itself in an `Arc` (`Arc`), the `clone` +// function can be called concurrently from multiple threads. This is why an +// `AtomicPtr` is used for the `arc` field vs. a `*const`. +// +// Care is taken to ensure that the need for synchronization is minimized. Most +// operations do not require any synchronization. +// +#[cfg(target_endian = "little")] +#[repr(C)] +struct Inner { + // WARNING: Do not access the fields directly unless you know what you are + // doing. Instead, use the fns. See implementation comment above. + arc: AtomicPtr, + ptr: *mut u8, + len: usize, + cap: usize, +} + +#[cfg(target_endian = "big")] +#[repr(C)] +struct Inner { + // WARNING: Do not access the fields directly unless you know what you are + // doing. Instead, use the fns. See implementation comment above. + ptr: *mut u8, + len: usize, + cap: usize, + arc: AtomicPtr, +} + +// Thread-safe reference-counted container for the shared storage. This mostly +// the same as `std::sync::Arc` but without the weak counter. The ref counting +// fns are based on the ones found in `std`. +// +// The main reason to use `Shared` instead of `std::sync::Arc` is that it ends +// up making the overall code simpler and easier to reason about. This is due to +// some of the logic around setting `Inner::arc` and other ways the `arc` field +// is used. Using `Arc` ended up requiring a number of funky transmutes and +// other shenanigans to make it work. +struct Shared { + vec: Vec, + original_capacity_repr: usize, + ref_count: AtomicUsize, +} + +// Buffer storage strategy flags. +const KIND_ARC: usize = 0b00; +const KIND_INLINE: usize = 0b01; +const KIND_STATIC: usize = 0b10; +const KIND_VEC: usize = 0b11; +const KIND_MASK: usize = 0b11; + +// The max original capacity value. Any `Bytes` allocated with a greater initial +// capacity will default to this. +const MAX_ORIGINAL_CAPACITY_WIDTH: usize = 17; +// The original capacity algorithm will not take effect unless the originally +// allocated capacity was at least 1kb in size. +const MIN_ORIGINAL_CAPACITY_WIDTH: usize = 10; +// The original capacity is stored in powers of 2 starting at 1kb to a max of +// 64kb. Representing it as such requires only 3 bits of storage. +const ORIGINAL_CAPACITY_MASK: usize = 0b11100; +const ORIGINAL_CAPACITY_OFFSET: usize = 2; + +// When the storage is in the `Vec` representation, the pointer can be advanced +// at most this value. This is due to the amount of storage available to track +// the offset is usize - number of KIND bits and number of ORIGINAL_CAPACITY +// bits. +const VEC_POS_OFFSET: usize = 5; +const MAX_VEC_POS: usize = usize::MAX >> VEC_POS_OFFSET; +const NOT_VEC_POS_MASK: usize = 0b11111; + +// Bit op constants for extracting the inline length value from the `arc` field. +const INLINE_LEN_MASK: usize = 0b11111100; +const INLINE_LEN_OFFSET: usize = 2; + +// Byte offset from the start of `Inner` to where the inline buffer data +// starts. On little endian platforms, the first byte of the struct is the +// storage flag, so the data is shifted by a byte. On big endian systems, the +// data starts at the beginning of the struct. +#[cfg(target_endian = "little")] +const INLINE_DATA_OFFSET: isize = 1; +#[cfg(target_endian = "big")] +const INLINE_DATA_OFFSET: isize = 0; + +#[cfg(target_pointer_width = "64")] +const PTR_WIDTH: usize = 64; +#[cfg(target_pointer_width = "32")] +const PTR_WIDTH: usize = 32; + +// Inline buffer capacity. This is the size of `Inner` minus 1 byte for the +// metadata. +#[cfg(target_pointer_width = "64")] +const INLINE_CAP: usize = 4 * 8 - 1; +#[cfg(target_pointer_width = "32")] +const INLINE_CAP: usize = 4 * 4 - 1; + +/* + * + * ===== Bytes ===== + * + */ + +impl Bytes { + /// Creates a new `Bytes` with the specified capacity. + /// + /// The returned `Bytes` will be able to hold at least `capacity` bytes + /// without reallocating. If `capacity` is under `4 * size_of::() - 1`, + /// then `BytesMut` will not allocate. + /// + /// It is important to note that this function does not specify the length + /// of the returned `Bytes`, but only the capacity. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut bytes = Bytes::with_capacity(64); + /// + /// // `bytes` contains no data, even though there is capacity + /// assert_eq!(bytes.len(), 0); + /// + /// bytes.extend_from_slice(&b"hello world"[..]); + /// + /// assert_eq!(&bytes[..], b"hello world"); + /// ``` + #[inline] + pub fn with_capacity(capacity: usize) -> Bytes { + Bytes { + inner: Inner::with_capacity(capacity), + } + } + + /// Creates a new empty `Bytes`. + /// + /// This will not allocate and the returned `Bytes` handle will be empty. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::new(); + /// assert_eq!(&b[..], b""); + /// ``` + #[inline] + pub fn new() -> Bytes { + Bytes::with_capacity(0) + } + + /// Creates a new `Bytes` from a static slice. + /// + /// The returned `Bytes` will point directly to the static slice. There is + /// no allocating or copying. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::from_static(b"hello"); + /// assert_eq!(&b[..], b"hello"); + /// ``` + #[inline] + pub fn from_static(bytes: &'static [u8]) -> Bytes { + Bytes { + inner: Inner::from_static(bytes), + } + } + + /// Returns the number of bytes contained in this `Bytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::from(&b"hello"[..]); + /// assert_eq!(b.len(), 5); + /// ``` + #[inline] + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Returns true if the `Bytes` has a length of 0. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let b = Bytes::new(); + /// assert!(b.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + /// Returns a slice of self for the index range `[begin..end)`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice(2, 5); + /// + /// assert_eq!(&b[..], b"llo"); + /// ``` + /// + /// # Panics + /// + /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing + /// will panic. + pub fn slice(&self, begin: usize, end: usize) -> Bytes { + assert!(begin <= end); + assert!(end <= self.len()); + + if end - begin <= INLINE_CAP { + return Bytes::from(&self[begin..end]); + } + + let mut ret = self.clone(); + + unsafe { + ret.inner.set_end(end); + ret.inner.set_start(begin); + } + + ret + } + + /// Returns a slice of self for the index range `[begin..self.len())`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)` and is equivalent to `self.slice(begin, + /// self.len())`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice_from(6); + /// + /// assert_eq!(&b[..], b"world"); + /// ``` + /// + /// # Panics + /// + /// Requires that `begin <= self.len()`, otherwise slicing will panic. + pub fn slice_from(&self, begin: usize) -> Bytes { + self.slice(begin, self.len()) + } + + /// Returns a slice of self for the index range `[0..end)`. + /// + /// This will increment the reference count for the underlying memory and + /// return a new `Bytes` handle set to the slice. + /// + /// This operation is `O(1)` and is equivalent to `self.slice(0, end)`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"hello world"[..]); + /// let b = a.slice_to(5); + /// + /// assert_eq!(&b[..], b"hello"); + /// ``` + /// + /// # Panics + /// + /// Requires that `end <= self.len()`, otherwise slicing will panic. + pub fn slice_to(&self, end: usize) -> Bytes { + self.slice(0, end) + } + + /// Returns a slice of self that is equivalent to the given `subset`. + /// + /// When processing a `Bytes` buffer with other tools, one often gets a + /// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it. + /// This function turns that `&[u8]` into another `Bytes`, as if one had + /// called `self.slice()` with the offsets that correspond to `subset`. + /// + /// This operation is `O(1)`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let bytes = Bytes::from(&b"012345678"[..]); + /// let as_slice = bytes.as_ref(); + /// let subset = &as_slice[2..6]; + /// let subslice = bytes.slice_ref(&subset); + /// assert_eq!(&subslice[..], b"2345"); + /// ``` + /// + /// # Panics + /// + /// Requires that the given `sub` slice is in fact contained within the + /// `Bytes` buffer; otherwise this function will panic. + pub fn slice_ref(&self, subset: &[u8]) -> Bytes { + let bytes_p = self.as_ptr() as usize; + let bytes_len = self.len(); + + let sub_p = subset.as_ptr() as usize; + let sub_len = subset.len(); + + assert!(sub_p >= bytes_p); + assert!(sub_p + sub_len <= bytes_p + bytes_len); + + let sub_offset = sub_p - bytes_p; + + self.slice(sub_offset, sub_offset + sub_len) + } + + /// Splits the bytes into two at the given index. + /// + /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes` + /// contains elements `[at, len)`. + /// + /// This is an `O(1)` operation that just increases the reference count and + /// sets a few indices. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut a = Bytes::from(&b"hello world"[..]); + /// let b = a.split_off(5); + /// + /// assert_eq!(&a[..], b"hello"); + /// assert_eq!(&b[..], b" world"); + /// ``` + /// + /// # Panics + /// + /// Panics if `at > len`. + pub fn split_off(&mut self, at: usize) -> Bytes { + assert!(at <= self.len()); + + if at == self.len() { + return Bytes::new(); + } + + if at == 0 { + return mem::replace(self, Bytes::new()); + } + + Bytes { + inner: self.inner.split_off(at), + } + } + + /// Splits the bytes into two at the given index. + /// + /// Afterwards `self` contains elements `[at, len)`, and the returned + /// `Bytes` contains elements `[0, at)`. + /// + /// This is an `O(1)` operation that just increases the reference count and + /// sets a few indices. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut a = Bytes::from(&b"hello world"[..]); + /// let b = a.split_to(5); + /// + /// assert_eq!(&a[..], b" world"); + /// assert_eq!(&b[..], b"hello"); + /// ``` + /// + /// # Panics + /// + /// Panics if `at > len`. + pub fn split_to(&mut self, at: usize) -> Bytes { + assert!(at <= self.len()); + + if at == self.len() { + return mem::replace(self, Bytes::new()); + } + + if at == 0 { + return Bytes::new(); + } + + Bytes { + inner: self.inner.split_to(at), + } + } + + #[deprecated(since = "0.4.1", note = "use split_to instead")] + #[doc(hidden)] + pub fn drain_to(&mut self, at: usize) -> Bytes { + self.split_to(at) + } + + /// Shortens the buffer, keeping the first `len` bytes and dropping the + /// rest. + /// + /// If `len` is greater than the buffer's current length, this has no + /// effect. + /// + /// The [`split_off`] method can emulate `truncate`, but this causes the + /// excess bytes to be returned instead of dropped. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut buf = Bytes::from(&b"hello world"[..]); + /// buf.truncate(5); + /// assert_eq!(buf, b"hello"[..]); + /// ``` + /// + /// [`split_off`]: #method.split_off + pub fn truncate(&mut self, len: usize) { + self.inner.truncate(len); + } + + /// Shortens the buffer, dropping the first `cnt` bytes and keeping the + /// rest. + /// + /// This is the same function as `Buf::advance`, and in the next breaking + /// release of `bytes`, this implementation will be removed in favor of + /// having `Bytes` implement `Buf`. + /// + /// # Panics + /// + /// This function panics if `cnt` is greater than `self.len()` + #[inline] + pub fn advance(&mut self, cnt: usize) { + assert!(cnt <= self.len(), "cannot advance past `remaining`"); + unsafe { self.inner.set_start(cnt); } + } + + /// Clears the buffer, removing all data. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut buf = Bytes::from(&b"hello world"[..]); + /// buf.clear(); + /// assert!(buf.is_empty()); + /// ``` + pub fn clear(&mut self) { + self.truncate(0); + } + + /// Attempts to convert into a `BytesMut` handle. + /// + /// This will only succeed if there are no other outstanding references to + /// the underlying chunk of memory. `Bytes` handles that contain inlined + /// bytes will always be convertable to `BytesMut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let a = Bytes::from(&b"Mary had a little lamb, little lamb, little lamb..."[..]); + /// + /// // Create a shallow clone + /// let b = a.clone(); + /// + /// // This will fail because `b` shares a reference with `a` + /// let a = a.try_mut().unwrap_err(); + /// + /// drop(b); + /// + /// // This will succeed + /// let mut a = a.try_mut().unwrap(); + /// + /// a[0] = b'b'; + /// + /// assert_eq!(&a[..4], b"bary"); + /// ``` + pub fn try_mut(mut self) -> Result { + if self.inner.is_mut_safe() { + Ok(BytesMut { inner: self.inner }) + } else { + Err(self) + } + } + + /// Appends given bytes to this object. + /// + /// If this `Bytes` object has not enough capacity, it is resized first. + /// If it is shared (`refcount > 1`), it is copied first. + /// + /// This operation can be less effective than the similar operation on + /// `BytesMut`, especially on small additions. + /// + /// # Examples + /// + /// ``` + /// use bytes::Bytes; + /// + /// let mut buf = Bytes::from("aabb"); + /// buf.extend_from_slice(b"ccdd"); + /// buf.extend_from_slice(b"eeff"); + /// + /// assert_eq!(b"aabbccddeeff", &buf[..]); + /// ``` + pub fn extend_from_slice(&mut self, extend: &[u8]) { + if extend.is_empty() { + return; + } + + let new_cap = self.len().checked_add(extend.len()).expect("capacity overflow"); + + let result = match mem::replace(self, Bytes::new()).try_mut() { + Ok(mut bytes_mut) => { + bytes_mut.extend_from_slice(extend); + bytes_mut + }, + Err(bytes) => { + let mut bytes_mut = BytesMut::with_capacity(new_cap); + bytes_mut.put_slice(&bytes); + bytes_mut.put_slice(extend); + bytes_mut + } + }; + + mem::replace(self, result.freeze()); + } +} + +impl IntoBuf for Bytes { + type Buf = Cursor; + + fn into_buf(self) -> Self::Buf { + Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a Bytes { + type Buf = Cursor; + + fn into_buf(self) -> Self::Buf { + Cursor::new(self) + } +} + +impl Clone for Bytes { + fn clone(&self) -> Bytes { + Bytes { + inner: unsafe { self.inner.shallow_clone(false) }, + } + } +} + +impl AsRef<[u8]> for Bytes { + #[inline] + fn as_ref(&self) -> &[u8] { + self.inner.as_ref() + } +} + +impl ops::Deref for Bytes { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + self.inner.as_ref() + } +} + +impl From for Bytes { + fn from(src: BytesMut) -> Bytes { + src.freeze() + } +} + +impl From> for Bytes { + fn from(src: Vec) -> Bytes { + BytesMut::from(src).freeze() + } +} + +impl From for Bytes { + fn from(src: String) -> Bytes { + BytesMut::from(src).freeze() + } +} + +impl<'a> From<&'a [u8]> for Bytes { + fn from(src: &'a [u8]) -> Bytes { + BytesMut::from(src).freeze() + } +} + +impl<'a> From<&'a str> for Bytes { + fn from(src: &'a str) -> Bytes { + BytesMut::from(src).freeze() + } +} + +impl FromIterator for BytesMut { + fn from_iter>(into_iter: T) -> Self { + let iter = into_iter.into_iter(); + let (min, maybe_max) = iter.size_hint(); + + let mut out = BytesMut::with_capacity(maybe_max.unwrap_or(min)); + + for i in iter { + out.reserve(1); + out.put(i); + } + + out + } +} + +impl FromIterator for Bytes { + fn from_iter>(into_iter: T) -> Self { + BytesMut::from_iter(into_iter).freeze() + } +} + +impl<'a> FromIterator<&'a u8> for BytesMut { + fn from_iter>(into_iter: T) -> Self { + BytesMut::from_iter(into_iter.into_iter().map(|b| *b)) + } +} + +impl<'a> FromIterator<&'a u8> for Bytes { + fn from_iter>(into_iter: T) -> Self { + BytesMut::from_iter(into_iter).freeze() + } +} + +impl PartialEq for Bytes { + fn eq(&self, other: &Bytes) -> bool { + self.inner.as_ref() == other.inner.as_ref() + } +} + +impl PartialOrd for Bytes { + fn partial_cmp(&self, other: &Bytes) -> Option { + self.inner.as_ref().partial_cmp(other.inner.as_ref()) + } +} + +impl Ord for Bytes { + fn cmp(&self, other: &Bytes) -> cmp::Ordering { + self.inner.as_ref().cmp(other.inner.as_ref()) + } +} + +impl Eq for Bytes { +} + +impl Default for Bytes { + #[inline] + fn default() -> Bytes { + Bytes::new() + } +} + +impl fmt::Debug for Bytes { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&debug::BsDebug(&self.inner.as_ref()), fmt) + } +} + +impl hash::Hash for Bytes { + fn hash(&self, state: &mut H) where H: hash::Hasher { + let s: &[u8] = self.as_ref(); + s.hash(state); + } +} + +impl Borrow<[u8]> for Bytes { + fn borrow(&self) -> &[u8] { + self.as_ref() + } +} + +impl IntoIterator for Bytes { + type Item = u8; + type IntoIter = Iter>; + + fn into_iter(self) -> Self::IntoIter { + self.into_buf().iter() + } +} + +impl<'a> IntoIterator for &'a Bytes { + type Item = u8; + type IntoIter = Iter>; + + fn into_iter(self) -> Self::IntoIter { + self.into_buf().iter() + } +} + +impl Extend for Bytes { + fn extend(&mut self, iter: T) where T: IntoIterator { + let iter = iter.into_iter(); + + let (lower, upper) = iter.size_hint(); + + // Avoid possible conversion into mut if there's nothing to add + if let Some(0) = upper { + return; + } + + let mut bytes_mut = match mem::replace(self, Bytes::new()).try_mut() { + Ok(bytes_mut) => bytes_mut, + Err(bytes) => { + let mut bytes_mut = BytesMut::with_capacity(bytes.len() + lower); + bytes_mut.put_slice(&bytes); + bytes_mut + } + }; + + bytes_mut.extend(iter); + + mem::replace(self, bytes_mut.freeze()); + } +} + +impl<'a> Extend<&'a u8> for Bytes { + fn extend(&mut self, iter: T) where T: IntoIterator { + self.extend(iter.into_iter().map(|b| *b)) + } +} + +/* + * + * ===== BytesMut ===== + * + */ + +impl BytesMut { + /// Creates a new `BytesMut` with the specified capacity. + /// + /// The returned `BytesMut` will be able to hold at least `capacity` bytes + /// without reallocating. If `capacity` is under `4 * size_of::() - 1`, + /// then `BytesMut` will not allocate. + /// + /// It is important to note that this function does not specify the length + /// of the returned `BytesMut`, but only the capacity. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// + /// let mut bytes = BytesMut::with_capacity(64); + /// + /// // `bytes` contains no data, even though there is capacity + /// assert_eq!(bytes.len(), 0); + /// + /// bytes.put(&b"hello world"[..]); + /// + /// assert_eq!(&bytes[..], b"hello world"); + /// ``` + #[inline] + pub fn with_capacity(capacity: usize) -> BytesMut { + BytesMut { + inner: Inner::with_capacity(capacity), + } + } + + /// Creates a new `BytesMut` with default capacity. + /// + /// Resulting object has length 0 and unspecified capacity. + /// This function does not allocate. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// + /// let mut bytes = BytesMut::new(); + /// + /// assert_eq!(0, bytes.len()); + /// + /// bytes.reserve(2); + /// bytes.put_slice(b"xy"); + /// + /// assert_eq!(&b"xy"[..], &bytes[..]); + /// ``` + #[inline] + pub fn new() -> BytesMut { + BytesMut::with_capacity(0) + } + + /// Returns the number of bytes contained in this `BytesMut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::from(&b"hello"[..]); + /// assert_eq!(b.len(), 5); + /// ``` + #[inline] + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Returns true if the `BytesMut` has a length of 0. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::with_capacity(64); + /// assert!(b.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the number of bytes the `BytesMut` can hold without reallocating. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let b = BytesMut::with_capacity(64); + /// assert_eq!(b.capacity(), 64); + /// ``` + #[inline] + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + /// Converts `self` into an immutable `Bytes`. + /// + /// The conversion is zero cost and is used to indicate that the slice + /// referenced by the handle will no longer be mutated. Once the conversion + /// is done, the handle can be cloned and shared across threads. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// use std::thread; + /// + /// let mut b = BytesMut::with_capacity(64); + /// b.put("hello world"); + /// let b1 = b.freeze(); + /// let b2 = b1.clone(); + /// + /// let th = thread::spawn(move || { + /// assert_eq!(&b1[..], b"hello world"); + /// }); + /// + /// assert_eq!(&b2[..], b"hello world"); + /// th.join().unwrap(); + /// ``` + #[inline] + pub fn freeze(self) -> Bytes { + Bytes { inner: self.inner } + } + + /// Splits the bytes into two at the given index. + /// + /// Afterwards `self` contains elements `[0, at)`, and the returned + /// `BytesMut` contains elements `[at, capacity)`. + /// + /// This is an `O(1)` operation that just increases the reference count + /// and sets a few indices. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let mut b = a.split_off(5); + /// + /// a[0] = b'j'; + /// b[0] = b'!'; + /// + /// assert_eq!(&a[..], b"jello"); + /// assert_eq!(&b[..], b"!world"); + /// ``` + /// + /// # Panics + /// + /// Panics if `at > capacity`. + pub fn split_off(&mut self, at: usize) -> BytesMut { + BytesMut { + inner: self.inner.split_off(at), + } + } + + /// Removes the bytes from the current view, returning them in a new + /// `BytesMut` handle. + /// + /// Afterwards, `self` will be empty, but will retain any additional + /// capacity that it had before the operation. This is identical to + /// `self.split_to(self.len())`. + /// + /// This is an `O(1)` operation that just increases the reference count and + /// sets a few indices. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// + /// let mut buf = BytesMut::with_capacity(1024); + /// buf.put(&b"hello world"[..]); + /// + /// let other = buf.take(); + /// + /// assert!(buf.is_empty()); + /// assert_eq!(1013, buf.capacity()); + /// + /// assert_eq!(other, b"hello world"[..]); + /// ``` + pub fn take(&mut self) -> BytesMut { + let len = self.len(); + self.split_to(len) + } + + #[deprecated(since = "0.4.1", note = "use take instead")] + #[doc(hidden)] + pub fn drain(&mut self) -> BytesMut { + self.take() + } + + /// Splits the buffer into two at the given index. + /// + /// Afterwards `self` contains elements `[at, len)`, and the returned `BytesMut` + /// contains elements `[0, at)`. + /// + /// This is an `O(1)` operation that just increases the reference count and + /// sets a few indices. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut a = BytesMut::from(&b"hello world"[..]); + /// let mut b = a.split_to(5); + /// + /// a[0] = b'!'; + /// b[0] = b'j'; + /// + /// assert_eq!(&a[..], b"!world"); + /// assert_eq!(&b[..], b"jello"); + /// ``` + /// + /// # Panics + /// + /// Panics if `at > len`. + pub fn split_to(&mut self, at: usize) -> BytesMut { + BytesMut { + inner: self.inner.split_to(at), + } + } + + #[deprecated(since = "0.4.1", note = "use split_to instead")] + #[doc(hidden)] + pub fn drain_to(&mut self, at: usize) -> BytesMut { + self.split_to(at) + } + + /// Shortens the buffer, keeping the first `len` bytes and dropping the + /// rest. + /// + /// If `len` is greater than the buffer's current length, this has no + /// effect. + /// + /// The [`split_off`] method can emulate `truncate`, but this causes the + /// excess bytes to be returned instead of dropped. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::from(&b"hello world"[..]); + /// buf.truncate(5); + /// assert_eq!(buf, b"hello"[..]); + /// ``` + /// + /// [`split_off`]: #method.split_off + pub fn truncate(&mut self, len: usize) { + self.inner.truncate(len); + } + + /// Shortens the buffer, dropping the first `cnt` bytes and keeping the + /// rest. + /// + /// This is the same function as `Buf::advance`, and in the next breaking + /// release of `bytes`, this implementation will be removed in favor of + /// having `BytesMut` implement `Buf`. + /// + /// # Panics + /// + /// This function panics if `cnt` is greater than `self.len()` + #[inline] + pub fn advance(&mut self, cnt: usize) { + assert!(cnt <= self.len(), "cannot advance past `remaining`"); + unsafe { self.inner.set_start(cnt); } + } + + /// Clears the buffer, removing all data. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::from(&b"hello world"[..]); + /// buf.clear(); + /// assert!(buf.is_empty()); + /// ``` + pub fn clear(&mut self) { + self.truncate(0); + } + + /// Resizes the buffer so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the buffer is extended by the + /// difference with each additional byte set to `value`. If `new_len` is + /// less than `len`, the buffer is simply truncated. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::new(); + /// + /// buf.resize(3, 0x1); + /// assert_eq!(&buf[..], &[0x1, 0x1, 0x1]); + /// + /// buf.resize(2, 0x2); + /// assert_eq!(&buf[..], &[0x1, 0x1]); + /// + /// buf.resize(4, 0x3); + /// assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]); + /// ``` + pub fn resize(&mut self, new_len: usize, value: u8) { + self.inner.resize(new_len, value); + } + + /// Sets the length of the buffer. + /// + /// This will explicitly set the size of the buffer without actually + /// modifying the data, so it is up to the caller to ensure that the data + /// has been initialized. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut b = BytesMut::from(&b"hello world"[..]); + /// + /// unsafe { + /// b.set_len(5); + /// } + /// + /// assert_eq!(&b[..], b"hello"); + /// + /// unsafe { + /// b.set_len(11); + /// } + /// + /// assert_eq!(&b[..], b"hello world"); + /// ``` + /// + /// # Panics + /// + /// This method will panic if `len` is out of bounds for the underlying + /// slice or if it comes after the `end` of the configured window. + pub unsafe fn set_len(&mut self, len: usize) { + self.inner.set_len(len) + } + + /// Reserves capacity for at least `additional` more bytes to be inserted + /// into the given `BytesMut`. + /// + /// More than `additional` bytes may be reserved in order to avoid frequent + /// reallocations. A call to `reserve` may result in an allocation. + /// + /// Before allocating new buffer space, the function will attempt to reclaim + /// space in the existing buffer. If the current handle references a small + /// view in the original buffer and all other handles have been dropped, + /// and the requested capacity is less than or equal to the existing + /// buffer's capacity, then the current view will be copied to the front of + /// the buffer and the handle will take ownership of the full buffer. + /// + /// # Examples + /// + /// In the following example, a new buffer is allocated. + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::from(&b"hello"[..]); + /// buf.reserve(64); + /// assert!(buf.capacity() >= 69); + /// ``` + /// + /// In the following example, the existing buffer is reclaimed. + /// + /// ``` + /// use bytes::{BytesMut, BufMut}; + /// + /// let mut buf = BytesMut::with_capacity(128); + /// buf.put(&[0; 64][..]); + /// + /// let ptr = buf.as_ptr(); + /// let other = buf.take(); + /// + /// assert!(buf.is_empty()); + /// assert_eq!(buf.capacity(), 64); + /// + /// drop(other); + /// buf.reserve(128); + /// + /// assert_eq!(buf.capacity(), 128); + /// assert_eq!(buf.as_ptr(), ptr); + /// ``` + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + pub fn reserve(&mut self, additional: usize) { + self.inner.reserve(additional) + } + + /// Appends given bytes to this object. + /// + /// If this `BytesMut` object has not enough capacity, it is resized first. + /// So unlike `put_slice` operation, `extend_from_slice` does not panic. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::with_capacity(0); + /// buf.extend_from_slice(b"aaabbb"); + /// buf.extend_from_slice(b"cccddd"); + /// + /// assert_eq!(b"aaabbbcccddd", &buf[..]); + /// ``` + pub fn extend_from_slice(&mut self, extend: &[u8]) { + self.reserve(extend.len()); + self.put_slice(extend); + } + + /// Combine splitted BytesMut objects back as contiguous. + /// + /// If `BytesMut` objects were not contiguous originally, they will be extended. + /// + /// # Examples + /// + /// ``` + /// use bytes::BytesMut; + /// + /// let mut buf = BytesMut::with_capacity(64); + /// buf.extend_from_slice(b"aaabbbcccddd"); + /// + /// let splitted = buf.split_off(6); + /// assert_eq!(b"aaabbb", &buf[..]); + /// assert_eq!(b"cccddd", &splitted[..]); + /// + /// buf.unsplit(splitted); + /// assert_eq!(b"aaabbbcccddd", &buf[..]); + /// ``` + pub fn unsplit(&mut self, other: BytesMut) { + let ptr; + + if other.is_empty() { + return; + } + + if self.is_empty() { + *self = other; + return; + } + + unsafe { + ptr = self.inner.ptr.offset(self.inner.len as isize); + } + if ptr == other.inner.ptr && + self.inner.kind() == KIND_ARC && + other.inner.kind() == KIND_ARC + { + debug_assert_eq!(self.inner.arc.load(Acquire), + other.inner.arc.load(Acquire)); + // Contiguous blocks, just combine directly + self.inner.len += other.inner.len; + self.inner.cap += other.inner.cap; + } + else { + self.extend_from_slice(&other); + } + } +} + +impl BufMut for BytesMut { + #[inline] + fn remaining_mut(&self) -> usize { + self.capacity() - self.len() + } + + #[inline] + unsafe fn advance_mut(&mut self, cnt: usize) { + let new_len = self.len() + cnt; + + // This call will panic if `cnt` is too big + self.inner.set_len(new_len); + } + + #[inline] + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + let len = self.len(); + + // This will never panic as `len` can never become invalid + &mut self.inner.as_raw()[len..] + } + + #[inline] + fn put_slice(&mut self, src: &[u8]) { + assert!(self.remaining_mut() >= src.len()); + + let len = src.len(); + + unsafe { + self.bytes_mut()[..len].copy_from_slice(src); + self.advance_mut(len); + } + } + + #[inline] + fn put_u8(&mut self, n: u8) { + self.inner.put_u8(n); + } + + #[inline] + fn put_i8(&mut self, n: i8) { + self.put_u8(n as u8); + } +} + +impl IntoBuf for BytesMut { + type Buf = Cursor; + + fn into_buf(self) -> Self::Buf { + Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a BytesMut { + type Buf = Cursor<&'a BytesMut>; + + fn into_buf(self) -> Self::Buf { + Cursor::new(self) + } +} + +impl AsRef<[u8]> for BytesMut { + #[inline] + fn as_ref(&self) -> &[u8] { + self.inner.as_ref() + } +} + +impl ops::Deref for BytesMut { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + self.as_ref() + } +} + +impl AsMut<[u8]> for BytesMut { + fn as_mut(&mut self) -> &mut [u8] { + self.inner.as_mut() + } +} + +impl ops::DerefMut for BytesMut { + #[inline] + fn deref_mut(&mut self) -> &mut [u8] { + self.inner.as_mut() + } +} + +impl From> for BytesMut { + fn from(src: Vec) -> BytesMut { + BytesMut { + inner: Inner::from_vec(src), + } + } +} + +impl From for BytesMut { + fn from(src: String) -> BytesMut { + BytesMut::from(src.into_bytes()) + } +} + +impl<'a> From<&'a [u8]> for BytesMut { + fn from(src: &'a [u8]) -> BytesMut { + let len = src.len(); + + if len == 0 { + BytesMut::new() + } else if len <= INLINE_CAP { + unsafe { + let mut inner: Inner = mem::uninitialized(); + + // Set inline mask + inner.arc = AtomicPtr::new(KIND_INLINE as *mut Shared); + inner.set_inline_len(len); + inner.as_raw()[0..len].copy_from_slice(src); + + BytesMut { + inner: inner, + } + } + } else { + BytesMut::from(src.to_vec()) + } + } +} + +impl<'a> From<&'a str> for BytesMut { + fn from(src: &'a str) -> BytesMut { + BytesMut::from(src.as_bytes()) + } +} + +impl From for BytesMut { + fn from(src: Bytes) -> BytesMut { + src.try_mut() + .unwrap_or_else(|src| BytesMut::from(&src[..])) + } +} + +impl PartialEq for BytesMut { + fn eq(&self, other: &BytesMut) -> bool { + self.inner.as_ref() == other.inner.as_ref() + } +} + +impl PartialOrd for BytesMut { + fn partial_cmp(&self, other: &BytesMut) -> Option { + self.inner.as_ref().partial_cmp(other.inner.as_ref()) + } +} + +impl Ord for BytesMut { + fn cmp(&self, other: &BytesMut) -> cmp::Ordering { + self.inner.as_ref().cmp(other.inner.as_ref()) + } +} + +impl Eq for BytesMut { +} + +impl Default for BytesMut { + #[inline] + fn default() -> BytesMut { + BytesMut::new() + } +} + +impl fmt::Debug for BytesMut { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&debug::BsDebug(&self.inner.as_ref()), fmt) + } +} + +impl hash::Hash for BytesMut { + fn hash(&self, state: &mut H) where H: hash::Hasher { + let s: &[u8] = self.as_ref(); + s.hash(state); + } +} + +impl Borrow<[u8]> for BytesMut { + fn borrow(&self) -> &[u8] { + self.as_ref() + } +} + +impl BorrowMut<[u8]> for BytesMut { + fn borrow_mut(&mut self) -> &mut [u8] { + self.as_mut() + } +} + +impl fmt::Write for BytesMut { + #[inline] + fn write_str(&mut self, s: &str) -> fmt::Result { + if self.remaining_mut() >= s.len() { + self.put_slice(s.as_bytes()); + Ok(()) + } else { + Err(fmt::Error) + } + } + + #[inline] + fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result { + fmt::write(self, args) + } +} + +impl Clone for BytesMut { + fn clone(&self) -> BytesMut { + BytesMut::from(&self[..]) + } +} + +impl IntoIterator for BytesMut { + type Item = u8; + type IntoIter = Iter>; + + fn into_iter(self) -> Self::IntoIter { + self.into_buf().iter() + } +} + +impl<'a> IntoIterator for &'a BytesMut { + type Item = u8; + type IntoIter = Iter>; + + fn into_iter(self) -> Self::IntoIter { + self.into_buf().iter() + } +} + +impl Extend for BytesMut { + fn extend(&mut self, iter: T) where T: IntoIterator { + let iter = iter.into_iter(); + + let (lower, _) = iter.size_hint(); + self.reserve(lower); + + for b in iter { + unsafe { + self.bytes_mut()[0] = b; + self.advance_mut(1); + } + } + } +} + +impl<'a> Extend<&'a u8> for BytesMut { + fn extend(&mut self, iter: T) where T: IntoIterator { + self.extend(iter.into_iter().map(|b| *b)) + } +} + +/* + * + * ===== Inner ===== + * + */ + +impl Inner { + #[inline] + fn from_static(bytes: &'static [u8]) -> Inner { + let ptr = bytes.as_ptr() as *mut u8; + + Inner { + // `arc` won't ever store a pointer. Instead, use it to + // track the fact that the `Bytes` handle is backed by a + // static buffer. + arc: AtomicPtr::new(KIND_STATIC as *mut Shared), + ptr: ptr, + len: bytes.len(), + cap: bytes.len(), + } + } + + #[inline] + fn from_vec(mut src: Vec) -> Inner { + let len = src.len(); + let cap = src.capacity(); + let ptr = src.as_mut_ptr(); + + mem::forget(src); + + let original_capacity_repr = original_capacity_to_repr(cap); + let arc = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC; + + Inner { + arc: AtomicPtr::new(arc as *mut Shared), + ptr: ptr, + len: len, + cap: cap, + } + } + + #[inline] + fn with_capacity(capacity: usize) -> Inner { + if capacity <= INLINE_CAP { + unsafe { + // Using uninitialized memory is ~30% faster + let mut inner: Inner = mem::uninitialized(); + inner.arc = AtomicPtr::new(KIND_INLINE as *mut Shared); + inner + } + } else { + Inner::from_vec(Vec::with_capacity(capacity)) + } + } + + /// Return a slice for the handle's view into the shared buffer + #[inline] + fn as_ref(&self) -> &[u8] { + unsafe { + if self.is_inline() { + slice::from_raw_parts(self.inline_ptr(), self.inline_len()) + } else { + slice::from_raw_parts(self.ptr, self.len) + } + } + } + + /// Return a mutable slice for the handle's view into the shared buffer + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + debug_assert!(!self.is_static()); + + unsafe { + if self.is_inline() { + slice::from_raw_parts_mut(self.inline_ptr(), self.inline_len()) + } else { + slice::from_raw_parts_mut(self.ptr, self.len) + } + } + } + + /// Return a mutable slice for the handle's view into the shared buffer + /// including potentially uninitialized bytes. + #[inline] + unsafe fn as_raw(&mut self) -> &mut [u8] { + debug_assert!(!self.is_static()); + + if self.is_inline() { + slice::from_raw_parts_mut(self.inline_ptr(), INLINE_CAP) + } else { + slice::from_raw_parts_mut(self.ptr, self.cap) + } + } + + /// Insert a byte into the next slot and advance the len by 1. + #[inline] + fn put_u8(&mut self, n: u8) { + if self.is_inline() { + let len = self.inline_len(); + assert!(len < INLINE_CAP); + unsafe { + *self.inline_ptr().offset(len as isize) = n; + } + self.set_inline_len(len + 1); + } else { + assert!(self.len < self.cap); + unsafe { + *self.ptr.offset(self.len as isize) = n; + } + self.len += 1; + } + } + + #[inline] + fn len(&self) -> usize { + if self.is_inline() { + self.inline_len() + } else { + self.len + } + } + + /// Pointer to the start of the inline buffer + #[inline] + unsafe fn inline_ptr(&self) -> *mut u8 { + (self as *const Inner as *mut Inner as *mut u8) + .offset(INLINE_DATA_OFFSET) + } + + #[inline] + fn inline_len(&self) -> usize { + let p: &usize = unsafe { mem::transmute(&self.arc) }; + (p & INLINE_LEN_MASK) >> INLINE_LEN_OFFSET + } + + /// Set the length of the inline buffer. This is done by writing to the + /// least significant byte of the `arc` field. + #[inline] + fn set_inline_len(&mut self, len: usize) { + debug_assert!(len <= INLINE_CAP); + let p = self.arc.get_mut(); + *p = ((*p as usize & !INLINE_LEN_MASK) | (len << INLINE_LEN_OFFSET)) as _; + } + + /// slice. + #[inline] + unsafe fn set_len(&mut self, len: usize) { + if self.is_inline() { + assert!(len <= INLINE_CAP); + self.set_inline_len(len); + } else { + assert!(len <= self.cap); + self.len = len; + } + } + + #[inline] + fn is_empty(&self) -> bool { + self.len() == 0 + } + + #[inline] + fn capacity(&self) -> usize { + if self.is_inline() { + INLINE_CAP + } else { + self.cap + } + } + + fn split_off(&mut self, at: usize) -> Inner { + let mut other = unsafe { self.shallow_clone(true) }; + + unsafe { + other.set_start(at); + self.set_end(at); + } + + return other + } + + fn split_to(&mut self, at: usize) -> Inner { + let mut other = unsafe { self.shallow_clone(true) }; + + unsafe { + other.set_end(at); + self.set_start(at); + } + + return other + } + + fn truncate(&mut self, len: usize) { + if len <= self.len() { + unsafe { self.set_len(len); } + } + } + + fn resize(&mut self, new_len: usize, value: u8) { + let len = self.len(); + if new_len > len { + let additional = new_len - len; + self.reserve(additional); + unsafe { + let dst = self.as_raw()[len..].as_mut_ptr(); + ptr::write_bytes(dst, value, additional); + self.set_len(new_len); + } + } else { + self.truncate(new_len); + } + } + + unsafe fn set_start(&mut self, start: usize) { + // Setting the start to 0 is a no-op, so return early if this is the + // case. + if start == 0 { + return; + } + + let kind = self.kind(); + + // Always check `inline` first, because if the handle is using inline + // data storage, all of the `Inner` struct fields will be gibberish. + if kind == KIND_INLINE { + assert!(start <= INLINE_CAP); + + let len = self.inline_len(); + + if len <= start { + self.set_inline_len(0); + } else { + // `set_start` is essentially shifting data off the front of the + // view. Inlined buffers only track the length of the slice. + // So, to update the start, the data at the new starting point + // is copied to the beginning of the buffer. + let new_len = len - start; + + let dst = self.inline_ptr(); + let src = (dst as *const u8).offset(start as isize); + + ptr::copy(src, dst, new_len); + + self.set_inline_len(new_len); + } + } else { + assert!(start <= self.cap); + + if kind == KIND_VEC { + // Setting the start when in vec representation is a little more + // complicated. First, we have to track how far ahead the + // "start" of the byte buffer from the beginning of the vec. We + // also have to ensure that we don't exceed the maximum shift. + let (mut pos, prev) = self.uncoordinated_get_vec_pos(); + pos += start; + + if pos <= MAX_VEC_POS { + self.uncoordinated_set_vec_pos(pos, prev); + } else { + // The repr must be upgraded to ARC. This will never happen + // on 64 bit systems and will only happen on 32 bit systems + // when shifting past 134,217,727 bytes. As such, we don't + // worry too much about performance here. + let _ = self.shallow_clone(true); + } + } + + // Updating the start of the view is setting `ptr` to point to the + // new start and updating the `len` field to reflect the new length + // of the view. + self.ptr = self.ptr.offset(start as isize); + + if self.len >= start { + self.len -= start; + } else { + self.len = 0; + } + + self.cap -= start; + } + } + + unsafe fn set_end(&mut self, end: usize) { + debug_assert!(self.is_shared()); + + // Always check `inline` first, because if the handle is using inline + // data storage, all of the `Inner` struct fields will be gibberish. + if self.is_inline() { + assert!(end <= INLINE_CAP); + let new_len = cmp::min(self.inline_len(), end); + self.set_inline_len(new_len); + } else { + assert!(end <= self.cap); + + self.cap = end; + self.len = cmp::min(self.len, end); + } + } + + /// Checks if it is safe to mutate the memory + fn is_mut_safe(&mut self) -> bool { + let kind = self.kind(); + + // Always check `inline` first, because if the handle is using inline + // data storage, all of the `Inner` struct fields will be gibberish. + if kind == KIND_INLINE { + // Inlined buffers can always be mutated as the data is never shared + // across handles. + true + } else if kind == KIND_VEC { + true + } else if kind == KIND_STATIC { + false + } else { + // Otherwise, the underlying buffer is potentially shared with other + // handles, so the ref_count needs to be checked. + unsafe { (**self.arc.get_mut()).is_unique() } + } + } + + /// Increments the ref count. This should only be done if it is known that + /// it can be done safely. As such, this fn is not public, instead other + /// fns will use this one while maintaining the guarantees. + /// Parameter `mut_self` should only be set to `true` if caller holds + /// `&mut self` reference. + /// + /// "Safely" is defined as not exposing two `BytesMut` values that point to + /// the same byte window. + /// + /// This function is thread safe. + unsafe fn shallow_clone(&self, mut_self: bool) -> Inner { + // Always check `inline` first, because if the handle is using inline + // data storage, all of the `Inner` struct fields will be gibberish. + // + // Additionally, if kind is STATIC, then Arc is *never* changed, making + // it safe and faster to check for it now before an atomic acquire. + + if self.is_inline_or_static() { + // In this case, a shallow_clone still involves copying the data. + let mut inner: Inner = mem::uninitialized(); + ptr::copy_nonoverlapping( + self, + &mut inner, + 1, + ); + inner + } else { + self.shallow_clone_sync(mut_self) + } + } + + + #[cold] + unsafe fn shallow_clone_sync(&self, mut_self: bool) -> Inner { + // The function requires `&self`, this means that `shallow_clone` + // could be called concurrently. + // + // The first step is to load the value of `arc`. This will determine + // how to proceed. The `Acquire` ordering synchronizes with the + // `compare_and_swap` that comes later in this function. The goal is + // to ensure that if `arc` is currently set to point to a `Shared`, + // that the current thread acquires the associated memory. + let arc = self.arc.load(Acquire); + let kind = arc as usize & KIND_MASK; + + if kind == KIND_ARC { + self.shallow_clone_arc(arc) + } else { + assert!(kind == KIND_VEC); + self.shallow_clone_vec(arc as usize, mut_self) + } + } + + unsafe fn shallow_clone_arc(&self, arc: *mut Shared) -> Inner { + debug_assert!(arc as usize & KIND_MASK == KIND_ARC); + + let old_size = (*arc).ref_count.fetch_add(1, Relaxed); + + if old_size == usize::MAX { + abort(); + } + + Inner { + arc: AtomicPtr::new(arc), + .. *self + } + } + + #[cold] + unsafe fn shallow_clone_vec(&self, arc: usize, mut_self: bool) -> Inner { + // If the buffer is still tracked in a `Vec`. It is time to + // promote the vec to an `Arc`. This could potentially be called + // concurrently, so some care must be taken. + + debug_assert!(arc & KIND_MASK == KIND_VEC); + + let original_capacity_repr = + (arc as usize & ORIGINAL_CAPACITY_MASK) >> ORIGINAL_CAPACITY_OFFSET; + + // The vec offset cannot be concurrently mutated, so there + // should be no danger reading it. + let off = (arc as usize) >> VEC_POS_OFFSET; + + // First, allocate a new `Shared` instance containing the + // `Vec` fields. It's important to note that `ptr`, `len`, + // and `cap` cannot be mutated without having `&mut self`. + // This means that these fields will not be concurrently + // updated and since the buffer hasn't been promoted to an + // `Arc`, those three fields still are the components of the + // vector. + let shared = Box::new(Shared { + vec: rebuild_vec(self.ptr, self.len, self.cap, off), + original_capacity_repr: original_capacity_repr, + // Initialize refcount to 2. One for this reference, and one + // for the new clone that will be returned from + // `shallow_clone`. + ref_count: AtomicUsize::new(2), + }); + + let shared = Box::into_raw(shared); + + // The pointer should be aligned, so this assert should + // always succeed. + debug_assert!(0 == (shared as usize & 0b11)); + + // If there are no references to self in other threads, + // expensive atomic operations can be avoided. + if mut_self { + self.arc.store(shared, Relaxed); + return Inner { + arc: AtomicPtr::new(shared), + .. *self + }; + } + + // Try compare & swapping the pointer into the `arc` field. + // `Release` is used synchronize with other threads that + // will load the `arc` field. + // + // If the `compare_and_swap` fails, then the thread lost the + // race to promote the buffer to shared. The `Acquire` + // ordering will synchronize with the `compare_and_swap` + // that happened in the other thread and the `Shared` + // pointed to by `actual` will be visible. + let actual = self.arc.compare_and_swap(arc as *mut Shared, shared, AcqRel); + + if actual as usize == arc { + // The upgrade was successful, the new handle can be + // returned. + return Inner { + arc: AtomicPtr::new(shared), + .. *self + }; + } + + // The upgrade failed, a concurrent clone happened. Release + // the allocation that was made in this thread, it will not + // be needed. + let shared = Box::from_raw(shared); + mem::forget(*shared); + + // Buffer already promoted to shared storage, so increment ref + // count. + self.shallow_clone_arc(actual) + } + + #[inline] + fn reserve(&mut self, additional: usize) { + let len = self.len(); + let rem = self.capacity() - len; + + if additional <= rem { + // The handle can already store at least `additional` more bytes, so + // there is no further work needed to be done. + return; + } + + let kind = self.kind(); + + // Always check `inline` first, because if the handle is using inline + // data storage, all of the `Inner` struct fields will be gibberish. + if kind == KIND_INLINE { + let new_cap = len + additional; + + // Promote to a vector + let mut v = Vec::with_capacity(new_cap); + v.extend_from_slice(self.as_ref()); + + self.ptr = v.as_mut_ptr(); + self.len = v.len(); + self.cap = v.capacity(); + + // Since the minimum capacity is `INLINE_CAP`, don't bother encoding + // the original capacity as INLINE_CAP + self.arc = AtomicPtr::new(KIND_VEC as *mut Shared); + + mem::forget(v); + return; + } + + if kind == KIND_VEC { + // If there's enough free space before the start of the buffer, then + // just copy the data backwards and reuse the already-allocated + // space. + // + // Otherwise, since backed by a vector, use `Vec::reserve` + unsafe { + let (off, prev) = self.uncoordinated_get_vec_pos(); + + // Only reuse space if we stand to gain at least capacity/2 + // bytes of space back + if off >= additional && off >= (self.cap / 2) { + // There's space - reuse it + // + // Just move the pointer back to the start after copying + // data back. + let base_ptr = self.ptr.offset(-(off as isize)); + ptr::copy(self.ptr, base_ptr, self.len); + self.ptr = base_ptr; + self.uncoordinated_set_vec_pos(0, prev); + + // Length stays constant, but since we moved backwards we + // can gain capacity back. + self.cap += off; + } else { + // No space - allocate more + let mut v = rebuild_vec(self.ptr, self.len, self.cap, off); + v.reserve(additional); + + // Update the info + self.ptr = v.as_mut_ptr().offset(off as isize); + self.len = v.len() - off; + self.cap = v.capacity() - off; + + // Drop the vec reference + mem::forget(v); + } + return; + } + } + + let arc = *self.arc.get_mut(); + + debug_assert!(kind == KIND_ARC); + + // Reserving involves abandoning the currently shared buffer and + // allocating a new vector with the requested capacity. + // + // Compute the new capacity + let mut new_cap = len + additional; + let original_capacity; + let original_capacity_repr; + + unsafe { + original_capacity_repr = (*arc).original_capacity_repr; + original_capacity = original_capacity_from_repr(original_capacity_repr); + + // First, try to reclaim the buffer. This is possible if the current + // handle is the only outstanding handle pointing to the buffer. + if (*arc).is_unique() { + // This is the only handle to the buffer. It can be reclaimed. + // However, before doing the work of copying data, check to make + // sure that the vector has enough capacity. + let v = &mut (*arc).vec; + + if v.capacity() >= new_cap { + // The capacity is sufficient, reclaim the buffer + let ptr = v.as_mut_ptr(); + + ptr::copy(self.ptr, ptr, len); + + self.ptr = ptr; + self.cap = v.capacity(); + + return; + } + + // The vector capacity is not sufficient. The reserve request is + // asking for more than the initial buffer capacity. Allocate more + // than requested if `new_cap` is not much bigger than the current + // capacity. + // + // There are some situations, using `reserve_exact` that the + // buffer capacity could be below `original_capacity`, so do a + // check. + new_cap = cmp::max( + cmp::max(v.capacity() << 1, new_cap), + original_capacity); + } else { + new_cap = cmp::max(new_cap, original_capacity); + } + } + + // Create a new vector to store the data + let mut v = Vec::with_capacity(new_cap); + + // Copy the bytes + v.extend_from_slice(self.as_ref()); + + // Release the shared handle. This must be done *after* the bytes are + // copied. + release_shared(arc); + + // Update self + self.ptr = v.as_mut_ptr(); + self.len = v.len(); + self.cap = v.capacity(); + + let arc = (original_capacity_repr << ORIGINAL_CAPACITY_OFFSET) | KIND_VEC; + + self.arc = AtomicPtr::new(arc as *mut Shared); + + // Forget the vector handle + mem::forget(v); + } + + /// Returns true if the buffer is stored inline + #[inline] + fn is_inline(&self) -> bool { + self.kind() == KIND_INLINE + } + + #[inline] + fn is_inline_or_static(&self) -> bool { + // The value returned by `kind` isn't itself safe, but the value could + // inform what operations to take, and unsafely do something without + // synchronization. + // + // KIND_INLINE and KIND_STATIC will *never* change, so branches on that + // information is safe. + let kind = self.kind(); + kind == KIND_INLINE || kind == KIND_STATIC + } + + /// Used for `debug_assert` statements. &mut is used to guarantee that it is + /// safe to check VEC_KIND + #[inline] + fn is_shared(&mut self) -> bool { + match self.kind() { + KIND_VEC => false, + _ => true, + } + } + + /// Used for `debug_assert` statements + #[inline] + fn is_static(&mut self) -> bool { + match self.kind() { + KIND_STATIC => true, + _ => false, + } + } + + #[inline] + fn kind(&self) -> usize { + // This function is going to probably raise some eyebrows. The function + // returns true if the buffer is stored inline. This is done by checking + // the least significant bit in the `arc` field. + // + // Now, you may notice that `arc` is an `AtomicPtr` and this is + // accessing it as a normal field without performing an atomic load... + // + // Again, the function only cares about the least significant bit, and + // this bit is set when `Inner` is created and never changed after that. + // All platforms have atomic "word" operations and won't randomly flip + // bits, so even without any explicit atomic operations, reading the + // flag will be correct. + // + // This is undefind behavior due to a data race, but experimental + // evidence shows that it works in practice (discussion: + // https://internals.rust-lang.org/t/bit-wise-reasoning-for-atomic-accesses/8853). + // + // This function is very critical performance wise as it is called for + // every operation. Performing an atomic load would mess with the + // compiler's ability to optimize. Simple benchmarks show up to a 10% + // slowdown using a `Relaxed` atomic load on x86. + + #[cfg(target_endian = "little")] + #[inline] + fn imp(arc: &AtomicPtr) -> usize { + unsafe { + let p: *const u8 = mem::transmute(arc); + (*p as usize) & KIND_MASK + } + } + + #[cfg(target_endian = "big")] + #[inline] + fn imp(arc: &AtomicPtr) -> usize { + unsafe { + let p: *const usize = mem::transmute(arc); + *p & KIND_MASK + } + } + + imp(&self.arc) + } + + #[inline] + fn uncoordinated_get_vec_pos(&mut self) -> (usize, usize) { + // Similar to above, this is a pretty crazed function. This should only + // be called when in the KIND_VEC mode. This + the &mut self argument + // guarantees that there is no possibility of concurrent calls to this + // function. + let prev = unsafe { + let p: &AtomicPtr = &self.arc; + let p: *const usize = mem::transmute(p); + *p + }; + + (prev >> VEC_POS_OFFSET, prev) + } + + #[inline] + fn uncoordinated_set_vec_pos(&mut self, pos: usize, prev: usize) { + // Once more... crazy + debug_assert!(pos <= MAX_VEC_POS); + + unsafe { + let p: &mut AtomicPtr = &mut self.arc; + let p: &mut usize = mem::transmute(p); + *p = (pos << VEC_POS_OFFSET) | (prev & NOT_VEC_POS_MASK); + } + } +} + +fn rebuild_vec(ptr: *mut u8, mut len: usize, mut cap: usize, off: usize) -> Vec { + unsafe { + let ptr = ptr.offset(-(off as isize)); + len += off; + cap += off; + + Vec::from_raw_parts(ptr, len, cap) + } +} + +impl Drop for Inner { + fn drop(&mut self) { + let kind = self.kind(); + + if kind == KIND_VEC { + let (off, _) = self.uncoordinated_get_vec_pos(); + + // Vector storage, free the vector + let _ = rebuild_vec(self.ptr, self.len, self.cap, off); + } else if kind == KIND_ARC { + release_shared(*self.arc.get_mut()); + } + } +} + +fn release_shared(ptr: *mut Shared) { + // `Shared` storage... follow the drop steps from Arc. + unsafe { + if (*ptr).ref_count.fetch_sub(1, Release) != 1 { + return; + } + + // This fence is needed to prevent reordering of use of the data and + // deletion of the data. Because it is marked `Release`, the decreasing + // of the reference count synchronizes with this `Acquire` fence. This + // means that use of the data happens before decreasing the reference + // count, which happens before this fence, which happens before the + // deletion of the data. + // + // As explained in the [Boost documentation][1], + // + // > It is important to enforce any possible access to the object in one + // > thread (through an existing reference) to *happen before* deleting + // > the object in a different thread. This is achieved by a "release" + // > operation after dropping a reference (any access to the object + // > through this reference must obviously happened before), and an + // > "acquire" operation before deleting the object. + // + // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + atomic::fence(Acquire); + + // Drop the data + Box::from_raw(ptr); + } +} + +impl Shared { + fn is_unique(&self) -> bool { + // The goal is to check if the current handle is the only handle + // that currently has access to the buffer. This is done by + // checking if the `ref_count` is currently 1. + // + // The `Acquire` ordering synchronizes with the `Release` as + // part of the `fetch_sub` in `release_shared`. The `fetch_sub` + // operation guarantees that any mutations done in other threads + // are ordered before the `ref_count` is decremented. As such, + // this `Acquire` will guarantee that those mutations are + // visible to the current thread. + self.ref_count.load(Acquire) == 1 + } +} + +fn original_capacity_to_repr(cap: usize) -> usize { + let width = PTR_WIDTH - ((cap >> MIN_ORIGINAL_CAPACITY_WIDTH).leading_zeros() as usize); + cmp::min(width, MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH) +} + +fn original_capacity_from_repr(repr: usize) -> usize { + if repr == 0 { + return 0; + } + + 1 << (repr + (MIN_ORIGINAL_CAPACITY_WIDTH - 1)) +} + +#[test] +fn test_original_capacity_to_repr() { + assert_eq!(original_capacity_to_repr(0), 0); + + let max_width = 32; + + for width in 1..(max_width + 1) { + let cap = 1 << width - 1; + + let expected = if width < MIN_ORIGINAL_CAPACITY_WIDTH { + 0 + } else if width < MAX_ORIGINAL_CAPACITY_WIDTH { + width - MIN_ORIGINAL_CAPACITY_WIDTH + } else { + MAX_ORIGINAL_CAPACITY_WIDTH - MIN_ORIGINAL_CAPACITY_WIDTH + }; + + assert_eq!(original_capacity_to_repr(cap), expected); + + if width > 1 { + assert_eq!(original_capacity_to_repr(cap + 1), expected); + } + + // MIN_ORIGINAL_CAPACITY_WIDTH must be bigger than 7 to pass tests below + if width == MIN_ORIGINAL_CAPACITY_WIDTH + 1 { + assert_eq!(original_capacity_to_repr(cap - 24), expected - 1); + assert_eq!(original_capacity_to_repr(cap + 76), expected); + } else if width == MIN_ORIGINAL_CAPACITY_WIDTH + 2 { + assert_eq!(original_capacity_to_repr(cap - 1), expected - 1); + assert_eq!(original_capacity_to_repr(cap - 48), expected - 1); + } + } +} + +#[test] +fn test_original_capacity_from_repr() { + assert_eq!(0, original_capacity_from_repr(0)); + + let min_cap = 1 << MIN_ORIGINAL_CAPACITY_WIDTH; + + assert_eq!(min_cap, original_capacity_from_repr(1)); + assert_eq!(min_cap * 2, original_capacity_from_repr(2)); + assert_eq!(min_cap * 4, original_capacity_from_repr(3)); + assert_eq!(min_cap * 8, original_capacity_from_repr(4)); + assert_eq!(min_cap * 16, original_capacity_from_repr(5)); + assert_eq!(min_cap * 32, original_capacity_from_repr(6)); + assert_eq!(min_cap * 64, original_capacity_from_repr(7)); +} + +unsafe impl Send for Inner {} +unsafe impl Sync for Inner {} + +/* + * + * ===== PartialEq / PartialOrd ===== + * + */ + +impl PartialEq<[u8]> for BytesMut { + fn eq(&self, other: &[u8]) -> bool { + &**self == other + } +} + +impl PartialOrd<[u8]> for BytesMut { + fn partial_cmp(&self, other: &[u8]) -> Option { + (**self).partial_cmp(other) + } +} + +impl PartialEq for [u8] { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl PartialOrd for [u8] { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq for BytesMut { + fn eq(&self, other: &str) -> bool { + &**self == other.as_bytes() + } +} + +impl PartialOrd for BytesMut { + fn partial_cmp(&self, other: &str) -> Option { + (**self).partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for str { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl PartialOrd for str { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq> for BytesMut { + fn eq(&self, other: &Vec) -> bool { + *self == &other[..] + } +} + +impl PartialOrd> for BytesMut { + fn partial_cmp(&self, other: &Vec) -> Option { + (**self).partial_cmp(&other[..]) + } +} + +impl PartialEq for Vec { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl PartialOrd for Vec { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq for BytesMut { + fn eq(&self, other: &String) -> bool { + *self == &other[..] + } +} + +impl PartialOrd for BytesMut { + fn partial_cmp(&self, other: &String) -> Option { + (**self).partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl PartialOrd for String { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl<'a, T: ?Sized> PartialEq<&'a T> for BytesMut + where BytesMut: PartialEq +{ + fn eq(&self, other: &&'a T) -> bool { + *self == **other + } +} + +impl<'a, T: ?Sized> PartialOrd<&'a T> for BytesMut + where BytesMut: PartialOrd +{ + fn partial_cmp(&self, other: &&'a T) -> Option { + self.partial_cmp(*other) + } +} + +impl<'a> PartialEq for &'a [u8] { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl<'a> PartialOrd for &'a [u8] { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl<'a> PartialOrd for &'a str { + fn partial_cmp(&self, other: &BytesMut) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq<[u8]> for Bytes { + fn eq(&self, other: &[u8]) -> bool { + self.inner.as_ref() == other + } +} + +impl PartialOrd<[u8]> for Bytes { + fn partial_cmp(&self, other: &[u8]) -> Option { + self.inner.as_ref().partial_cmp(other) + } +} + +impl PartialEq for [u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl PartialOrd for [u8] { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq for Bytes { + fn eq(&self, other: &str) -> bool { + self.inner.as_ref() == other.as_bytes() + } +} + +impl PartialOrd for Bytes { + fn partial_cmp(&self, other: &str) -> Option { + self.inner.as_ref().partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for str { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl PartialOrd for str { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq> for Bytes { + fn eq(&self, other: &Vec) -> bool { + *self == &other[..] + } +} + +impl PartialOrd> for Bytes { + fn partial_cmp(&self, other: &Vec) -> Option { + self.inner.as_ref().partial_cmp(&other[..]) + } +} + +impl PartialEq for Vec { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl PartialOrd for Vec { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl PartialEq for Bytes { + fn eq(&self, other: &String) -> bool { + *self == &other[..] + } +} + +impl PartialOrd for Bytes { + fn partial_cmp(&self, other: &String) -> Option { + self.inner.as_ref().partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl PartialOrd for String { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl<'a> PartialEq for &'a [u8] { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl<'a> PartialOrd for &'a [u8] { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl<'a> PartialOrd for &'a str { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + +impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes + where Bytes: PartialEq +{ + fn eq(&self, other: &&'a T) -> bool { + *self == **other + } +} + +impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes + where Bytes: PartialOrd +{ + fn partial_cmp(&self, other: &&'a T) -> Option { + self.partial_cmp(&**other) + } +} + +impl PartialEq for Bytes +{ + fn eq(&self, other: &BytesMut) -> bool { + &other[..] == &self[..] + } +} + +impl PartialEq for BytesMut +{ + fn eq(&self, other: &Bytes) -> bool { + &other[..] == &self[..] + } +} + +// While there is `std::process:abort`, it's only available in Rust 1.17, and +// our minimum supported version is currently 1.15. So, this acts as an abort +// by triggering a double panic, which always aborts in Rust. +struct Abort; + +impl Drop for Abort { + fn drop(&mut self) { + panic!(); + } +} + +#[inline(never)] +#[cold] +fn abort() { + let _a = Abort; + panic!(); +} diff -Nru cargo-0.33.0/vendor/bytes/src/debug.rs cargo-0.35.0/vendor/bytes/src/debug.rs --- cargo-0.33.0/vendor/bytes/src/debug.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/debug.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,40 @@ +use std::fmt; + +/// Alternative implementation of `fmt::Debug` for byte slice. +/// +/// Standard `Debug` implementation for `[u8]` is comma separated +/// list of numbers. Since large amount of byte strings are in fact +/// ASCII strings or contain a lot of ASCII strings (e. g. HTTP), +/// it is convenient to print strings as ASCII when possible. +/// +/// This struct wraps `&[u8]` just to override `fmt::Debug`. +/// +/// `BsDebug` is not a part of public API of bytes crate. +pub struct BsDebug<'a>(pub &'a [u8]); + +impl<'a> fmt::Debug for BsDebug<'a> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { + try!(write!(fmt, "b\"")); + for &c in self.0 { + // https://doc.rust-lang.org/reference.html#byte-escapes + if c == b'\n' { + try!(write!(fmt, "\\n")); + } else if c == b'\r' { + try!(write!(fmt, "\\r")); + } else if c == b'\t' { + try!(write!(fmt, "\\t")); + } else if c == b'\\' || c == b'"' { + try!(write!(fmt, "\\{}", c as char)); + } else if c == b'\0' { + try!(write!(fmt, "\\0")); + // ASCII printable + } else if c >= 0x20 && c < 0x7f { + try!(write!(fmt, "{}", c as char)); + } else { + try!(write!(fmt, "\\x{:02x}", c)); + } + } + try!(write!(fmt, "\"")); + Ok(()) + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/either.rs cargo-0.35.0/vendor/bytes/src/either.rs --- cargo-0.33.0/vendor/bytes/src/either.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/either.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,89 @@ +extern crate either; + +use {Buf, BufMut}; + +use self::either::Either; +use self::either::Either::*; +use iovec::IoVec; + +impl Buf for Either +where + L: Buf, + R: Buf, +{ + fn remaining(&self) -> usize { + match *self { + Left(ref b) => b.remaining(), + Right(ref b) => b.remaining(), + } + } + + fn bytes(&self) -> &[u8] { + match *self { + Left(ref b) => b.bytes(), + Right(ref b) => b.bytes(), + } + } + + fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { + match *self { + Left(ref b) => b.bytes_vec(dst), + Right(ref b) => b.bytes_vec(dst), + } + } + + fn advance(&mut self, cnt: usize) { + match *self { + Left(ref mut b) => b.advance(cnt), + Right(ref mut b) => b.advance(cnt), + } + } + + fn copy_to_slice(&mut self, dst: &mut [u8]) { + match *self { + Left(ref mut b) => b.copy_to_slice(dst), + Right(ref mut b) => b.copy_to_slice(dst), + } + } +} + +impl BufMut for Either +where + L: BufMut, + R: BufMut, +{ + fn remaining_mut(&self) -> usize { + match *self { + Left(ref b) => b.remaining_mut(), + Right(ref b) => b.remaining_mut(), + } + } + + unsafe fn bytes_mut(&mut self) -> &mut [u8] { + match *self { + Left(ref mut b) => b.bytes_mut(), + Right(ref mut b) => b.bytes_mut(), + } + } + + unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { + match *self { + Left(ref mut b) => b.bytes_vec_mut(dst), + Right(ref mut b) => b.bytes_vec_mut(dst), + } + } + + unsafe fn advance_mut(&mut self, cnt: usize) { + match *self { + Left(ref mut b) => b.advance_mut(cnt), + Right(ref mut b) => b.advance_mut(cnt), + } + } + + fn put_slice(&mut self, src: &[u8]) { + match *self { + Left(ref mut b) => b.put_slice(src), + Right(ref mut b) => b.put_slice(src), + } + } +} diff -Nru cargo-0.33.0/vendor/bytes/src/lib.rs cargo-0.35.0/vendor/bytes/src/lib.rs --- cargo-0.33.0/vendor/bytes/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,105 @@ +//! Provides abstractions for working with bytes. +//! +//! The `bytes` crate provides an efficient byte buffer structure +//! ([`Bytes`](struct.Bytes.html)) and traits for working with buffer +//! implementations ([`Buf`], [`BufMut`]). +//! +//! [`Buf`]: trait.Buf.html +//! [`BufMut`]: trait.BufMut.html +//! +//! # `Bytes` +//! +//! `Bytes` is an efficient container for storing and operating on continguous +//! slices of memory. It is intended for use primarily in networking code, but +//! could have applications elsewhere as well. +//! +//! `Bytes` values facilitate zero-copy network programming by allowing multiple +//! `Bytes` objects to point to the same underlying memory. This is managed by +//! using a reference count to track when the memory is no longer needed and can +//! be freed. +//! +//! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]` +//! or `Vec`), but usually a `BytesMut` is used first and written to. For +//! example: +//! +//! ```rust +//! use bytes::{BytesMut, BufMut, BigEndian}; +//! +//! let mut buf = BytesMut::with_capacity(1024); +//! buf.put(&b"hello world"[..]); +//! buf.put_u16::(1234); +//! +//! let a = buf.take(); +//! assert_eq!(a, b"hello world\x04\xD2"[..]); +//! +//! buf.put(&b"goodbye world"[..]); +//! +//! let b = buf.take(); +//! assert_eq!(b, b"goodbye world"[..]); +//! +//! assert_eq!(buf.capacity(), 998); +//! ``` +//! +//! In the above example, only a single buffer of 1024 is allocated. The handles +//! `a` and `b` will share the underlying buffer and maintain indices tracking +//! the view into the buffer represented by the handle. +//! +//! See the [struct docs] for more details. +//! +//! [struct docs]: struct.Bytes.html +//! +//! # `Buf`, `BufMut` +//! +//! These two traits provide read and write access to buffers. The underlying +//! storage may or may not be in contiguous memory. For example, `Bytes` is a +//! buffer that guarantees contiguous memory, but a [rope] stores the bytes in +//! disjoint chunks. `Buf` and `BufMut` maintain cursors tracking the current +//! position in the underlying byte storage. When bytes are read or written, the +//! cursor is advanced. +//! +//! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure) +//! +//! ## Relation with `Read` and `Write` +//! +//! At first glance, it may seem that `Buf` and `BufMut` overlap in +//! functionality with `std::io::Read` and `std::io::Write`. However, they +//! serve different purposes. A buffer is the value that is provided as an +//! argument to `Read::read` and `Write::write`. `Read` and `Write` may then +//! perform a syscall, which has the potential of failing. Operations on `Buf` +//! and `BufMut` are infallible. + +#![deny(warnings, missing_docs, missing_debug_implementations)] +#![doc(html_root_url = "https://docs.rs/bytes/0.4.12")] + +extern crate byteorder; +extern crate iovec; + +pub mod buf; +pub use buf::{ + Buf, + BufMut, + IntoBuf, +}; +#[deprecated(since = "0.4.1", note = "moved to `buf` module")] +#[doc(hidden)] +pub use buf::{ + Reader, + Writer, + Take, +}; + +mod bytes; +mod debug; +pub use bytes::{Bytes, BytesMut}; + +#[deprecated] +pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; + +// Optional Serde support +#[cfg(feature = "serde")] +#[doc(hidden)] +pub mod serde; + +// Optional `Either` support +#[cfg(feature = "either")] +mod either; diff -Nru cargo-0.33.0/vendor/bytes/src/serde.rs cargo-0.35.0/vendor/bytes/src/serde.rs --- cargo-0.33.0/vendor/bytes/src/serde.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/src/serde.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,82 @@ +extern crate serde; + +use std::{cmp, fmt}; +use self::serde::{Serialize, Serializer, Deserialize, Deserializer, de}; +use super::{Bytes, BytesMut}; + +macro_rules! serde_impl { + ($ty:ident, $visitor_ty:ident) => ( + impl Serialize for $ty { + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer + { + serializer.serialize_bytes(&self) + } + } + + struct $visitor_ty; + + impl<'de> de::Visitor<'de> for $visitor_ty { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + #[inline] + fn visit_seq(self, mut seq: V) -> Result + where V: de::SeqAccess<'de> + { + let len = cmp::min(seq.size_hint().unwrap_or(0), 4096); + let mut values = Vec::with_capacity(len); + + while let Some(value) = try!(seq.next_element()) { + values.push(value); + } + + Ok(values.into()) + } + + #[inline] + fn visit_bytes(self, v: &[u8]) -> Result + where E: de::Error + { + Ok($ty::from(v)) + } + + #[inline] + fn visit_byte_buf(self, v: Vec) -> Result + where E: de::Error + { + Ok($ty::from(v)) + } + + #[inline] + fn visit_str(self, v: &str) -> Result + where E: de::Error + { + Ok($ty::from(v)) + } + + #[inline] + fn visit_string(self, v: String) -> Result + where E: de::Error + { + Ok($ty::from(v)) + } + } + + impl<'de> Deserialize<'de> for $ty { + #[inline] + fn deserialize(deserializer: D) -> Result<$ty, D::Error> + where D: Deserializer<'de> + { + deserializer.deserialize_byte_buf($visitor_ty) + } + } + ); +} + +serde_impl!(Bytes, BytesVisitor); +serde_impl!(BytesMut, BytesMutVisitor); diff -Nru cargo-0.33.0/vendor/bytes/tests/test_buf_mut.rs cargo-0.35.0/vendor/bytes/tests/test_buf_mut.rs --- cargo-0.33.0/vendor/bytes/tests/test_buf_mut.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_buf_mut.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,83 @@ +extern crate bytes; +extern crate byteorder; +extern crate iovec; + +use bytes::{BufMut, BytesMut}; +use iovec::IoVec; +use std::usize; +use std::fmt::Write; + +#[test] +fn test_vec_as_mut_buf() { + let mut buf = Vec::with_capacity(64); + + assert_eq!(buf.remaining_mut(), usize::MAX); + + unsafe { + assert!(buf.bytes_mut().len() >= 64); + } + + buf.put(&b"zomg"[..]); + + assert_eq!(&buf, b"zomg"); + + assert_eq!(buf.remaining_mut(), usize::MAX - 4); + assert_eq!(buf.capacity(), 64); + + for _ in 0..16 { + buf.put(&b"zomg"[..]); + } + + assert_eq!(buf.len(), 68); +} + +#[test] +fn test_put_u8() { + let mut buf = Vec::with_capacity(8); + buf.put::(33); + assert_eq!(b"\x21", &buf[..]); +} + +#[test] +fn test_put_u16() { + let mut buf = Vec::with_capacity(8); + buf.put_u16_be(8532); + assert_eq!(b"\x21\x54", &buf[..]); + + buf.clear(); + buf.put_u16_le(8532); + assert_eq!(b"\x54\x21", &buf[..]); +} + +#[test] +fn test_vec_advance_mut() { + // Regression test for carllerche/bytes#108. + let mut buf = Vec::with_capacity(8); + unsafe { + buf.advance_mut(12); + assert_eq!(buf.len(), 12); + assert!(buf.capacity() >= 12, "capacity: {}", buf.capacity()); + } +} + +#[test] +fn test_clone() { + let mut buf = BytesMut::with_capacity(100); + buf.write_str("this is a test").unwrap(); + let buf2 = buf.clone(); + + buf.write_str(" of our emergecy broadcast system").unwrap(); + assert!(buf != buf2); +} + +#[test] +fn test_bufs_vec_mut() { + use std::mem; + + let mut buf = BytesMut::from(&b"hello world"[..]); + + unsafe { + let mut dst: [&mut IoVec; 2] = mem::zeroed(); + assert_eq!(1, buf.bytes_vec_mut(&mut dst[..])); + } +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_buf.rs cargo-0.35.0/vendor/bytes/tests/test_buf.rs --- cargo-0.33.0/vendor/bytes/tests/test_buf.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_buf.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,58 @@ +extern crate bytes; +extern crate byteorder; +extern crate iovec; + +use bytes::Buf; +use iovec::IoVec; +use std::io::Cursor; + +#[test] +fn test_fresh_cursor_vec() { + let mut buf = Cursor::new(b"hello".to_vec()); + + assert_eq!(buf.remaining(), 5); + assert_eq!(buf.bytes(), b"hello"); + + buf.advance(2); + + assert_eq!(buf.remaining(), 3); + assert_eq!(buf.bytes(), b"llo"); + + buf.advance(3); + + assert_eq!(buf.remaining(), 0); + assert_eq!(buf.bytes(), b""); +} + +#[test] +fn test_get_u8() { + let mut buf = Cursor::new(b"\x21zomg"); + assert_eq!(0x21, buf.get_u8()); +} + +#[test] +fn test_get_u16() { + let buf = b"\x21\x54zomg"; + assert_eq!(0x2154, Cursor::new(buf).get_u16_be()); + assert_eq!(0x5421, Cursor::new(buf).get_u16_le()); +} + +#[test] +#[should_panic] +fn test_get_u16_buffer_underflow() { + let mut buf = Cursor::new(b"\x21"); + buf.get_u16_be(); +} + +#[test] +fn test_bufs_vec() { + let buf = Cursor::new(b"hello world"); + + let b1: &[u8] = &mut [0]; + let b2: &[u8] = &mut [0]; + + let mut dst: [&IoVec; 2] = + [b1.into(), b2.into()]; + + assert_eq!(1, buf.bytes_vec(&mut dst[..])); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_bytes.rs cargo-0.35.0/vendor/bytes/tests/test_bytes.rs --- cargo-0.33.0/vendor/bytes/tests/test_bytes.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_bytes.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,773 @@ +extern crate bytes; + +use bytes::{Bytes, BytesMut, BufMut, IntoBuf}; + +const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb"; +const SHORT: &'static [u8] = b"hello world"; + +fn inline_cap() -> usize { + use std::mem; + 4 * mem::size_of::() - 1 +} + +fn is_sync() {} +fn is_send() {} + +#[test] +fn test_bounds() { + is_sync::(); + is_sync::(); + is_send::(); + is_send::(); +} + +#[test] +fn from_slice() { + let a = Bytes::from(&b"abcdefgh"[..]); + assert_eq!(a, b"abcdefgh"[..]); + assert_eq!(a, &b"abcdefgh"[..]); + assert_eq!(a, Vec::from(&b"abcdefgh"[..])); + assert_eq!(b"abcdefgh"[..], a); + assert_eq!(&b"abcdefgh"[..], a); + assert_eq!(Vec::from(&b"abcdefgh"[..]), a); + + let a = BytesMut::from(&b"abcdefgh"[..]); + assert_eq!(a, b"abcdefgh"[..]); + assert_eq!(a, &b"abcdefgh"[..]); + assert_eq!(a, Vec::from(&b"abcdefgh"[..])); + assert_eq!(b"abcdefgh"[..], a); + assert_eq!(&b"abcdefgh"[..], a); + assert_eq!(Vec::from(&b"abcdefgh"[..]), a); +} + +#[test] +fn fmt() { + let a = format!("{:?}", Bytes::from(&b"abcdefg"[..])); + let b = "b\"abcdefg\""; + + assert_eq!(a, b); + + let a = format!("{:?}", BytesMut::from(&b"abcdefg"[..])); + assert_eq!(a, b); +} + +#[test] +fn fmt_write() { + use std::fmt::Write; + use std::iter::FromIterator; + let s = String::from_iter((0..10).map(|_| "abcdefg")); + + let mut a = BytesMut::with_capacity(64); + write!(a, "{}", &s[..64]).unwrap(); + assert_eq!(a, s[..64].as_bytes()); + + + let mut b = BytesMut::with_capacity(64); + write!(b, "{}", &s[..32]).unwrap(); + write!(b, "{}", &s[32..64]).unwrap(); + assert_eq!(b, s[..64].as_bytes()); + + + let mut c = BytesMut::with_capacity(64); + write!(c, "{}", s).unwrap_err(); + assert!(c.is_empty()); +} + +#[test] +fn len() { + let a = Bytes::from(&b"abcdefg"[..]); + assert_eq!(a.len(), 7); + + let a = BytesMut::from(&b"abcdefg"[..]); + assert_eq!(a.len(), 7); + + let a = Bytes::from(&b""[..]); + assert!(a.is_empty()); + + let a = BytesMut::from(&b""[..]); + assert!(a.is_empty()); +} + +#[test] +fn index() { + let a = Bytes::from(&b"hello world"[..]); + assert_eq!(a[0..5], *b"hello"); +} + +#[test] +fn slice() { + let a = Bytes::from(&b"hello world"[..]); + + let b = a.slice(3, 5); + assert_eq!(b, b"lo"[..]); + + let b = a.slice(0, 0); + assert_eq!(b, b""[..]); + + let b = a.slice(3, 3); + assert_eq!(b, b""[..]); + + let b = a.slice(a.len(), a.len()); + assert_eq!(b, b""[..]); + + let b = a.slice_to(5); + assert_eq!(b, b"hello"[..]); + + let b = a.slice_from(3); + assert_eq!(b, b"lo world"[..]); +} + +#[test] +#[should_panic] +fn slice_oob_1() { + let a = Bytes::from(&b"hello world"[..]); + a.slice(5, inline_cap() + 1); +} + +#[test] +#[should_panic] +fn slice_oob_2() { + let a = Bytes::from(&b"hello world"[..]); + a.slice(inline_cap() + 1, inline_cap() + 5); +} + +#[test] +fn split_off() { + let mut hello = Bytes::from(&b"helloworld"[..]); + let world = hello.split_off(5); + + assert_eq!(hello, &b"hello"[..]); + assert_eq!(world, &b"world"[..]); + + let mut hello = BytesMut::from(&b"helloworld"[..]); + let world = hello.split_off(5); + + assert_eq!(hello, &b"hello"[..]); + assert_eq!(world, &b"world"[..]); +} + +#[test] +#[should_panic] +fn split_off_oob() { + let mut hello = Bytes::from(&b"helloworld"[..]); + hello.split_off(inline_cap() + 1); +} + +#[test] +fn split_off_uninitialized() { + let mut bytes = BytesMut::with_capacity(1024); + let other = bytes.split_off(128); + + assert_eq!(bytes.len(), 0); + assert_eq!(bytes.capacity(), 128); + + assert_eq!(other.len(), 0); + assert_eq!(other.capacity(), 896); +} + +#[test] +fn split_off_to_loop() { + let s = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + for i in 0..(s.len() + 1) { + { + let mut bytes = Bytes::from(&s[..]); + let off = bytes.split_off(i); + assert_eq!(i, bytes.len()); + let mut sum = Vec::new(); + sum.extend(&bytes); + sum.extend(&off); + assert_eq!(&s[..], &sum[..]); + } + { + let mut bytes = BytesMut::from(&s[..]); + let off = bytes.split_off(i); + assert_eq!(i, bytes.len()); + let mut sum = Vec::new(); + sum.extend(&bytes); + sum.extend(&off); + assert_eq!(&s[..], &sum[..]); + } + { + let mut bytes = Bytes::from(&s[..]); + let off = bytes.split_to(i); + assert_eq!(i, off.len()); + let mut sum = Vec::new(); + sum.extend(&off); + sum.extend(&bytes); + assert_eq!(&s[..], &sum[..]); + } + { + let mut bytes = BytesMut::from(&s[..]); + let off = bytes.split_to(i); + assert_eq!(i, off.len()); + let mut sum = Vec::new(); + sum.extend(&off); + sum.extend(&bytes); + assert_eq!(&s[..], &sum[..]); + } + } +} + +#[test] +fn split_to_1() { + // Inline + let mut a = Bytes::from(SHORT); + let b = a.split_to(4); + + assert_eq!(SHORT[4..], a); + assert_eq!(SHORT[..4], b); + + // Allocated + let mut a = Bytes::from(LONG); + let b = a.split_to(4); + + assert_eq!(LONG[4..], a); + assert_eq!(LONG[..4], b); + + let mut a = Bytes::from(LONG); + let b = a.split_to(30); + + assert_eq!(LONG[30..], a); + assert_eq!(LONG[..30], b); +} + +#[test] +fn split_to_2() { + let mut a = Bytes::from(LONG); + assert_eq!(LONG, a); + + let b = a.split_to(1); + + assert_eq!(LONG[1..], a); + drop(b); +} + +#[test] +#[should_panic] +fn split_to_oob() { + let mut hello = Bytes::from(&b"helloworld"[..]); + hello.split_to(inline_cap() + 1); +} + +#[test] +#[should_panic] +fn split_to_oob_mut() { + let mut hello = BytesMut::from(&b"helloworld"[..]); + hello.split_to(inline_cap() + 1); +} + +#[test] +fn split_to_uninitialized() { + let mut bytes = BytesMut::with_capacity(1024); + let other = bytes.split_to(128); + + assert_eq!(bytes.len(), 0); + assert_eq!(bytes.capacity(), 896); + + assert_eq!(other.len(), 0); + assert_eq!(other.capacity(), 128); +} + +#[test] +fn split_off_to_at_gt_len() { + fn make_bytes() -> Bytes { + let mut bytes = BytesMut::with_capacity(100); + bytes.put_slice(&[10, 20, 30, 40]); + bytes.freeze() + } + + use std::panic; + + make_bytes().split_to(4); + make_bytes().split_off(4); + + assert!(panic::catch_unwind(move || { + make_bytes().split_to(5); + }).is_err()); + + assert!(panic::catch_unwind(move || { + make_bytes().split_off(5); + }).is_err()); +} + +#[test] +fn fns_defined_for_bytes_mut() { + let mut bytes = BytesMut::from(&b"hello world"[..]); + + bytes.as_ptr(); + bytes.as_mut_ptr(); + + // Iterator + let v: Vec = bytes.iter().map(|b| *b).collect(); + assert_eq!(&v[..], bytes); +} + +#[test] +fn mut_into_buf() { + let mut v = vec![0, 0, 0, 0]; + let s = &mut v[..]; + s.into_buf().put_u32_le(42); +} + +#[test] +fn reserve_convert() { + // Inline -> Vec + let mut bytes = BytesMut::with_capacity(8); + bytes.put("hello"); + bytes.reserve(40); + assert_eq!(bytes.capacity(), 45); + assert_eq!(bytes, "hello"); + + // Inline -> Inline + let mut bytes = BytesMut::with_capacity(inline_cap()); + bytes.put("abcdefghijkl"); + + let a = bytes.split_to(10); + bytes.reserve(inline_cap() - 3); + assert_eq!(inline_cap(), bytes.capacity()); + + assert_eq!(bytes, "kl"); + assert_eq!(a, "abcdefghij"); + + // Vec -> Vec + let mut bytes = BytesMut::from(LONG); + bytes.reserve(64); + assert_eq!(bytes.capacity(), LONG.len() + 64); + + // Arc -> Vec + let mut bytes = BytesMut::from(LONG); + let a = bytes.split_to(30); + + bytes.reserve(128); + assert!(bytes.capacity() >= bytes.len() + 128); + + drop(a); +} + +#[test] +fn reserve_growth() { + let mut bytes = BytesMut::with_capacity(64); + bytes.put("hello world"); + let _ = bytes.take(); + + bytes.reserve(65); + assert_eq!(bytes.capacity(), 128); +} + +#[test] +fn reserve_allocates_at_least_original_capacity() { + let mut bytes = BytesMut::with_capacity(1024); + + for i in 0..1020 { + bytes.put(i as u8); + } + + let _other = bytes.take(); + + bytes.reserve(16); + assert_eq!(bytes.capacity(), 1024); +} + +#[test] +fn reserve_max_original_capacity_value() { + const SIZE: usize = 128 * 1024; + + let mut bytes = BytesMut::with_capacity(SIZE); + + for _ in 0..SIZE { + bytes.put(0u8); + } + + let _other = bytes.take(); + + bytes.reserve(16); + assert_eq!(bytes.capacity(), 64 * 1024); +} + +// Without either looking at the internals of the BytesMut or doing weird stuff +// with the memory allocator, there's no good way to automatically verify from +// within the program that this actually recycles memory. Instead, just exercise +// the code path to ensure that the results are correct. +#[test] +fn reserve_vec_recycling() { + let mut bytes = BytesMut::from(Vec::with_capacity(16)); + assert_eq!(bytes.capacity(), 16); + bytes.put("0123456789012345"); + bytes.advance(10); + assert_eq!(bytes.capacity(), 6); + bytes.reserve(8); + assert_eq!(bytes.capacity(), 16); +} + +#[test] +fn reserve_in_arc_unique_does_not_overallocate() { + let mut bytes = BytesMut::with_capacity(1000); + bytes.take(); + + // now bytes is Arc and refcount == 1 + + assert_eq!(1000, bytes.capacity()); + bytes.reserve(2001); + assert_eq!(2001, bytes.capacity()); +} + +#[test] +fn reserve_in_arc_unique_doubles() { + let mut bytes = BytesMut::with_capacity(1000); + bytes.take(); + + // now bytes is Arc and refcount == 1 + + assert_eq!(1000, bytes.capacity()); + bytes.reserve(1001); + assert_eq!(2000, bytes.capacity()); +} + +#[test] +fn reserve_in_arc_nonunique_does_not_overallocate() { + let mut bytes = BytesMut::with_capacity(1000); + let _copy = bytes.take(); + + // now bytes is Arc and refcount == 2 + + assert_eq!(1000, bytes.capacity()); + bytes.reserve(2001); + assert_eq!(2001, bytes.capacity()); +} + +#[test] +fn inline_storage() { + let mut bytes = BytesMut::with_capacity(inline_cap()); + let zero = [0u8; 64]; + + bytes.put(&zero[0..inline_cap()]); + assert_eq!(*bytes, zero[0..inline_cap()]); +} + +#[test] +fn extend_mut() { + let mut bytes = BytesMut::with_capacity(0); + bytes.extend(LONG); + assert_eq!(*bytes, LONG[..]); +} + +#[test] +fn extend_shr() { + let mut bytes = Bytes::new(); + bytes.extend(LONG); + assert_eq!(*bytes, LONG[..]); +} + +#[test] +fn extend_from_slice_mut() { + for &i in &[3, 34] { + let mut bytes = BytesMut::new(); + bytes.extend_from_slice(&LONG[..i]); + bytes.extend_from_slice(&LONG[i..]); + assert_eq!(LONG[..], *bytes); + } +} + +#[test] +fn extend_from_slice_shr() { + for &i in &[3, 34] { + let mut bytes = Bytes::new(); + bytes.extend_from_slice(&LONG[..i]); + bytes.extend_from_slice(&LONG[i..]); + assert_eq!(LONG[..], *bytes); + } +} + +#[test] +fn from_static() { + let mut a = Bytes::from_static(b"ab"); + let b = a.split_off(1); + + assert_eq!(a, b"a"[..]); + assert_eq!(b, b"b"[..]); +} + +#[test] +fn advance_inline() { + let mut a = Bytes::from(&b"hello world"[..]); + a.advance(6); + assert_eq!(a, &b"world"[..]); +} + +#[test] +fn advance_static() { + let mut a = Bytes::from_static(b"hello world"); + a.advance(6); + assert_eq!(a, &b"world"[..]); +} + +#[test] +fn advance_vec() { + let mut a = BytesMut::from(b"hello world boooo yah world zomg wat wat".to_vec()); + a.advance(16); + assert_eq!(a, b"o yah world zomg wat wat"[..]); + + a.advance(4); + assert_eq!(a, b"h world zomg wat wat"[..]); + + // Reserve some space. + a.reserve(1024); + assert_eq!(a, b"h world zomg wat wat"[..]); + + a.advance(6); + assert_eq!(a, b"d zomg wat wat"[..]); +} + +#[test] +#[should_panic] +fn advance_past_len() { + let mut a = BytesMut::from(b"hello world".to_vec()); + a.advance(20); +} + +#[test] +// Only run these tests on little endian systems. CI uses qemu for testing +// little endian... and qemu doesn't really support threading all that well. +#[cfg(target_endian = "little")] +fn stress() { + // Tests promoting a buffer from a vec -> shared in a concurrent situation + use std::sync::{Arc, Barrier}; + use std::thread; + + const THREADS: usize = 8; + const ITERS: usize = 1_000; + + for i in 0..ITERS { + let data = [i as u8; 256]; + let buf = Arc::new(Bytes::from(&data[..])); + + let barrier = Arc::new(Barrier::new(THREADS)); + let mut joins = Vec::with_capacity(THREADS); + + for _ in 0..THREADS { + let c = barrier.clone(); + let buf = buf.clone(); + + joins.push(thread::spawn(move || { + c.wait(); + let buf: Bytes = (*buf).clone(); + drop(buf); + })); + } + + for th in joins { + th.join().unwrap(); + } + + assert_eq!(*buf, data[..]); + } +} + +#[test] +fn partial_eq_bytesmut() { + let bytes = Bytes::from(&b"The quick red fox"[..]); + let bytesmut = BytesMut::from(&b"The quick red fox"[..]); + assert!(bytes == bytesmut); + assert!(bytesmut == bytes); + let bytes2 = Bytes::from(&b"Jumped over the lazy brown dog"[..]); + assert!(bytes2 != bytesmut); + assert!(bytesmut != bytes2); +} + +#[test] +fn unsplit_basic() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaabbbcccddd"); + + let splitted = buf.split_off(6); + assert_eq!(b"aaabbb", &buf[..]); + assert_eq!(b"cccddd", &splitted[..]); + + buf.unsplit(splitted); + assert_eq!(b"aaabbbcccddd", &buf[..]); +} + +#[test] +fn unsplit_empty_other() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaabbbcccddd"); + + // empty other + let other = BytesMut::new(); + + buf.unsplit(other); + assert_eq!(b"aaabbbcccddd", &buf[..]); +} + +#[test] +fn unsplit_empty_self() { + // empty self + let mut buf = BytesMut::new(); + + let mut other = BytesMut::with_capacity(64); + other.extend_from_slice(b"aaabbbcccddd"); + + buf.unsplit(other); + assert_eq!(b"aaabbbcccddd", &buf[..]); +} + +#[test] +fn unsplit_inline_arc() { + let mut buf = BytesMut::with_capacity(8); //inline + buf.extend_from_slice(b"aaaabbbb"); + + let mut buf2 = BytesMut::with_capacity(64); + buf2.extend_from_slice(b"ccccddddeeee"); + + buf2.split_off(8); //arc + + buf.unsplit(buf2); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); +} + +#[test] +fn unsplit_arc_inline() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaaabbbbeeee"); + + buf.split_off(8); //arc + + let mut buf2 = BytesMut::with_capacity(8); //inline + buf2.extend_from_slice(b"ccccdddd"); + + buf.unsplit(buf2); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); + +} + +#[test] +fn unsplit_both_inline() { + let mut buf = BytesMut::with_capacity(16); //inline + buf.extend_from_slice(b"aaaabbbbccccdddd"); + + let splitted = buf.split_off(8); // both inline + assert_eq!(b"aaaabbbb", &buf[..]); + assert_eq!(b"ccccdddd", &splitted[..]); + + buf.unsplit(splitted); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); +} + + +#[test] +fn unsplit_arc_different() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaaabbbbeeee"); + + buf.split_off(8); //arc + + let mut buf2 = BytesMut::with_capacity(64); + buf2.extend_from_slice(b"ccccddddeeee"); + + buf2.split_off(8); //arc + + buf.unsplit(buf2); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); +} + +#[test] +fn unsplit_arc_non_contiguous() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaaabbbbeeeeccccdddd"); + + let mut buf2 = buf.split_off(8); //arc + + let buf3 = buf2.split_off(4); //arc + + buf.unsplit(buf3); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); +} + +#[test] +fn unsplit_two_split_offs() { + let mut buf = BytesMut::with_capacity(64); + buf.extend_from_slice(b"aaaabbbbccccdddd"); + + let mut buf2 = buf.split_off(8); //arc + let buf3 = buf2.split_off(4); //arc + + buf2.unsplit(buf3); + buf.unsplit(buf2); + assert_eq!(b"aaaabbbbccccdddd", &buf[..]); +} + +#[test] +fn from_iter_no_size_hint() { + use std::iter; + + let mut expect = vec![]; + + let actual: Bytes = iter::repeat(b'x') + .scan(100, |cnt, item| { + if *cnt >= 1 { + *cnt -= 1; + expect.push(item); + Some(item) + } else { + None + } + }) + .collect(); + + assert_eq!(&actual[..], &expect[..]); +} + +fn test_slice_ref(bytes: &Bytes, start: usize, end: usize, expected: &[u8]) { + let slice = &(bytes.as_ref()[start..end]); + let sub = bytes.slice_ref(&slice); + assert_eq!(&sub[..], expected); +} + +#[test] +fn slice_ref_works() { + let bytes = Bytes::from(&b"012345678"[..]); + + test_slice_ref(&bytes, 0, 0, b""); + test_slice_ref(&bytes, 0, 3, b"012"); + test_slice_ref(&bytes, 2, 6, b"2345"); + test_slice_ref(&bytes, 7, 9, b"78"); + test_slice_ref(&bytes, 9, 9, b""); +} + + +#[test] +fn slice_ref_empty() { + let bytes = Bytes::from(&b""[..]); + let slice = &(bytes.as_ref()[0..0]); + + let sub = bytes.slice_ref(&slice); + assert_eq!(&sub[..], b""); +} + +#[test] +#[should_panic] +fn slice_ref_catches_not_a_subset() { + let bytes = Bytes::from(&b"012345678"[..]); + let slice = &b"012345"[0..4]; + + bytes.slice_ref(slice); +} + +#[test] +#[should_panic] +fn slice_ref_catches_not_an_empty_subset() { + let bytes = Bytes::from(&b"012345678"[..]); + let slice = &b""[0..0]; + + bytes.slice_ref(slice); +} + +#[test] +#[should_panic] +fn empty_slice_ref_catches_not_an_empty_subset() { + let bytes = Bytes::from(&b""[..]); + let slice = &b""[0..0]; + + bytes.slice_ref(slice); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_chain.rs cargo-0.35.0/vendor/bytes/tests/test_chain.rs --- cargo-0.33.0/vendor/bytes/tests/test_chain.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_chain.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,122 @@ +extern crate bytes; +extern crate iovec; + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use bytes::buf::Chain; +use iovec::IoVec; +use std::io::Cursor; + +#[test] +fn collect_two_bufs() { + let a = Cursor::new(Bytes::from(&b"hello"[..])); + let b = Cursor::new(Bytes::from(&b"world"[..])); + + let res: Vec = a.chain(b).collect(); + assert_eq!(res, &b"helloworld"[..]); +} + +#[test] +fn writing_chained() { + let mut a = BytesMut::with_capacity(64); + let mut b = BytesMut::with_capacity(64); + + { + let mut buf = Chain::new(&mut a, &mut b); + + for i in 0..128 { + buf.put(i as u8); + } + } + + assert_eq!(64, a.len()); + assert_eq!(64, b.len()); + + for i in 0..64 { + let expect = i as u8; + assert_eq!(expect, a[i]); + assert_eq!(expect + 64, b[i]); + } +} + +#[test] +fn iterating_two_bufs() { + let a = Cursor::new(Bytes::from(&b"hello"[..])); + let b = Cursor::new(Bytes::from(&b"world"[..])); + + let res: Vec = a.chain(b).iter().collect(); + assert_eq!(res, &b"helloworld"[..]); +} + +#[test] +fn vectored_read() { + let a = Cursor::new(Bytes::from(&b"hello"[..])); + let b = Cursor::new(Bytes::from(&b"world"[..])); + + let mut buf = a.chain(b); + + { + let b1: &[u8] = &mut [0]; + let b2: &[u8] = &mut [0]; + let b3: &[u8] = &mut [0]; + let b4: &[u8] = &mut [0]; + let mut iovecs: [&IoVec; 4] = + [b1.into(), b2.into(), b3.into(), b4.into()]; + + assert_eq!(2, buf.bytes_vec(&mut iovecs)); + assert_eq!(iovecs[0][..], b"hello"[..]); + assert_eq!(iovecs[1][..], b"world"[..]); + assert_eq!(iovecs[2][..], b"\0"[..]); + assert_eq!(iovecs[3][..], b"\0"[..]); + } + + buf.advance(2); + + { + let b1: &[u8] = &mut [0]; + let b2: &[u8] = &mut [0]; + let b3: &[u8] = &mut [0]; + let b4: &[u8] = &mut [0]; + let mut iovecs: [&IoVec; 4] = + [b1.into(), b2.into(), b3.into(), b4.into()]; + + assert_eq!(2, buf.bytes_vec(&mut iovecs)); + assert_eq!(iovecs[0][..], b"llo"[..]); + assert_eq!(iovecs[1][..], b"world"[..]); + assert_eq!(iovecs[2][..], b"\0"[..]); + assert_eq!(iovecs[3][..], b"\0"[..]); + } + + buf.advance(3); + + { + let b1: &[u8] = &mut [0]; + let b2: &[u8] = &mut [0]; + let b3: &[u8] = &mut [0]; + let b4: &[u8] = &mut [0]; + let mut iovecs: [&IoVec; 4] = + [b1.into(), b2.into(), b3.into(), b4.into()]; + + assert_eq!(1, buf.bytes_vec(&mut iovecs)); + assert_eq!(iovecs[0][..], b"world"[..]); + assert_eq!(iovecs[1][..], b"\0"[..]); + assert_eq!(iovecs[2][..], b"\0"[..]); + assert_eq!(iovecs[3][..], b"\0"[..]); + } + + buf.advance(3); + + { + let b1: &[u8] = &mut [0]; + let b2: &[u8] = &mut [0]; + let b3: &[u8] = &mut [0]; + let b4: &[u8] = &mut [0]; + let mut iovecs: [&IoVec; 4] = + [b1.into(), b2.into(), b3.into(), b4.into()]; + + assert_eq!(1, buf.bytes_vec(&mut iovecs)); + assert_eq!(iovecs[0][..], b"ld"[..]); + assert_eq!(iovecs[1][..], b"\0"[..]); + assert_eq!(iovecs[2][..], b"\0"[..]); + assert_eq!(iovecs[3][..], b"\0"[..]); + } +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_debug.rs cargo-0.35.0/vendor/bytes/tests/test_debug.rs --- cargo-0.33.0/vendor/bytes/tests/test_debug.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_debug.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,35 @@ +extern crate bytes; + +use bytes::Bytes; + +#[test] +fn fmt() { + let vec: Vec<_> = (0..0x100).map(|b| b as u8).collect(); + + let expected = "b\"\ + \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\ + \\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\ + \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\ + \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f\ + \x20!\\\"#$%&'()*+,-./0123456789:;<=>?\ + @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_\ + `abcdefghijklmnopqrstuvwxyz{|}~\\x7f\ + \\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\ + \\x88\\x89\\x8a\\x8b\\x8c\\x8d\\x8e\\x8f\ + \\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\ + \\x98\\x99\\x9a\\x9b\\x9c\\x9d\\x9e\\x9f\ + \\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\ + \\xa8\\xa9\\xaa\\xab\\xac\\xad\\xae\\xaf\ + \\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\ + \\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\ + \\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\ + \\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\ + \\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7\ + \\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\ + \\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\ + \\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\ + \\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\ + \\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff\""; + + assert_eq!(expected, format!("{:?}", Bytes::from(vec))); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_from_buf.rs cargo-0.35.0/vendor/bytes/tests/test_from_buf.rs --- cargo-0.33.0/vendor/bytes/tests/test_from_buf.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_from_buf.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,34 @@ +extern crate bytes; + +use bytes::{Buf, Bytes, BytesMut}; +use std::io::Cursor; + +const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb"; +const SHORT: &'static [u8] = b"hello world"; + +#[test] +fn collect_to_vec() { + let buf: Vec = Cursor::new(SHORT).collect(); + assert_eq!(buf, SHORT); + + let buf: Vec = Cursor::new(LONG).collect(); + assert_eq!(buf, LONG); +} + +#[test] +fn collect_to_bytes() { + let buf: Bytes = Cursor::new(SHORT).collect(); + assert_eq!(buf, SHORT); + + let buf: Bytes = Cursor::new(LONG).collect(); + assert_eq!(buf, LONG); +} + +#[test] +fn collect_to_bytes_mut() { + let buf: BytesMut = Cursor::new(SHORT).collect(); + assert_eq!(buf, SHORT); + + let buf: BytesMut = Cursor::new(LONG).collect(); + assert_eq!(buf, LONG); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_iter.rs cargo-0.35.0/vendor/bytes/tests/test_iter.rs --- cargo-0.33.0/vendor/bytes/tests/test_iter.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_iter.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,22 @@ +extern crate bytes; + +use bytes::{Buf, IntoBuf, Bytes}; + +#[test] +fn iter_len() { + let buf = Bytes::from(&b"hello world"[..]).into_buf(); + let iter = buf.iter(); + + assert_eq!(iter.size_hint(), (11, Some(11))); + assert_eq!(iter.len(), 11); +} + + +#[test] +fn empty_iter_len() { + let buf = Bytes::from(&b""[..]).into_buf(); + let iter = buf.iter(); + + assert_eq!(iter.size_hint(), (0, Some(0))); + assert_eq!(iter.len(), 0); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_reader.rs cargo-0.35.0/vendor/bytes/tests/test_reader.rs --- cargo-0.33.0/vendor/bytes/tests/test_reader.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_reader.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,28 @@ +extern crate bytes; + +use std::io::{BufRead, Cursor, Read}; + +use bytes::Buf; + +#[test] +fn read() { + let buf1 = Cursor::new(b"hello "); + let buf2 = Cursor::new(b"world"); + let buf = Buf::chain(buf1, buf2); // Disambiguate with Read::chain + let mut buffer = Vec::new(); + buf.reader().read_to_end(&mut buffer).unwrap(); + assert_eq!(b"hello world", &buffer[..]); +} + +#[test] +fn buf_read() { + let buf1 = Cursor::new(b"hell"); + let buf2 = Cursor::new(b"o\nworld"); + let mut reader = Buf::chain(buf1, buf2).reader(); + let mut line = String::new(); + reader.read_line(&mut line).unwrap(); + assert_eq!("hello\n", &line); + line.clear(); + reader.read_line(&mut line).unwrap(); + assert_eq!("world", &line); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_serde.rs cargo-0.35.0/vendor/bytes/tests/test_serde.rs --- cargo-0.33.0/vendor/bytes/tests/test_serde.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_serde.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +#![cfg(feature = "serde")] + +extern crate bytes; +extern crate serde_test; +use serde_test::{Token, assert_tokens}; + +#[test] +fn test_ser_de_empty() { + let b = bytes::Bytes::new(); + assert_tokens(&b, &[Token::Bytes(b"")]); + let b = bytes::BytesMut::with_capacity(0); + assert_tokens(&b, &[Token::Bytes(b"")]); +} + +#[test] +fn test_ser_de() { + let b = bytes::Bytes::from(&b"bytes"[..]); + assert_tokens(&b, &[Token::Bytes(b"bytes")]); + let b = bytes::BytesMut::from(&b"bytes"[..]); + assert_tokens(&b, &[Token::Bytes(b"bytes")]); +} diff -Nru cargo-0.33.0/vendor/bytes/tests/test_take.rs cargo-0.35.0/vendor/bytes/tests/test_take.rs --- cargo-0.33.0/vendor/bytes/tests/test_take.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/bytes/tests/test_take.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +extern crate bytes; + +use bytes::Buf; +use std::io::Cursor; + +#[test] +fn long_take() { + // Tests that take with a size greater than the buffer length will not + // overrun the buffer. Regression test for #138. + let buf = Cursor::new(b"hello world").take(100); + assert_eq!(11, buf.remaining()); + assert_eq!(b"hello world", buf.bytes()); +} diff -Nru cargo-0.33.0/vendor/cc/azure-pipelines.yml cargo-0.35.0/vendor/cc/azure-pipelines.yml --- cargo-0.33.0/vendor/cc/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/cc/azure-pipelines.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,101 @@ +trigger: + - master + +jobs: + - job: min_linux + pool: + vmImage: ubuntu-16.04 + displayName: Minimum Rust (Linux) + variables: + TOOLCHAIN: 1.16.0 + steps: + - template: ci/azure-install-rust.yml + - script: cargo build + + - job: min_Windows + pool: + vmImage: vs2017-win2016 + displayName: Minimum Rust (Windows) + variables: + TOOLCHAIN: 1.16.0 + steps: + - template: ci/azure-install-rust.yml + - script: cargo build + + - job: Linux + pool: + vmImage: ubuntu-16.04 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64: + TARGET: x86_64-unknown-linux-gnu + i686: + TARGET: i686-unknown-linux-gnu + x86_64-beta: + TARGET: x86_64-unknown-linux-gnu + TOOLCHAIN: beta + x86_64-nightly: + TARGET: x86_64-unknown-linux-gnu + TOOLCHAIN: nightly + + - job: macOS + pool: + vmImage: macos-10.13 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64: + TARGET: x86_64-apple-darwin + aarch64-ios: + TARGET: aarch64-apple-ios + NO_RUN: --no-run + + - job: Windows_vs2019 + pool: + vmImage: windows-2019 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + + - job: Windows_vs2017 + pool: + vmImage: vs2017-win2016 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + i686-msvc: + TARGET: i686-pc-windows-msvc + x86_64-gnu: + TARGET: x86_64-pc-windows-gnu + i686-gnu: + TARGET: i686-pc-windows-gnu + + - job: Windows_vs2015 + pool: + vmImage: vs2015-win2012r2 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + i686-msvc: + TARGET: i686-pc-windows-msvc + + - job: docs + steps: + - template: ci/azure-install-rust.yml + - script: cargo doc --no-deps --all-features + - script: curl -LsSf https://git.io/fhJ8n | rustc - && (cd target/doc && ../../rust_out) + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + env: + GITHUB_DEPLOY_KEY: $(GITHUB_DEPLOY_KEY) diff -Nru cargo-0.33.0/vendor/cc/.cargo-checksum.json cargo-0.35.0/vendor/cc/.cargo-checksum.json --- cargo-0.33.0/vendor/cc/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"} \ No newline at end of file +{"files":{},"package":"39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/cc/Cargo.toml cargo-0.35.0/vendor/cc/Cargo.toml --- cargo-0.33.0/vendor/cc/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "cc" -version = "1.0.29" +version = "1.0.37" authors = ["Alex Crichton "] exclude = ["/.travis.yml", "/appveyor.yml"] description = "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n" @@ -31,8 +31,3 @@ [features] parallel = ["rayon"] -[badges.appveyor] -repository = "alexcrichton/cc-rs" - -[badges.travis-ci] -repository = "alexcrichton/cc-rs" diff -Nru cargo-0.33.0/vendor/cc/ci/azure-install-rust.yml cargo-0.35.0/vendor/cc/ci/azure-install-rust.yml --- cargo-0.33.0/vendor/cc/ci/azure-install-rust.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/cc/ci/azure-install-rust.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,24 @@ +steps: + - bash: | + set -e + toolchain=$TOOLCHAIN + if [ "$toolchain" = "" ]; then + toolchain=stable + fi + curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $toolchain + echo "##vso[task.prependpath]$HOME/.cargo/bin" + displayName: Install rust (unix) + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + IF "%TOOLCHAIN%"=="" (SET TOOLCHAIN=stable-%TARGET%) + curl -sSf -o rustup-init.exe https://win.rustup.rs + rustup-init.exe -y --default-toolchain %TOOLCHAIN% + echo ##vso[task.prependpath]%USERPROFILE%\.cargo\bin + displayName: Install rust (windows) + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + rustc -Vv + cargo -V + displayName: Query rust and cargo versions diff -Nru cargo-0.33.0/vendor/cc/ci/azure-steps.yml cargo-0.35.0/vendor/cc/ci/azure-steps.yml --- cargo-0.33.0/vendor/cc/ci/azure-steps.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/cc/ci/azure-steps.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +steps: + - template: azure-install-rust.yml + - bash: rustup target add $TARGET + displayName: Install Rust target + + - bash: sudo apt-get install g++-multilib + condition: eq( variables['Agent.OS'], 'Linux' ) + displayName: Install g++-multilib + + - script: cargo build + displayName: "Normal build" + - bash: cargo test $NO_RUN -- --test-threads 1 + displayName: "Crate tests" + - bash: cargo test $NO_RUN --features parallel -- --test-threads 1 + displayName: "Crate tests (parallel)" + - bash: cargo test $NO_RUN --manifest-path cc-test/Cargo.toml --target $TARGET + displayName: "cc-test tests" + - bash: cargo test $NO_RUN --manifest-path cc-test/Cargo.toml --target $TARGET --features parallel + displayName: "cc-test tests (parallel)" + - bash: cargo test $NO_RUN --manifest-path cc-test/Cargo.toml --target $TARGET --release + displayName: "cc-test tests (release)" diff -Nru cargo-0.33.0/vendor/cc/README.md cargo-0.35.0/vendor/cc/README.md --- cargo-0.33.0/vendor/cc/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,7 @@ A library to compile C/C++/assembly into a Rust library/application. -[![Build Status](https://travis-ci.com/alexcrichton/cc-rs.svg?branch=master)](https://travis-ci.com/alexcrichton/cc-rs) -[![Build status](https://ci.appveyor.com/api/projects/status/onu270iw98h81nwv?svg=true)](https://ci.appveyor.com/project/alexcrichton/cc-rs) +[![Build Status](https://dev.azure.com/alexcrichton/cc-rs/_apis/build/status/alexcrichton.cc-rs?branchName=master)](https://dev.azure.com/alexcrichton/cc-rs/_build/latest?definitionId=5&branchName=master) [Documentation](https://docs.rs/cc) @@ -77,6 +76,7 @@ certain `TARGET`s, it also is assumed to know about other flags (most common is `-fPIC`). * `AR` - the `ar` (archiver) executable to use to build the static library. +* `CRATE_CC_NO_DEFAULTS` - the default compiler flags may cause conflicts in some cross compiling scenarios. Setting this variable will disable the generation of default compiler flags. Each of these variables can also be supplied with certain prefixes and suffixes, in the following prioritized order: @@ -88,7 +88,7 @@ If none of these variables exist, cc-rs uses built-in defaults -In addition to the the above optional environment variables, `cc-rs` has some +In addition to the above optional environment variables, `cc-rs` has some functions with hard requirements on some variables supplied by [cargo's build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`, and `HOST` variables. diff -Nru cargo-0.33.0/vendor/cc/src/com.rs cargo-0.35.0/vendor/cc/src/com.rs --- cargo-0.33.0/vendor/cc/src/com.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/src/com.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,12 +13,12 @@ use std::os::windows::ffi::{OsStrExt, OsStringExt}; use std::ptr::null_mut; use std::slice::from_raw_parts; +use winapi::CoInitializeEx; +use winapi::IUnknown; use winapi::Interface; use winapi::BSTR; -use winapi::CoInitializeEx; use winapi::COINIT_MULTITHREADED; use winapi::{SysFreeString, SysStringLen}; -use winapi::IUnknown; use winapi::{HRESULT, S_FALSE, S_OK}; pub fn initialize() -> Result<(), HRESULT> { diff -Nru cargo-0.33.0/vendor/cc/src/lib.rs cargo-0.35.0/vendor/cc/src/lib.rs --- cargo-0.33.0/vendor/cc/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -61,15 +61,15 @@ #[cfg(feature = "parallel")] extern crate rayon; +use std::collections::HashMap; use std::env; use std::ffi::{OsStr, OsString}; use std::fs; +use std::io::{self, BufRead, BufReader, Read, Write}; use std::path::{Path, PathBuf}; use std::process::{Child, Command, Stdio}; -use std::io::{self, BufRead, BufReader, Read, Write}; -use std::thread::{self, JoinHandle}; -use std::collections::HashMap; use std::sync::{Arc, Mutex}; +use std::thread::{self, JoinHandle}; // These modules are all glue to support reading the MSVC version from // the registry and from COM interfaces @@ -891,7 +891,7 @@ return Err(Error::new( ErrorKind::IOError, "Getting object file details failed.", - )) + )); } }; @@ -956,7 +956,7 @@ fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> { use self::rayon::prelude::*; - if let Ok(amt) = env::var("NUM_JOBS") { + if let Some(amt) = self.getenv("NUM_JOBS") { if let Ok(amt) = amt.parse() { let _ = rayon::ThreadPoolBuilder::new() .num_threads(amt) @@ -1093,7 +1093,86 @@ let target = self.get_target()?; let mut cmd = self.get_base_compiler()?; + let envflags = self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }); + + // Disable default flag generation via environment variable or when + // certain cross compiling arguments are set + let use_defaults = self.getenv("CRATE_CC_NO_DEFAULTS").is_none(); + + if use_defaults { + self.add_default_flags(&mut cmd, &target, &opt_level)?; + } else { + println!("Info: default compiler flags are disabled"); + } + + for arg in envflags { + cmd.push_cc_arg(arg.into()); + } + + for directory in self.include_directories.iter() { + cmd.args.push(cmd.family.include_flag().into()); + cmd.args.push(directory.into()); + } + + // If warnings and/or extra_warnings haven't been explicitly set, + // then we set them only if the environment doesn't already have + // CFLAGS/CXXFLAGS, since those variables presumably already contain + // the desired set of warnings flags. + + if self + .warnings + .unwrap_or(if self.has_flags() { false } else { true }) + { + let wflags = cmd.family.warnings_flags().into(); + cmd.push_cc_arg(wflags); + } + + if self + .extra_warnings + .unwrap_or(if self.has_flags() { false } else { true }) + { + if let Some(wflags) = cmd.family.extra_warnings_flags() { + cmd.push_cc_arg(wflags.into()); + } + } + + for flag in self.flags.iter() { + cmd.args.push(flag.into()); + } + for flag in self.flags_supported.iter() { + if self.is_flag_supported(flag).unwrap_or(false) { + cmd.push_cc_arg(flag.into()); + } + } + + for &(ref key, ref value) in self.definitions.iter() { + let lead = if let ToolFamily::Msvc { .. } = cmd.family { + "/" + } else { + "-" + }; + if let Some(ref value) = *value { + cmd.args.push(format!("{}D{}={}", lead, key, value).into()); + } else { + cmd.args.push(format!("{}D{}", lead, key).into()); + } + } + + if self.warnings_into_errors { + let warnings_to_errors_flag = cmd.family.warnings_to_errors_flag().into(); + cmd.push_cc_arg(warnings_to_errors_flag); + } + + Ok(cmd) + } + + fn add_default_flags( + &self, + cmd: &mut Tool, + target: &str, + opt_level: &str, + ) -> Result<(), Error> { // Non-target flags // If the flag is not conditioned on target variable, it belongs here :) match cmd.family { @@ -1107,8 +1186,9 @@ Some(true) => "/MT", Some(false) => "/MD", None => { - let features = - env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new()); + let features = self + .getenv("CARGO_CFG_TARGET_FEATURE") + .unwrap_or(String::new()); if features.contains("crt-static") { "/MT" } else { @@ -1120,9 +1200,9 @@ match &opt_level[..] { // Msvc uses /O1 to enable all optimizations that minimize code size. - "z" | "s" | "1" => cmd.args.push("/O1".into()), + "z" | "s" | "1" => cmd.push_opt_unless_duplicate("/O1".into()), // -O3 is a valid value for gcc and clang compilers, but not msvc. Cap to /O2. - "2" | "3" => cmd.args.push("/O2".into()), + "2" | "3" => cmd.push_opt_unless_duplicate("/O2".into()), _ => {} } } @@ -1130,9 +1210,9 @@ // arm-linux-androideabi-gcc 4.8 shipped with Android NDK does // not support '-Oz' if opt_level == "z" && cmd.family != ToolFamily::Clang { - cmd.args.push("-Os".into()); + cmd.push_opt_unless_duplicate("-Os".into()); } else { - cmd.args.push(format!("-O{}", opt_level).into()); + cmd.push_opt_unless_duplicate(format!("-O{}", opt_level).into()); } if !target.contains("-ios") { @@ -1149,9 +1229,6 @@ } } } - for arg in self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }) { - cmd.args.push(arg.into()); - } if self.get_debug() { if self.cuda { @@ -1159,7 +1236,7 @@ cmd.args.push(nvcc_debug_flag); } let family = cmd.family; - family.add_debug_flags(&mut cmd); + family.add_debug_flags(cmd); } // Target flags @@ -1193,7 +1270,8 @@ // the SDK, but for all released versions of the // Windows SDK it is required. if target.contains("arm") || target.contains("thumb") { - cmd.args.push("/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into()); + cmd.args + .push("/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1".into()); } } ToolFamily::Gnu => { @@ -1206,14 +1284,18 @@ } if self.static_flag.is_none() { - let features = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new()); + let features = self + .getenv("CARGO_CFG_TARGET_FEATURE") + .unwrap_or(String::new()); if features.contains("crt-static") { cmd.args.push("-static".into()); } } // armv7 targets get to use armv7 instructions - if (target.starts_with("armv7") || target.starts_with("thumbv7")) && target.contains("-linux-") { + if (target.starts_with("armv7") || target.starts_with("thumbv7")) + && target.contains("-linux-") + { cmd.args.push("-march=armv7-a".into()); } @@ -1346,7 +1428,7 @@ if target.contains("-ios") { // FIXME: potential bug. iOS is always compiled with Clang, but Gcc compiler may be // detected instead. - self.ios_flags(&mut cmd)?; + self.ios_flags(cmd)?; } if self.static_flag.unwrap_or(false) { @@ -1372,62 +1454,17 @@ } } - for directory in self.include_directories.iter() { - cmd.args.push(cmd.family.include_flag().into()); - cmd.args.push(directory.into()); - } - - // If warnings and/or extra_warnings haven't been explicitly set, - // then we set them only if the environment doesn't already have - // CFLAGS/CXXFLAGS, since those variables presumably already contain - // the desired set of warnings flags. - - if self.warnings.unwrap_or(if self.has_flags() { false } else { true }) { - let wflags = cmd.family.warnings_flags().into(); - cmd.push_cc_arg(wflags); - } - - if self.extra_warnings.unwrap_or(if self.has_flags() { false } else { true }) { - if let Some(wflags) = cmd.family.extra_warnings_flags() { - cmd.push_cc_arg(wflags.into()); - } - } - - for flag in self.flags.iter() { - cmd.args.push(flag.into()); - } - - for flag in self.flags_supported.iter() { - if self.is_flag_supported(flag).unwrap_or(false) { - cmd.push_cc_arg(flag.into()); - } - } - - for &(ref key, ref value) in self.definitions.iter() { - let lead = if let ToolFamily::Msvc { .. } = cmd.family { - "/" - } else { - "-" - }; - if let Some(ref value) = *value { - cmd.args.push(format!("{}D{}={}", lead, key, value).into()); - } else { - cmd.args.push(format!("{}D{}", lead, key).into()); - } - } - - if self.warnings_into_errors { - let warnings_to_errors_flag = cmd.family.warnings_to_errors_flag().into(); - cmd.push_cc_arg(warnings_to_errors_flag); - } - - Ok(cmd) + Ok(()) } fn has_flags(&self) -> bool { let flags_env_var_name = if self.cpp { "CXXFLAGS" } else { "CFLAGS" }; let flags_env_var_value = self.get_var(flags_env_var_name); - if let Ok(_) = flags_env_var_value { true } else { false } + if let Ok(_) = flags_env_var_value { + true + } else { + false + } } fn msvc_macro_assembler(&self) -> Result<(Command, String), Error> { @@ -1471,12 +1508,7 @@ let objects: Vec<_> = objs.iter().map(|obj| obj.dst.clone()).collect(); let target = self.get_target()?; if target.contains("msvc") { - let mut cmd = match self.archiver { - Some(ref s) => self.cmd(s), - None => windows_registry::find(&target, "lib.exe") - .unwrap_or_else(|| self.cmd("lib.exe")), - }; - + let (mut cmd, program) = self.get_ar()?; let mut out = OsString::from("/OUT:"); out.push(dst); cmd.arg(out).arg("/nologo"); @@ -1521,7 +1553,7 @@ } else { cmd.args(&objects).args(&self.objects); } - run(&mut cmd, "lib.exe")?; + run(&mut cmd, &program)?; // The Rust compiler will look for libfoo.a and foo.lib, but the // MSVC linker will also be passed foo.lib, so be sure that both @@ -1537,7 +1569,7 @@ return Err(Error::new( ErrorKind::IOError, "Could not copy or create a hard-link to the generated lib file.", - )) + )); } }; } else { @@ -1574,7 +1606,7 @@ return Err(Error::new( ErrorKind::ArchitectureInvalid, "Unknown architecture for iOS target.", - )) + )); } }; @@ -1593,7 +1625,8 @@ }; self.print(&format!("Detecting iOS SDK path for {}", sdk)); - let sdk_path = self.cmd("xcrun") + let sdk_path = self + .cmd("xcrun") .arg("--show-sdk-path") .arg("--sdk") .arg(sdk) @@ -1607,7 +1640,7 @@ return Err(Error::new( ErrorKind::IOError, "Unable to determine iOS SDK path.", - )) + )); } }; @@ -1658,7 +1691,8 @@ let cl_exe = windows_registry::find_tool(&target, "cl.exe"); - let tool_opt: Option = self.env_tool(env) + let tool_opt: Option = self + .env_tool(env) .map(|(tool, cc, args)| { // chop off leading/trailing whitespace to work around // semi-buggy build scripts which are shared in @@ -1717,6 +1751,10 @@ } } else if target.contains("cloudabi") { format!("{}-{}", target, traditional) + } else if target == "wasm32-wasi" || + target == "wasm32-unknown-wasi" || + target == "wasm32-unknown-unknown" { + "clang".to_string() } else if self.get_host()? != target { // CROSS_COMPILE is of the form: "arm-linux-gnueabi-" let cc_env = self.getenv("CROSS_COMPILE"); @@ -1751,6 +1789,12 @@ "mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"), "mips64-unknown-linux-gnuabi64" => Some("mips64-linux-gnuabi64"), "mips64el-unknown-linux-gnuabi64" => Some("mips64el-linux-gnuabi64"), + "mipsisa32r6-unknown-linux-gnu" => Some("mipsisa32r6-linux-gnu"), + "mipsisa32r6el-unknown-linux-gnu" => Some("mipsisa32r6el-linux-gnu"), + "mipsisa64r6-unknown-linux-gnuabi64" => Some("mipsisa64r6-linux-gnuabi64"), + "mipsisa64r6el-unknown-linux-gnuabi64" => { + Some("mipsisa64r6el-linux-gnuabi64") + } "powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"), "powerpc-unknown-linux-gnuspe" => Some("powerpc-linux-gnuspe"), "powerpc-unknown-netbsd" => Some("powerpc--netbsd"), @@ -1818,9 +1862,9 @@ // configure for invocations like `clang-cl` we still get a "works out // of the box" experience. if let Some(cl_exe) = cl_exe { - if tool.family == (ToolFamily::Msvc { clang_cl: true }) && - tool.env.len() == 0 && - target.contains("msvc") + if tool.family == (ToolFamily::Msvc { clang_cl: true }) + && tool.env.len() == 0 + && target.contains("msvc") { for &(ref k, ref v) in cl_exe.env.iter() { tool.env.push((k.to_owned(), v.to_owned())); @@ -1836,7 +1880,8 @@ let host = self.get_host()?; let kind = if host == target { "HOST" } else { "TARGET" }; let target_u = target.replace("-", "_"); - let res = self.getenv(&format!("{}_{}", var_base, target)) + let res = self + .getenv(&format!("{}_{}", var_base, target)) .or_else(|| self.getenv(&format!("{}_{}", var_base, target_u))) .or_else(|| self.getenv(&format!("{}_{}", kind, var_base))) .or_else(|| self.getenv(var_base)); @@ -1961,9 +2006,10 @@ if let Ok(p) = self.get_var("AR") { return Ok((self.cmd(&p), p)); } - let program = if self.get_target()?.contains("android") { - format!("{}-ar", self.get_target()?.replace("armv7", "arm")) - } else if self.get_target()?.contains("emscripten") { + let target = self.get_target()?; + let program = if target.contains("android") { + format!("{}-ar", target.replace("armv7", "arm")) + } else if target.contains("emscripten") { // Windows use bat files so we have to be a bit more specific if cfg!(windows) { let mut cmd = self.cmd("cmd"); @@ -1972,6 +2018,11 @@ } "emar".to_string() + } else if target.contains("msvc") { + match windows_registry::find(&target, "lib.exe") { + Some(t) => return Ok((t, "lib.exe".to_string())), + None => "lib.exe".to_string(), + } } else { "ar".to_string() }; @@ -2021,7 +2072,7 @@ fn getenv(&self, v: &str) -> Option { let mut cache = self.env_cache.lock().unwrap(); if let Some(val) = cache.get(v) { - return val.clone() + return val.clone(); } let r = env::var(v).ok(); self.print(&format!("{} = {:?}", v, r)); @@ -2062,10 +2113,11 @@ let family = if let Some(fname) = path.file_name().and_then(|p| p.to_str()) { if fname.contains("clang-cl") { ToolFamily::Msvc { clang_cl: true } - } else if fname.contains("cl") && - !fname.contains("cloudabi") && - !fname.contains("uclibc") && - !fname.contains("clang") { + } else if fname.contains("cl") + && !fname.contains("cloudabi") + && !fname.contains("uclibc") + && !fname.contains("clang") + { ToolFamily::Msvc { clang_cl: false } } else if fname.contains("clang") { ToolFamily::Clang @@ -2104,6 +2156,42 @@ self.args.push(flag); } + fn is_duplicate_opt_arg(&self, flag: &OsString) -> bool { + let flag = flag.to_str().unwrap(); + let mut chars = flag.chars(); + + // Only duplicate check compiler flags + if self.is_like_msvc() { + if chars.next() != Some('/') { + return false; + } + } else if self.is_like_gnu() || self.is_like_clang() { + if chars.next() != Some('-') { + return false; + } + } + + // Check for existing optimization flags (-O, /O) + if chars.next() == Some('O') { + return self + .args() + .iter() + .any(|ref a| a.to_str().unwrap_or("").chars().nth(1) == Some('O')); + } + + // TODO Check for existing -m..., -m...=..., /arch:... flags + return false; + } + + /// Don't push optimization arg if it conflicts with existing args + fn push_opt_unless_duplicate(&mut self, flag: OsString) { + if self.is_duplicate_opt_arg(&flag) { + println!("Info: Ignoring duplicate arg {:?}", &flag); + } else { + self.push_cc_arg(flag); + } + } + /// Converts this compiler into a `Command` that's ready to be run. /// /// This is useful for when the compiler needs to be executed and the @@ -2120,7 +2208,11 @@ }; cmd.args(&self.cc_wrapper_args); - let value = self.args.iter().filter(|a| !self.removed_args.contains(a)).collect::>(); + let value = self + .args + .iter() + .filter(|a| !self.removed_args.contains(a)) + .collect::>(); cmd.args(&value); for &(ref k, ref v) in self.env.iter() { @@ -2215,7 +2307,7 @@ "Failed to wait on spawned child process, command {:?} with args {:?}.", cmd, program ), - )) + )); } }; print.join().unwrap(); @@ -2253,7 +2345,7 @@ "Failed to wait on spawned child process, command {:?} with args {:?}.", cmd, program ), - )) + )); } }; print.join().unwrap(); @@ -2311,7 +2403,8 @@ } fn fail(s: &str) -> ! { - panic!("\n\nInternal error occurred: {}\n\n", s) + let _ = writeln!(io::stderr(), "\n\nerror occurred: {}\n\n", s); + std::process::exit(1); } fn command_add_output_file(cmd: &mut Command, dst: &Path, msvc: bool, is_asm: bool, is_arm: bool) { diff -Nru cargo-0.33.0/vendor/cc/src/setup_config.rs cargo-0.35.0/vendor/cc/src/setup_config.rs --- cargo-0.33.0/vendor/cc/src/setup_config.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/src/setup_config.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,14 +11,14 @@ use std::ffi::OsString; use std::ptr::null_mut; use winapi::Interface; -use winapi::{LPFILETIME, ULONG}; -use winapi::S_FALSE; use winapi::BSTR; use winapi::LPCOLESTR; -use winapi::{CoCreateInstance, CLSCTX_ALL}; use winapi::LPSAFEARRAY; +use winapi::S_FALSE; +use winapi::{CoCreateInstance, CLSCTX_ALL}; use winapi::{IUnknown, IUnknownVtbl}; use winapi::{HRESULT, LCID, LPCWSTR, PULONGLONG}; +use winapi::{LPFILETIME, ULONG}; use com::{BStr, ComPtr}; @@ -31,7 +31,7 @@ pub const eNoRebootRequired: InstanceState = 4; pub const eComplete: InstanceState = -1i32 as u32; -RIDL!{#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)] +RIDL! {#[uuid(0xb41463c3, 0x8866, 0x43b5, 0xbc, 0x33, 0x2b, 0x06, 0x76, 0xf7, 0xf4, 0x2e)] interface ISetupInstance(ISetupInstanceVtbl): IUnknown(IUnknownVtbl) { fn GetInstanceId( pbstrInstanceId: *mut BSTR, @@ -62,7 +62,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)] +RIDL! {#[uuid(0x89143c9a, 0x05af, 0x49b0, 0xb7, 0x17, 0x72, 0xe2, 0x18, 0xa2, 0x18, 0x5c)] interface ISetupInstance2(ISetupInstance2Vtbl): ISetupInstance(ISetupInstanceVtbl) { fn GetState( pState: *mut InstanceState, @@ -78,7 +78,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)] +RIDL! {#[uuid(0x6380bcff, 0x41d3, 0x4b2e, 0x8b, 0x2e, 0xbf, 0x8a, 0x68, 0x10, 0xc8, 0x48)] interface IEnumSetupInstances(IEnumSetupInstancesVtbl): IUnknown(IUnknownVtbl) { fn Next( celt: ULONG, @@ -94,7 +94,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)] +RIDL! {#[uuid(0x42843719, 0xdb4c, 0x46c2, 0x8e, 0x7c, 0x64, 0xf1, 0x81, 0x6e, 0xfd, 0x5b)] interface ISetupConfiguration(ISetupConfigurationVtbl): IUnknown(IUnknownVtbl) { fn EnumInstances( ppEnumInstances: *mut *mut IEnumSetupInstances, @@ -108,7 +108,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)] +RIDL! {#[uuid(0x26aab78c, 0x4a60, 0x49d6, 0xaf, 0x3b, 0x3c, 0x35, 0xbc, 0x93, 0x36, 0x5d)] interface ISetupConfiguration2(ISetupConfiguration2Vtbl): ISetupConfiguration(ISetupConfigurationVtbl) { fn EnumAllInstances( @@ -116,7 +116,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)] +RIDL! {#[uuid(0xda8d8a16, 0xb2b6, 0x4487, 0xa2, 0xf1, 0x59, 0x4c, 0xcc, 0xcd, 0x6b, 0xf5)] interface ISetupPackageReference(ISetupPackageReferenceVtbl): IUnknown(IUnknownVtbl) { fn GetId( pbstrId: *mut BSTR, @@ -141,7 +141,7 @@ ) -> HRESULT, }} -RIDL!{#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)] +RIDL! {#[uuid(0x42b21b78, 0x6192, 0x463e, 0x87, 0xbf, 0xd5, 0x77, 0x83, 0x8f, 0x1d, 0x5c)] interface ISetupHelper(ISetupHelperVtbl): IUnknown(IUnknownVtbl) { fn ParseVersion( pwszVersion: LPCOLESTR, @@ -154,7 +154,7 @@ ) -> HRESULT, }} -DEFINE_GUID!{CLSID_SetupConfiguration, +DEFINE_GUID! {CLSID_SetupConfiguration, 0x177f0c4a, 0x1cd3, 0x4de7, 0xa3, 0x2c, 0x71, 0xdb, 0xbb, 0x9f, 0xa3, 0x6d} // Safe wrapper around the COM interfaces diff -Nru cargo-0.33.0/vendor/cc/src/winapi.rs cargo-0.35.0/vendor/cc/src/winapi.rs --- cargo-0.33.0/vendor/cc/src/winapi.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/src/winapi.rs 2019-05-15 11:26:24.000000000 +0000 @@ -115,7 +115,7 @@ Data3: $w2, Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], }; - } + }; } macro_rules! RIDL { @@ -207,7 +207,7 @@ ); } -RIDL!{#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)] +RIDL! {#[uuid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46)] interface IUnknown(IUnknownVtbl) { fn QueryInterface( riid: REFIID, diff -Nru cargo-0.33.0/vendor/cc/src/windows_registry.rs cargo-0.35.0/vendor/cc/src/windows_registry.rs --- cargo-0.33.0/vendor/cc/src/windows_registry.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/src/windows_registry.rs 2019-05-15 11:26:24.000000000 +0000 @@ -17,10 +17,12 @@ #[cfg(windows)] macro_rules! otry { - ($expr:expr) => (match $expr { - Some(val) => val, - None => return None, - }) + ($expr:expr) => { + match $expr { + Some(val) => val, + None => return None, + } + }; } /// Attempts to find a tool within an MSVC installation using the Windows @@ -103,6 +105,8 @@ Vs14, /// Visual Studio 15 (2017) Vs15, + /// Visual Studio 16 (2019) + Vs16, /// Hidden variant that should not be matched on. Callers that want to /// handle an enumeration of `VsVers` instances should always have a default @@ -128,6 +132,7 @@ match env::var("VisualStudioVersion") { Ok(version) => match &version[..] { + "16.0" => Ok(VsVers::Vs16), "15.0" => Ok(VsVers::Vs15), "14.0" => Ok(VsVers::Vs14), "12.0" => Ok(VsVers::Vs12), @@ -144,7 +149,9 @@ _ => { // Check for the presense of a specific registry key // that indicates visual studio is installed. - if impl_::has_msbuild_version("15.0") { + if impl_::has_msbuild_version("16.0") { + Ok(VsVers::Vs16) + } else if impl_::has_msbuild_version("15.0") { Ok(VsVers::Vs15) } else if impl_::has_msbuild_version("14.0") { Ok(VsVers::Vs14) @@ -166,15 +173,16 @@ #[cfg(windows)] mod impl_ { + use com; + use registry::{RegistryKey, LOCAL_MACHINE}; + use setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance}; use std::env; use std::ffi::OsString; - use std::mem; - use std::path::{Path, PathBuf}; use std::fs::File; use std::io::Read; - use registry::{RegistryKey, LOCAL_MACHINE}; - use com; - use setup_config::{EnumSetupInstances, SetupConfiguration, SetupInstance}; + use std::mem; + use std::iter; + use std::path::{Path, PathBuf}; use Tool; @@ -210,6 +218,41 @@ } } + fn vs16_instances() -> Box> { + let instances = if let Some(instances) = vs15_instances() { + instances + } else { + return Box::new(iter::empty()); + }; + Box::new(instances.filter_map(|instance| { + let instance = otry!(instance.ok()); + let installation_name = otry!(instance.installation_name().ok()); + if otry!(installation_name.to_str()).starts_with("VisualStudio/16.") { + Some(PathBuf::from(otry!(instance.installation_path().ok()))) + } else { + None + } + })) + } + + fn find_tool_in_vs16_path(tool: &str, target: &str) -> Option { + vs16_instances().filter_map(|path| { + let path = path.join(tool); + if !path.is_file() { + return None; + } + let mut tool = Tool::new(path); + if target.contains("x86_64") { + tool.env.push(("Platform".into(), "X64".into())); + } + Some(tool) + }).next() + } + + fn find_msbuild_vs16(target: &str) -> Option { + find_tool_in_vs16_path(r"MSBuild\Current\Bin\MSBuild.exe", target) + } + // In MSVC 15 (2017) MS once again changed the scheme for locating // the tooling. Now we must go through some COM interfaces, which // is super fun for Rust. @@ -251,7 +294,8 @@ instance .ok() .and_then(|instance| instance.installation_path().ok()) - }).map(|path| PathBuf::from(path).join(tool)) + }) + .map(|path| PathBuf::from(path).join(tool)) .find(|ref path| path.is_file()), None => None, }; @@ -263,7 +307,7 @@ .ok() .and_then(|key| key.query_str("15.0").ok()) .map(|path| PathBuf::from(path).join(tool)) - .filter(|ref path| path.is_file()); + .and_then(|path| if path.is_file() { Some(path) } else { None }); } path.map(|path| { @@ -319,13 +363,15 @@ let path = instance_path.join(r"VC\Tools\MSVC").join(version); // This is the path to the toolchain for a particular target, running // on a given host - let bin_path = path.join("bin") + let bin_path = path + .join("bin") .join(&format!("Host{}", host)) .join(&target); // But! we also need PATH to contain the target directory for the host // architecture, because it contains dlls like mspdb140.dll compiled for // the host architecture. - let host_dylib_path = path.join("bin") + let host_dylib_path = path + .join("bin") .join(&format!("Host{}", host)) .join(&host.to_lowercase()); let lib_path = path.join("lib").join(&target); @@ -478,17 +524,16 @@ let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok()); let root = otry!(key.query_str("KitsRoot10").ok()); let readdir = otry!(Path::new(&root).join("lib").read_dir().ok()); - let max_libdir = otry!( - readdir - .filter_map(|dir| dir.ok()) - .map(|dir| dir.path()) - .filter(|dir| dir.components() - .last() - .and_then(|c| c.as_os_str().to_str()) - .map(|c| c.starts_with("10.") && dir.join("ucrt").is_dir()) - .unwrap_or(false)) - .max() - ); + let max_libdir = otry!(readdir + .filter_map(|dir| dir.ok()) + .map(|dir| dir.path()) + .filter(|dir| dir + .components() + .last() + .and_then(|c| c.as_os_str().to_str()) + .map(|c| c.starts_with("10.") && dir.join("ucrt").is_dir()) + .unwrap_or(false)) + .max()); let version = max_libdir.components().last().unwrap(); let version = version.as_os_str().to_str().unwrap().to_string(); Some((root.into(), version)) @@ -512,12 +557,11 @@ .map(|dir| dir.path()) .collect::>(); dirs.sort(); - let dir = otry!( - dirs.into_iter() - .rev() - .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file()) - .next() - ); + let dir = otry!(dirs + .into_iter() + .rev() + .filter(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file()) + .next()); let version = dir.components().last().unwrap(); let version = version.as_os_str().to_str().unwrap().to_string(); Some((root.into(), version)) @@ -637,7 +681,7 @@ for subkey in key.iter().filter_map(|k| k.ok()) { let val = subkey .to_str() - .and_then(|s| s.trim_start_matches("v").replace(".", "").parse().ok()); + .and_then(|s| s.trim_left_matches("v").replace(".", "").parse().ok()); let val = match val { Some(s) => s, None => continue, @@ -654,6 +698,10 @@ pub fn has_msbuild_version(version: &str) -> bool { match version { + "16.0" => { + find_msbuild_vs16("x86_64-pc-windows-msvc").is_some() + || find_msbuild_vs16("i686-pc-windows-msvc").is_some() + } "15.0" => { find_msbuild_vs15("x86_64-pc-windows-msvc").is_some() || find_msbuild_vs15("i686-pc-windows-msvc").is_some() diff -Nru cargo-0.33.0/vendor/cc/tests/cc_env.rs cargo-0.35.0/vendor/cc/tests/cc_env.rs --- cargo-0.33.0/vendor/cc/tests/cc_env.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/tests/cc_env.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,8 @@ extern crate tempdir; use std::env; -use std::path::Path; use std::ffi::OsString; +use std::path::Path; mod support; use support::Test; @@ -63,14 +63,16 @@ .cflags_env() .into_string() .unwrap() - .contains("ccache") == false + .contains("ccache") + == false ); assert!( compiler .cflags_env() .into_string() .unwrap() - .contains(" lol-this-is-not-a-compiler") == false + .contains(" lol-this-is-not-a-compiler") + == false ); env::set_var("CC", ""); diff -Nru cargo-0.33.0/vendor/cc/tests/support/mod.rs cargo-0.35.0/vendor/cc/tests/support/mod.rs --- cargo-0.33.0/vendor/cc/tests/support/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/tests/support/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -113,10 +113,12 @@ } pub fn must_have_in_order(&self, before: &str, after: &str) -> &Execution { - let before_position = self.args + let before_position = self + .args .iter() .rposition(|x| OsStr::new(x) == OsStr::new(before)); - let after_position = self.args + let after_position = self + .args .iter() .rposition(|x| OsStr::new(x) == OsStr::new(after)); match (before_position, after_position) { diff -Nru cargo-0.33.0/vendor/cc/tests/test.rs cargo-0.35.0/vendor/cc/tests/test.rs --- cargo-0.33.0/vendor/cc/tests/test.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cc/tests/test.rs 2019-05-15 11:26:24.000000000 +0000 @@ -115,9 +115,7 @@ fn gnu_no_warnings_if_cflags() { env::set_var("CFLAGS", "-Wflag-does-not-exist"); let test = Test::gnu(); - test.gcc() - .file("foo.c") - .compile("foo"); + test.gcc().file("foo.c").compile("foo"); test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra"); env::set_var("CFLAGS", ""); @@ -127,9 +125,7 @@ fn gnu_no_warnings_if_cxxflags() { env::set_var("CXXFLAGS", "-Wflag-does-not-exist"); let test = Test::gnu(); - test.gcc() - .file("foo.c") - .compile("foo"); + test.gcc().file("foo.c").compile("foo"); test.cmd(0).must_not_have("-Wall").must_not_have("-Wextra"); env::set_var("CXXFLAGS", ""); diff -Nru cargo-0.33.0/vendor/cfg-if/.cargo-checksum.json cargo-0.35.0/vendor/cfg-if/.cargo-checksum.json --- cargo-0.33.0/vendor/cfg-if/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cfg-if/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"} \ No newline at end of file +{"files":{},"package":"b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/cfg-if/Cargo.toml cargo-0.35.0/vendor/cfg-if/Cargo.toml --- cargo-0.33.0/vendor/cfg-if/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cfg-if/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "cfg-if" -version = "0.1.6" +version = "0.1.9" authors = ["Alex Crichton "] description = "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n" homepage = "https://github.com/alexcrichton/cfg-if" diff -Nru cargo-0.33.0/vendor/cfg-if/README.md cargo-0.35.0/vendor/cfg-if/README.md --- cargo-0.33.0/vendor/cfg-if/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cfg-if/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,6 @@ # cfg-if -[![Build Status](https://travis-ci.org/alexcrichton/cfg-if.svg?branch=master)](https://travis-ci.org/alexcrichton/cfg-if) +[![Build Status](https://travis-ci.com/alexcrichton/cfg-if.svg?branch=master)](https://travis-ci.com/alexcrichton/cfg-if) [Documentation](https://docs.rs/cfg-if) diff -Nru cargo-0.33.0/vendor/cfg-if/src/lib.rs cargo-0.35.0/vendor/cfg-if/src/lib.rs --- cargo-0.33.0/vendor/cfg-if/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/cfg-if/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -32,6 +32,8 @@ #![deny(missing_docs)] #![cfg_attr(test, deny(warnings))] +/// The main macro provided by this crate. See crate documentation for more +/// information. #[macro_export(local_inner_macros)] macro_rules! cfg_if { // match if/else chains with a final `else` diff -Nru cargo-0.33.0/vendor/clap/.cargo-checksum.json cargo-0.35.0/vendor/clap/.cargo-checksum.json --- cargo-0.33.0/vendor/clap/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"} \ No newline at end of file +{"files":{},"package":"5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/clap/Cargo.toml cargo-0.35.0/vendor/clap/Cargo.toml --- cargo-0.33.0/vendor/clap/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,17 +12,17 @@ [package] name = "clap" -version = "2.32.0" +version = "2.33.0" authors = ["Kevin K. "] exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"] -description = "A simple to use, efficient, and full featured Command Line Argument Parser\n" +description = "A simple to use, efficient, and full-featured Command Line Argument Parser\n" homepage = "https://clap.rs/" documentation = "https://docs.rs/clap/" readme = "README.md" keywords = ["argument", "cli", "arg", "parser", "parse"] categories = ["command-line-interface"] license = "MIT" -repository = "https://github.com/kbknapp/clap-rs" +repository = "https://github.com/clap-rs/clap" [package.metadata.docs.rs] features = ["doc"] [profile.test] @@ -33,14 +33,6 @@ debug-assertions = true rpath = false -[profile.doc] -opt-level = 0 -lto = false -codegen-units = 4 -debug = true -debug-assertions = true -rpath = false - [profile.bench] opt-level = 3 lto = true @@ -72,7 +64,7 @@ version = "1.0" [dependencies.strsim] -version = "0.7.0" +version = "0.8" optional = true [dependencies.term_size] @@ -80,7 +72,7 @@ optional = true [dependencies.textwrap] -version = ">= 0.10, < 0.12" +version = "0.11.0" [dependencies.unicode-width] version = "0.1.4" @@ -93,13 +85,13 @@ version = ">= 0.3.5, < 0.5" optional = true [dev-dependencies.lazy_static] -version = "1" +version = "1.3" [dev-dependencies.regex] version = "1" [dev-dependencies.version-sync] -version = "0.5" +version = "0.8" [features] color = ["ansi_term", "atty"] @@ -116,20 +108,20 @@ version = "0.11" optional = true [badges.appveyor] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.coveralls] branch = "master" -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-issue-resolution] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-open-issues] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.maintenance] status = "actively-developed" [badges.travis-ci] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" diff -Nru cargo-0.33.0/vendor/clap/CHANGELOG.md cargo-0.35.0/vendor/clap/CHANGELOG.md --- cargo-0.33.0/vendor/clap/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,3 +1,44 @@ + +## v2.33.0 (2019-04-06) + +#### New Sponsor + +* Stephen Oats is now a sponsor \o/ ([823457c0](https://github.com/kbknapp/clap-rs/commit/823457c0ef5e994ed7080cf62addbfe1aa3b1833)) +* **SPONSORS.md:** fixes Josh Triplett's info in the sponsor document ([24cb5740](https://github.com/kbknapp/clap-rs/commit/24cb574090a11159b48bba105d5ec2dfb0a20e4e)) + +#### Features + +* **Completions:** adds completion support for Elvish. ([e9d0562a](https://github.com/kbknapp/clap-rs/commit/e9d0562a1dc5dfe731ed7c767e6cee0af08f0cf9)) +* There is a new setting to disable automatic building of `--help` and `-h` flags (`AppSettings::DisableAutoHelp`) + +#### Improvements + +* **arg_matches.rs:** add Debug implementations ([47192b7a](https://github.com/kbknapp/clap-rs/commit/47192b7a2d84ec716b81ae4af621e008a8762dc9)) +* **macros:** Support shorthand syntax for ArgGroups ([df9095e7](https://github.com/kbknapp/clap-rs/commit/df9095e75bb1e7896415251d0d4ffd8a0ebcd559)) + +#### Documentation + +* Refer to macOS rather than OSX. ([ab0d767f](https://github.com/kbknapp/clap-rs/commit/ab0d767f3a5a57e2bbb97d0183c2ef63c8c77a6c)) +* **README.md:** use https for all links ([96a7639a](https://github.com/kbknapp/clap-rs/commit/96a7639a36bcb184c3f45348986883115ef1ab3a)) + +#### Bug Fixes + +* add debug assertion for missing args in subcommand ArgGroup ([2699d9e5](https://github.com/kbknapp/clap-rs/commit/2699d9e51e7eadc258ba64c4e347c5d1fef61343)) +* Restore compat with Rust 1.21 ([6b263de1](https://github.com/kbknapp/clap-rs/commit/6b263de1d42ede692ec5ee55019ad2fc6386f92e)) +* Dont mention unused subcommands ([ef92e2b6](https://github.com/kbknapp/clap-rs/commit/ef92e2b639ed305bdade4741f60fa85cb0101c5a)) +* **OsValues:** Add `ExactSizeIterator` implementation ([356c69e5](https://github.com/kbknapp/clap-rs/commit/356c69e508fd25a9f0ea2d27bf80ae1d9a8d88f4)) +* **arg_enum!:** + * Fix comma position for valid values. ([1f1f9ff3](https://github.com/kbknapp/clap-rs/commit/1f1f9ff3fa38a43231ef8be9cfea89a32e53f518)) + * Invalid expansions of some trailing-comma patterns ([7023184f](https://github.com/kbknapp/clap-rs/commit/7023184fca04e852c270341548d6a16207d13862)) +* **completions:** improve correctness of completions when whitespace is involved ([5a08ff29](https://github.com/kbknapp/clap-rs/commit/5a08ff295b2aa6ce29420df6252a0e3ff4441bdc)) +* **help message:** Unconditionally uses long description for subcommands ([6acc8b6a](https://github.com/kbknapp/clap-rs/commit/6acc8b6a621a765cbf513450188000d943676a30), closes [#897](https://github.com/kbknapp/clap-rs/issues/897)) +* **macros:** fixes broken pattern which prevented calling multi-argument Arg methods ([9e7a352e](https://github.com/kbknapp/clap-rs/commit/9e7a352e13aaf8025d80f2bac5c47fb32528672b)) +* **parser:** Better interaction between AllowExternalSubcommands and SubcommandRequired ([9601c95a](https://github.com/kbknapp/clap-rs/commit/9601c95a03d2b82bf265c328b4769238f1b79002)) + +#### Minimum Required Rust + +* As of this release, `clap` requires `rustc 1.31.0` or greater. + ## v2.32.0 (2018-06-26) diff -Nru cargo-0.33.0/vendor/clap/debian/patches/relax-dep-versions.patch cargo-0.35.0/vendor/clap/debian/patches/relax-dep-versions.patch --- cargo-0.33.0/vendor/clap/debian/patches/relax-dep-versions.patch 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/debian/patches/relax-dep-versions.patch 2019-05-15 11:26:24.000000000 +0000 @@ -1,15 +1,6 @@ --- a/Cargo.toml +++ b/Cargo.toml -@@ -80,7 +80,7 @@ - optional = true - - [dependencies.textwrap] --version = "0.10.0" -+version = ">= 0.10, < 0.12" - - [dependencies.unicode-width] - version = "0.1.4" -@@ -90,7 +90,7 @@ +@@ -82,7 +82,7 @@ optional = true [dependencies.yaml-rust] @@ -17,4 +8,4 @@ +version = ">= 0.3.5, < 0.5" optional = true [dev-dependencies.lazy_static] - version = "1" + version = "1.3" diff -Nru cargo-0.33.0/vendor/clap/index.html cargo-0.35.0/vendor/clap/index.html --- cargo-0.33.0/vendor/clap/index.html 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/index.html 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - diff -Nru cargo-0.33.0/vendor/clap/justfile cargo-0.35.0/vendor/clap/justfile --- cargo-0.33.0/vendor/clap/justfile 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/justfile 2019-05-15 11:26:24.000000000 +0000 @@ -5,7 +5,7 @@ echo "the following is a list of contributors:" > CONTRIBUTORS.md echo "" >> CONTRIBUTORS.md echo "" >> CONTRIBUTORS.md - githubcontrib --owner kbknapp --repo clap-rs --sha master --cols 6 --format md --showlogin true --sortBy contributions --sortOrder desc >> CONTRIBUTORS.md + githubcontrib --owner clap-rs --repo clap --sha master --cols 6 --format md --showlogin true --sortBy contributions --sortOrder desc >> CONTRIBUTORS.md echo "" >> CONTRIBUTORS.md echo "" >> CONTRIBUTORS.md echo "This list was generated by [mgechev/github-contributors-list](https://github.com/mgechev/github-contributors-list)" >> CONTRIBUTORS.md diff -Nru cargo-0.33.0/vendor/clap/.pc/no-clippy.patch/Cargo.toml cargo-0.35.0/vendor/clap/.pc/no-clippy.patch/Cargo.toml --- cargo-0.33.0/vendor/clap/.pc/no-clippy.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/.pc/no-clippy.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,17 +12,17 @@ [package] name = "clap" -version = "2.32.0" +version = "2.33.0" authors = ["Kevin K. "] exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"] -description = "A simple to use, efficient, and full featured Command Line Argument Parser\n" +description = "A simple to use, efficient, and full-featured Command Line Argument Parser\n" homepage = "https://clap.rs/" documentation = "https://docs.rs/clap/" readme = "README.md" keywords = ["argument", "cli", "arg", "parser", "parse"] categories = ["command-line-interface"] license = "MIT" -repository = "https://github.com/kbknapp/clap-rs" +repository = "https://github.com/clap-rs/clap" [package.metadata.docs.rs] features = ["doc"] [profile.test] @@ -33,14 +33,6 @@ debug-assertions = true rpath = false -[profile.doc] -opt-level = 0 -lto = false -codegen-units = 4 -debug = true -debug-assertions = true -rpath = false - [profile.bench] opt-level = 3 lto = true @@ -76,7 +68,7 @@ optional = true [dependencies.strsim] -version = "0.7.0" +version = "0.8" optional = true [dependencies.term_size] @@ -84,7 +76,7 @@ optional = true [dependencies.textwrap] -version = "0.10.0" +version = "0.11.0" [dependencies.unicode-width] version = "0.1.4" @@ -97,13 +89,13 @@ version = "0.3.5" optional = true [dev-dependencies.lazy_static] -version = "1" +version = "1.3" [dev-dependencies.regex] version = "1" [dev-dependencies.version-sync] -version = "0.5" +version = "0.8" [features] color = ["ansi_term", "atty"] @@ -121,20 +113,20 @@ version = "0.11" optional = true [badges.appveyor] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.coveralls] branch = "master" -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-issue-resolution] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-open-issues] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.maintenance] status = "actively-developed" [badges.travis-ci] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" diff -Nru cargo-0.33.0/vendor/clap/.pc/relax-dep-versions.patch/Cargo.toml cargo-0.35.0/vendor/clap/.pc/relax-dep-versions.patch/Cargo.toml --- cargo-0.33.0/vendor/clap/.pc/relax-dep-versions.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/.pc/relax-dep-versions.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,17 +12,17 @@ [package] name = "clap" -version = "2.32.0" +version = "2.33.0" authors = ["Kevin K. "] exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"] -description = "A simple to use, efficient, and full featured Command Line Argument Parser\n" +description = "A simple to use, efficient, and full-featured Command Line Argument Parser\n" homepage = "https://clap.rs/" documentation = "https://docs.rs/clap/" readme = "README.md" keywords = ["argument", "cli", "arg", "parser", "parse"] categories = ["command-line-interface"] license = "MIT" -repository = "https://github.com/kbknapp/clap-rs" +repository = "https://github.com/clap-rs/clap" [package.metadata.docs.rs] features = ["doc"] [profile.test] @@ -33,14 +33,6 @@ debug-assertions = true rpath = false -[profile.doc] -opt-level = 0 -lto = false -codegen-units = 4 -debug = true -debug-assertions = true -rpath = false - [profile.bench] opt-level = 3 lto = true @@ -72,7 +64,7 @@ version = "1.0" [dependencies.strsim] -version = "0.7.0" +version = "0.8" optional = true [dependencies.term_size] @@ -80,7 +72,7 @@ optional = true [dependencies.textwrap] -version = "0.10.0" +version = "0.11.0" [dependencies.unicode-width] version = "0.1.4" @@ -93,13 +85,13 @@ version = "0.3.5" optional = true [dev-dependencies.lazy_static] -version = "1" +version = "1.3" [dev-dependencies.regex] version = "1" [dev-dependencies.version-sync] -version = "0.5" +version = "0.8" [features] color = ["ansi_term", "atty"] @@ -116,20 +108,20 @@ version = "0.11" optional = true [badges.appveyor] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.coveralls] branch = "master" -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-issue-resolution] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.is-it-maintained-open-issues] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" [badges.maintenance] status = "actively-developed" [badges.travis-ci] -repository = "kbknapp/clap-rs" +repository = "clap-rs/clap" diff -Nru cargo-0.33.0/vendor/clap/README.md cargo-0.35.0/vendor/clap/README.md --- cargo-0.33.0/vendor/clap/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ clap ==== -[![Crates.io](https://img.shields.io/crates/v/clap.svg)](https://crates.io/crates/clap) [![Crates.io](https://img.shields.io/crates/d/clap.svg)](https://crates.io/crates/clap) [![license](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/kbknapp/clap-rs/blob/master/LICENSE-MIT) [![Coverage Status](https://coveralls.io/repos/kbknapp/clap-rs/badge.svg?branch=master&service=github)](https://coveralls.io/github/kbknapp/clap-rs?branch=master) [![Join the chat at https://gitter.im/kbknapp/clap-rs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kbknapp/clap-rs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Crates.io](https://img.shields.io/crates/v/clap.svg)](https://crates.io/crates/clap) [![Crates.io](https://img.shields.io/crates/d/clap.svg)](https://crates.io/crates/clap) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/clap-rs/clap/blob/master/LICENSE-MIT) [![Coverage Status](https://coveralls.io/repos/kbknapp/clap-rs/badge.svg?branch=master&service=github)](https://coveralls.io/github/kbknapp/clap-rs?branch=master) [![Join the chat at https://gitter.im/kbknapp/clap-rs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kbknapp/clap-rs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Linux: [![Build Status](https://travis-ci.org/kbknapp/clap-rs.svg?branch=master)](https://travis-ci.org/kbknapp/clap-rs) +Linux: [![Build Status](https://travis-ci.org/clap-rs/clap.svg?branch=master)](https://travis-ci.org/clap-rs/clap) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/ejg8c33dn31nhv36/branch/master?svg=true)](https://ci.appveyor.com/project/kbknapp/clap-rs/branch/master) Command Line Argument Parser for Rust @@ -17,7 +17,6 @@ Table of Contents ================= -* [What's New](#whats-new) * [About](#about) * [FAQ](#faq) * [Features](#features) @@ -40,38 +39,6 @@ Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc) -## What's New - -Here's whats new in 2.32.0: - -* `clap` requires `rustc 1.21.0` or greater. -* **Completions:** adds completion support for Elvish. ([e9d0562a](https://github.com/kbknapp/clap-rs/commit/e9d0562a1dc5dfe731ed7c767e6cee0af08f0cf9)) -* **ArgGroup and macros:** Support shorthand syntax for ArgGroups ([df9095e7](https://github.com/kbknapp/clap-rs/commit/df9095e75bb1e7896415251d0d4ffd8a0ebcd559)) -* **OsValues:** Add `ExactSizeIterator` implementation ([356c69e5](https://github.com/kbknapp/clap-rs/commit/356c69e508fd25a9f0ea2d27bf80ae1d9a8d88f4)) -* **arg_enum!:** Invalid expansions of some trailing-comma patterns ([7023184f](https://github.com/kbknapp/clap-rs/commit/7023184fca04e852c270341548d6a16207d13862)) -* **help messages:** Unconditionally uses long description for subcommands ([6acc8b6a](https://github.com/kbknapp/clap-rs/commit/6acc8b6a621a765cbf513450188000d943676a30), closes [#897](https://github.com/kbknapp/clap-rs/issues/897)) -* **Docs:** Refer to macOS rather than OSX. ([ab0d767f](https://github.com/kbknapp/clap-rs/commit/ab0d767f3a5a57e2bbb97d0183c2ef63c8c77a6c)) - -Here's whats new in 2.31.x: - -* **Fish Completions:** fixes a bug that only allowed a single completion in in Fish Shell -* **AllowExternalSubcommands**: fixes a bug where external subcommands would be blocked by a similarly named subcommand -* Fixes some typos in the `README.md` -* **AllowMissingPositional:** improves the ability of `AppSetting::AllowMissingPositional` to allow "skipping" to the last positional arg with the `--` operator -* **Arg Indices:** adds the ability to query argument value indices - * implements an `Indices` iterator - * adds the documentation for the arg index querying methods -* **Improves PowerShell completions** - Uses the short help tool-tip for PowerShell completion scripts -* Adds WASM support (clap now compiles on WASM!) -* **Raw Args** adds a convenience function to `Arg` that allows implying all of `Arg::last` `Arg::allow_hyphen_values` and `Arg::multiple(true)` -* **CONTRIBUTING.md:** fix url to clippy upstream repo -* **Values Documentation:** improves the docs example of the Values iterator -* Updates README.md to hint that the `wrap_help` feature is a thing -* Use `codegen-units = 1` in release and bench profiles to improve bench performance -* Fix some typos and markdown issues in the docs - -For full details, see [CHANGELOG.md](https://github.com/kbknapp/clap-rs/blob/master/CHANGELOG.md) - ## About `clap` is used to parse *and validate* the string of command line arguments provided by a user at runtime. You provide the list of valid possibilities, and `clap` handles the rest. This means you focus on your *applications* functionality, and less on the parsing and validating of arguments. @@ -82,7 +49,7 @@ ## FAQ -For a full FAQ and more in depth details, see [the wiki page](https://github.com/kbknapp/clap-rs/wiki/FAQ) +For a full FAQ and more in depth details, see [the wiki page](https://github.com/clap-rs/clap/wiki/FAQ) ### Comparisons @@ -110,7 +77,7 @@ #### All else being equal, what are some reasons *not* to use `clap`? (The Anti Pitch) -Depending on the style in which you choose to define the valid arguments, `clap` can be very verbose. `clap` also offers so many finetuning knobs and dials, that learning everything can seem overwhelming. I strive to keep the simple cases simple, but when turning all those custom dials it can get complex. `clap` is also opinionated about parsing. Even though so much can be tweaked and tuned with `clap` (and I'm adding more all the time), there are still certain features which `clap` implements in specific ways which may be contrary to some users use-cases. Finally, `clap` is "stringly typed" when referring to arguments which can cause typos in code. This particular paper-cut is being actively worked on, and should be gone in v3.x. +Depending on the style in which you choose to define the valid arguments, `clap` can be very verbose. `clap` also offers so many fine-tuning knobs and dials, that learning everything can seem overwhelming. I strive to keep the simple cases simple, but when turning all those custom dials it can get complex. `clap` is also opinionated about parsing. Even though so much can be tweaked and tuned with `clap` (and I'm adding more all the time), there are still certain features which `clap` implements in specific ways which may be contrary to some users use-cases. Finally, `clap` is "stringly typed" when referring to arguments which can cause typos in code. This particular paper-cut is being actively worked on, and should be gone in v3.x. ## Features @@ -241,7 +208,7 @@ } ``` -One could also optionally decleare their CLI in YAML format and keep your Rust source tidy +One could also optionally declare their CLI in YAML format and keep your Rust source tidy or support multiple localized translations by having different YAML files for each localization. First, create the `cli.yml` file to hold your CLI options, but it could be called anything we like: @@ -279,7 +246,7 @@ Since this feature requires additional dependencies that not everyone may want, it is *not* compiled in by default and we need to enable a feature flag in Cargo.toml: -Simply change your `clap = "2.32"` to `clap = {version = "2.32", features = ["yaml"]}`. +Simply change your `clap = "2.33"` to `clap = {version = "2.33", features = ["yaml"]}`. Finally we create our `main.rs` file just like we would have with the previous two examples: @@ -343,18 +310,18 @@ To try out the pre-built examples, use the following steps: -* Clone the repository `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/` +* Clone the repository `$ git clone https://github.com/clap-rs/clap && cd clap-rs/` * Compile the example `$ cargo build --example ` * Run the help info `$ ./target/debug/examples/ --help` * Play with the arguments! -* You can also do a onetime run via `$ cargo run --example -- [args to example] +* You can also do a onetime run via `$ cargo run --example -- [args to example]` ### BYOB (Build Your Own Binary) To test out `clap`'s default auto-generated help/version follow these steps: * Create a new cargo project `$ cargo new fake --bin && cd fake` * Add `clap` to your `Cargo.toml` -* + ```toml [dependencies] clap = "2" @@ -380,7 +347,7 @@ ```toml [dependencies] -clap = "~2.32" +clap = "~2.33" ``` (**note**: If you are concerned with supporting a minimum version of Rust that is *older* than the current stable Rust minus 2 stable releases, it's recommended to use the `~major.minor.patch` style versions in your `Cargo.toml` which will only update the patch version automatically. For more information see the [Compatibility Policy](#compatibility-policy)) @@ -403,7 +370,7 @@ ```toml [dependencies.clap] -version = "2.32" +version = "2.33" default-features = false ``` @@ -411,7 +378,7 @@ ```toml [dependencies.clap] -version = "2.32" +version = "2.33" default-features = false # Cherry-pick the features you'd like to use @@ -460,7 +427,7 @@ ```toml [dependencies] -clap = "~2.32" +clap = "~2.33" ``` This will cause *only* the patch version to be updated upon a `cargo update` call, and therefore cannot break due to new features, or bumped minimum versions of Rust. @@ -477,20 +444,20 @@ # In one Cargo.toml [dependencies] -clap = "~2.32.0" +clap = "~2.33.0" # In another Cargo.toml [dependencies] -clap = "2.31.0" +clap = "2.33.0" ``` This is inherently an unresolvable crate graph in Cargo right now. Cargo requires there's only one major version of a crate, and being in the same workspace these two crates must share a version. This is impossible in this location, though, as these version constraints cannot be met. #### Minimum Version of Rust -`clap` will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.21.0, meaning `clap` is guaranteed to compile with 1.19.0 and beyond. +`clap` will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.32.0, meaning `clap` is guaranteed to compile with 1.30.0 and beyond. -At the 1.22.0 stable release, `clap` will be guaranteed to compile with 1.20.0 and beyond, etc. +At the 1.33.0 stable release, `clap` will be guaranteed to compile with 1.31.0 and beyond, etc. Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be clearly annotated in the `CHANGELOG.md` @@ -516,7 +483,7 @@ There are several excellent crates which can be used with `clap`, I recommend checking them all out! If you've got a crate that would be a good fit to be used with `clap` open an issue and let me know, I'd love to add it! * [`structopt`](https://github.com/TeXitoi/structopt) - This crate allows you to define a struct, and build a CLI from it! No more "stringly typed" and it uses `clap` behind the scenes! (*Note*: There is work underway to pull this crate into mainline `clap`). -* [`assert_cli`](https://github.com/killercup/assert_cli) - This crate allows you test your CLIs in a very intuitive and functional way! +* [`assert_cli`](https://github.com/assert-rs/assert_cli) - This crate allows you test your CLIs in a very intuitive and functional way! ## Recent Breaking Changes diff -Nru cargo-0.33.0/vendor/clap/SPONSORS.md cargo-0.35.0/vendor/clap/SPONSORS.md --- cargo-0.33.0/vendor/clap/SPONSORS.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/SPONSORS.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,17 @@ -The following is a list of [sponsors](https://clap.rs/sponsorship/) for the clap-rs project: +Below is a list of sponsors for the clap-rs project -[Noelia Seva-Gonzalez](https://noeliasg.com/about/) -Noelia Seva-Gonzalez +If you are interested in becoming a sponsor for this project please our [sponsorship page](https://clap.rs/sponsorship/). -[Rob Tsuk](https://github.com/rtsuk) -Rob Tsuk +## Recurring Sponsors: + +| [Noelia Seva-Gonzalez](https://noeliasg.com/about/) | [messense](https://github.com/messense) | [Josh](https://joshtriplett.org) | Stephen Oats | +|:-:|:-:|:-:|:-:| +|Noelia Seva-Gonzalez | Messense | Josh Triplett | Stephen Oats | + + +## Single-Donation and Former Sponsors: + +| [Rob Tsuk](https://github.com/rtsuk)| | | +|:-:|:-:|:-:| +|Rob Tsuk| | | -[messense](https://github.com/messense) -Messense diff -Nru cargo-0.33.0/vendor/clap/src/app/mod.rs cargo-0.35.0/vendor/clap/src/app/mod.rs --- cargo-0.33.0/vendor/clap/src/app/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/app/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -149,8 +149,8 @@ /// # } /// ``` /// [`App`]: ./struct.App.html - /// [`examples/17_yaml.rs`]: https://github.com/kbknapp/clap-rs/blob/master/examples/17_yaml.rs - /// [`examples/17_yaml.yml`]: https://github.com/kbknapp/clap-rs/blob/master/examples/17_yaml.yml + /// [`examples/17_yaml.rs`]: https://github.com/clap-rs/clap/blob/master/examples/17_yaml.rs + /// [`examples/17_yaml.yml`]: https://github.com/clap-rs/clap/blob/master/examples/17_yaml.yml /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html #[cfg(feature = "yaml")] pub fn from_yaml(yaml: &'a Yaml) -> App<'a, 'a> { App::from(yaml) } @@ -174,7 +174,7 @@ /// # ; /// ``` /// [`crate_authors!`]: ./macro.crate_authors!.html - /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples + /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples pub fn author>(mut self, author: S) -> Self { self.p.meta.author = Some(author.into()); self @@ -332,7 +332,7 @@ /// # ; /// ``` /// [`crate_version!`]: ./macro.crate_version!.html - /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples + /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples /// [`App::long_version`]: ./struct.App.html#method.long_version pub fn version>(mut self, ver: S) -> Self { self.p.meta.version = Some(ver.into()); @@ -363,7 +363,7 @@ /// # ; /// ``` /// [`crate_version!`]: ./macro.crate_version!.html - /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples + /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples /// [`App::version`]: ./struct.App.html#method.version pub fn long_version>(mut self, ver: S) -> Self { self.p.meta.long_version = Some(ver.into()); @@ -560,8 +560,9 @@ /// .template("{bin} ({version}) - {usage}") /// # ; /// ``` - /// **NOTE:**The template system is, on purpose, very simple. Therefore the tags have to written - /// in the lowercase and without spacing. + /// **NOTE:** The template system is, on purpose, very simple. Therefore the tags have to be + /// written in lowercase and without spacing. + /// /// [`App::about`]: ./struct.App.html#method.about /// [`App::after_help`]: ./struct.App.html#method.after_help /// [`App::before_help`]: ./struct.App.html#method.before_help @@ -820,7 +821,7 @@ /// .arg_from_usage("-c --config= 'Sets a configuration file to use'") /// # ; /// ``` - /// [arguments]: ./struct.Arg.html + /// [argument]: ./struct.Arg.html /// [`Arg`]: ./struct.Arg.html /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage pub fn arg_from_usage(mut self, usage: &'a str) -> Self { @@ -1186,13 +1187,6 @@ /// [`-h` (short)]: ./struct.Arg.html#method.help /// [`--help` (long)]: ./struct.Arg.html#method.long_help pub fn print_long_help(&mut self) -> ClapResult<()> { - // If there are global arguments, or settings we need to propagate them down to subcommands - // before parsing incase we run into a subcommand - self.p.propagate_globals(); - self.p.propagate_settings(); - self.p.derive_display_order(); - - self.p.create_help_and_version(); let out = io::stdout(); let mut buf_w = BufWriter::new(out.lock()); self.write_long_help(&mut buf_w) @@ -1222,7 +1216,7 @@ /// [`--help` (long)]: ./struct.Arg.html#method.long_help pub fn write_help(&self, w: &mut W) -> ClapResult<()> { // PENDING ISSUE: 808 - // https://github.com/kbknapp/clap-rs/issues/808 + // https://github.com/clap-rs/clap/issues/808 // If there are global arguments, or settings we need to propagate them down to subcommands // before parsing incase we run into a subcommand // self.p.propagate_globals(); @@ -1252,6 +1246,8 @@ /// [`-h` (short)]: ./struct.Arg.html#method.help /// [`--help` (long)]: ./struct.Arg.html#method.long_help pub fn write_long_help(&mut self, w: &mut W) -> ClapResult<()> { + // If there are global arguments, or settings we need to propagate them down to subcommands + // before parsing incase we run into a subcommand self.p.propagate_globals(); self.p.propagate_settings(); self.p.derive_display_order(); @@ -1668,6 +1664,7 @@ } yaml_str!(a, yaml, version); + yaml_str!(a, yaml, long_version); yaml_str!(a, yaml, author); yaml_str!(a, yaml, bin_name); yaml_str!(a, yaml, about); diff -Nru cargo-0.33.0/vendor/clap/src/app/parser.rs cargo-0.35.0/vendor/clap/src/app/parser.rs --- cargo-0.33.0/vendor/clap/src/app/parser.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/app/parser.rs 2019-05-15 11:26:24.000000000 +0000 @@ -135,7 +135,7 @@ } #[inline] - fn app_debug_asserts(&mut self) -> bool { + fn app_debug_asserts(&self) -> bool { assert!(self.verify_positionals()); let should_err = self.groups.iter().all(|g| { g.args.iter().all(|arg| { @@ -512,11 +512,11 @@ pub fn unset(&mut self, s: AS) { self.settings.unset(s) } #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))] - pub fn verify_positionals(&mut self) -> bool { + pub fn verify_positionals(&self) -> bool { // Because you must wait until all arguments have been supplied, this is the first chance // to make assertions on positional argument indexes // - // Firt we verify that the index highest supplied index, is equal to the number of + // First we verify that the index highest supplied index, is equal to the number of // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3 // but no 2) if let Some((idx, p)) = self.positionals.iter().rev().next() { @@ -871,6 +871,7 @@ let mut subcmd_name: Option = None; let mut needs_val_of: ParseResult<'a> = ParseResult::NotFound; let mut pos_counter = 1; + let mut sc_is_external = false; while let Some(arg) = it.next() { let arg_os = arg.into(); debugln!( @@ -928,7 +929,7 @@ } if arg_os.starts_with(b"--") { - needs_val_of = self.parse_long_arg(matcher, &arg_os)?; + needs_val_of = self.parse_long_arg(matcher, &arg_os, it)?; debugln!( "Parser:get_matches_with: After parse_long_arg {:?}", needs_val_of @@ -1115,6 +1116,7 @@ name: sc_name, matches: sc_m.into(), }); + sc_is_external = true; } else if !((self.is_set(AS::AllowLeadingHyphen) || self.is_set(AS::AllowNegativeNumbers)) && arg_os.starts_with(b"-")) @@ -1154,32 +1156,34 @@ } } - if let Some(ref pos_sc_name) = subcmd_name { - let sc_name = { - find_subcmd!(self, pos_sc_name) - .expect(INTERNAL_ERROR_MSG) - .p - .meta - .name - .clone() - }; - self.parse_subcommand(&*sc_name, matcher, it)?; - } else if self.is_set(AS::SubcommandRequired) { - let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name); - return Err(Error::missing_subcommand( - bn, - &usage::create_error_usage(self, matcher, None), - self.color(), - )); - } else if self.is_set(AS::SubcommandRequiredElseHelp) { - debugln!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); - let mut out = vec![]; - self.write_help_err(&mut out)?; - return Err(Error { - message: String::from_utf8_lossy(&*out).into_owned(), - kind: ErrorKind::MissingArgumentOrSubcommand, - info: None, - }); + if !sc_is_external { + if let Some(ref pos_sc_name) = subcmd_name { + let sc_name = { + find_subcmd!(self, pos_sc_name) + .expect(INTERNAL_ERROR_MSG) + .p + .meta + .name + .clone() + }; + self.parse_subcommand(&*sc_name, matcher, it)?; + } else if self.is_set(AS::SubcommandRequired) { + let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name); + return Err(Error::missing_subcommand( + bn, + &usage::create_error_usage(self, matcher, None), + self.color(), + )); + } else if self.is_set(AS::SubcommandRequiredElseHelp) { + debugln!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); + let mut out = vec![]; + self.write_help_err(&mut out)?; + return Err(Error { + message: String::from_utf8_lossy(&*out).into_owned(), + kind: ErrorKind::MissingArgumentOrSubcommand, + info: None, + }); + } } // In case the last arg was new, we need to process it's overrides @@ -1362,6 +1366,8 @@ } pub fn args_in_group(&self, group: &str) -> Vec { + debug_assert!(self.app_debug_asserts()); + let mut g_vec = vec![]; let mut args = vec![]; @@ -1413,7 +1419,7 @@ pub fn create_help_and_version(&mut self) { debugln!("Parser::create_help_and_version;"); // name is "hclap_help" because flags are sorted by name - if !self.contains_long("help") { + if !self.is_set(AS::DisableHelpFlags) && !self.contains_long("help") { debugln!("Parser::create_help_and_version: Building --help"); if self.help_short.is_none() && !self.contains_short('h') { self.help_short = Some('h'); @@ -1554,11 +1560,16 @@ } } - fn parse_long_arg( + fn parse_long_arg( &mut self, matcher: &mut ArgMatcher<'a>, full_arg: &OsStr, - ) -> ClapResult> { + it: &mut Peekable, + ) -> ClapResult> + where + I: Iterator, + T: Into + Clone, + { // maybe here lifetime should be 'a debugln!("Parser::parse_long_arg;"); @@ -1614,8 +1625,14 @@ } debugln!("Parser::parse_long_arg: Didn't match anything"); - self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher) - .map(|_| ParseResult::NotFound) + + let args_rest: Vec<_> = it.map(|x| x.clone().into()).collect(); + let args_rest2: Vec<_> = args_rest.iter().map(|x| x.to_str().expect(INVALID_UTF8)).collect(); + self.did_you_mean_error( + arg.to_str().expect(INVALID_UTF8), + matcher, + &args_rest2[..] + ).map(|_| ParseResult::NotFound) } #[cfg_attr(feature = "lints", allow(len_zero))] @@ -1872,9 +1889,9 @@ Ok(ParseResult::Flag) } - fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> { + fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>, args_rest: &[&str]) -> ClapResult<()> { // Didn't match a flag or option - let suffix = suggestions::did_you_mean_flag_suffix(arg, longs!(self), &self.subcommands); + let suffix = suggestions::did_you_mean_flag_suffix(arg, &args_rest, longs!(self), &self.subcommands); // Add the arg to the matches to build a proper usage string if let Some(name) = suffix.1 { diff -Nru cargo-0.33.0/vendor/clap/src/app/settings.rs cargo-0.35.0/vendor/clap/src/app/settings.rs --- cargo-0.33.0/vendor/clap/src/app/settings.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/app/settings.rs 2019-05-15 11:26:24.000000000 +0000 @@ -47,6 +47,7 @@ const INFER_SUBCOMMANDS = 1 << 38; const CONTAINS_LAST = 1 << 39; const ARGS_OVERRIDE_SELF = 1 << 40; + const DISABLE_HELP_FLAGS = 1 << 41; } } @@ -89,6 +90,7 @@ DontDelimitTrailingValues => Flags::DONT_DELIM_TRAIL, DontCollapseArgsInUsage => Flags::DONT_COLLAPSE_ARGS, DeriveDisplayOrder => Flags::DERIVE_DISP_ORDER, + DisableHelpFlags => Flags::DISABLE_HELP_FLAGS, DisableHelpSubcommand => Flags::DISABLE_HELP_SC, DisableVersion => Flags::DISABLE_VERSION, GlobalVersion => Flags::GLOBAL_VERSION, @@ -165,6 +167,7 @@ /// [`ArgMatches::os_values_of`]: ./struct.ArgMatches.html#method.os_values_of /// [`ArgMatches::lossy_value_of`]: ./struct.ArgMatches.html#method.lossy_value_of /// [`ArgMatches::lossy_values_of`]: ./struct.ArgMatches.html#method.lossy_values_of + /// [`SubCommand`]: ./struct.SubCommand.html AllowInvalidUtf8, /// Essentially sets [`Arg::overrides_with("itself")`] for all arguments. @@ -511,6 +514,37 @@ /// [`Arg::use_delimiter(false)`]: ./struct.Arg.html#method.use_delimiter DontDelimitTrailingValues, + /// Disables `-h` and `--help` [`App`] without affecting any of the [`SubCommand`]s + /// (Defaults to `false`; application *does* have help flags) + /// + /// # Examples + /// + /// ```rust + /// # use clap::{App, AppSettings, ErrorKind}; + /// let res = App::new("myprog") + /// .setting(AppSettings::DisableHelpFlags) + /// .get_matches_from_safe(vec![ + /// "myprog", "-h" + /// ]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument); + /// ``` + /// + /// ```rust + /// # use clap::{App, SubCommand, AppSettings, ErrorKind}; + /// let res = App::new("myprog") + /// .setting(AppSettings::DisableHelpFlags) + /// .subcommand(SubCommand::with_name("test")) + /// .get_matches_from_safe(vec![ + /// "myprog", "test", "-h" + /// ]); + /// assert!(res.is_err()); + /// assert_eq!(res.unwrap_err().kind, ErrorKind::HelpDisplayed); + /// ``` + /// [`SubCommand`]: ./struct.SubCommand.html + /// [`App`]: ./struct.App.html + DisableHelpFlags, + /// Disables the `help` subcommand /// /// # Examples @@ -562,6 +596,7 @@ /// assert_eq!(res.unwrap_err().kind, ErrorKind::VersionDisplayed); /// ``` /// [`SubCommand`]: ./struct.SubCommand.html + /// [`App`]: ./struct.App.html DisableVersion, /// Displays the arguments and [`SubCommand`]s in the help message in the order that they were @@ -884,7 +919,7 @@ /// Disables `-V` and `--version` for all [`SubCommand`]s /// (Defaults to `false`; subcommands *do* have version flags.) /// - /// **NOTE:** This setting must be set **prior** adding any subcommands + /// **NOTE:** This setting must be set **prior** to adding any subcommands. /// /// # Examples /// @@ -903,7 +938,7 @@ /// [`SubCommand`]: ./struct.SubCommand.html VersionlessSubcommands, - /// Will display a message "Press [ENTER]/[RETURN] to continue..." and wait for user before + /// Will display a message "Press \[ENTER\]/\[RETURN\] to continue..." and wait for user before /// exiting /// /// This is most useful when writing an application which is run from a GUI shortcut, or on @@ -948,6 +983,7 @@ type Err = String; fn from_str(s: &str) -> Result::Err> { match &*s.to_ascii_lowercase() { + "disablehelpflags" => Ok(AppSettings::DisableHelpFlags), "argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp), "argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands), "allowinvalidutf8" => Ok(AppSettings::AllowInvalidUtf8), @@ -994,6 +1030,10 @@ #[test] fn app_settings_fromstr() { assert_eq!( + "disablehelpflags".parse::().unwrap(), + AppSettings::DisableHelpFlags + ); + assert_eq!( "argsnegatesubcommands".parse::().unwrap(), AppSettings::ArgsNegateSubcommands ); diff -Nru cargo-0.33.0/vendor/clap/src/app/validator.rs cargo-0.35.0/vendor/clap/src/app/validator.rs --- cargo-0.33.0/vendor/clap/src/app/validator.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/app/validator.rs 2019-05-15 11:26:24.000000000 +0000 @@ -401,8 +401,8 @@ } else { false }; - // Issue 665 (https://github.com/kbknapp/clap-rs/issues/665) - // Issue 1105 (https://github.com/kbknapp/clap-rs/issues/1105) + // Issue 665 (https://github.com/clap-rs/clap/issues/665) + // Issue 1105 (https://github.com/clap-rs/clap/issues/1105) if a.takes_value() && !min_vals_zero && ma.vals.is_empty() { return Err(Error::empty_value( a, diff -Nru cargo-0.33.0/vendor/clap/src/args/arg_matches.rs cargo-0.35.0/vendor/clap/src/args/arg_matches.rs --- cargo-0.33.0/vendor/clap/src/args/arg_matches.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/args/arg_matches.rs 2019-05-15 11:26:24.000000000 +0000 @@ -786,8 +786,7 @@ /// assert_eq!(values.next(), None); /// ``` /// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of -#[derive(Clone)] -#[allow(missing_debug_implementations)] +#[derive(Debug, Clone)] pub struct Values<'a> { iter: Map, fn(&'a OsString) -> &'a str>, } @@ -838,8 +837,7 @@ /// ``` /// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os /// [`Values`]: ./struct.Values.html -#[derive(Clone)] -#[allow(missing_debug_implementations)] +#[derive(Debug, Clone)] pub struct OsValues<'a> { iter: Map, fn(&'a OsString) -> &'a OsStr>, } @@ -890,8 +888,7 @@ /// assert_eq!(indices.next(), None); /// ``` /// [`ArgMatches::indices_of`]: ./struct.ArgMatches.html#method.indices_of -#[derive(Clone)] -#[allow(missing_debug_implementations)] +#[derive(Debug, Clone)] pub struct Indices<'a> { // would rather use '_, but: https://github.com/rust-lang/rust/issues/48469 iter: Map, fn(&'a usize) -> usize>, } diff -Nru cargo-0.33.0/vendor/clap/src/args/arg.rs cargo-0.35.0/vendor/clap/src/args/arg.rs --- cargo-0.33.0/vendor/clap/src/args/arg.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/args/arg.rs 2019-05-15 11:26:24.000000000 +0000 @@ -139,6 +139,7 @@ "conflicts_with" => yaml_vec_or_str!(v, a, conflicts_with), "overrides_with" => yaml_vec_or_str!(v, a, overrides_with), "possible_values" => yaml_vec_or_str!(v, a, possible_value), + "case_insensitive" => yaml_to_bool!(a, v, case_insensitive), "required_unless_one" => yaml_vec_or_str!(v, a, required_unless), "required_unless_all" => { a = yaml_vec_or_str!(v, a, required_unless); @@ -2301,7 +2302,7 @@ /// /// **NOTE:** Implicitly sets [`Arg::hidden_short_help(true)`] and [`Arg::hidden_long_help(true)`] /// when set to true - /// + /// /// **NOTE:** This does **not** hide the argument from usage strings on error /// /// # Examples @@ -3580,6 +3581,12 @@ /// /// assert_eq!(m.values_of("flag").unwrap().collect::>(), vec!["env1", "env2"]); /// ``` + /// [`ArgMatches::occurrences_of`]: ./struct.ArgMatches.html#method.occurrences_of + /// [`ArgMatches::value_of`]: ./struct.ArgMatches.html#method.value_of + /// [`ArgMatches::is_present`]: ./struct.ArgMatches.html#method.is_present + /// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value + /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple + /// [`Arg::use_delimiter(true)`]: ./struct.Arg.html#method.use_delimiter pub fn env(self, name: &'a str) -> Self { self.env_os(OsStr::new(name)) } @@ -3746,7 +3753,7 @@ /// /// **NOTE:** Setting this option will cause next-line-help output style to be used /// when long help (`--help`) is called. - /// + /// /// # Examples /// /// ```rust @@ -3781,9 +3788,9 @@ /// -h, --help Prints help information /// -V, --version Prints version information /// ``` - /// + /// /// However, when --help is called - /// + /// /// ```rust /// # use clap::{App, Arg}; /// let m = App::new("prog") @@ -3795,24 +3802,24 @@ /// "prog", "--help" /// ]); /// ``` - /// + /// /// Then the following would be displayed - /// + /// /// ```notrust /// helptest - /// + /// /// USAGE: /// helptest [FLAGS] - /// + /// /// FLAGS: /// --config Some help text describing the --config arg /// -h, --help Prints help information /// -V, --version Prints version information /// ``` pub fn hidden_short_help(self, hide: bool) -> Self { - if hide { + if hide { self.set(ArgSettings::HiddenShortHelp) - } else { + } else { self.unset(ArgSettings::HiddenShortHelp) } } @@ -3823,7 +3830,7 @@ /// /// **NOTE:** Setting this option will cause next-line-help output style to be used /// when long help (`--help`) is called. - /// + /// /// # Examples /// /// ```rust @@ -3858,9 +3865,9 @@ /// -h, --help Prints help information /// -V, --version Prints version information /// ``` - /// + /// /// However, when -h is called - /// + /// /// ```rust /// # use clap::{App, Arg}; /// let m = App::new("prog") @@ -3872,15 +3879,15 @@ /// "prog", "-h" /// ]); /// ``` - /// + /// /// Then the following would be displayed - /// + /// /// ```notrust /// helptest - /// + /// /// USAGE: /// helptest [FLAGS] - /// + /// /// FLAGS: /// --config Some help text describing the --config arg /// -h, --help Prints help information @@ -3894,20 +3901,23 @@ } } - /// Checks if one of the [`ArgSettings`] settings is set for the argument + /// Checks if one of the [`ArgSettings`] settings is set for the argument. + /// /// [`ArgSettings`]: ./enum.ArgSettings.html pub fn is_set(&self, s: ArgSettings) -> bool { self.b.is_set(s) } - /// Sets one of the [`ArgSettings`] settings for the argument + /// Sets one of the [`ArgSettings`] settings for the argument. + /// /// [`ArgSettings`]: ./enum.ArgSettings.html pub fn set(mut self, s: ArgSettings) -> Self { self.setb(s); self } - /// Unsets one of the [`ArgSettings`] settings for the argument + /// Unsets one of the [`ArgSettings`] settings for the argument. + /// /// [`ArgSettings`]: ./enum.ArgSettings.html pub fn unset(mut self, s: ArgSettings) -> Self { self.unsetb(s); diff -Nru cargo-0.33.0/vendor/clap/src/args/group.rs cargo-0.35.0/vendor/clap/src/args/group.rs --- cargo-0.33.0/vendor/clap/src/args/group.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/args/group.rs 2019-05-15 11:26:24.000000000 +0000 @@ -45,7 +45,7 @@ /// --minor 'auto increase minor' /// --patch 'auto increase patch'") /// .group(ArgGroup::with_name("vers") -/// .args(&["set-ver", "major", "minor","patch"]) +/// .args(&["set-ver", "major", "minor", "patch"]) /// .required(true)) /// .get_matches_from_safe(vec!["app", "--major", "--patch"]); /// // Because we used two args in the group it's an error diff -Nru cargo-0.33.0/vendor/clap/src/args/settings.rs cargo-0.35.0/vendor/clap/src/args/settings.rs --- cargo-0.33.0/vendor/clap/src/args/settings.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/args/settings.rs 2019-05-15 11:26:24.000000000 +0000 @@ -77,7 +77,8 @@ Multiple, /// The argument allows empty values such as `--option ""` EmptyValues, - /// The argument should be propagated down through all child [`SubCommands`] + /// The argument should be propagated down through all child [`SubCommand`]s + /// /// [`SubCommand`]: ./struct.SubCommand.html Global, /// The argument should **not** be shown in help text diff -Nru cargo-0.33.0/vendor/clap/src/completions/bash.rs cargo-0.35.0/vendor/clap/src/completions/bash.rs --- cargo-0.33.0/vendor/clap/src/completions/bash.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/completions/bash.rs 2019-05-15 11:26:24.000000000 +0000 @@ -20,19 +20,19 @@ w!( buf, format!( - "_{name}() {{ + r#"_{name}() {{ local i cur prev opts cmds COMPREPLY=() - cur=\"${{COMP_WORDS[COMP_CWORD]}}\" - prev=\"${{COMP_WORDS[COMP_CWORD-1]}}\" - cmd=\"\" - opts=\"\" + cur="${{COMP_WORDS[COMP_CWORD]}}" + prev="${{COMP_WORDS[COMP_CWORD-1]}}" + cmd="" + opts="" for i in ${{COMP_WORDS[@]}} do - case \"${{i}}\" in + case "${{i}}" in {name}) - cmd=\"{name}\" + cmd="{name}" ;; {subcmds} *) @@ -40,20 +40,20 @@ esac done - case \"${{cmd}}\" in + case "${{cmd}}" in {name}) - opts=\"{name_opts}\" + opts="{name_opts}" if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq 1 ]] ; then - COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) + COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") ) return 0 fi - case \"${{prev}}\" in + case "${{prev}}" in {name_opts_details} *) COMPREPLY=() ;; esac - COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) + COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") ) return 0 ;; {subcmd_details} @@ -61,7 +61,7 @@ }} complete -F _{name} -o bashdefault -o default {name} -", +"#, name = self.p.meta.bin_name.as_ref().unwrap(), name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()), name_opts_details = @@ -79,10 +79,10 @@ for sc in &scs { subcmds = format!( - "{} + r#"{} {name}) - cmd+=\"__{fn_name}\" - ;;", + cmd+="__{fn_name}" + ;;"#, subcmds, name = sc, fn_name = sc.replace("-", "__") @@ -101,22 +101,22 @@ for sc in &scs { subcmd_dets = format!( - "{} + r#"{} {subcmd}) - opts=\"{sc_opts}\" + opts="{sc_opts}" if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then - COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) + COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") ) return 0 fi - case \"${{prev}}\" in + case "${{prev}}" in {opts_details} *) COMPREPLY=() ;; esac - COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) + COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") ) return 0 - ;;", + ;;"#, subcmd_dets, subcmd = sc.replace("-", "__"), sc_opts = self.all_options_for_path(&*sc), @@ -169,9 +169,9 @@ debugln!("BashGen::vals_for: o={}", o.b.name); use args::AnyArg; if let Some(vals) = o.possible_vals() { - format!("$(compgen -W \"{}\" -- ${{cur}})", vals.join(" ")) + format!(r#"$(compgen -W "{}" -- "${{cur}}")"#, vals.join(" ")) } else { - String::from("$(compgen -f ${cur})") + String::from(r#"$(compgen -f "${cur}")"#) } } diff -Nru cargo-0.33.0/vendor/clap/src/errors.rs cargo-0.35.0/vendor/clap/src/errors.rs --- cargo-0.33.0/vendor/clap/src/errors.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/errors.rs 2019-05-15 11:26:24.000000000 +0000 @@ -196,7 +196,7 @@ /// assert!(result.is_err()); /// assert_eq!(result.unwrap_err().kind, ErrorKind::WrongNumberOfValues); /// ``` - /// [`Arg::number_of_values`] + /// /// [`Arg::number_of_values`]: ./struct.Arg.html#method.number_of_values /// [`Arg::value_names`]: ./struct.Arg.html#method.value_names WrongNumberOfValues, @@ -365,6 +365,7 @@ /// Represents a [Format error] (which is a part of [`Display`]). /// Typically caused by writing to `stderr` or `stdout`. + /// /// [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html /// [Format error]: https://doc.rust-lang.org/std/fmt/struct.Error.html Format, diff -Nru cargo-0.33.0/vendor/clap/src/fmt.rs cargo-0.35.0/vendor/clap/src/fmt.rs --- cargo-0.33.0/vendor/clap/src/fmt.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/fmt.rs 2019-05-15 11:26:24.000000000 +0000 @@ -62,11 +62,11 @@ let is_a_tty = is_a_tty(option.use_stderr); let is_term_dumb = is_term_dumb(); Colorizer { - when: if is_a_tty && !is_term_dumb { - option.when - } else { - ColorWhen::Never - }, + when: match option.when { + ColorWhen::Auto if is_a_tty && !is_term_dumb => ColorWhen::Auto, + ColorWhen::Auto => ColorWhen::Never, + when => when, + } } } diff -Nru cargo-0.33.0/vendor/clap/src/lib.rs cargo-0.35.0/vendor/clap/src/lib.rs --- cargo-0.33.0/vendor/clap/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/kbknapp/clap-rs/blob/master/CONTRIBUTORS.md). +// Copyright ⓒ 2015-2016 Kevin B. Knapp and [`clap-rs` contributors](https://github.com/clap-rs/clap/blob/master/CONTRIBUTORS.md). // Licensed under the MIT license // (see LICENSE or ) All files in the project carrying such // notice may not be copied, modified, or distributed except according to those terms. @@ -29,8 +29,8 @@ //! //! The following examples show a quick example of some of the very basic functionality of `clap`. //! For more advanced usage, such as requirements, conflicts, groups, multiple values and -//! occurrences see the [documentation](https://docs.rs/clap/), [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) directory of -//! this repository or the [video tutorials](https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U). +//! occurrences see the [documentation](https://docs.rs/clap/), [examples/] directory of +//! this repository or the [video tutorials]. //! //! **NOTE:** All of these examples are functionally the same, but show different styles in which to //! use `clap` @@ -266,7 +266,7 @@ //! //! To try out the pre-built example, use the following steps: //! -//! * Clone the repository `$ git clone https://github.com/kbknapp/clap-rs && cd clap-rs/tests` +//! * Clone the repository `$ git clone https://github.com/clap-rs/clap && cd clap-rs/tests` //! * Compile the example `$ cargo build --release` //! * Run the help info `$ ./target/release/claptests --help` //! * Play with the arguments! @@ -313,13 +313,13 @@ //! //! ```toml //! [dependencies.clap] -//! git = "https://github.com/kbknapp/clap-rs.git" +//! git = "https://github.com/clap-rs/clap.git" //! ``` //! //! Add `extern crate clap;` to your crate root. //! //! Define a list of valid arguments for your program (see the -//! [documentation](https://docs.rs/clap/) or [examples/](examples) directory of this repo) +//! [documentation](https://docs.rs/clap/) or [examples/] directory of this repo) //! //! Then run `cargo build` or `cargo update && cargo build` for your project. //! @@ -366,17 +366,17 @@ //! * **Red** Color: **NOT** included by default (must use cargo `features` to enable) //! * **Blue** Color: Dev dependency, only used while developing. //! -//! ![clap dependencies](https://raw.githubusercontent.com/kbknapp/clap-rs/master/clap_dep_graph.png) +//! ![clap dependencies](https://raw.githubusercontent.com/clap-rs/clap/master/clap_dep_graph.png) //! //! ### More Information //! //! You can find complete documentation on the [docs.rs](https://docs.rs/clap/) for this project. //! -//! You can also find usage examples in the [examples/](https://github.com/kbknapp/clap-rs/tree/master/examples) directory of this repo. +//! You can also find usage examples in the [examples/] directory of this repo. //! //! #### Video Tutorials //! -//! There's also the video tutorial series [Argument Parsing with Rust v2](https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U). +//! There's also the video tutorial series [Argument Parsing with Rust v2][video tutorials]. //! //! These videos slowly trickle out as I finish them and currently a work in progress. //! @@ -388,10 +388,10 @@ //! appreciated! //! //! Another really great way to help is if you find an interesting, or helpful way in which to use -//! `clap`. You can either add it to the [examples/](examples) directory, or file an issue and tell +//! `clap`. You can either add it to the [examples/] directory, or file an issue and tell //! me. I'm all about giving credit where credit is due :) //! -//! Please read [CONTRIBUTING.md](https://raw.githubusercontent.com/kbknapp/clap-rs/master/.github/CONTRIBUTING.md) before you start contributing. +//! Please read [CONTRIBUTING.md](https://raw.githubusercontent.com/clap-rs/clap/master/.github/CONTRIBUTING.md) before you start contributing. //! //! //! ### Testing Code @@ -509,11 +509,15 @@ //! //! ## License //! -//! `clap` is licensed under the MIT license. Please read the [LICENSE-MIT](LICENSE-MIT) file in +//! `clap` is licensed under the MIT license. Please read the [LICENSE-MIT][license] file in //! this repository for more information. +//! +//! [examples/]: https://github.com/clap-rs/clap/tree/master/examples +//! [video tutorials]: https://www.youtube.com/playlist?list=PLza5oFLQGTl2Z5T8g1pRkIynR3E0_pc7U +//! [license]: https://raw.githubusercontent.com/clap-rs/clap/master/LICENSE-MIT #![crate_type = "lib"] -#![doc(html_root_url = "https://docs.rs/clap/2.32.0")] +#![doc(html_root_url = "https://docs.rs/clap/2.33.0")] #![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts, unused_import_braces, unused_allocation)] // Lints we'd like to deny but are currently failing for upstream crates @@ -567,7 +571,7 @@ mod map; const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \ - report at https://github.com/kbknapp/clap-rs/issues"; + report at https://github.com/clap-rs/clap/issues"; const INVALID_UTF8: &'static str = "unexpected invalid UTF-8 code point"; #[cfg(unstable)] diff -Nru cargo-0.33.0/vendor/clap/src/macros.rs cargo-0.35.0/vendor/clap/src/macros.rs --- cargo-0.33.0/vendor/clap/src/macros.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/macros.rs 2019-05-15 11:26:24.000000000 +0000 @@ -254,7 +254,7 @@ macro_rules! _clap_count_exprs { () => { 0 }; ($e:expr) => { 1 }; - ($e:expr, $($es:expr),+) => { 1 + _clap_count_exprs!($($es),*) }; + ($e:expr, $($es:expr),+) => { 1 + $crate::_clap_count_exprs!($($es),*) }; } /// Convenience macro to generate more complete enums with variants to be used as a type when @@ -267,7 +267,7 @@ /// /// **NOTE:** This macro automatically implements [`std::str::FromStr`] and [`std::fmt::Display`] /// -/// **NOTE:** These enums support pub (or not) and uses of the #[derive()] traits +/// **NOTE:** These enums support pub (or not) and uses of the `#[derive()]` traits /// /// # Examples /// @@ -324,7 +324,7 @@ $(stringify!($v),)+ ]; format!("valid values: {}", - v.join(" ,")) + v.join(", ")) }), } } @@ -338,7 +338,7 @@ } impl $e { #[allow(dead_code)] - pub fn variants() -> [&'static str; _clap_count_exprs!($(stringify!($v)),+)] { + pub fn variants() -> [&'static str; $crate::_clap_count_exprs!($(stringify!($v)),+)] { [ $(stringify!($v),)+ ] @@ -600,7 +600,8 @@ /// (author: "Someone E. ") /// (@arg verbose: -v --verbose "Print test information verbosely") /// ) -/// ); +/// ) +/// .get_matches(); /// # } /// ``` /// # Shorthand Syntax for Args @@ -775,9 +776,13 @@ (@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => { clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* } }; -// Inherit builder's functions - (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr)*) $($tail:tt)*) => { - clap_app!{ @arg ($arg.$ident($($expr)*)) $modes $($tail)* } +// Inherit builder's functions, e.g. `index(2)`, `requires_if("val", "arg")` + (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr),*) $($tail:tt)*) => { + clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } + }; +// Inherit builder's functions with trailing comma, e.g. `index(2,)`, `requires_if("val", "arg",)` + (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr,)*) $($tail:tt)*) => { + clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } }; // Build a subcommand outside of an app. diff -Nru cargo-0.33.0/vendor/clap/src/suggestions.rs cargo-0.35.0/vendor/clap/src/suggestions.rs --- cargo-0.33.0/vendor/clap/src/suggestions.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/clap/src/suggestions.rs 2019-05-15 11:26:24.000000000 +0000 @@ -44,6 +44,7 @@ #[cfg_attr(feature = "lints", allow(needless_lifetimes))] pub fn did_you_mean_flag_suffix<'z, T, I>( arg: &str, + args_rest: &'z [&str], longs: I, subcommands: &'z [App], ) -> (String, Option<&'z str>) @@ -51,16 +52,18 @@ T: AsRef + 'z, I: IntoIterator, { - match did_you_mean(arg, longs) { - Some(candidate) => { - let suffix = format!( - "\n\tDid you mean {}{}?", - Format::Good("--"), - Format::Good(candidate) + if let Some(candidate) = did_you_mean(arg, longs) { + let suffix = format!( + "\n\tDid you mean {}{}?", + Format::Good("--"), + Format::Good(candidate) ); - return (suffix, Some(candidate)); - } - None => for subcommand in subcommands { + return (suffix, Some(candidate)); + } + + subcommands + .into_iter() + .filter_map(|subcommand| { let opts = subcommand .p .flags @@ -68,18 +71,27 @@ .filter_map(|f| f.s.long) .chain(subcommand.p.opts.iter().filter_map(|o| o.s.long)); - if let Some(candidate) = did_you_mean(arg, opts) { - let suffix = format!( - "\n\tDid you mean to put '{}{}' after the subcommand '{}'?", - Format::Good("--"), - Format::Good(candidate), - Format::Good(subcommand.get_name()) - ); - return (suffix, Some(candidate)); - } - }, - } - (String::new(), None) + let candidate = match did_you_mean(arg, opts) { + Some(candidate) => candidate, + None => return None + }; + let score = match args_rest.iter().position(|x| *x == subcommand.get_name()) { + Some(score) => score, + None => return None + }; + + let suffix = format!( + "\n\tDid you mean to put '{}{}' after the subcommand '{}'?", + Format::Good("--"), + Format::Good(candidate), + Format::Good(subcommand.get_name()) + ); + + Some((score, (suffix, Some(candidate)))) + }) + .min_by_key(|&(score, _)| score) + .map(|(_, suggestion)| suggestion) + .unwrap_or_else(|| (String::new(), None)) } /// Returns a suffix that can be empty, or is the standard 'did you mean' phrase diff -Nru cargo-0.33.0/vendor/core-foundation/.cargo-checksum.json cargo-0.35.0/vendor/core-foundation/.cargo-checksum.json --- cargo-0.33.0/vendor/core-foundation/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"} \ No newline at end of file +{"files":{},"package":"25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/core-foundation/Cargo.toml cargo-0.35.0/vendor/core-foundation/Cargo.toml --- cargo-0.33.0/vendor/core-foundation/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,10 +12,12 @@ [package] name = "core-foundation" -version = "0.6.3" +version = "0.6.4" authors = ["The Servo Project Developers"] -description = "Bindings to Core Foundation for OS X" +description = "Bindings to Core Foundation for macOS" homepage = "https://github.com/servo/core-foundation-rs" +keywords = ["macos", "framework", "objc"] +categories = ["os::macos-apis"] license = "MIT / Apache-2.0" repository = "https://github.com/servo/core-foundation-rs" [dependencies.chrono] diff -Nru cargo-0.33.0/vendor/core-foundation/debian/patches/series cargo-0.35.0/vendor/core-foundation/debian/patches/series --- cargo-0.33.0/vendor/core-foundation/debian/patches/series 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/debian/patches/series 2019-05-15 11:26:24.000000000 +0000 @@ -1,2 +1 @@ -0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch update-dep-uuid-version.patch diff -Nru cargo-0.33.0/vendor/core-foundation/debian/patches/update-dep-uuid-version.patch cargo-0.35.0/vendor/core-foundation/debian/patches/update-dep-uuid-version.patch --- cargo-0.33.0/vendor/core-foundation/debian/patches/update-dep-uuid-version.patch 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/debian/patches/update-dep-uuid-version.patch 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,6 @@ --- a/Cargo.toml +++ b/Cargo.toml -@@ -29,7 +29,7 @@ +@@ -31,7 +31,7 @@ version = "0.2" [dependencies.uuid] @@ -11,7 +11,7 @@ [features] --- a/src/uuid.rs +++ b/src/uuid.rs -@@ -62,7 +62,7 @@ +@@ -68,7 +68,7 @@ b.byte14, b.byte15, ]; diff -Nru cargo-0.33.0/vendor/core-foundation/.pc/0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch/src/url.rs cargo-0.35.0/vendor/core-foundation/.pc/0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch/src/url.rs --- cargo-0.33.0/vendor/core-foundation/.pc/0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch/src/url.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/.pc/0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch/src/url.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -// Copyright 2013 The Servo Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A URL type for Core Foundation. - -pub use core_foundation_sys::url::*; - -use base::{TCFType, CFIndex}; -use string::{CFString}; - -use core_foundation_sys::base::{kCFAllocatorDefault, Boolean}; -use std::fmt; -use std::ptr; -use std::path::{Path, PathBuf}; -use std::mem; - -use libc::{strlen, PATH_MAX}; - -#[cfg(unix)] -use std::os::unix::ffi::OsStrExt; -#[cfg(unix)] -use std::ffi::OsStr; - - -declare_TCFType!(CFURL, CFURLRef); -impl_TCFType!(CFURL, CFURLRef, CFURLGetTypeID); - -impl fmt::Debug for CFURL { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - unsafe { - let string: CFString = TCFType::wrap_under_get_rule(CFURLGetString(self.0)); - write!(f, "{}", string.to_string()) - } - } -} - -impl CFURL { - pub fn from_path>(path: P, isDirectory: bool) -> Option { - let path_bytes; - #[cfg(unix)] - { - path_bytes = path.as_ref().as_os_str().as_bytes() - } - #[cfg(not(unix))] - { - // XXX: Getting non-valid UTF8 paths into CoreFoundation on Windows is going to be unpleasant - // CFURLGetWideFileSystemRepresentation might help - path_bytes = match path.as_ref().to_str() { - Some(path) => path, - None => return None, - } - } - - unsafe { - let url_ref = CFURLCreateFromFileSystemRepresentation(ptr::null_mut(), path_bytes.as_ptr(), path_bytes.len() as CFIndex, isDirectory as u8); - if url_ref.is_null() { - return None; - } - Some(TCFType::wrap_under_create_rule(url_ref)) - } - } - - pub fn from_file_system_path(filePath: CFString, pathStyle: CFURLPathStyle, isDirectory: bool) -> CFURL { - unsafe { - let url_ref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath.as_concrete_TypeRef(), pathStyle, isDirectory as u8); - TCFType::wrap_under_create_rule(url_ref) - } - } - - #[cfg(unix)] - pub fn to_path(&self) -> Option { - // implementing this on Windows is more complicated because of the different OsStr representation - unsafe { - let mut buf: [u8; PATH_MAX as usize] = mem::uninitialized(); - let result = CFURLGetFileSystemRepresentation(self.0, true as Boolean, buf.as_mut_ptr(), buf.len() as CFIndex); - if result == false as Boolean { - return None; - } - let len = strlen(buf.as_ptr() as *const i8); - let path = OsStr::from_bytes(&buf[0..len]); - Some(PathBuf::from(path)) - } - } - - pub fn get_string(&self) -> CFString { - unsafe { - TCFType::wrap_under_get_rule(CFURLGetString(self.0)) - } - } - - pub fn get_file_system_path(&self, pathStyle: CFURLPathStyle) -> CFString { - unsafe { - TCFType::wrap_under_create_rule(CFURLCopyFileSystemPath(self.as_concrete_TypeRef(), pathStyle)) - } - } - - pub fn absolute(&self) -> CFURL { - unsafe { - TCFType::wrap_under_create_rule(CFURLCopyAbsoluteURL(self.as_concrete_TypeRef())) - } - } -} - -#[test] -fn file_url_from_path() { - let path = "/usr/local/foo/"; - let cfstr_path = CFString::from_static_string(path); - let cfurl = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true); - assert_eq!(cfurl.get_string().to_string(), "file:///usr/local/foo/"); -} - -#[cfg(unix)] -#[test] -fn non_utf8() { - use std::ffi::OsStr; - let path = Path::new(OsStr::from_bytes(b"/\xC0/blame")); - let cfurl = CFURL::from_path(path, false).unwrap(); - assert_eq!(cfurl.to_path().unwrap(), path); - let len = unsafe { CFURLGetBytes(cfurl.as_concrete_TypeRef(), ptr::null_mut(), 0) }; - assert_eq!(len, 17); -} - -#[test] -fn absolute_file_url() { - use core_foundation_sys::url::CFURLCreateWithFileSystemPathRelativeToBase; - use std::path::PathBuf; - - let path = "/usr/local/foo"; - let file = "bar"; - - let cfstr_path = CFString::from_static_string(path); - let cfstr_file = CFString::from_static_string(file); - let cfurl_base = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true); - let cfurl_relative: CFURL = unsafe { - let url_ref = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, - cfstr_file.as_concrete_TypeRef(), - kCFURLPOSIXPathStyle, - false as u8, - cfurl_base.as_concrete_TypeRef()); - TCFType::wrap_under_create_rule(url_ref) - }; - - let mut absolute_path = PathBuf::from(path); - absolute_path.push(file); - - assert_eq!(cfurl_relative.get_file_system_path(kCFURLPOSIXPathStyle).to_string(), file); - assert_eq!(cfurl_relative.absolute().get_file_system_path(kCFURLPOSIXPathStyle).to_string(), - absolute_path.to_str().unwrap()); -} diff -Nru cargo-0.33.0/vendor/core-foundation/.pc/applied-patches cargo-0.35.0/vendor/core-foundation/.pc/applied-patches --- cargo-0.33.0/vendor/core-foundation/.pc/applied-patches 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/.pc/applied-patches 2019-05-15 11:26:24.000000000 +0000 @@ -1,2 +1 @@ -0001-Use-libc-c_char-instead-of-i8-for-libc-calls.patch update-dep-uuid-version.patch diff -Nru cargo-0.33.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/Cargo.toml cargo-0.35.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/Cargo.toml --- cargo-0.33.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,10 +12,12 @@ [package] name = "core-foundation" -version = "0.6.3" +version = "0.6.4" authors = ["The Servo Project Developers"] -description = "Bindings to Core Foundation for OS X" +description = "Bindings to Core Foundation for macOS" homepage = "https://github.com/servo/core-foundation-rs" +keywords = ["macos", "framework", "objc"] +categories = ["os::macos-apis"] license = "MIT / Apache-2.0" repository = "https://github.com/servo/core-foundation-rs" [dependencies.chrono] diff -Nru cargo-0.33.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/src/uuid.rs cargo-0.35.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/src/uuid.rs --- cargo-0.33.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/src/uuid.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/.pc/update-dep-uuid-version.patch/src/uuid.rs 2019-05-15 11:26:24.000000000 +0000 @@ -38,6 +38,12 @@ } } +impl Default for CFUUID { + fn default() -> Self { + Self::new() + } +} + #[cfg(feature = "with-uuid")] impl Into for CFUUID { fn into(self) -> Uuid { @@ -107,6 +113,6 @@ let cf_uuid = CFUUID::new(); let uuid: Uuid = cf_uuid.clone().into(); let converted = CFUUID::from(uuid); - assert!(cf_uuid == converted); + assert_eq!(cf_uuid, converted); } } diff -Nru cargo-0.33.0/vendor/core-foundation/src/array.rs cargo-0.35.0/vendor/core-foundation/src/array.rs --- cargo-0.33.0/vendor/core-foundation/src/array.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/array.rs 2019-05-15 11:26:24.000000000 +0000 @@ -66,7 +66,7 @@ pub fn from_copyable(elems: &[T]) -> CFArray where T: Copy { unsafe { let array_ref = CFArrayCreate(kCFAllocatorDefault, - mem::transmute(elems.as_ptr()), + elems.as_ptr() as *const *const c_void, elems.len().to_CFIndex(), ptr::null()); TCFType::wrap_under_create_rule(array_ref) @@ -78,7 +78,7 @@ unsafe { let elems: Vec = elems.iter().map(|elem| elem.as_CFTypeRef()).collect(); let array_ref = CFArrayCreate(kCFAllocatorDefault, - mem::transmute(elems.as_ptr()), + elems.as_ptr(), elems.len().to_CFIndex(), &kCFTypeArrayCallBacks); TCFType::wrap_under_create_rule(array_ref) @@ -250,12 +250,17 @@ n5.as_CFType(), ]); - assert!(arr.get_all_values() == &[n0.as_CFTypeRef(), - n1.as_CFTypeRef(), - n2.as_CFTypeRef(), - n3.as_CFTypeRef(), - n4.as_CFTypeRef(), - n5.as_CFTypeRef()]); + assert_eq!( + arr.get_all_values(), + &[ + n0.as_CFTypeRef(), + n1.as_CFTypeRef(), + n2.as_CFTypeRef(), + n3.as_CFTypeRef(), + n4.as_CFTypeRef(), + n5.as_CFTypeRef() + ] + ); let mut sum = 0; @@ -269,13 +274,13 @@ sum += number.to_i64().unwrap() } - assert!(sum == 15); + assert_eq!(sum, 15); for elem in arr.iter() { let number: CFNumber = elem.downcast::().unwrap(); sum += number.to_i64().unwrap() } - assert!(sum == 30); + assert_eq!(sum, 30); } } diff -Nru cargo-0.33.0/vendor/core-foundation/src/attributed_string.rs cargo-0.35.0/vendor/core-foundation/src/attributed_string.rs --- cargo-0.33.0/vendor/core-foundation/src/attributed_string.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/attributed_string.rs 2019-05-15 11:26:24.000000000 +0000 @@ -77,3 +77,9 @@ } } } + +impl Default for CFMutableAttributedString { + fn default() -> Self { + Self::new() + } +} diff -Nru cargo-0.33.0/vendor/core-foundation/src/base.rs cargo-0.35.0/vendor/core-foundation/src/base.rs --- cargo-0.33.0/vendor/core-foundation/src/base.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/base.rs 2019-05-15 11:26:24.000000000 +0000 @@ -59,7 +59,7 @@ /// // Cast it up to a CFType. /// let cf_type: CFType = string.as_CFType(); /// // Cast it down again. - /// assert!(cf_type.downcast::().unwrap().to_string() == "FooBar"); + /// assert_eq!(cf_type.downcast::().unwrap().to_string(), "FooBar"); /// // Casting it to some other type will yield `None` /// assert!(cf_type.downcast::().is_none()); /// ``` @@ -111,6 +111,9 @@ } impl fmt::Debug for CFType { + /// Formats the value using [`CFCopyDescription`]. + /// + /// [`CFCopyDescription`]: https://developer.apple.com/documentation/corefoundation/1521252-cfcopydescription?language=objc fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let desc = unsafe { CFString::wrap_under_create_rule(CFCopyDescription(self.0)) @@ -154,6 +157,10 @@ /// All Core Foundation types implement this trait. The associated type `Ref` specifies the /// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is /// `CFArrayRef`. +/// +/// Most structs that implement this trait will do so via the [`impl_TCFType`] macro. +/// +/// [`impl_TCFType`]: ../macro.impl_TCFType.html pub trait TCFType { /// The reference type wrapped inside this type. type Ref: TCFTypeRef; diff -Nru cargo-0.33.0/vendor/core-foundation/src/dictionary.rs cargo-0.35.0/vendor/core-foundation/src/dictionary.rs --- cargo-0.33.0/vendor/core-foundation/src/dictionary.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/dictionary.rs 2019-05-15 11:26:24.000000000 +0000 @@ -44,8 +44,8 @@ unsafe { let dictionary_ref = CFDictionaryCreate(kCFAllocatorDefault, - mem::transmute(keys.as_ptr()), - mem::transmute(values.as_ptr()), + keys.as_ptr(), + values.as_ptr(), keys.len().to_CFIndex(), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -58,6 +58,13 @@ unsafe { CFDictionary::wrap_under_get_rule(self.0) } } + /// Returns a `CFMutableDictionary` pointing to the same underlying dictionary as this immutable one. + /// This should only be used when the underlying dictionary is mutable. + #[inline] + pub unsafe fn to_mutable(&self) -> CFMutableDictionary { + CFMutableDictionary::wrap_under_get_rule(self.0 as CFMutableDictionaryRef) + } + /// Returns the same dictionary, but with the types reset to void pointers. /// Equal to `to_untyped`, but is faster since it does not increment the retain count. #[inline] @@ -103,7 +110,7 @@ #[inline] pub fn get<'a, T: ToVoid>(&'a self, key: T) -> ItemRef<'a, V> where V: FromVoid, K: ToVoid { let ptr = key.to_void(); - self.find(key).expect(&format!("No entry found for key {:p}", ptr)) + self.find(key).unwrap_or_else(|| panic!("No entry found for key {:p}", ptr)) } pub fn get_keys_and_values(&self) -> (Vec<*const c_void>, Vec<*const c_void>) { @@ -223,7 +230,7 @@ #[inline] pub fn get<'a>(&'a self, key: &K) -> ItemRef<'a, V> where V: FromVoid, K: ToVoid { let ptr = key.to_void(); - self.find(&key).expect(&format!("No entry found for key {:p}", ptr)) + self.find(&key).unwrap_or_else(|| panic!("No entry found for key {:p}", ptr)) } pub fn get_keys_and_values(&self) -> (Vec<*const c_void>, Vec<*const c_void>) { @@ -272,6 +279,12 @@ } } +impl Default for CFMutableDictionary { + fn default() -> Self { + Self::new() + } +} + impl<'a, K, V> From<&'a CFDictionary> for CFMutableDictionary { /// Creates a new mutable dictionary with the key-value pairs from another dictionary. /// The capacity of the new mutable dictionary is not limited. @@ -309,8 +322,8 @@ ]); let (v1, v2) = d.get_keys_and_values(); - assert!(v1 == &[bar.as_CFTypeRef(), baz.as_CFTypeRef(), foo.as_CFTypeRef()]); - assert!(v2 == &[boo.as_CFTypeRef(), tru.as_CFTypeRef(), n42.as_CFTypeRef()]); + assert_eq!(v1, &[bar.as_CFTypeRef(), baz.as_CFTypeRef(), foo.as_CFTypeRef()]); + assert_eq!(v2, &[boo.as_CFTypeRef(), tru.as_CFTypeRef(), n42.as_CFTypeRef()]); } #[test] @@ -329,15 +342,15 @@ assert_eq!(d.len(), 3); let (v1, v2) = d.get_keys_and_values(); - assert!(v1 == &[bar.as_CFTypeRef(), baz.as_CFTypeRef(), foo.as_CFTypeRef()]); - assert!(v2 == &[boo.as_CFTypeRef(), tru.as_CFTypeRef(), n42.as_CFTypeRef()]); + assert_eq!(v1, &[bar.as_CFTypeRef(), baz.as_CFTypeRef(), foo.as_CFTypeRef()]); + assert_eq!(v2, &[boo.as_CFTypeRef(), tru.as_CFTypeRef(), n42.as_CFTypeRef()]); d.remove(baz); assert_eq!(d.len(), 2); let (v1, v2) = d.get_keys_and_values(); - assert!(v1 == &[bar.as_CFTypeRef(), foo.as_CFTypeRef()]); - assert!(v2 == &[boo.as_CFTypeRef(), n42.as_CFTypeRef()]); + assert_eq!(v1, &[bar.as_CFTypeRef(), foo.as_CFTypeRef()]); + assert_eq!(v2, &[boo.as_CFTypeRef(), n42.as_CFTypeRef()]); d.remove_all(); assert_eq!(d.len(), 0) diff -Nru cargo-0.33.0/vendor/core-foundation/src/lib.rs cargo-0.35.0/vendor/core-foundation/src/lib.rs --- cargo-0.33.0/vendor/core-foundation/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -6,8 +6,15 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. + #![allow(non_snake_case)] +//! This crate provides wrappers around the underlying CoreFoundation +//! types and functions that are available on Apple's operating systems. +//! +//! It also provides a framework for other crates to use when wrapping +//! other frameworks that use the CoreFoundation framework. + extern crate core_foundation_sys; extern crate libc; @@ -18,6 +25,34 @@ pub unsafe trait ConcreteCFType: TCFType {} +/// Declare a Rust type that wraps an underlying CoreFoundation type. +/// +/// This will provide an implementation of `Drop` using [`CFRelease`]. +/// The type must have an implementation of the [`TCFType`] trait, usually +/// provided using the [`impl_TCFType`] macro. +/// +/// ``` +/// #[macro_use] extern crate core_foundation; +/// // Make sure that the `TCFType` trait is in scope. +/// use core_foundation::base::{CFTypeID, TCFType}; +/// +/// extern "C" { +/// // We need a function that returns the `CFTypeID`. +/// pub fn ShrubberyGetTypeID() -> CFTypeID; +/// } +/// +/// pub struct __Shrubbery {} +/// // The ref type must be a pointer to the underlying struct. +/// pub type ShrubberyRef = *const __Shrubbery; +/// +/// declare_TCFType!(Shrubbery, ShrubberyRef); +/// impl_TCFType!(Shrubbery, ShrubberyRef, ShrubberyGetTypeID); +/// # fn main() {} +/// ``` +/// +/// [`CFRelease`]: https://developer.apple.com/documentation/corefoundation/1521153-cfrelease +/// [`TCFType`]: base/trait.TCFType.html +/// [`impl_TCFType`]: macro.impl_TCFType.html #[macro_export] macro_rules! declare_TCFType { ( @@ -35,6 +70,13 @@ } } +/// Provide an implementation of the [`TCFType`] trait for the Rust +/// wrapper type around an underlying CoreFoundation type. +/// +/// See [`declare_TCFType`] for details. +/// +/// [`declare_TCFType`]: macro.declare_TCFType.html +/// [`TCFType`]: base/trait.TCFType.html #[macro_export] macro_rules! impl_TCFType { ($ty:ident, $ty_ref:ident, $ty_id:ident) => { @@ -122,6 +164,18 @@ } +/// Implement `std::fmt::Debug` for the given type. +/// +/// This will invoke the implementation of `Debug` for [`CFType`] +/// which invokes [`CFCopyDescription`]. +/// +/// The type must have an implementation of the [`TCFType`] trait, usually +/// provided using the [`impl_TCFType`] macro. +/// +/// [`CFType`]: base/struct.CFType.html#impl-Debug +/// [`CFCopyDescription`]: https://developer.apple.com/documentation/corefoundation/1521252-cfcopydescription?language=objc +/// [`TCFType`]: base/trait.TCFType.html +/// [`impl_TCFType`]: macro.impl_TCFType.html #[macro_export] macro_rules! impl_CFTypeDescription { ($ty:ident) => { diff -Nru cargo-0.33.0/vendor/core-foundation/src/number.rs cargo-0.35.0/vendor/core-foundation/src/number.rs --- cargo-0.33.0/vendor/core-foundation/src/number.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/number.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,7 +11,7 @@ use core_foundation_sys::base::kCFAllocatorDefault; pub use core_foundation_sys::number::*; -use std::mem; +use std::os::raw::c_void; use base::TCFType; @@ -30,7 +30,7 @@ pub fn to_i32(&self) -> Option { unsafe { let mut value: i32 = 0; - let ok = CFNumberGetValue(self.0, kCFNumberSInt32Type, mem::transmute(&mut value)); + let ok = CFNumberGetValue(self.0, kCFNumberSInt32Type, &mut value as *mut i32 as *mut c_void); if ok { Some(value) } else { None } } } @@ -39,7 +39,7 @@ pub fn to_i64(&self) -> Option { unsafe { let mut value: i64 = 0; - let ok = CFNumberGetValue(self.0, kCFNumberSInt64Type, mem::transmute(&mut value)); + let ok = CFNumberGetValue(self.0, kCFNumberSInt64Type, &mut value as *mut i64 as *mut c_void); if ok { Some(value) } else { None } } } @@ -48,7 +48,7 @@ pub fn to_f32(&self) -> Option { unsafe { let mut value: f32 = 0.0; - let ok = CFNumberGetValue(self.0, kCFNumberFloat32Type, mem::transmute(&mut value)); + let ok = CFNumberGetValue(self.0, kCFNumberFloat32Type, &mut value as *mut f32 as *mut c_void); if ok { Some(value) } else { None } } } @@ -57,7 +57,7 @@ pub fn to_f64(&self) -> Option { unsafe { let mut value: f64 = 0.0; - let ok = CFNumberGetValue(self.0, kCFNumberFloat64Type, mem::transmute(&mut value)); + let ok = CFNumberGetValue(self.0, kCFNumberFloat64Type, &mut value as *mut f64 as *mut c_void); if ok { Some(value) } else { None } } } @@ -70,7 +70,7 @@ let number_ref = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type, - mem::transmute(&value), + &value as *const i32 as *const c_void, ); TCFType::wrap_under_create_rule(number_ref) } @@ -84,7 +84,7 @@ let number_ref = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt64Type, - mem::transmute(&value), + &value as *const i64 as *const c_void, ); TCFType::wrap_under_create_rule(number_ref) } @@ -98,7 +98,7 @@ let number_ref = CFNumberCreate( kCFAllocatorDefault, kCFNumberFloat32Type, - mem::transmute(&value), + &value as *const f32 as *const c_void, ); TCFType::wrap_under_create_rule(number_ref) } @@ -112,7 +112,7 @@ let number_ref = CFNumberCreate( kCFAllocatorDefault, kCFNumberFloat64Type, - mem::transmute(&value), + &value as *const f64 as *const c_void, ); TCFType::wrap_under_create_rule(number_ref) } diff -Nru cargo-0.33.0/vendor/core-foundation/src/propertylist.rs cargo-0.35.0/vendor/core-foundation/src/propertylist.rs --- cargo-0.33.0/vendor/core-foundation/src/propertylist.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/propertylist.rs 2019-05-15 11:26:24.000000000 +0000 @@ -121,7 +121,7 @@ #[inline] pub unsafe fn wrap_under_get_rule(reference: CFPropertyListRef) -> CFPropertyList { - let reference = mem::transmute(CFRetain(mem::transmute(reference))); + let reference = CFRetain(reference); CFPropertyList(reference) } @@ -142,7 +142,7 @@ #[inline] pub fn as_CFTypeRef(&self) -> ::core_foundation_sys::base::CFTypeRef { - unsafe { mem::transmute(self.as_concrete_TypeRef()) } + self.as_concrete_TypeRef() } #[inline] @@ -208,7 +208,7 @@ /// // Cast it up to a property list. /// let propertylist: CFPropertyList = string.to_CFPropertyList(); /// // Cast it down again. - /// assert!(propertylist.downcast::().unwrap().to_string() == "FooBar"); + /// assert_eq!(propertylist.downcast::().unwrap().to_string(), "FooBar"); /// ``` /// /// [`CFPropertyList`]: struct.CFPropertyList.html @@ -271,7 +271,7 @@ let data = create_data(dict1.as_CFTypeRef(), kCFPropertyListXMLFormat_v1_0).unwrap(); let (dict2, _) = create_with_data(data, kCFPropertyListImmutable).unwrap(); unsafe { - assert!(CFEqual(dict1.as_CFTypeRef(), dict2) == 1); + assert_eq!(CFEqual(dict1.as_CFTypeRef(), dict2), 1); } } @@ -291,7 +291,7 @@ #[test] fn downcast_string() { let propertylist = CFString::from_static_string("Bar").to_CFPropertyList(); - assert!(propertylist.downcast::().unwrap().to_string() == "Bar"); + assert_eq!(propertylist.downcast::().unwrap().to_string(), "Bar"); assert!(propertylist.downcast::().is_none()); } @@ -319,7 +319,7 @@ assert_eq!(string.retain_count(), 2); let string2 = propertylist.downcast_into::().unwrap(); - assert!(string2.to_string() == "Bar"); + assert_eq!(string2.to_string(), "Bar"); assert_eq!(string2.retain_count(), 2); } } diff -Nru cargo-0.33.0/vendor/core-foundation/src/set.rs cargo-0.35.0/vendor/core-foundation/src/set.rs --- cargo-0.33.0/vendor/core-foundation/src/set.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/set.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,7 +14,6 @@ use base::{CFIndexConvertible, TCFType}; -use std::mem; use std::os::raw::c_void; use std::marker::PhantomData; @@ -36,7 +35,7 @@ unsafe { let elems: Vec = elems.iter().map(|elem| elem.as_CFTypeRef()).collect(); let set_ref = CFSetCreate(kCFAllocatorDefault, - mem::transmute(elems.as_ptr()), + elems.as_ptr(), elems.len().to_CFIndex(), &kCFTypeSetCallBacks); TCFType::wrap_under_create_rule(set_ref) diff -Nru cargo-0.33.0/vendor/core-foundation/src/string.rs cargo-0.35.0/vendor/core-foundation/src/string.rs --- cargo-0.33.0/vendor/core-foundation/src/string.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/string.rs 2019-05-15 11:26:24.000000000 +0000 @@ -50,7 +50,7 @@ unsafe { // Do this without allocating if we can get away with it let c_string = CFStringGetCStringPtr(cf_str.0, kCFStringEncodingUTF8); - if c_string != ptr::null() { + if !c_string.is_null() { let c_str = CStr::from_ptr(c_string); Cow::Borrowed(str::from_utf8_unchecked(c_str.to_bytes())) } else { @@ -79,11 +79,11 @@ buffer.as_mut_ptr(), buffer.len().to_CFIndex(), &mut bytes_used); - assert!(chars_written == char_len); + assert_eq!(chars_written, char_len); // This is dangerous; we over-allocate and null-terminate the string (during // initialization). - assert!(bytes_used == buffer.len().to_CFIndex()); + assert_eq!(bytes_used, buffer.len().to_CFIndex()); Cow::Owned(String::from_utf8_unchecked(buffer)) } } @@ -146,5 +146,5 @@ let original = "The quick brown fox jumped over the slow lazy dog."; let cfstr = CFString::from_static_string(original); let converted = cfstr.to_string(); - assert!(converted == original); + assert_eq!(converted, original); } diff -Nru cargo-0.33.0/vendor/core-foundation/src/uuid.rs cargo-0.35.0/vendor/core-foundation/src/uuid.rs --- cargo-0.33.0/vendor/core-foundation/src/uuid.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/core-foundation/src/uuid.rs 2019-05-15 11:26:24.000000000 +0000 @@ -38,6 +38,12 @@ } } +impl Default for CFUUID { + fn default() -> Self { + Self::new() + } +} + #[cfg(feature = "with-uuid")] impl Into for CFUUID { fn into(self) -> Uuid { @@ -107,6 +113,6 @@ let cf_uuid = CFUUID::new(); let uuid: Uuid = cf_uuid.clone().into(); let converted = CFUUID::from(uuid); - assert!(cf_uuid == converted); + assert_eq!(cf_uuid, converted); } } diff -Nru cargo-0.33.0/vendor/crc32fast/benches/bench.rs cargo-0.35.0/vendor/crc32fast/benches/bench.rs --- cargo-0.33.0/vendor/crc32fast/benches/bench.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/benches/bench.rs 2019-05-15 11:26:24.000000000 +0000 @@ -21,19 +21,19 @@ } fn bench_kilobyte_baseline(b: &mut Bencher) { - bench(b, 1024, Hasher::internal_new_baseline()) + bench(b, 1024, Hasher::internal_new_baseline(0)) } fn bench_kilobyte_specialized(b: &mut Bencher) { - bench(b, 1024, Hasher::internal_new_specialized().unwrap()) + bench(b, 1024, Hasher::internal_new_specialized(0).unwrap()) } fn bench_megabyte_baseline(b: &mut Bencher) { - bench(b, 1024 * 1024, Hasher::internal_new_baseline()) + bench(b, 1024 * 1024, Hasher::internal_new_baseline(0)) } fn bench_megabyte_specialized(b: &mut Bencher) { - bench(b, 1024 * 1024, Hasher::internal_new_specialized().unwrap()) + bench(b, 1024 * 1024, Hasher::internal_new_specialized(0).unwrap()) } benchmark_group!( diff -Nru cargo-0.33.0/vendor/crc32fast/.cargo-checksum.json cargo-0.35.0/vendor/crc32fast/.cargo-checksum.json --- cargo-0.33.0/vendor/crc32fast/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"} \ No newline at end of file +{"files":{},"package":"ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/crc32fast/Cargo.toml cargo-0.35.0/vendor/crc32fast/Cargo.toml --- cargo-0.33.0/vendor/crc32fast/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "crc32fast" -version = "1.1.2" +version = "1.2.0" authors = ["Sam Rijs ", "Alex Crichton "] description = "Fast, SIMD-accelerated CRC32 (IEEE) checksum computation" readme = "README.md" @@ -34,3 +34,8 @@ [dev-dependencies.rand] version = "0.4" + +[features] +default = ["std"] +nightly = [] +std = [] diff -Nru cargo-0.33.0/vendor/crc32fast/README.md cargo-0.35.0/vendor/crc32fast/README.md --- cargo-0.33.0/vendor/crc32fast/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -27,6 +27,7 @@ - A fast baseline implementation which processes up to 16 bytes per iteration - An optimized implementation for modern `x86` using `sse` and `pclmulqdq` instructions +- An optimized implementation for `aarch64` using `crc32` instructions Calling the `Hasher::new` constructor at runtime will perform a feature detection to select the most optimal implementation for the current CPU feature set. @@ -47,6 +48,21 @@ Even though neither fuzzing not sanitization has revealed any safety bugs yet, please don't hesitate to file an issue if you run into any crashes or other unexpected behaviour. +## Available feature flags + +### `std` (default: enabled) + +This library supports being built without the Rust `std` library, which is useful for low-level use-cases such as embedded where no operating system is available. To build the crate in a `no_std` context, disable the default `std` feature. + +Note: Because runtime CPU feature detection requires OS support, the specialized SIMD implementations will be unavailable when the `std` feature is disabled. + +### `nightly` (default: disabled) + +This feature flag enables unstable features that are only available on the `nightly` channel. Keep in mind that when enabling this feature flag, you +might experience breaking changes when updating compiler versions. + +Currently, enabling this feature flag will make the optimized `aarch64` implementation available. + ## License This project is licensed under either of diff -Nru cargo-0.33.0/vendor/crc32fast/src/baseline.rs cargo-0.35.0/vendor/crc32fast/src/baseline.rs --- cargo-0.33.0/vendor/crc32fast/src/baseline.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/src/baseline.rs 2019-05-15 11:26:24.000000000 +0000 @@ -6,8 +6,8 @@ } impl State { - pub fn new() -> Self { - State { state: 0 } + pub fn new(state: u32) -> Self { + State { state } } pub fn update(&mut self, buf: &[u8]) { diff -Nru cargo-0.33.0/vendor/crc32fast/src/lib.rs cargo-0.35.0/vendor/crc32fast/src/lib.rs --- cargo-0.33.0/vendor/crc32fast/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -18,6 +18,12 @@ //! Calling the `Hasher::new` constructor at runtime will perform a feature detection to select the most //! optimal implementation for the current CPU feature set. +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr( + all(feature = "nightly", target_arch = "aarch64"), + feature(stdsimd, aarch64_target_feature) +)] + #[deny(missing_docs)] #[cfg(test)] #[macro_use] @@ -26,8 +32,11 @@ #[macro_use] extern crate cfg_if; -use std::fmt; -use std::hash; +#[cfg(feature = "std")] +use std as core; + +use core::fmt; +use core::hash; mod baseline; mod combine; @@ -47,29 +56,39 @@ state: State, } +const DEFAULT_INIT_STATE: u32 = 0; + impl Hasher { /// Create a new `Hasher`. /// /// This will perform a CPU feature detection at runtime to select the most /// optimal implementation for the current processor architecture. pub fn new() -> Self { - Self::internal_new_specialized().unwrap_or_else(|| Self::internal_new_baseline()) + Self::new_with_initial(DEFAULT_INIT_STATE) + } + + /// Create a new `Hasher` with an initial CRC32 state. + /// + /// This works just like `Hasher::new`, except that it allows for an initial + /// CRC32 state to be passed in. + pub fn new_with_initial(init: u32) -> Self { + Self::internal_new_specialized(init).unwrap_or_else(|| Self::internal_new_baseline(init)) } #[doc(hidden)] // Internal-only API. Don't use. - pub fn internal_new_baseline() -> Self { + pub fn internal_new_baseline(init: u32) -> Self { Hasher { amount: 0, - state: State::Baseline(baseline::State::new()), + state: State::Baseline(baseline::State::new(init)), } } #[doc(hidden)] // Internal-only API. Don't use. - pub fn internal_new_specialized() -> Option { + pub fn internal_new_specialized(init: u32) -> Option { { - if let Some(state) = specialized::State::new() { + if let Some(state) = specialized::State::new(init) { return Some(Hasher { amount: 0, state: State::Specialized(state), @@ -134,7 +153,7 @@ } fn finish(&self) -> u64 { - self.clone().finalize() as u64 + u64::from(self.clone().finalize()) } } diff -Nru cargo-0.33.0/vendor/crc32fast/src/specialized/aarch64.rs cargo-0.35.0/vendor/crc32fast/src/specialized/aarch64.rs --- cargo-0.33.0/vendor/crc32fast/src/specialized/aarch64.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/src/specialized/aarch64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,88 @@ +use std::arch::aarch64 as arch; + +#[derive(Clone)] +pub struct State { + state: u32, +} + +impl State { + pub fn new(state: u32) -> Option { + if is_aarch64_feature_detected!("crc") { + // SAFETY: The conditions above ensure that all + // required instructions are supported by the CPU. + Some(Self { state }) + } else { + None + } + } + + pub fn update(&mut self, buf: &[u8]) { + // SAFETY: The `State::new` constructor ensures that all + // required instructions are supported by the CPU. + self.state = unsafe { calculate(self.state, buf) } + } + + pub fn finalize(self) -> u32 { + self.state + } + + pub fn reset(&mut self) { + self.state = 0; + } + + pub fn combine(&mut self, other: u32, amount: u64) { + self.state = ::combine::combine(self.state, other, amount); + } +} + +// target_feature is necessary to allow rustc to inline the crc32* wrappers +#[target_feature(enable = "crc")] +pub unsafe fn calculate(crc: u32, data: &[u8]) -> u32 { + let mut c32 = !crc; + let (pre_quad, quads, post_quad) = data.align_to::(); + + c32 = pre_quad.iter().fold(c32, |acc, &b| arch::__crc32b(acc, b)); + + // unrolling increases performance by a lot + let mut quad_iter = quads.chunks_exact(8); + for chunk in &mut quad_iter { + c32 = arch::__crc32d(c32, chunk[0]); + c32 = arch::__crc32d(c32, chunk[1]); + c32 = arch::__crc32d(c32, chunk[2]); + c32 = arch::__crc32d(c32, chunk[3]); + c32 = arch::__crc32d(c32, chunk[4]); + c32 = arch::__crc32d(c32, chunk[5]); + c32 = arch::__crc32d(c32, chunk[6]); + c32 = arch::__crc32d(c32, chunk[7]); + } + c32 = quad_iter + .remainder() + .iter() + .fold(c32, |acc, &q| arch::__crc32d(acc, q)); + + c32 = post_quad.iter().fold(c32, |acc, &b| arch::__crc32b(acc, b)); + + !c32 +} + +#[cfg(test)] +mod test { + quickcheck! { + fn check_against_baseline(init: u32, chunks: Vec<(Vec, usize)>) -> bool { + let mut baseline = super::super::super::baseline::State::new(init); + let mut aarch64 = super::State::new(init).expect("not supported"); + for (chunk, mut offset) in chunks { + // simulate random alignments by offsetting the slice by up to 15 bytes + offset &= 0xF; + if chunk.len() <= offset { + baseline.update(&chunk); + aarch64.update(&chunk); + } else { + baseline.update(&chunk[offset..]); + aarch64.update(&chunk[offset..]); + } + } + aarch64.finalize() == baseline.finalize() + } + } +} diff -Nru cargo-0.33.0/vendor/crc32fast/src/specialized/mod.rs cargo-0.35.0/vendor/crc32fast/src/specialized/mod.rs --- cargo-0.33.0/vendor/crc32fast/src/specialized/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/src/specialized/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,11 +5,14 @@ ))] { mod pclmulqdq; pub use self::pclmulqdq::State; + } else if #[cfg(all(feature = "nightly", target_arch = "aarch64"))] { + mod aarch64; + pub use self::aarch64::State; } else { #[derive(Clone)] pub enum State {} impl State { - pub fn new() -> Option { + pub fn new(_: u32) -> Option { None } diff -Nru cargo-0.33.0/vendor/crc32fast/src/specialized/pclmulqdq.rs cargo-0.35.0/vendor/crc32fast/src/specialized/pclmulqdq.rs --- cargo-0.33.0/vendor/crc32fast/src/specialized/pclmulqdq.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/crc32fast/src/specialized/pclmulqdq.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,7 @@ #[cfg(target_arch = "x86")] -use std::arch::x86 as arch; +use core::arch::x86 as arch; #[cfg(target_arch = "x86_64")] -use std::arch::x86_64 as arch; +use core::arch::x86_64 as arch; #[derive(Clone)] pub struct State { @@ -9,14 +9,29 @@ } impl State { - pub fn new() -> Option { + #[cfg(not(feature = "std"))] + pub fn new(state: u32) -> Option { + if cfg!(target_feature = "pclmulqdq") + && cfg!(target_feature = "sse2") + && cfg!(target_feature = "sse4.1") + { + // SAFETY: The conditions above ensure that all + // required instructions are supported by the CPU. + Some(Self { state }) + } else { + None + } + } + + #[cfg(feature = "std")] + pub fn new(state: u32) -> Option { if is_x86_feature_detected!("pclmulqdq") && is_x86_feature_detected!("sse2") && is_x86_feature_detected!("sse4.1") { // SAFETY: The conditions above ensure that all // required instructions are supported by the CPU. - Some(Self { state: 0 }) + Some(Self { state }) } else { None } @@ -51,6 +66,7 @@ const P_X: i64 = 0x1DB710641; const U_PRIME: i64 = 0x1F7011641; +#[cfg(feature = "std")] unsafe fn debug(s: &str, a: arch::__m128i) -> arch::__m128i { if false { union A { @@ -67,6 +83,11 @@ return a; } +#[cfg(not(feature = "std"))] +unsafe fn debug(_s: &str, a: arch::__m128i) -> arch::__m128i { + a +} + #[target_feature(enable = "pclmulqdq", enable = "sse2", enable = "sse4.1")] pub unsafe fn calculate(crc: u32, mut data: &[u8]) -> u32 { // In theory we can accelerate smaller chunks too, but for now just rely on @@ -161,7 +182,7 @@ // C(x) = R(x) ^ T2(x) / x^32 let c = arch::_mm_extract_epi32(arch::_mm_xor_si128(x, t2), 1) as u32; - if data.len() > 0 { + if !data.is_empty() { ::baseline::update_fast_16(!c, data) } else { !c @@ -184,12 +205,12 @@ #[cfg(test)] mod test { quickcheck! { - fn check_against_baseline(chunks: Vec<(Vec, usize)>) -> bool { - let mut baseline = super::super::super::baseline::State::new(); - let mut pclmulqdq = super::State::new().expect("not supported"); + fn check_against_baseline(init: u32, chunks: Vec<(Vec, usize)>) -> bool { + let mut baseline = super::super::super::baseline::State::new(init); + let mut pclmulqdq = super::State::new(init).expect("not supported"); for (chunk, mut offset) in chunks { // simulate random alignments by offsetting the slice by up to 15 bytes - offset = offset & 0xF; + offset &= 0xF; if chunk.len() <= offset { baseline.update(&chunk); pclmulqdq.update(&chunk); diff -Nru cargo-0.33.0/vendor/curl/appveyor.yml cargo-0.35.0/vendor/curl/appveyor.yml --- cargo-0.33.0/vendor/curl/appveyor.yml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -environment: - matrix: - - # Ensure vanilla builds work - - TARGET: i686-pc-windows-msvc - - TARGET: x86_64-pc-windows-msvc - - # Pin to specific VS versions to ensure the build works - - TARGET: x86_64-pc-windows-msvc - ARCH: amd64 - VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat - - TARGET: x86_64-pc-windows-msvc - ARCH: amd64 - VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat - -install: - # Install rust, x86_64-pc-windows-msvc host - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - # use nightly if required until -Ctarget-feature=+crt-static is stable (expected in rust 1.19) - - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc - - if defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - # Install the target we're compiling for - - if NOT "%TARGET%" == "x86_64-pc-windows-msvc" rustup target add %TARGET% - - # If we're pinning to a specific visual studio, do so now - - if defined VS call "%VS%" %ARCH% - - # let's see what we got - - where gcc rustc cargo - - rustc -vV - - cargo -vV - - set CARGO_TARGET_DIR=%CD%\target - -build: false - -test_script: - - cargo test --target %TARGET% - - cargo run --manifest-path systest/Cargo.toml --target %TARGET% diff -Nru cargo-0.33.0/vendor/curl/azure-pipelines.yml cargo-0.35.0/vendor/curl/azure-pipelines.yml --- cargo-0.33.0/vendor/curl/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/curl/azure-pipelines.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,101 @@ +trigger: + - master + +jobs: + - job: Linux + pool: + vmImage: ubuntu-16.04 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64: + TARGET: x86_64-unknown-linux-gnu + DOCKER: linux64 + i686: + TARGET: i686-unknown-linux-gnu + DOCKER: linux32 + x86_64-musl: + TARGET: x86_64-unknown-linux-musl + DOCKER: musl + mingw: + TARGET: x86_64-pc-windows-gnu + DOCKER: mingw + NO_RUN: 1 + TOOLCHAIN: nightly + system-curl: + TARGET: x86_64-unknown-linux-gnu + DOCKER: linux64-curl + openssl-110: + TARGET: x86_64-unknown-linux-gnu + DOCKER: centos7 + x86_64-beta: + TARGET: x86_64-unknown-linux-gnu + DOCKER: linux64 + TOOLCHAIN: beta + x86_64-nightly: + TARGET: x86_64-unknown-linux-gnu + DOCKER: linux64 + TOOLCHAIN: nightly + + - job: macOS + pool: + vmImage: macos-10.13 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64: + TARGET: x86_64-apple-darwin + i686: + TARGET: i686-apple-darwin + + - job: macOS_static + pool: + vmImage: macos-10.13 + steps: + - checkout: self + submodules: true + - template: ci/azure-install-rust.yml + - script: cargo test --features curl-sys/static-curl -vvv + + - job: Windows_vs2019 + pool: + vmImage: windows-2019 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + + - job: Windows_vs2017 + pool: + vmImage: vs2017-win2016 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + i686-msvc: + TARGET: i686-pc-windows-msvc + + - job: Windows_vs2015 + pool: + vmImage: vs2015-win2012r2 + steps: + - template: ci/azure-steps.yml + strategy: + matrix: + x86_64-msvc: + TARGET: x86_64-pc-windows-msvc + + - job: docs + steps: + - template: ci/azure-install-rust.yml + - script: cargo doc --no-deps --all-features + - script: curl -LsSf https://git.io/fhJ8n | rustc - && (cd target/doc && ../../rust_out) + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + env: + GITHUB_DEPLOY_KEY: $(GITHUB_DEPLOY_KEY) diff -Nru cargo-0.33.0/vendor/curl/build.rs cargo-0.35.0/vendor/curl/build.rs --- cargo-0.33.0/vendor/curl/build.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/curl/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,24 @@ +use std::env; +use std::str::FromStr; + +fn main() { + // OpenSSL >= 1.1.0 can be initialized concurrently and is initialized correctly by libcurl. + // <= 1.0.2 need locking callbacks, which are provided by openssl_sys::init(). + let use_openssl = match env::var("DEP_OPENSSL_VERSION") { + Ok(ver) => { + let ver = u32::from_str(&ver).unwrap(); + if ver < 110 { + println!("cargo:rustc-cfg=need_openssl_init"); + } + true + } + Err(_) => false, + }; + + if use_openssl { + // The system libcurl should have the default certificate paths configured. + if env::var_os("DEP_CURL_STATIC").is_some() { + println!("cargo:rustc-cfg=need_openssl_probe"); + } + } +} diff -Nru cargo-0.33.0/vendor/curl/.cargo-checksum.json cargo-0.35.0/vendor/curl/.cargo-checksum.json --- cargo-0.33.0/vendor/curl/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"} \ No newline at end of file +{"files":{},"package":"a85f2f95f2bd277d316d1aa8a477687ab4a6942258c7db7c89c187534669979c"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/curl/Cargo.toml cargo-0.35.0/vendor/curl/Cargo.toml --- cargo-0.33.0/vendor/curl/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "curl" -version = "0.4.19" +version = "0.4.21" authors = ["Alex Crichton "] autotests = true description = "Rust bindings to libcurl for making HTTP requests" @@ -26,7 +26,7 @@ name = "atexit" harness = false [dependencies.curl-sys] -version = "0.4.15" +version = "0.4.18" default-features = false [dependencies.libc] @@ -52,14 +52,15 @@ optional = true [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies.openssl-sys] -version = "0.9.33" +version = "0.9.43" optional = true +[target."cfg(target_env = \"msvc\")".dependencies.kernel32-sys] +version = "0.2.2" [target."cfg(target_env = \"msvc\")".dependencies.schannel] version = "0.1.13" [target."cfg(windows)".dependencies.winapi] -version = "0.3" -features = ["winsock2", "wincrypt", "libloaderapi"] +version = "0.2.7" [badges.appveyor] repository = "alexcrichton/curl-rust" diff -Nru cargo-0.33.0/vendor/curl/ci/azure-install-rust.yml cargo-0.35.0/vendor/curl/ci/azure-install-rust.yml --- cargo-0.33.0/vendor/curl/ci/azure-install-rust.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/curl/ci/azure-install-rust.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,23 @@ +steps: + - bash: | + set -e + toolchain=$TOOLCHAIN + if [ "$toolchain" = "" ]; then + toolchain=stable + fi + curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $toolchain + echo "##vso[task.prependpath]$HOME/.cargo/bin" + displayName: Install rust (unix) + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + curl -sSf -o rustup-init.exe https://win.rustup.rs + rustup-init.exe -y --default-toolchain stable-%TARGET% + echo ##vso[task.prependpath]%USERPROFILE%\.cargo\bin + displayName: Install rust (windows) + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + + - script: | + rustc -Vv + cargo -V + displayName: Query rust and cargo versions diff -Nru cargo-0.33.0/vendor/curl/ci/azure-steps.yml cargo-0.35.0/vendor/curl/ci/azure-steps.yml --- cargo-0.33.0/vendor/curl/ci/azure-steps.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/curl/ci/azure-steps.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,31 @@ +steps: + - checkout: self + submodules: true + + - template: azure-install-rust.yml + + - bash: rustup target add $TARGET + displayName: Install Rust target + + - bash: ./ci/run.sh + condition: ne( variables['Agent.OS'], 'Linux' ) + displayName: Run test script + + - bash: | + set -e + cargo generate-lockfile + mkdir .cargo target + docker build -t rust -f ci/Dockerfile-$DOCKER ci + docker run \ + -w /src \ + -v `pwd`:/src:ro \ + -v `pwd`/target:/src/target \ + -v `pwd`/ci/.cargo:/src/.cargo:ro \ + -v `rustc --print sysroot`:/usr/local:ro \ + -e TARGET \ + -e NO_RUN \ + -e CARGO_TARGET_DIR=/src/target \ + rust \ + sh ci/run.sh \ + condition: eq( variables['Agent.OS'], 'Linux' ) + displayName: Run docker test script diff -Nru cargo-0.33.0/vendor/curl/ci/Dockerfile-centos7 cargo-0.35.0/vendor/curl/ci/Dockerfile-centos7 --- cargo-0.33.0/vendor/curl/ci/Dockerfile-centos7 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/curl/ci/Dockerfile-centos7 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,7 @@ +FROM centos:7 + +RUN yum update -y +RUN yum install -y \ + gcc ca-certificates make \ + openssl-devel \ + pkgconfig diff -Nru cargo-0.33.0/vendor/curl/debian/patches/winapi3.patch cargo-0.35.0/vendor/curl/debian/patches/winapi3.patch --- cargo-0.33.0/vendor/curl/debian/patches/winapi3.patch 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/debian/patches/winapi3.patch 2019-05-15 11:26:24.000000000 +0000 @@ -1,24 +1,19 @@ ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -54,13 +54,12 @@ - [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies.openssl-sys] +--- a/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 ++++ b/Cargo.toml 2018-09-21 18:54:24.693880364 +0000 +@@ -48,4 +48,2 @@ version = "0.1.2" version = "0.9.33" - optional = true --[target."cfg(target_env = \"msvc\")".dependencies.kernel32-sys] +-[target."cfg(target_env=\"msvc\")".dependencies.kernel32-sys] -version = "0.2.2" - [target."cfg(target_env = \"msvc\")".dependencies.schannel] - version = "0.1.13" +@@ -54,3 +52,4 @@ version = "0.1.13" [target."cfg(windows)".dependencies.winapi] -version = "0.2.7" +version = "0.3" +features = ["winsock2", "wincrypt", "libloaderapi"] [badges.appveyor] - repository = "alexcrichton/curl-rust" - ---- a/src/easy/windows.rs -+++ b/src/easy/windows.rs -@@ -4,21 +4,21 @@ +--- a/src/easy/windows.rs 2018-09-21 18:01:35.962553903 +0000 ++++ b/src/easy/windows.rs 2018-09-21 18:01:35.962553903 +0000 +@@ -4,21 +4,21 @@ use libc::c_void; #[cfg(target_env = "msvc")] mod win { @@ -43,20 +38,20 @@ if n == ptr::null() { None } else { ---- a/src/lib.rs -+++ b/src/lib.rs -@@ -62,8 +62,6 @@ +--- a/src/lib.rs 2018-09-21 18:01:35.962553903 +0000 ++++ b/src/lib.rs 2018-09-21 18:01:35.962553903 +0000 +@@ -61,8 +61,6 @@ extern crate openssl_probe; + #[cfg(windows)] extern crate winapi; - #[cfg(target_env = "msvc")] --extern crate kernel32; -#[cfg(target_env = "msvc")] +-extern crate kernel32; + #[cfg(target_env = "msvc")] extern crate schannel; - use std::ffi::CStr; ---- a/src/multi.rs -+++ b/src/multi.rs -@@ -8,7 +8,7 @@ +--- a/src/multi.rs 2018-09-21 18:01:35.962553903 +0000 ++++ b/src/multi.rs 2018-09-21 18:01:35.962553903 +0000 +@@ -8,7 +8,7 @@ use libc::{c_int, c_char, c_void, c_long, c_short}; use curl_sys; #[cfg(windows)] diff -Nru cargo-0.33.0/vendor/curl/.pc/applied-patches cargo-0.35.0/vendor/curl/.pc/applied-patches --- cargo-0.33.0/vendor/curl/.pc/applied-patches 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -winapi3.patch diff -Nru cargo-0.33.0/vendor/curl/.pc/winapi3.patch/Cargo.toml cargo-0.35.0/vendor/curl/.pc/winapi3.patch/Cargo.toml --- cargo-0.33.0/vendor/curl/.pc/winapi3.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.pc/winapi3.patch/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "curl" -version = "0.4.19" -authors = ["Alex Crichton "] -autotests = true -description = "Rust bindings to libcurl for making HTTP requests" -homepage = "https://github.com/alexcrichton/curl-rust" -documentation = "https://docs.rs/curl" -categories = ["api-bindings", "web-programming::http-client"] -license = "MIT" -repository = "https://github.com/alexcrichton/curl-rust" - -[[test]] -name = "atexit" -harness = false -[dependencies.curl-sys] -version = "0.4.15" -default-features = false - -[dependencies.libc] -version = "0.2.42" - -[dependencies.socket2] -version = "0.3.7" -[dev-dependencies.mio] -version = "0.6" - -[dev-dependencies.mio-extras] -version = "2.0.3" - -[features] -default = ["ssl"] -force-system-lib-on-osx = ["curl-sys/force-system-lib-on-osx"] -http2 = ["curl-sys/http2"] -ssl = ["openssl-sys", "openssl-probe", "curl-sys/ssl"] -static-curl = ["curl-sys/static-curl"] -static-ssl = ["curl-sys/static-ssl"] -[target."cfg(all(unix, not(target_os = \"macos\")))".dependencies.openssl-probe] -version = "0.1.2" -optional = true - -[target."cfg(all(unix, not(target_os = \"macos\")))".dependencies.openssl-sys] -version = "0.9.33" -optional = true -[target."cfg(target_env = \"msvc\")".dependencies.kernel32-sys] -version = "0.2.2" - -[target."cfg(target_env = \"msvc\")".dependencies.schannel] -version = "0.1.13" -[target."cfg(windows)".dependencies.winapi] -version = "0.2.7" -[badges.appveyor] -repository = "alexcrichton/curl-rust" - -[badges.travis-ci] -repository = "alexcrichton/curl-rust" diff -Nru cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/easy/windows.rs cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/easy/windows.rs --- cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/easy/windows.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/easy/windows.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -#![allow(non_camel_case_types, non_snake_case)] - -use libc::c_void; - -#[cfg(target_env = "msvc")] -mod win { - use kernel32; - use std::ffi::CString; - use std::mem; - use std::ptr; - use schannel::cert_context::ValidUses; - use schannel::cert_store::CertStore; - use winapi::{self, c_void, c_uchar, c_long, c_int}; - - fn lookup(module: &str, symbol: &str) -> Option<*const c_void> { - unsafe { - let symbol = CString::new(symbol).unwrap(); - let mut mod_buf: Vec = module.encode_utf16().collect(); - mod_buf.push(0); - let handle = kernel32::GetModuleHandleW(mod_buf.as_mut_ptr()); - let n = kernel32::GetProcAddress(handle, symbol.as_ptr()); - if n == ptr::null() { - None - } else { - Some(n) - } - } - } - - pub enum X509_STORE {} - pub enum X509 {} - pub enum SSL_CTX {} - - type d2i_X509_fn = unsafe extern "C" fn( - a: *mut *mut X509, - pp: *mut *const c_uchar, - length: c_long, - ) -> *mut X509; - type X509_free_fn = unsafe extern "C" fn(x: *mut X509); - type X509_STORE_add_cert_fn = unsafe extern "C" fn(store: *mut X509_STORE, x: *mut X509) - -> c_int; - type SSL_CTX_get_cert_store_fn = unsafe extern "C" fn(ctx: *const SSL_CTX) - -> *mut X509_STORE; - - struct OpenSSL { - d2i_X509: d2i_X509_fn, - X509_free: X509_free_fn, - X509_STORE_add_cert: X509_STORE_add_cert_fn, - SSL_CTX_get_cert_store: SSL_CTX_get_cert_store_fn, - } - - unsafe fn lookup_functions(crypto_module: &str, ssl_module: &str) - -> Option - { - macro_rules! get { - ($(let $sym:ident in $module:expr;)*) => ($( - let $sym = match lookup($module, stringify!($sym)) { - Some(p) => p, - None => return None, - }; - )*) - } - get! { - let d2i_X509 in crypto_module; - let X509_free in crypto_module; - let X509_STORE_add_cert in crypto_module; - let SSL_CTX_get_cert_store in ssl_module; - } - Some(OpenSSL { - d2i_X509: mem::transmute(d2i_X509), - X509_free: mem::transmute(X509_free), - X509_STORE_add_cert: mem::transmute(X509_STORE_add_cert), - SSL_CTX_get_cert_store: mem::transmute(SSL_CTX_get_cert_store), - }) - } - - pub unsafe fn add_certs_to_context(ssl_ctx: *mut c_void) { - // check the runtime version of OpenSSL - let openssl = match ::version::Version::get().ssl_version() { - Some(ssl_ver) if ssl_ver.starts_with("OpenSSL/1.1.0") => { - lookup_functions("libcrypto", "libssl") - } - Some(ssl_ver) if ssl_ver.starts_with("OpenSSL/1.0.2") => { - lookup_functions("libeay32", "ssleay32") - } - _ => return, - }; - let openssl = match openssl { - Some(s) => s, - None => return, - }; - - let openssl_store = (openssl.SSL_CTX_get_cert_store)(ssl_ctx as *const SSL_CTX); - let mut store = match CertStore::open_current_user("ROOT") { - Ok(s) => s, - Err(_) => return, - }; - - for cert in store.certs() { - let valid_uses = match cert.valid_uses() { - Ok(v) => v, - Err(_) => continue, - }; - - // check the extended key usage for the "Server Authentication" OID - match valid_uses { - ValidUses::All => {} - ValidUses::Oids(ref oids) => { - let oid = winapi::wincrypt::szOID_PKIX_KP_SERVER_AUTH.to_owned(); - if !oids.contains(&oid) { - continue - } - } - } - - let der = cert.to_der(); - let x509 = (openssl.d2i_X509)(ptr::null_mut(), - &mut der.as_ptr(), - der.len() as c_long); - if !x509.is_null() { - (openssl.X509_STORE_add_cert)(openssl_store, x509); - (openssl.X509_free)(x509); - } - } - } -} - -#[cfg(target_env = "msvc")] -pub fn add_certs_to_context(ssl_ctx: *mut c_void) { - unsafe { - win::add_certs_to_context(ssl_ctx as *mut _); - } -} - -#[cfg(not(target_env = "msvc"))] -pub fn add_certs_to_context(_: *mut c_void) {} diff -Nru cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/lib.rs cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/lib.rs --- cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -//! Rust bindings to the libcurl C library -//! -//! This crate contains bindings for an HTTP/HTTPS client which is powered by -//! [libcurl], the same library behind the `curl` command line tool. The API -//! currently closely matches that of libcurl itself, except that a Rustic layer -//! of safety is applied on top. -//! -//! [libcurl]: https://curl.haxx.se/libcurl/ -//! -//! # The "Easy" API -//! -//! The easiest way to send a request is to use the `Easy` api which corresponds -//! to `CURL` in libcurl. This handle supports a wide variety of options and can -//! be used to make a single blocking request in a thread. Callbacks can be -//! specified to deal with data as it arrives and a handle can be reused to -//! cache connections and such. -//! -//! ```rust,no_run -//! use std::io::{stdout, Write}; -//! -//! use curl::easy::Easy; -//! -//! // Write the contents of rust-lang.org to stdout -//! let mut easy = Easy::new(); -//! easy.url("https://www.rust-lang.org/").unwrap(); -//! easy.write_function(|data| { -//! stdout().write_all(data).unwrap(); -//! Ok(data.len()) -//! }).unwrap(); -//! easy.perform().unwrap(); -//! ``` -//! -//! # What about multiple concurrent HTTP requests? -//! -//! One option you have currently is to send multiple requests in multiple -//! threads, but otherwise libcurl has a "multi" interface for doing this -//! operation. Initial bindings of this interface can be found in the `multi` -//! module, but feedback is welcome! -//! -//! # Where does libcurl come from? -//! -//! This crate links to the `curl-sys` crate which is in turn responsible for -//! acquiring and linking to the libcurl library. Currently this crate will -//! build libcurl from source if one is not already detected on the system. -//! -//! There is a large number of releases for libcurl, all with different sets of -//! capabilities. Robust programs may wish to inspect `Version::get()` to test -//! what features are implemented in the linked build of libcurl at runtime. - -#![deny(missing_docs, missing_debug_implementations)] -#![doc(html_root_url = "https://docs.rs/curl/0.4")] - -extern crate curl_sys; -extern crate libc; -extern crate socket2; - -#[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] -extern crate openssl_sys; -#[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] -extern crate openssl_probe; -#[cfg(windows)] -extern crate winapi; - -#[cfg(target_env = "msvc")] -extern crate kernel32; -#[cfg(target_env = "msvc")] -extern crate schannel; - -use std::ffi::CStr; -use std::str; -use std::sync::{Once, ONCE_INIT}; - -pub use error::{Error, ShareError, MultiError, FormError}; -mod error; - -pub use version::{Version, Protocols}; -mod version; - -mod panic; -pub mod easy; -pub mod multi; - -/// Initializes the underlying libcurl library. -/// -/// It's not required to call this before the library is used, but it's -/// recommended to do so as soon as the program starts. -pub fn init() { - static INIT: Once = ONCE_INIT; - INIT.call_once(|| { - platform_init(); - unsafe { - assert_eq!(curl_sys::curl_global_init(curl_sys::CURL_GLOBAL_ALL), 0); - } - - // Note that we explicitly don't schedule a call to - // `curl_global_cleanup`. The documentation for that function says - // - // > You must not call it when any other thread in the program (i.e. a - // > thread sharing the same memory) is running. This doesn't just mean - // > no other thread that is using libcurl. - // - // We can't ever be sure of that, so unfortunately we can't call the - // function. - }); - - #[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] - fn platform_init() { - openssl_sys::init(); - } - - #[cfg(not(all(unix, not(target_os = "macos"), feature = "ssl")))] - fn platform_init() {} -} - -unsafe fn opt_str<'a>(ptr: *const libc::c_char) -> Option<&'a str> { - if ptr.is_null() { - None - } else { - Some(str::from_utf8(CStr::from_ptr(ptr).to_bytes()).unwrap()) - } -} - -fn cvt(r: curl_sys::CURLcode) -> Result<(), Error> { - if r == curl_sys::CURLE_OK { - Ok(()) - } else { - Err(Error::new(r)) - } -} diff -Nru cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/multi.rs cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/multi.rs --- cargo-0.33.0/vendor/curl/.pc/winapi3.patch/src/multi.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/.pc/winapi3.patch/src/multi.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1069 +0,0 @@ -//! Multi - initiating multiple requests simultaneously - -use std::fmt; -use std::marker; -use std::time::Duration; - -use libc::{c_int, c_char, c_void, c_long, c_short}; -use curl_sys; - -#[cfg(windows)] -use winapi::winsock2::fd_set; -#[cfg(unix)] -use libc::{fd_set, pollfd, POLLIN, POLLPRI, POLLOUT}; - -use {MultiError, Error}; -use easy::{Easy, Easy2}; -use panic; - -/// A multi handle for initiating multiple connections simultaneously. -/// -/// This structure corresponds to `CURLM` in libcurl and provides the ability to -/// have multiple transfers in flight simultaneously. This handle is then used -/// to manage each transfer. The main purpose of a `CURLM` is for the -/// *application* to drive the I/O rather than libcurl itself doing all the -/// blocking. Methods like `action` allow the application to inform libcurl of -/// when events have happened. -/// -/// Lots more documentation can be found on the libcurl [multi tutorial] where -/// the APIs correspond pretty closely with this crate. -/// -/// [multi tutorial]: https://curl.haxx.se/libcurl/c/libcurl-multi.html -pub struct Multi { - raw: *mut curl_sys::CURLM, - data: Box, -} - -struct MultiData { - socket: Box, - timer: Box) -> bool + Send>, -} - -/// Message from the `messages` function of a multi handle. -/// -/// Currently only indicates whether a transfer is done. -pub struct Message<'multi> { - ptr: *mut curl_sys::CURLMsg, - _multi: &'multi Multi, -} - -/// Wrapper around an easy handle while it's owned by a multi handle. -/// -/// Once an easy handle has been added to a multi handle then it can no longer -/// be used via `perform`. This handle is also used to remove the easy handle -/// from the multi handle when desired. -pub struct EasyHandle { - easy: Easy, - // This is now effecitvely bound to a `Multi`, so it is no longer sendable. - _marker: marker::PhantomData<&'static Multi>, -} - -/// Wrapper around an easy handle while it's owned by a multi handle. -/// -/// Once an easy handle has been added to a multi handle then it can no longer -/// be used via `perform`. This handle is also used to remove the easy handle -/// from the multi handle when desired. -pub struct Easy2Handle { - easy: Easy2, - // This is now effecitvely bound to a `Multi`, so it is no longer sendable. - _marker: marker::PhantomData<&'static Multi>, -} - -/// Notification of the events that have happened on a socket. -/// -/// This type is passed as an argument to the `action` method on a multi handle -/// to indicate what events have occurred on a socket. -pub struct Events { - bits: c_int, -} - -/// Notification of events that are requested on a socket. -/// -/// This type is yielded to the `socket_function` callback to indicate what -/// events are requested on a socket. -pub struct SocketEvents { - bits: c_int, -} - -/// Raw underlying socket type that the multi handles use -pub type Socket = curl_sys::curl_socket_t; - -/// File descriptor to wait on for use with the `wait` method on a multi handle. -pub struct WaitFd { - inner: curl_sys::curl_waitfd, -} - -impl Multi { - /// Creates a new multi session through which multiple HTTP transfers can be - /// initiated. - pub fn new() -> Multi { - unsafe { - ::init(); - let ptr = curl_sys::curl_multi_init(); - assert!(!ptr.is_null()); - Multi { - raw: ptr, - data: Box::new(MultiData { - socket: Box::new(|_, _, _| ()), - timer: Box::new(|_| true), - }), - } - } - } - - /// Set the callback informed about what to wait for - /// - /// When the `action` function runs, it informs the application about - /// updates in the socket (file descriptor) status by doing none, one, or - /// multiple calls to the socket callback. The callback gets status updates - /// with changes since the previous time the callback was called. See - /// `action` for more details on how the callback is used and should work. - /// - /// The `SocketEvents` parameter informs the callback on the status of the - /// given socket, and the methods on that type can be used to learn about - /// what's going on with the socket. - /// - /// The third `usize` parameter is a custom value set by the `assign` method - /// below. - pub fn socket_function(&mut self, f: F) -> Result<(), MultiError> - where F: FnMut(Socket, SocketEvents, usize) + Send + 'static, - { - self._socket_function(Box::new(f)) - } - - fn _socket_function(&mut self, - f: Box) - -> Result<(), MultiError> - { - self.data.socket = f; - let cb: curl_sys::curl_socket_callback = cb; - try!(self.setopt_ptr(curl_sys::CURLMOPT_SOCKETFUNCTION, - cb as usize as *const c_char)); - let ptr = &*self.data as *const _; - try!(self.setopt_ptr(curl_sys::CURLMOPT_SOCKETDATA, - ptr as *const c_char)); - return Ok(()); - - // TODO: figure out how to expose `_easy` - extern fn cb(_easy: *mut curl_sys::CURL, - socket: curl_sys::curl_socket_t, - what: c_int, - userptr: *mut c_void, - socketp: *mut c_void) -> c_int { - panic::catch(|| unsafe { - let f = &mut (*(userptr as *mut MultiData)).socket; - f(socket, SocketEvents { bits: what }, socketp as usize) - }); - 0 - } - } - - /// Set data to associate with an internal socket - /// - /// This function creates an association in the multi handle between the - /// given socket and a private token of the application. This is designed - /// for `action` uses. - /// - /// When set, the token will be passed to all future socket callbacks for - /// the specified socket. - /// - /// If the given socket isn't already in use by libcurl, this function will - /// return an error. - /// - /// libcurl only keeps one single token associated with a socket, so - /// calling this function several times for the same socket will make the - /// last set token get used. - /// - /// The idea here being that this association (socket to token) is something - /// that just about every application that uses this API will need and then - /// libcurl can just as well do it since it already has an internal hash - /// table lookup for this. - /// - /// # Typical Usage - /// - /// In a typical application you allocate a struct or at least use some kind - /// of semi-dynamic data for each socket that we must wait for action on - /// when using the `action` approach. - /// - /// When our socket-callback gets called by libcurl and we get to know about - /// yet another socket to wait for, we can use `assign` to point out the - /// particular data so that when we get updates about this same socket - /// again, we don't have to find the struct associated with this socket by - /// ourselves. - pub fn assign(&self, - socket: Socket, - token: usize) -> Result<(), MultiError> { - unsafe { - try!(cvt(curl_sys::curl_multi_assign(self.raw, socket, - token as *mut _))); - Ok(()) - } - } - - /// Set callback to receive timeout values - /// - /// Certain features, such as timeouts and retries, require you to call - /// libcurl even when there is no activity on the file descriptors. - /// - /// Your callback function should install a non-repeating timer with the - /// interval specified. Each time that timer fires, call either `action` or - /// `perform`, depending on which interface you use. - /// - /// A timeout value of `None` means you should delete your timer. - /// - /// A timeout value of 0 means you should call `action` or `perform` (once) - /// as soon as possible. - /// - /// This callback will only be called when the timeout changes. - /// - /// The timer callback should return `true` on success, and `false` on - /// error. This callback can be used instead of, or in addition to, - /// `get_timeout`. - pub fn timer_function(&mut self, f: F) -> Result<(), MultiError> - where F: FnMut(Option) -> bool + Send + 'static, - { - self._timer_function(Box::new(f)) - } - - fn _timer_function(&mut self, - f: Box) -> bool + Send>) - -> Result<(), MultiError> - { - self.data.timer = f; - let cb: curl_sys::curl_multi_timer_callback = cb; - try!(self.setopt_ptr(curl_sys::CURLMOPT_TIMERFUNCTION, - cb as usize as *const c_char)); - let ptr = &*self.data as *const _; - try!(self.setopt_ptr(curl_sys::CURLMOPT_TIMERDATA, - ptr as *const c_char)); - return Ok(()); - - // TODO: figure out how to expose `_multi` - extern fn cb(_multi: *mut curl_sys::CURLM, - timeout_ms: c_long, - user: *mut c_void) -> c_int { - let keep_going = panic::catch(|| unsafe { - let f = &mut (*(user as *mut MultiData)).timer; - if timeout_ms == -1 { - f(None) - } else { - f(Some(Duration::from_millis(timeout_ms as u64))) - } - }).unwrap_or(false); - if keep_going {0} else {-1} - } - } - - /// Enable or disable HTTP pipelining and multiplexing. - /// - /// When http_1 is true, enable HTTP/1.1 pipelining, which means that if - /// you add a second request that can use an already existing connection, - /// the second request will be "piped" on the same connection rather than - /// being executed in parallel. - /// - /// When multiplex is true, enable HTTP/2 multiplexing, which means that - /// follow-up requests can re-use an existing connection and send the new - /// request multiplexed over that at the same time as other transfers are - /// already using that single connection. - pub fn pipelining(&mut self, http_1: bool, multiplex: bool) -> Result<(), MultiError> { - let bitmask = if http_1 { curl_sys::CURLPIPE_HTTP1 } else { 0 } | if multiplex { curl_sys::CURLPIPE_MULTIPLEX } else { 0 }; - self.setopt_long(curl_sys::CURLMOPT_PIPELINING, bitmask) - } - - /// Sets the max number of connections to a single host. - /// - /// Pass a long to indicate the max number of simultaneously open connections - /// to a single host (a host being the same as a host name + port number pair). - /// For each new session to a host, libcurl will open up a new connection up to the - /// limit set by the provided value. When the limit is reached, the sessions will - /// be pending until a connection becomes available. If pipelining is enabled, - /// libcurl will try to pipeline if the host is capable of it. - pub fn set_max_host_connections(&mut self, val: usize) -> Result<(), MultiError> { - self.setopt_long(curl_sys::CURLMOPT_MAX_HOST_CONNECTIONS, val as c_long) - } - - /// Sets the pipeline length. - /// - /// This sets the max number that will be used as the maximum amount of - /// outstanding reuqests in an HTTP/1.1 pipelined connection. This option - /// is only used for HTTP/1.1 pipelining, and not HTTP/2 multiplexing. - pub fn set_pipeline_length(&mut self, val: usize) -> Result<(), MultiError> { - self.setopt_long(curl_sys::CURLMOPT_MAX_PIPELINE_LENGTH, val as c_long) - } - - fn setopt_long(&mut self, - opt: curl_sys::CURLMoption, - val: c_long) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) - } - } - - fn setopt_ptr(&mut self, - opt: curl_sys::CURLMoption, - val: *const c_char) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) - } - } - - /// Add an easy handle to a multi session - /// - /// Adds a standard easy handle to the multi stack. This function call will - /// make this multi handle control the specified easy handle. - /// - /// When an easy interface is added to a multi handle, it will use a shared - /// connection cache owned by the multi handle. Removing and adding new easy - /// handles will not affect the pool of connections or the ability to do - /// connection re-use. - /// - /// If you have `timer_function` set in the multi handle (and you really - /// should if you're working event-based with `action` and friends), that - /// callback will be called from within this function to ask for an updated - /// timer so that your main event loop will get the activity on this handle - /// to get started. - /// - /// The easy handle will remain added to the multi handle until you remove - /// it again with `remove` on the returned handle - even when a transfer - /// with that specific easy handle is completed. - pub fn add(&self, mut easy: Easy) -> Result { - // Clear any configuration set by previous transfers because we're - // moving this into a `Send+'static` situation now basically. - easy.transfer(); - - unsafe { - try!(cvt(curl_sys::curl_multi_add_handle(self.raw, easy.raw()))); - } - Ok(EasyHandle { - easy: easy, - _marker: marker::PhantomData, - }) - } - - /// Same as `add`, but works with the `Easy2` type. - pub fn add2(&self, easy: Easy2) -> Result, MultiError> { - unsafe { - try!(cvt(curl_sys::curl_multi_add_handle(self.raw, easy.raw()))); - } - Ok(Easy2Handle { - easy: easy, - _marker: marker::PhantomData, - }) - } - - /// Remove an easy handle from this multi session - /// - /// Removes the easy handle from this multi handle. This will make the - /// returned easy handle be removed from this multi handle's control. - /// - /// When the easy handle has been removed from a multi stack, it is again - /// perfectly legal to invoke `perform` on it. - /// - /// Removing an easy handle while being used is perfectly legal and will - /// effectively halt the transfer in progress involving that easy handle. - /// All other easy handles and transfers will remain unaffected. - pub fn remove(&self, easy: EasyHandle) -> Result { - unsafe { - try!(cvt(curl_sys::curl_multi_remove_handle(self.raw, - easy.easy.raw()))); - } - Ok(easy.easy) - } - - /// Same as `remove`, but for `Easy2Handle`. - pub fn remove2(&self, easy: Easy2Handle) -> Result, MultiError> { - unsafe { - try!(cvt(curl_sys::curl_multi_remove_handle(self.raw, - easy.easy.raw()))); - } - Ok(easy.easy) - } - - /// Read multi stack informationals - /// - /// Ask the multi handle if there are any messages/informationals from the - /// individual transfers. Messages may include informationals such as an - /// error code from the transfer or just the fact that a transfer is - /// completed. More details on these should be written down as well. - pub fn messages(&self, mut f: F) where F: FnMut(Message) { - self._messages(&mut f) - } - - fn _messages(&self, f: &mut FnMut(Message)) { - let mut queue = 0; - unsafe { - loop { - let ptr = curl_sys::curl_multi_info_read(self.raw, &mut queue); - if ptr.is_null() { - break - } - f(Message { ptr: ptr, _multi: self }) - } - } - } - - /// Inform of reads/writes available data given an action - /// - /// When the application has detected action on a socket handled by libcurl, - /// it should call this function with the sockfd argument set to - /// the socket with the action. When the events on a socket are known, they - /// can be passed `events`. When the events on a socket are unknown, pass - /// `Events::new()` instead, and libcurl will test the descriptor - /// internally. - /// - /// The returned integer will contain the number of running easy handles - /// within the multi handle. When this number reaches zero, all transfers - /// are complete/done. When you call `action` on a specific socket and the - /// counter decreases by one, it DOES NOT necessarily mean that this exact - /// socket/transfer is the one that completed. Use `messages` to figure out - /// which easy handle that completed. - /// - /// The `action` function informs the application about updates in the - /// socket (file descriptor) status by doing none, one, or multiple calls to - /// the socket callback function set with the `socket_function` method. They - /// update the status with changes since the previous time the callback was - /// called. - pub fn action(&self, socket: Socket, events: &Events) - -> Result { - let mut remaining = 0; - unsafe { - try!(cvt(curl_sys::curl_multi_socket_action(self.raw, - socket, - events.bits, - &mut remaining))); - Ok(remaining as u32) - } - } - - /// Inform libcurl that a timeout has expired and sockets should be tested. - /// - /// The returned integer will contain the number of running easy handles - /// within the multi handle. When this number reaches zero, all transfers - /// are complete/done. When you call `action` on a specific socket and the - /// counter decreases by one, it DOES NOT necessarily mean that this exact - /// socket/transfer is the one that completed. Use `messages` to figure out - /// which easy handle that completed. - /// - /// Get the timeout time by calling the `timer_function` method. Your - /// application will then get called with information on how long to wait - /// for socket actions at most before doing the timeout action: call the - /// `timeout` method. You can also use the `get_timeout` function to - /// poll the value at any given time, but for an event-based system using - /// the callback is far better than relying on polling the timeout value. - pub fn timeout(&self) -> Result { - let mut remaining = 0; - unsafe { - try!(cvt(curl_sys::curl_multi_socket_action(self.raw, - curl_sys::CURL_SOCKET_BAD, - 0, - &mut remaining))); - Ok(remaining as u32) - } - } - - /// Get how long to wait for action before proceeding - /// - /// An application using the libcurl multi interface should call - /// `get_timeout` to figure out how long it should wait for socket actions - - /// at most - before proceeding. - /// - /// Proceeding means either doing the socket-style timeout action: call the - /// `timeout` function, or call `perform` if you're using the simpler and - /// older multi interface approach. - /// - /// The timeout value returned is the duration at this very moment. If 0, it - /// means you should proceed immediately without waiting for anything. If it - /// returns `None`, there's no timeout at all set. - /// - /// Note: if libcurl returns a `None` timeout here, it just means that - /// libcurl currently has no stored timeout value. You must not wait too - /// long (more than a few seconds perhaps) before you call `perform` again. - pub fn get_timeout(&self) -> Result, MultiError> { - let mut ms = 0; - unsafe { - try!(cvt(curl_sys::curl_multi_timeout(self.raw, &mut ms))); - if ms == -1 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(ms as u64))) - } - } - } - - /// Block until activity is detected or a timeout passes. - /// - /// The timeout is used in millisecond-precision. Large durations are - /// clamped at the maximum value curl accepts. - /// - /// The returned integer will contain the number of internal file - /// descriptors on which interesting events occured. - /// - /// This function is a simpler alternative to using `fdset()` and `select()` - /// and does not suffer from file descriptor limits. - /// - /// # Example - /// - /// ``` - /// use curl::multi::Multi; - /// use std::time::Duration; - /// - /// let m = Multi::new(); - /// - /// // Add some Easy handles... - /// - /// while m.perform().unwrap() > 0 { - /// m.wait(&mut [], Duration::from_secs(1)).unwrap(); - /// } - /// ``` - pub fn wait(&self, waitfds: &mut [WaitFd], timeout: Duration) - -> Result { - let timeout_ms = { - let secs = timeout.as_secs(); - if secs > (i32::max_value() / 1000) as u64 { - // Duration too large, clamp at maximum value. - i32::max_value() - } else { - secs as i32 * 1000 + timeout.subsec_nanos() as i32 / 1000_000 - } - }; - unsafe { - let mut ret = 0; - try!(cvt(curl_sys::curl_multi_wait(self.raw, - waitfds.as_mut_ptr() as *mut _, - waitfds.len() as u32, - timeout_ms, - &mut ret))); - Ok(ret as u32) - } - } - - /// Reads/writes available data from each easy handle. - /// - /// This function handles transfers on all the added handles that need - /// attention in an non-blocking fashion. - /// - /// When an application has found out there's data available for this handle - /// or a timeout has elapsed, the application should call this function to - /// read/write whatever there is to read or write right now etc. This - /// method returns as soon as the reads/writes are done. This function does - /// not require that there actually is any data available for reading or - /// that data can be written, it can be called just in case. It will return - /// the number of handles that still transfer data. - /// - /// If the amount of running handles is changed from the previous call (or - /// is less than the amount of easy handles you've added to the multi - /// handle), you know that there is one or more transfers less "running". - /// You can then call `info` to get information about each individual - /// completed transfer, and that returned info includes `Error` and more. - /// If an added handle fails very quickly, it may never be counted as a - /// running handle. - /// - /// When running_handles is set to zero (0) on the return of this function, - /// there is no longer any transfers in progress. - /// - /// # Return - /// - /// Before libcurl version 7.20.0: If you receive `is_call_perform`, this - /// basically means that you should call `perform` again, before you select - /// on more actions. You don't have to do it immediately, but the return - /// code means that libcurl may have more data available to return or that - /// there may be more data to send off before it is "satisfied". Do note - /// that `perform` will return `is_call_perform` only when it wants to be - /// called again immediately. When things are fine and there is nothing - /// immediate it wants done, it'll return `Ok` and you need to wait for - /// "action" and then call this function again. - /// - /// This function only returns errors etc regarding the whole multi stack. - /// Problems still might have occurred on individual transfers even when - /// this function returns `Ok`. Use `info` to figure out how individual - /// transfers did. - pub fn perform(&self) -> Result { - unsafe { - let mut ret = 0; - try!(cvt(curl_sys::curl_multi_perform(self.raw, &mut ret))); - Ok(ret as u32) - } - } - - /// Extracts file descriptor information from a multi handle - /// - /// This function extracts file descriptor information from a given - /// handle, and libcurl returns its `fd_set` sets. The application can use - /// these to `select()` on, but be sure to `FD_ZERO` them before calling - /// this function as curl_multi_fdset only adds its own descriptors, it - /// doesn't zero or otherwise remove any others. The curl_multi_perform - /// function should be called as soon as one of them is ready to be read - /// from or written to. - /// - /// If no file descriptors are set by libcurl, this function will return - /// `Ok(None)`. Otherwise `Ok(Some(n))` will be returned where `n` the - /// highest descriptor number libcurl set. When `Ok(None)` is returned it - /// is because libcurl currently does something that isn't possible for - /// your application to monitor with a socket and unfortunately you can - /// then not know exactly when the current action is completed using - /// `select()`. You then need to wait a while before you proceed and call - /// `perform` anyway. - /// - /// When doing `select()`, you should use `get_timeout` to figure out - /// how long to wait for action. Call `perform` even if no activity has - /// been seen on the `fd_set`s after the timeout expires as otherwise - /// internal retries and timeouts may not work as you'd think and want. - /// - /// If one of the sockets used by libcurl happens to be larger than what - /// can be set in an `fd_set`, which on POSIX systems means that the file - /// descriptor is larger than `FD_SETSIZE`, then libcurl will try to not - /// set it. Setting a too large file descriptor in an `fd_set` implies an out - /// of bounds write which can cause crashes, or worse. The effect of NOT - /// storing it will possibly save you from the crash, but will make your - /// program NOT wait for sockets it should wait for... - pub fn fdset2(&self, - read: Option<&mut curl_sys::fd_set>, - write: Option<&mut curl_sys::fd_set>, - except: Option<&mut curl_sys::fd_set>) -> Result, MultiError> { - unsafe { - let mut ret = 0; - let read = read.map(|r| r as *mut _).unwrap_or(0 as *mut _); - let write = write.map(|r| r as *mut _).unwrap_or(0 as *mut _); - let except = except.map(|r| r as *mut _).unwrap_or(0 as *mut _); - try!(cvt(curl_sys::curl_multi_fdset(self.raw, - read, - write, - except, - &mut ret))); - if ret == -1 { - Ok(None) - } else { - Ok(Some(ret)) - } - } - } - - #[doc(hidden)] - #[deprecated(note = "renamed to fdset2")] - pub fn fdset(&self, - read: Option<&mut fd_set>, - write: Option<&mut fd_set>, - except: Option<&mut fd_set>) -> Result, MultiError> { - unsafe { - let mut ret = 0; - let read = read.map(|r| r as *mut _).unwrap_or(0 as *mut _); - let write = write.map(|r| r as *mut _).unwrap_or(0 as *mut _); - let except = except.map(|r| r as *mut _).unwrap_or(0 as *mut _); - try!(cvt(curl_sys::curl_multi_fdset(self.raw, - read as *mut _, - write as *mut _, - except as *mut _, - &mut ret))); - if ret == -1 { - Ok(None) - } else { - Ok(Some(ret)) - } - } - } - - /// Attempt to close the multi handle and clean up all associated resources. - /// - /// Cleans up and removes a whole multi stack. It does not free or touch any - /// individual easy handles in any way - they still need to be closed - /// individually. - pub fn close(&self) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_cleanup(self.raw)) - } - } -} - -fn cvt(code: curl_sys::CURLMcode) -> Result<(), MultiError> { - if code == curl_sys::CURLM_OK { - Ok(()) - } else { - Err(MultiError::new(code)) - } -} - -impl fmt::Debug for Multi { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Multi") - .field("raw", &self.raw) - .finish() - } -} - -impl Drop for Multi { - fn drop(&mut self) { - let _ = self.close(); - } -} - -impl EasyHandle { - /// Sets an internal private token for this `EasyHandle`. - /// - /// This function will set the `CURLOPT_PRIVATE` field on the underlying - /// easy handle. - pub fn set_token(&mut self, token: usize) -> Result<(), Error> { - unsafe { - ::cvt(curl_sys::curl_easy_setopt(self.easy.raw(), - curl_sys::CURLOPT_PRIVATE, - token)) - } - } - - /// Unpause reading on a connection. - /// - /// Using this function, you can explicitly unpause a connection that was - /// previously paused. - /// - /// A connection can be paused by letting the read or the write callbacks - /// return `ReadError::Pause` or `WriteError::Pause`. - /// - /// The chance is high that you will get your write callback called before - /// this function returns. - pub fn unpause_read(&self) -> Result<(), Error> { - self.easy.unpause_read() - } - - /// Unpause writing on a connection. - /// - /// Using this function, you can explicitly unpause a connection that was - /// previously paused. - /// - /// A connection can be paused by letting the read or the write callbacks - /// return `ReadError::Pause` or `WriteError::Pause`. A write callback that - /// returns pause signals to the library that it couldn't take care of any - /// data at all, and that data will then be delivered again to the callback - /// when the writing is later unpaused. - pub fn unpause_write(&self) -> Result<(), Error> { - self.easy.unpause_write() - } -} - -impl fmt::Debug for EasyHandle { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.easy.fmt(f) - } -} - -impl Easy2Handle { - /// Acquires a reference to the underlying handler for events. - pub fn get_ref(&self) -> &H { - self.easy.get_ref() - } - - /// Acquires a reference to the underlying handler for events. - pub fn get_mut(&mut self) -> &mut H { - self.easy.get_mut() - } - - /// Same as `EasyHandle::set_token` - pub fn set_token(&mut self, token: usize) -> Result<(), Error> { - unsafe { - ::cvt(curl_sys::curl_easy_setopt(self.easy.raw(), - curl_sys::CURLOPT_PRIVATE, - token)) - } - } - - /// Unpause reading on a connection. - /// - /// Using this function, you can explicitly unpause a connection that was - /// previously paused. - /// - /// A connection can be paused by letting the read or the write callbacks - /// return `ReadError::Pause` or `WriteError::Pause`. - /// - /// The chance is high that you will get your write callback called before - /// this function returns. - pub fn unpause_read(&self) -> Result<(), Error> { - self.easy.unpause_read() - } - - /// Unpause writing on a connection. - /// - /// Using this function, you can explicitly unpause a connection that was - /// previously paused. - /// - /// A connection can be paused by letting the read or the write callbacks - /// return `ReadError::Pause` or `WriteError::Pause`. A write callback that - /// returns pause signals to the library that it couldn't take care of any - /// data at all, and that data will then be delivered again to the callback - /// when the writing is later unpaused. - pub fn unpause_write(&self) -> Result<(), Error> { - self.easy.unpause_write() - } -} - -impl fmt::Debug for Easy2Handle { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.easy.fmt(f) - } -} - -impl<'multi> Message<'multi> { - /// If this message indicates that a transfer has finished, returns the - /// result of the transfer in `Some`. - /// - /// If the message doesn't indicate that a transfer has finished, then - /// `None` is returned. - /// - /// Note that the `result*_for` methods below should be preferred as they - /// provide better error messages as the associated error data on the - /// handle can be associated with the error type. - pub fn result(&self) -> Option> { - unsafe { - if (*self.ptr).msg == curl_sys::CURLMSG_DONE { - Some(::cvt((*self.ptr).data as curl_sys::CURLcode)) - } else { - None - } - } - } - - /// Same as `result`, except only returns `Some` for the specified handle. - /// - /// Note that this function produces better error messages than `result` as - /// it uses `take_error_buf` to associate error information with the - /// returned error. - pub fn result_for(&self, handle: &EasyHandle) -> Option> { - if !self.is_for(handle) { - return None - } - let mut err = self.result(); - if let Some(Err(e)) = &mut err { - if let Some(s) = handle.easy.take_error_buf() { - e.set_extra(s); - } - } - return err - } - - /// Same as `result`, except only returns `Some` for the specified handle. - /// - /// Note that this function produces better error messages than `result` as - /// it uses `take_error_buf` to associate error information with the - /// returned error. - pub fn result_for2(&self, handle: &Easy2Handle) -> Option> { - if !self.is_for2(handle) { - return None - } - let mut err = self.result(); - if let Some(Err(e)) = &mut err { - if let Some(s) = handle.easy.take_error_buf() { - e.set_extra(s); - } - } - return err - } - - /// Returns whether this easy message was for the specified easy handle or - /// not. - pub fn is_for(&self, handle: &EasyHandle) -> bool { - unsafe { (*self.ptr).easy_handle == handle.easy.raw() } - } - - /// Same as `is_for`, but for `Easy2Handle`. - pub fn is_for2(&self, handle: &Easy2Handle) -> bool { - unsafe { (*self.ptr).easy_handle == handle.easy.raw() } - } - - /// Returns the token associated with the easy handle that this message - /// represents a completion for. - /// - /// This function will return the token assigned with - /// `EasyHandle::set_token`. This reads the `CURLINFO_PRIVATE` field of the - /// underlying `*mut CURL`. - pub fn token(&self) -> Result { - unsafe { - let mut p = 0usize; - try!(::cvt(curl_sys::curl_easy_getinfo((*self.ptr).easy_handle, - curl_sys::CURLINFO_PRIVATE, - &mut p))); - Ok(p) - } - } -} - -impl<'a> fmt::Debug for Message<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Message") - .field("ptr", &self.ptr) - .finish() - } -} - -impl Events { - /// Creates a new blank event bit mask. - pub fn new() -> Events { - Events { bits: 0 } - } - - /// Set or unset the whether these events indicate that input is ready. - pub fn input(&mut self, val: bool) -> &mut Events { - self.flag(curl_sys::CURL_CSELECT_IN, val) - } - - /// Set or unset the whether these events indicate that output is ready. - pub fn output(&mut self, val: bool) -> &mut Events { - self.flag(curl_sys::CURL_CSELECT_OUT, val) - } - - /// Set or unset the whether these events indicate that an error has - /// happened. - pub fn error(&mut self, val: bool) -> &mut Events { - self.flag(curl_sys::CURL_CSELECT_ERR, val) - } - - fn flag(&mut self, flag: c_int, val: bool) -> &mut Events { - if val { - self.bits |= flag; - } else { - self.bits &= !flag; - } - self - } -} - -impl fmt::Debug for Events { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Events") - .field("input", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .field("output", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .field("error", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .finish() - } -} - -impl SocketEvents { - /// Wait for incoming data. For the socket to become readable. - pub fn input(&self) -> bool { - self.bits & curl_sys::CURL_POLL_IN == curl_sys::CURL_POLL_IN - } - - /// Wait for outgoing data. For the socket to become writable. - pub fn output(&self) -> bool { - self.bits & curl_sys::CURL_POLL_OUT == curl_sys::CURL_POLL_OUT - } - - /// Wait for incoming and outgoing data. For the socket to become readable - /// or writable. - pub fn input_and_output(&self) -> bool { - self.bits & curl_sys::CURL_POLL_INOUT == curl_sys::CURL_POLL_INOUT - } - - /// The specified socket/file descriptor is no longer used by libcurl. - pub fn remove(&self) -> bool { - self.bits & curl_sys::CURL_POLL_REMOVE == curl_sys::CURL_POLL_REMOVE - } -} - -impl fmt::Debug for SocketEvents { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Events") - .field("input", &self.input()) - .field("output", &self.output()) - .field("remove", &self.remove()) - .finish() - } -} - -impl WaitFd { - /// Constructs an empty (invalid) WaitFd. - pub fn new() -> WaitFd { - WaitFd { - inner: curl_sys::curl_waitfd { - fd: 0, - events: 0, - revents: 0, - } - } - } - - /// Set the file descriptor to wait for. - pub fn set_fd(&mut self, fd: Socket) { - self.inner.fd = fd; - } - - /// Indicate that the socket should poll on read events such as new data - /// received. - /// - /// Corresponds to `CURL_WAIT_POLLIN`. - pub fn poll_on_read(&mut self, val: bool) -> &mut WaitFd { - self.flag(curl_sys::CURL_WAIT_POLLIN, val) - } - - /// Indicate that the socket should poll on high priority read events such - /// as out of band data. - /// - /// Corresponds to `CURL_WAIT_POLLPRI`. - pub fn poll_on_priority_read(&mut self, val: bool) -> &mut WaitFd { - self.flag(curl_sys::CURL_WAIT_POLLPRI, val) - } - - /// Indicate that the socket should poll on write events such as the socket - /// being clear to write without blocking. - /// - /// Corresponds to `CURL_WAIT_POLLOUT`. - pub fn poll_on_write(&mut self, val: bool) -> &mut WaitFd { - self.flag(curl_sys::CURL_WAIT_POLLOUT, val) - } - - fn flag(&mut self, flag: c_short, val: bool) -> &mut WaitFd { - if val { - self.inner.events |= flag; - } else { - self.inner.events &= !flag; - } - self - } - - /// After a call to `wait`, returns `true` if `poll_on_read` was set and a - /// read event occured. - pub fn received_read(&self) -> bool { - self.inner.revents & curl_sys::CURL_WAIT_POLLIN == curl_sys::CURL_WAIT_POLLIN - } - - /// After a call to `wait`, returns `true` if `poll_on_priority_read` was set and a - /// priority read event occured. - pub fn received_priority_read(&self) -> bool { - self.inner.revents & curl_sys::CURL_WAIT_POLLPRI == curl_sys::CURL_WAIT_POLLPRI - } - - /// After a call to `wait`, returns `true` if `poll_on_write` was set and a - /// write event occured. - pub fn received_write(&self) -> bool { - self.inner.revents & curl_sys::CURL_WAIT_POLLOUT == curl_sys::CURL_WAIT_POLLOUT - } -} - -#[cfg(unix)] -impl From for WaitFd { - fn from(pfd: pollfd) -> WaitFd { - let mut events = 0; - if pfd.events & POLLIN == POLLIN { - events |= curl_sys::CURL_WAIT_POLLIN; - } - if pfd.events & POLLPRI == POLLPRI { - events |= curl_sys::CURL_WAIT_POLLPRI; - } - if pfd.events & POLLOUT == POLLOUT { - events |= curl_sys::CURL_WAIT_POLLOUT; - } - WaitFd { - inner: curl_sys::curl_waitfd { - fd: pfd.fd, - events: events, - revents: 0, - } - } - } -} - -impl fmt::Debug for WaitFd { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("WaitFd") - .field("fd", &self.inner.fd) - .field("events", &self.inner.fd) - .field("revents", &self.inner.fd) - .finish() - } -} diff -Nru cargo-0.33.0/vendor/curl/README.md cargo-0.35.0/vendor/curl/README.md --- cargo-0.33.0/vendor/curl/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,7 @@ libcurl bindings for Rust -[![Build Status](https://travis-ci.org/alexcrichton/curl-rust.svg?branch=master)](https://travis-ci.org/alexcrichton/curl-rust) -[![Build status](https://ci.appveyor.com/api/projects/status/lx98wtbxhhhajpr9?svg=true)](https://ci.appveyor.com/project/alexcrichton/curl-rust) +[![Build Status](https://dev.azure.com/alexcrichton/curl-rust/_apis/build/status/alexcrichton.curl-rust?branchName=master)](https://dev.azure.com/alexcrichton/curl-rust/_build/latest?definitionId=6&branchName=master) [Documentation](https://docs.rs/curl) @@ -144,6 +143,28 @@ work with any newer version of curl and possibly with older versions, but this has not been tested. +## Troubleshooting + +### Curl built against the NSS SSL library + +If you encounter the following error message: + +``` + [77] Problem with the SSL CA cert (path? access rights?) +``` + +That means most likely, that curl was linked against `libcurl-nss.so` due to +installed libcurl NSS development files, and that the required library +`libnsspem.so` is missing. See also the curl man page: "If curl is built +against the NSS SSL library, the NSS PEM PKCS#11 module (libnsspem.so) needs to +be available for this option to work properly." + +In order to avoid this failure you can either + + * install the missing library (e.g. Debian: `nss-plugin-pem`), or + * remove the libcurl NSS development files (e.g. Debian: `libcurl4-nss-dev`) and + rebuild curl-rust. + ## License The `curl-rust` crate is licensed under the MIT license, see `LICENSE` for more diff -Nru cargo-0.33.0/vendor/curl/src/easy/form.rs cargo-0.35.0/vendor/curl/src/easy/form.rs --- cargo-0.33.0/vendor/curl/src/easy/form.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/form.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,9 +2,9 @@ use std::fmt; use std::path::Path; -use FormError; use curl_sys; use easy::{list, List}; +use FormError; /// Multipart/formdata for an HTTP POST request. /// @@ -62,9 +62,7 @@ impl fmt::Debug for Form { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // TODO: fill this out more - f.debug_struct("Form") - .field("fields", &"...") - .finish() + f.debug_struct("Form").field("fields", &"...").finish() } } @@ -88,16 +86,23 @@ b"\x00" } else { contents - }.as_ptr(); + } + .as_ptr(); - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_COPYCONTENTS, - value: ptr as *mut _, - }); - self.array.insert(pos + 1, curl_sys::curl_forms { - option: curl_sys::CURLFORM_CONTENTSLENGTH, - value: contents.len() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_COPYCONTENTS, + value: ptr as *mut _, + }, + ); + self.array.insert( + pos + 1, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_CONTENTSLENGTH, + value: contents.len() as *mut _, + }, + ); self } @@ -112,7 +117,8 @@ /// contain a unicode filename then the `add` function will eventually /// return an error. pub fn file_content

(&mut self, file: P) -> &mut Self - where P: AsRef + where + P: AsRef, { self._file_content(file.as_ref()) } @@ -120,10 +126,13 @@ fn _file_content(&mut self, file: &Path) -> &mut Self { if let Some(bytes) = self.path2cstr(file) { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_FILECONTENT, - value: bytes.as_ptr() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_FILECONTENT, + value: bytes.as_ptr() as *mut _, + }, + ); self.form.strings.push(bytes); } self @@ -150,7 +159,8 @@ /// contain a unicode filename then this function will cause `add` to return /// an error when called. pub fn file(&mut self, file: &'data P) -> &mut Self - where P: AsRef + where + P: AsRef, { self._file(file.as_ref()) } @@ -158,10 +168,13 @@ fn _file(&mut self, file: &'data Path) -> &mut Self { if let Some(bytes) = self.path2cstr(file) { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_FILE, - value: bytes.as_ptr() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_FILE, + value: bytes.as_ptr() as *mut _, + }, + ); self.form.strings.push(bytes); } self @@ -177,10 +190,13 @@ pub fn content_type(&mut self, content_type: &'data str) -> &mut Self { if let Some(bytes) = self.bytes2cstr(content_type.as_bytes()) { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_CONTENTTYPE, - value: bytes.as_ptr() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_CONTENTTYPE, + value: bytes.as_ptr() as *mut _, + }, + ); self.form.strings.push(bytes); } self @@ -195,7 +211,8 @@ /// not valid unicode then this function will return an error when `add` is /// called. pub fn filename(&mut self, name: &'data P) -> &mut Self - where P: AsRef + where + P: AsRef, { self._filename(name.as_ref()) } @@ -203,10 +220,13 @@ fn _filename(&mut self, name: &'data Path) -> &mut Self { if let Some(bytes) = self.path2cstr(name) { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_FILENAME, - value: bytes.as_ptr() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_FILENAME, + value: bytes.as_ptr() as *mut _, + }, + ); self.form.strings.push(bytes); } self @@ -223,9 +243,9 @@ /// If `name` contains an internal nul byte, or if on Windows the path is /// not valid unicode then this function will return an error when `add` is /// called. - pub fn buffer(&mut self, name: &'data P, data: Vec) - -> &mut Self - where P: AsRef + pub fn buffer(&mut self, name: &'data P, data: Vec) -> &mut Self + where + P: AsRef, { self._buffer(name.as_ref(), data) } @@ -233,19 +253,28 @@ fn _buffer(&mut self, name: &'data Path, data: Vec) -> &mut Self { if let Some(bytes) = self.path2cstr(name) { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_BUFFER, - value: bytes.as_ptr() as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_BUFFER, + value: bytes.as_ptr() as *mut _, + }, + ); self.form.strings.push(bytes); - self.array.insert(pos + 1, curl_sys::curl_forms { - option: curl_sys::CURLFORM_BUFFERPTR, - value: data.as_ptr() as *mut _, - }); - self.array.insert(pos + 2, curl_sys::curl_forms { - option: curl_sys::CURLFORM_BUFFERLENGTH, - value: data.len() as *mut _, - }); + self.array.insert( + pos + 1, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_BUFFERPTR, + value: data.as_ptr() as *mut _, + }, + ); + self.array.insert( + pos + 2, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_BUFFERLENGTH, + value: data.len() as *mut _, + }, + ); self.form.buffers.push(data); } self @@ -256,10 +285,13 @@ /// Appends the list of headers to those libcurl automatically generates. pub fn content_header(&mut self, headers: List) -> &mut Self { let pos = self.array.len() - 1; - self.array.insert(pos, curl_sys::curl_forms { - option: curl_sys::CURLFORM_CONTENTHEADER, - value: list::raw(&headers) as *mut _, - }); + self.array.insert( + pos, + curl_sys::curl_forms { + option: curl_sys::CURLFORM_CONTENTHEADER, + value: list::raw(&headers) as *mut _, + }, + ); self.form.headers.push(headers); self } @@ -270,18 +302,20 @@ /// `Ok(())` is returned. pub fn add(&mut self) -> Result<(), FormError> { if let Some(err) = self.error.clone() { - return Err(err) + return Err(err); } let rc = unsafe { - curl_sys::curl_formadd(&mut self.form.head, - &mut self.form.tail, - curl_sys::CURLFORM_COPYNAME, - self.name.as_ptr(), - curl_sys::CURLFORM_NAMELENGTH, - self.name.len(), - curl_sys::CURLFORM_ARRAY, - self.array.as_ptr(), - curl_sys::CURLFORM_END) + curl_sys::curl_formadd( + &mut self.form.head, + &mut self.form.tail, + curl_sys::CURLFORM_COPYNAME, + self.name.as_ptr(), + curl_sys::CURLFORM_NAMELENGTH, + self.name.len(), + curl_sys::CURLFORM_ARRAY, + self.array.as_ptr(), + curl_sys::CURLFORM_END, + ) }; if rc == curl_sys::CURL_FORMADD_OK { Ok(()) @@ -326,8 +360,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // TODO: fill this out more f.debug_struct("Part") - .field("name", &self.name) - .field("form", &self.form) - .finish() + .field("name", &self.name) + .field("form", &self.form) + .finish() } } diff -Nru cargo-0.33.0/vendor/curl/src/easy/handler.rs cargo-0.35.0/vendor/curl/src/easy/handler.rs --- cargo-0.33.0/vendor/curl/src/easy/handler.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/handler.rs 2019-05-15 11:26:24.000000000 +0000 @@ -8,15 +8,15 @@ use std::time::Duration; use curl_sys; -use libc::{self, c_void, c_char, c_long, size_t, c_int, c_double, c_ulong}; +use libc::{self, c_char, c_double, c_int, c_long, c_ulong, c_void, size_t}; use socket2::Socket; -use Error; use easy::form; use easy::list; -use easy::{List, Form}; use easy::windows; +use easy::{Form, List}; use panic; +use Error; /// A trait for the various callbacks used by libcurl to invoke user code. /// @@ -219,11 +219,7 @@ /// /// By default this function calls an internal method and corresponds to /// `CURLOPT_PROGRESSFUNCTION` and `CURLOPT_PROGRESSDATA`. - fn progress(&mut self, - dltotal: f64, - dlnow: f64, - ultotal: f64, - ulnow: f64) -> bool { + fn progress(&mut self, dltotal: f64, dlnow: f64, ultotal: f64, ulnow: f64) -> bool { drop((dltotal, dlnow, ultotal, ulnow)); true } @@ -275,16 +271,18 @@ /// /// By default this function opens a standard socket and /// corresponds to `CURLOPT_OPENSOCKETFUNCTION `. - fn open_socket(&mut self, - family: c_int, - socktype: c_int, - protocol: c_int) -> Option { + fn open_socket( + &mut self, + family: c_int, + socktype: c_int, + protocol: c_int, + ) -> Option { // Note that we override this to calling a function in `socket2` to // ensure that we open all sockets with CLOEXEC. Otherwise if we rely on // libcurl to open sockets it won't use CLOEXEC. return Socket::new(family.into(), socktype.into(), Some(protocol.into())) - .ok() - .map(cvt); + .ok() + .map(cvt); #[cfg(unix)] fn cvt(socket: Socket) -> curl_sys::curl_socket_t { @@ -306,10 +304,8 @@ InfoType::Text => "*", InfoType::HeaderIn => "<", InfoType::HeaderOut => ">", - InfoType::DataIn | - InfoType::SslDataIn => "{", - InfoType::DataOut | - InfoType::SslDataOut => "}", + InfoType::DataIn | InfoType::SslDataIn => "{", + InfoType::DataOut | InfoType::SslDataOut => "}", InfoType::__Nonexhaustive => " ", }; let mut out = out.lock(); @@ -479,9 +475,10 @@ Tlsv1 = curl_sys::CURL_SSLVERSION_TLSv1 as isize, Sslv2 = curl_sys::CURL_SSLVERSION_SSLv2 as isize, Sslv3 = curl_sys::CURL_SSLVERSION_SSLv3 as isize, - // Tlsv10 = curl_sys::CURL_SSLVERSION_TLSv1_0 as isize, - // Tlsv11 = curl_sys::CURL_SSLVERSION_TLSv1_1 as isize, - // Tlsv12 = curl_sys::CURL_SSLVERSION_TLSv1_2 as isize, + Tlsv10 = curl_sys::CURL_SSLVERSION_TLSv1_0 as isize, + Tlsv11 = curl_sys::CURL_SSLVERSION_TLSv1_1 as isize, + Tlsv12 = curl_sys::CURL_SSLVERSION_TLSv1_2 as isize, + Tlsv13 = curl_sys::CURL_SSLVERSION_TLSv1_3 as isize, /// Hidden variant to indicate that this enum should not be matched on, it /// may grow over time. @@ -623,7 +620,7 @@ }), }; ret.default_configure(); - return ret + return ret; } } @@ -640,16 +637,17 @@ } fn default_configure(&mut self) { - self.setopt_ptr(curl_sys::CURLOPT_ERRORBUFFER, - self.inner.error_buf.borrow().as_ptr() as *const _) - .expect("failed to set error buffer"); + self.setopt_ptr( + curl_sys::CURLOPT_ERRORBUFFER, + self.inner.error_buf.borrow().as_ptr() as *const _, + ) + .expect("failed to set error buffer"); let _ = self.signal(false); self.ssl_configure(); let ptr = &*self.inner as *const _ as *const _; - let cb: extern fn(*mut c_char, size_t, size_t, *mut c_void) -> size_t - = header_cb::; + let cb: extern "C" fn(*mut c_char, size_t, size_t, *mut c_void) -> size_t = header_cb::; self.setopt_ptr(curl_sys::CURLOPT_HEADERFUNCTION, cb as *const _) .expect("failed to set header callback"); self.setopt_ptr(curl_sys::CURLOPT_HEADERDATA, ptr) @@ -690,13 +688,13 @@ drop(self.setopt_ptr(curl_sys::CURLOPT_SSL_CTX_DATA, ptr)); let cb: curl_sys::curl_opensocket_callback = opensocket_cb::; - self.setopt_ptr(curl_sys::CURLOPT_OPENSOCKETFUNCTION , cb as *const _) + self.setopt_ptr(curl_sys::CURLOPT_OPENSOCKETFUNCTION, cb as *const _) .expect("failed to set open socket callback"); self.setopt_ptr(curl_sys::CURLOPT_OPENSOCKETDATA, ptr) .expect("failed to set open socket callback"); } - #[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] + #[cfg(need_openssl_probe)] fn ssl_configure(&mut self) { let probe = ::openssl_probe::probe(); if let Some(ref path) = probe.cert_file { @@ -707,7 +705,7 @@ } } - #[cfg(not(all(unix, not(target_os = "macos"), feature = "ssl")))] + #[cfg(not(need_openssl_probe))] fn ssl_configure(&mut self) {} } @@ -751,8 +749,7 @@ /// By default this option is `false` and corresponds to /// `CURLOPT_NOPROGRESS`. pub fn progress(&mut self, progress: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_NOPROGRESS, - (!progress) as c_long) + self.setopt_long(curl_sys::CURLOPT_NOPROGRESS, (!progress) as c_long) } /// Inform libcurl whether or not it should install signal handlers or @@ -769,8 +766,7 @@ /// /// [libcurl docs]: https://curl.haxx.se/libcurl/c/threadsafe.html pub fn signal(&mut self, signal: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_NOSIGNAL, - (!signal) as c_long) + self.setopt_long(curl_sys::CURLOPT_NOSIGNAL, (!signal) as c_long) } /// Indicates whether multiple files will be transferred based on the file @@ -796,7 +792,6 @@ self.setopt_str(curl_sys::CURLOPT_UNIX_SOCKET_PATH, &socket) } - // ========================================================================= // Internal accessors @@ -904,8 +899,7 @@ /// By default this option is `false` and corresponds to /// `CURLOPT_HTTPPROXYTUNNEL`. pub fn http_proxy_tunnel(&mut self, tunnel: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_HTTPPROXYTUNNEL, - tunnel as c_long) + self.setopt_long(curl_sys::CURLOPT_HTTPPROXYTUNNEL, tunnel as c_long) } /// Tell curl which interface to bind to for an outgoing network interface. @@ -933,8 +927,20 @@ /// By default this option is 1 and corresponds to /// `CURLOPT_LOCALPORTRANGE`. pub fn local_port_range(&mut self, range: u16) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_LOCALPORTRANGE, - range as c_long) + self.setopt_long(curl_sys::CURLOPT_LOCALPORTRANGE, range as c_long) + } + + /// Sets the DNS servers that wil be used. + /// + /// Provide a comma separated list, for example: `8.8.8.8,8.8.4.4`. + /// + /// By default this option is not set and the OS's DNS resolver is used. + /// This option can only be used if libcurl is linked against + /// [c-ares](https://c-ares.haxx.se), otherwise setting it will return + /// an error. + pub fn dns_servers(&mut self, servers: &str) -> Result<(), Error> { + let s = try!(CString::new(servers)); + self.setopt_str(curl_sys::CURLOPT_DNS_SERVERS, &s) } /// Sets the timeout of how long name resolves will be kept in memory. @@ -944,8 +950,7 @@ /// By default this option is 60s and corresponds to /// `CURLOPT_DNS_CACHE_TIMEOUT`. pub fn dns_cache_timeout(&mut self, dur: Duration) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_DNS_CACHE_TIMEOUT, - dur.as_secs() as c_long) + self.setopt_long(curl_sys::CURLOPT_DNS_CACHE_TIMEOUT, dur.as_secs() as c_long) } /// Specify the preferred receive buffer size, in bytes. @@ -998,16 +1003,14 @@ /// /// By default this corresponds to `CURLOPT_TCP_KEEPIDLE`. pub fn tcp_keepidle(&mut self, amt: Duration) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_TCP_KEEPIDLE, - amt.as_secs() as c_long) + self.setopt_long(curl_sys::CURLOPT_TCP_KEEPIDLE, amt.as_secs() as c_long) } /// Configures the delay between keepalive probes. /// /// By default this corresponds to `CURLOPT_TCP_KEEPINTVL`. pub fn tcp_keepintvl(&mut self, amt: Duration) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_TCP_KEEPINTVL, - amt.as_secs() as c_long) + self.setopt_long(curl_sys::CURLOPT_TCP_KEEPINTVL, amt.as_secs() as c_long) } /// Configures the scope for local IPv6 addresses. @@ -1017,8 +1020,7 @@ /// /// By default this value is 0 and corresponds to `CURLOPT_ADDRESS_SCOPE` pub fn address_scope(&mut self, scope: u32) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_ADDRESS_SCOPE, - scope as c_long) + self.setopt_long(curl_sys::CURLOPT_ADDRESS_SCOPE, scope as c_long) } // ========================================================================= @@ -1193,14 +1195,13 @@ pub fn post_fields_copy(&mut self, data: &[u8]) -> Result<(), Error> { // Set the length before the pointer so libcurl knows how much to read try!(self.post_field_size(data.len() as u64)); - self.setopt_ptr(curl_sys::CURLOPT_COPYPOSTFIELDS, - data.as_ptr() as *const _) + self.setopt_ptr(curl_sys::CURLOPT_COPYPOSTFIELDS, data.as_ptr() as *const _) } /// Configures the size of data that's going to be uploaded as part of a /// POST operation. /// - /// This is called automaticsally as part of `post_fields` and should only + /// This is called automatically as part of `post_fields` and should only /// be called if data is being provided in a read callback (and even then /// it's optional). /// @@ -1209,8 +1210,10 @@ pub fn post_field_size(&mut self, size: u64) -> Result<(), Error> { // Clear anything previous to ensure we don't read past a buffer try!(self.setopt_ptr(curl_sys::CURLOPT_POSTFIELDS, 0 as *const _)); - self.setopt_off_t(curl_sys::CURLOPT_POSTFIELDSIZE_LARGE, - size as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_POSTFIELDSIZE_LARGE, + size as curl_sys::curl_off_t, + ) } /// Tells libcurl you want a multipart/formdata HTTP POST to be made and you @@ -1219,8 +1222,7 @@ /// By default this option is set to null and corresponds to /// `CURLOPT_HTTPPOST`. pub fn httppost(&mut self, form: Form) -> Result<(), Error> { - try!(self.setopt_ptr(curl_sys::CURLOPT_HTTPPOST, - form::raw(&form) as *const _)); + try!(self.setopt_ptr(curl_sys::CURLOPT_HTTPPOST, form::raw(&form) as *const _)); self.inner.form = Some(form); Ok(()) } @@ -1403,8 +1405,7 @@ /// By default this option is `false` and corresponds to /// `CURLOPT_IGNORE_CONTENT_LENGTH`. pub fn ignore_content_length(&mut self, ignore: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_IGNORE_CONTENT_LENGTH, - ignore as c_long) + self.setopt_long(curl_sys::CURLOPT_IGNORE_CONTENT_LENGTH, ignore as c_long) } /// Enable or disable HTTP content decoding. @@ -1412,8 +1413,7 @@ /// By default this option is `true` and corresponds to /// `CURLOPT_HTTP_CONTENT_DECODING`. pub fn http_content_decoding(&mut self, enable: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_HTTP_CONTENT_DECODING, - enable as c_long) + self.setopt_long(curl_sys::CURLOPT_HTTP_CONTENT_DECODING, enable as c_long) } /// Enable or disable HTTP transfer decoding. @@ -1421,8 +1421,7 @@ /// By default this option is `true` and corresponds to /// `CURLOPT_HTTP_TRANSFER_DECODING`. pub fn http_transfer_decoding(&mut self, enable: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_HTTP_TRANSFER_DECODING, - enable as c_long) + self.setopt_long(curl_sys::CURLOPT_HTTP_TRANSFER_DECODING, enable as c_long) } // /// Timeout for the Expect: 100-continue response @@ -1461,7 +1460,6 @@ // pub fn http_pipewait(&mut self, enable: bool) -> Result<(), Error> { // } - // ========================================================================= // Protocol Options @@ -1484,8 +1482,10 @@ /// By default this option is 0 and corresponds to /// `CURLOPT_RESUME_FROM_LARGE`. pub fn resume_from(&mut self, from: u64) -> Result<(), Error> { - self.setopt_off_t(curl_sys::CURLOPT_RESUME_FROM_LARGE, - from as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_RESUME_FROM_LARGE, + from as curl_sys::curl_off_t, + ) } /// Set a custom request string @@ -1528,8 +1528,10 @@ /// By default this option is not set and corresponds to /// `CURLOPT_INFILESIZE_LARGE`. pub fn in_filesize(&mut self, size: u64) -> Result<(), Error> { - self.setopt_off_t(curl_sys::CURLOPT_INFILESIZE_LARGE, - size as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_INFILESIZE_LARGE, + size as curl_sys::curl_off_t, + ) } /// Enable or disable data upload. @@ -1548,8 +1550,10 @@ /// By default this option is not set and corresponds to /// `CURLOPT_MAXFILESIZE_LARGE`. pub fn max_filesize(&mut self, size: u64) -> Result<(), Error> { - self.setopt_off_t(curl_sys::CURLOPT_MAXFILESIZE_LARGE, - size as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_MAXFILESIZE_LARGE, + size as curl_sys::curl_off_t, + ) } /// Selects a condition for a time request. @@ -1600,10 +1604,8 @@ pub fn timeout(&mut self, timeout: Duration) -> Result<(), Error> { // TODO: checked arithmetic and casts // TODO: use CURLOPT_TIMEOUT if the timeout is too great - let ms = timeout.as_secs() * 1000 + - (timeout.subsec_nanos() / 1_000_000) as u64; + let ms = timeout.as_secs() * 1000 + (timeout.subsec_nanos() / 1_000_000) as u64; self.setopt_long(curl_sys::CURLOPT_TIMEOUT_MS, ms as c_long) - } /// Set the low speed limit in bytes per second. @@ -1626,8 +1628,7 @@ /// By default this option is not set and corresponds to /// `CURLOPT_LOW_SPEED_TIME`. pub fn low_speed_time(&mut self, dur: Duration) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_LOW_SPEED_TIME, - dur.as_secs() as c_long) + self.setopt_long(curl_sys::CURLOPT_LOW_SPEED_TIME, dur.as_secs() as c_long) } /// Rate limit data upload speed @@ -1639,8 +1640,10 @@ /// By default this option is not set (unlimited speed) and corresponds to /// `CURLOPT_MAX_SEND_SPEED_LARGE`. pub fn max_send_speed(&mut self, speed: u64) -> Result<(), Error> { - self.setopt_off_t(curl_sys::CURLOPT_MAX_SEND_SPEED_LARGE, - speed as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_MAX_SEND_SPEED_LARGE, + speed as curl_sys::curl_off_t, + ) } /// Rate limit data download speed @@ -1652,8 +1655,10 @@ /// By default this option is not set (unlimited speed) and corresponds to /// `CURLOPT_MAX_RECV_SPEED_LARGE`. pub fn max_recv_speed(&mut self, speed: u64) -> Result<(), Error> { - self.setopt_off_t(curl_sys::CURLOPT_MAX_RECV_SPEED_LARGE, - speed as curl_sys::curl_off_t) + self.setopt_off_t( + curl_sys::CURLOPT_MAX_RECV_SPEED_LARGE, + speed as curl_sys::curl_off_t, + ) } /// Set the maximum connection cache size. @@ -1710,8 +1715,7 @@ /// By default this value is 300 seconds and corresponds to /// `CURLOPT_CONNECTTIMEOUT_MS`. pub fn connect_timeout(&mut self, timeout: Duration) -> Result<(), Error> { - let ms = timeout.as_secs() * 1000 + - (timeout.subsec_nanos() / 1_000_000) as u64; + let ms = timeout.as_secs() * 1000 + (timeout.subsec_nanos() / 1_000_000) as u64; self.setopt_long(curl_sys::CURLOPT_CONNECTTIMEOUT_MS, ms as c_long) } @@ -1732,7 +1736,8 @@ /// system resolver. /// /// # Examples - /// ``` + /// + /// ```no_run /// use curl::easy::{Easy, List}; /// /// let mut list = List::new(); @@ -1749,7 +1754,6 @@ self.setopt_ptr(curl_sys::CURLOPT_RESOLVE, ptr as *const _) } - /// Configure whether to stop when connected to target server /// /// When enabled it tells the library to perform all the required proxy @@ -1957,7 +1961,7 @@ /// By default this option is set to `true` and corresponds to /// `CURLOPT_SSL_VERIFYHOST`. pub fn ssl_verify_host(&mut self, verify: bool) -> Result<(), Error> { - let val = if verify {2} else {0}; + let val = if verify { 2 } else { 0 }; self.setopt_long(curl_sys::CURLOPT_SSL_VERIFYHOST, val) } @@ -2149,8 +2153,7 @@ /// /// This corresponds to the `CURLOPT_SSL_SESSIONID_CACHE` option. pub fn ssl_sessionid_cache(&mut self, enable: bool) -> Result<(), Error> { - self.setopt_long(curl_sys::CURLOPT_SSL_SESSIONID_CACHE, - enable as c_long) + self.setopt_long(curl_sys::CURLOPT_SSL_SESSIONID_CACHE, enable as c_long) } /// Set SSL behavior options @@ -2190,7 +2193,6 @@ // ========================================================================= // getters - /// Get info on unmet time conditional /// /// Returns if the condition provided in the previous request didn't match @@ -2198,13 +2200,15 @@ //// This corresponds to `CURLINFO_CONDITION_UNMET` and may return an error if the /// option is not supported pub fn time_condition_unmet(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_CONDITION_UNMET).map(|r| { - if r==0 { - false - } else { - true - } - }) + self.getopt_long(curl_sys::CURLINFO_CONDITION_UNMET).map( + |r| { + if r == 0 { + false + } else { + true + } + }, + ) } /// Get the last used URL @@ -2242,7 +2246,8 @@ /// Corresponds to `CURLINFO_RESPONSE_CODE` and returns an error if this /// option is not supported. pub fn response_code(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_RESPONSE_CODE).map(|c| c as u32) + self.getopt_long(curl_sys::CURLINFO_RESPONSE_CODE) + .map(|c| c as u32) } /// Get the CONNECT response code @@ -2253,7 +2258,8 @@ /// Corresponds to `CURLINFO_HTTP_CONNECTCODE` and returns an error if this /// option is not supported. pub fn http_connectcode(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_HTTP_CONNECTCODE).map(|c| c as u32) + self.getopt_long(curl_sys::CURLINFO_HTTP_CONNECTCODE) + .map(|c| c as u32) } /// Get the remote time of the retrieved document @@ -2404,7 +2410,8 @@ /// Corresponds to `CURLINFO_REDIRECT_COUNT` and may return an error if the /// option isn't supported. pub fn redirect_count(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_REDIRECT_COUNT).map(|c| c as u32) + self.getopt_long(curl_sys::CURLINFO_REDIRECT_COUNT) + .map(|c| c as u32) } /// Get the URL a redirect would go to @@ -2439,7 +2446,8 @@ /// Corresponds to `CURLINFO_HEADER_SIZE` and may return an error if the /// option isn't supported. pub fn header_size(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_HEADER_SIZE).map(|c| c as u64) + self.getopt_long(curl_sys::CURLINFO_HEADER_SIZE) + .map(|c| c as u64) } /// Get size of sent request. @@ -2447,7 +2455,8 @@ /// Corresponds to `CURLINFO_REQUEST_SIZE` and may return an error if the /// option isn't supported. pub fn request_size(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_REQUEST_SIZE).map(|c| c as u64) + self.getopt_long(curl_sys::CURLINFO_REQUEST_SIZE) + .map(|c| c as u64) } /// Get Content-Type @@ -2484,7 +2493,8 @@ /// Corresponds to `CURLINFO_OS_ERRNO` and may return an error if the /// option isn't supported. pub fn os_errno(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_OS_ERRNO).map(|c| c as i32) + self.getopt_long(curl_sys::CURLINFO_OS_ERRNO) + .map(|c| c as i32) } /// Get IP address of last connection. @@ -2504,7 +2514,8 @@ /// Corresponds to `CURLINFO_PRIMARY_PORT` and may return an error if the /// option isn't supported. pub fn primary_port(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_PRIMARY_PORT).map(|c| c as u16) + self.getopt_long(curl_sys::CURLINFO_PRIMARY_PORT) + .map(|c| c as u16) } /// Get local IP address of last connection @@ -2524,7 +2535,8 @@ /// Corresponds to `CURLINFO_LOCAL_PORT` and may return an error if the /// option isn't supported. pub fn local_port(&mut self) -> Result { - self.getopt_long(curl_sys::CURLINFO_LOCAL_PORT).map(|c| c as u16) + self.getopt_long(curl_sys::CURLINFO_LOCAL_PORT) + .map(|c| c as u16) } /// Get all known cookies @@ -2536,9 +2548,11 @@ pub fn cookies(&mut self) -> Result { unsafe { let mut list = 0 as *mut _; - let rc = curl_sys::curl_easy_getinfo(self.inner.handle, - curl_sys::CURLINFO_COOKIELIST, - &mut list); + let rc = curl_sys::curl_easy_getinfo( + self.inner.handle, + curl_sys::CURLINFO_COOKIELIST, + &mut list, + ); try!(self.cvt(rc)); Ok(list::from_raw(list)) } @@ -2571,7 +2585,7 @@ /// protocol and support level. /// /// This corresponds to the `CURLOPT_PIPEWAIT` option. - pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> { + pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> { self.setopt_long(curl_sys::CURLOPT_PIPEWAIT, wait as c_long) } @@ -2594,11 +2608,9 @@ /// call methods like `unpause_write` and `unpause_read` while a transfer is /// in progress. pub fn perform(&self) -> Result<(), Error> { - let ret = unsafe { - self.cvt(curl_sys::curl_easy_perform(self.inner.handle)) - }; + let ret = unsafe { self.cvt(curl_sys::curl_easy_perform(self.inner.handle)) }; panic::propagate(); - return ret + return ret; } /// Unpause reading on a connection. @@ -2617,8 +2629,7 @@ /// this function returns. pub fn unpause_read(&self) -> Result<(), Error> { unsafe { - let rc = curl_sys::curl_easy_pause(self.inner.handle, - curl_sys::CURLPAUSE_RECV_CONT); + let rc = curl_sys::curl_easy_pause(self.inner.handle, curl_sys::CURLPAUSE_RECV_CONT); self.cvt(rc) } } @@ -2639,8 +2650,7 @@ /// paused. pub fn unpause_write(&self) -> Result<(), Error> { unsafe { - let rc = curl_sys::curl_easy_pause(self.inner.handle, - curl_sys::CURLPAUSE_SEND_CONT); + let rc = curl_sys::curl_easy_pause(self.inner.handle, curl_sys::CURLPAUSE_SEND_CONT); self.cvt(rc) } } @@ -2648,17 +2658,19 @@ /// URL encodes a string `s` pub fn url_encode(&mut self, s: &[u8]) -> String { if s.len() == 0 { - return String::new() + return String::new(); } unsafe { - let p = curl_sys::curl_easy_escape(self.inner.handle, - s.as_ptr() as *const _, - s.len() as c_int); + let p = curl_sys::curl_easy_escape( + self.inner.handle, + s.as_ptr() as *const _, + s.len() as c_int, + ); assert!(!p.is_null()); let ret = str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap(); let ret = String::from(ret); curl_sys::curl_free(p as *mut _); - return ret + return ret; } } @@ -2675,24 +2687,24 @@ let orig_len = s.len(); let mut data; let mut s = s; - if iter.next() == Some('%') || - iter.next() == Some('%') || - iter.next() == Some('%') { + if iter.next() == Some('%') || iter.next() == Some('%') || iter.next() == Some('%') { data = s.to_string(); data.push(0u8 as char); s = &data[..]; } unsafe { let mut len = 0; - let p = curl_sys::curl_easy_unescape(self.inner.handle, - s.as_ptr() as *const _, - orig_len as c_int, - &mut len); + let p = curl_sys::curl_easy_unescape( + self.inner.handle, + s.as_ptr() as *const _, + orig_len as c_int, + &mut len, + ); assert!(!p.is_null()); let slice = slice::from_raw_parts(p as *const u8, len as usize); let ret = slice.to_vec(); curl_sys::curl_free(p as *mut _); - return ret + return ret; } } @@ -2731,10 +2743,12 @@ pub fn recv(&mut self, data: &mut [u8]) -> Result { unsafe { let mut n = 0; - let r = curl_sys::curl_easy_recv(self.inner.handle, - data.as_mut_ptr() as *mut _, - data.len(), - &mut n); + let r = curl_sys::curl_easy_recv( + self.inner.handle, + data.as_mut_ptr() as *mut _, + data.len(), + &mut n, + ); if r == curl_sys::CURLE_OK { Ok(n) } else { @@ -2750,10 +2764,12 @@ pub fn send(&mut self, data: &[u8]) -> Result { unsafe { let mut n = 0; - let rc = curl_sys::curl_easy_send(self.inner.handle, - data.as_ptr() as *const _, - data.len(), - &mut n); + let rc = curl_sys::curl_easy_send( + self.inner.handle, + data.as_ptr() as *const _, + data.len(), + &mut n, + ); try!(self.cvt(rc)); Ok(n) } @@ -2765,57 +2781,44 @@ } #[cfg(unix)] - fn setopt_path(&mut self, - opt: curl_sys::CURLoption, - val: &Path) -> Result<(), Error> { + fn setopt_path(&mut self, opt: curl_sys::CURLoption, val: &Path) -> Result<(), Error> { use std::os::unix::prelude::*; let s = try!(CString::new(val.as_os_str().as_bytes())); self.setopt_str(opt, &s) } #[cfg(windows)] - fn setopt_path(&mut self, - opt: curl_sys::CURLoption, - val: &Path) -> Result<(), Error> { + fn setopt_path(&mut self, opt: curl_sys::CURLoption, val: &Path) -> Result<(), Error> { match val.to_str() { Some(s) => self.setopt_str(opt, &try!(CString::new(s))), None => Err(Error::new(curl_sys::CURLE_CONV_FAILED)), } } - fn setopt_long(&mut self, - opt: curl_sys::CURLoption, - val: c_long) -> Result<(), Error> { - unsafe { - self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) - } + fn setopt_long(&mut self, opt: curl_sys::CURLoption, val: c_long) -> Result<(), Error> { + unsafe { self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) } } - fn setopt_str(&mut self, - opt: curl_sys::CURLoption, - val: &CStr) -> Result<(), Error> { + fn setopt_str(&mut self, opt: curl_sys::CURLoption, val: &CStr) -> Result<(), Error> { self.setopt_ptr(opt, val.as_ptr()) } - fn setopt_ptr(&self, - opt: curl_sys::CURLoption, - val: *const c_char) -> Result<(), Error> { - unsafe { - self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) - } + fn setopt_ptr(&self, opt: curl_sys::CURLoption, val: *const c_char) -> Result<(), Error> { + unsafe { self.cvt(curl_sys::curl_easy_setopt(self.inner.handle, opt, val)) } } - fn setopt_off_t(&mut self, - opt: curl_sys::CURLoption, - val: curl_sys::curl_off_t) -> Result<(), Error> { + fn setopt_off_t( + &mut self, + opt: curl_sys::CURLoption, + val: curl_sys::curl_off_t, + ) -> Result<(), Error> { unsafe { let rc = curl_sys::curl_easy_setopt(self.inner.handle, opt, val); self.cvt(rc) } } - fn getopt_bytes(&mut self, opt: curl_sys::CURLINFO) - -> Result, Error> { + fn getopt_bytes(&mut self, opt: curl_sys::CURLINFO) -> Result, Error> { unsafe { let p = try!(self.getopt_ptr(opt)); if p.is_null() { @@ -2826,8 +2829,7 @@ } } - fn getopt_ptr(&mut self, opt: curl_sys::CURLINFO) - -> Result<*const c_char, Error> { + fn getopt_ptr(&mut self, opt: curl_sys::CURLINFO) -> Result<*const c_char, Error> { unsafe { let mut p = 0 as *const c_char; let rc = curl_sys::curl_easy_getinfo(self.inner.handle, opt, &mut p); @@ -2836,17 +2838,14 @@ } } - fn getopt_str(&mut self, opt: curl_sys::CURLINFO) - -> Result, Error> { + fn getopt_str(&mut self, opt: curl_sys::CURLINFO) -> Result, Error> { match self.getopt_bytes(opt) { Ok(None) => Ok(None), Err(e) => Err(e), - Ok(Some(bytes)) => { - match str::from_utf8(bytes) { - Ok(s) => Ok(Some(s)), - Err(_) => Err(Error::new(curl_sys::CURLE_CONV_FAILED)), - } - } + Ok(Some(bytes)) => match str::from_utf8(bytes) { + Ok(s) => Ok(Some(s)), + Err(_) => Err(Error::new(curl_sys::CURLE_CONV_FAILED)), + }, } } @@ -2885,7 +2884,7 @@ pub fn take_error_buf(&self) -> Option { let mut buf = self.inner.error_buf.borrow_mut(); if buf[0] == 0 { - return None + return None; } let pos = buf.iter().position(|i| *i == 0).unwrap_or(buf.len()); let msg = String::from_utf8_lossy(&buf[..pos]).into_owned(); @@ -2895,7 +2894,7 @@ fn cvt(&self, rc: curl_sys::CURLcode) -> Result<(), Error> { if rc == curl_sys::CURLE_OK { - return Ok(()) + return Ok(()); } let mut err = Error::new(rc); if let Some(msg) = self.take_error_buf() { @@ -2908,9 +2907,9 @@ impl fmt::Debug for Easy2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Easy") - .field("handle", &self.inner.handle) - .field("handler", &self.inner.handle) - .finish() + .field("handle", &self.inner.handle) + .field("handler", &self.inner.handle) + .finish() } } @@ -2922,15 +2921,17 @@ } } -extern fn header_cb(buffer: *mut c_char, - size: size_t, - nitems: size_t, - userptr: *mut c_void) -> size_t { +extern "C" fn header_cb( + buffer: *mut c_char, + size: size_t, + nitems: size_t, + userptr: *mut c_void, +) -> size_t { let keep_going = panic::catch(|| unsafe { - let data = slice::from_raw_parts(buffer as *const u8, - size * nitems); + let data = slice::from_raw_parts(buffer as *const u8, size * nitems); (*(userptr as *mut Inner)).handler.header(data) - }).unwrap_or(false); + }) + .unwrap_or(false); if keep_going { size * nitems } else { @@ -2938,44 +2939,48 @@ } } -extern fn write_cb(ptr: *mut c_char, - size: size_t, - nmemb: size_t, - data: *mut c_void) -> size_t { +extern "C" fn write_cb( + ptr: *mut c_char, + size: size_t, + nmemb: size_t, + data: *mut c_void, +) -> size_t { panic::catch(|| unsafe { - let input = slice::from_raw_parts(ptr as *const u8, - size * nmemb); + let input = slice::from_raw_parts(ptr as *const u8, size * nmemb); match (*(data as *mut Inner)).handler.write(input) { Ok(s) => s, - Err(WriteError::Pause) | - Err(WriteError::__Nonexhaustive) => curl_sys::CURL_WRITEFUNC_PAUSE, + Err(WriteError::Pause) | Err(WriteError::__Nonexhaustive) => { + curl_sys::CURL_WRITEFUNC_PAUSE + } } - }).unwrap_or(!0) + }) + .unwrap_or(!0) } -extern fn read_cb(ptr: *mut c_char, - size: size_t, - nmemb: size_t, - data: *mut c_void) -> size_t { +extern "C" fn read_cb( + ptr: *mut c_char, + size: size_t, + nmemb: size_t, + data: *mut c_void, +) -> size_t { panic::catch(|| unsafe { - let input = slice::from_raw_parts_mut(ptr as *mut u8, - size * nmemb); + let input = slice::from_raw_parts_mut(ptr as *mut u8, size * nmemb); match (*(data as *mut Inner)).handler.read(input) { Ok(s) => s, - Err(ReadError::Pause) => { - curl_sys::CURL_READFUNC_PAUSE - } - Err(ReadError::__Nonexhaustive) | - Err(ReadError::Abort) => { + Err(ReadError::Pause) => curl_sys::CURL_READFUNC_PAUSE, + Err(ReadError::__Nonexhaustive) | Err(ReadError::Abort) => { curl_sys::CURL_READFUNC_ABORT } } - }).unwrap_or(!0) + }) + .unwrap_or(!0) } -extern fn seek_cb(data: *mut c_void, - offset: curl_sys::curl_off_t, - origin: c_int) -> c_int { +extern "C" fn seek_cb( + data: *mut c_void, + offset: curl_sys::curl_off_t, + origin: c_int, +) -> c_int { panic::catch(|| unsafe { let from = if origin == libc::SEEK_SET { SeekFrom::Start(offset as u64) @@ -2983,17 +2988,23 @@ panic!("unknown origin from libcurl: {}", origin); }; (*(data as *mut Inner)).handler.seek(from) as c_int - }).unwrap_or(!0) + }) + .unwrap_or(!0) } -extern fn progress_cb(data: *mut c_void, - dltotal: c_double, - dlnow: c_double, - ultotal: c_double, - ulnow: c_double) -> c_int { +extern "C" fn progress_cb( + data: *mut c_void, + dltotal: c_double, + dlnow: c_double, + ultotal: c_double, + ulnow: c_double, +) -> c_int { let keep_going = panic::catch(|| unsafe { - (*(data as *mut Inner)).handler.progress(dltotal, dlnow, ultotal, ulnow) - }).unwrap_or(false); + (*(data as *mut Inner)) + .handler + .progress(dltotal, dlnow, ultotal, ulnow) + }) + .unwrap_or(false); if keep_going { 0 } else { @@ -3002,11 +3013,13 @@ } // TODO: expose `handle`? is that safe? -extern fn debug_cb(_handle: *mut curl_sys::CURL, - kind: curl_sys::curl_infotype, - data: *mut c_char, - size: size_t, - userptr: *mut c_void) -> c_int { +extern "C" fn debug_cb( + _handle: *mut curl_sys::CURL, + kind: curl_sys::curl_infotype, + data: *mut c_char, + size: size_t, + userptr: *mut c_void, +) -> c_int { panic::catch(|| unsafe { let data = slice::from_raw_parts(data as *const u8, size); let kind = match kind { @@ -3021,12 +3034,14 @@ }; (*(userptr as *mut Inner)).handler.debug(kind, data) }); - return 0 + return 0; } -extern fn ssl_ctx_cb(_handle: *mut curl_sys::CURL, - ssl_ctx: *mut c_void, - data: *mut c_void) -> curl_sys::CURLcode { +extern "C" fn ssl_ctx_cb( + _handle: *mut curl_sys::CURL, + ssl_ctx: *mut c_void, + data: *mut c_void, +) -> curl_sys::CURLcode { let res = panic::catch(|| unsafe { match (*(data as *mut Inner)).handler.ssl_ctx(ssl_ctx) { Ok(()) => curl_sys::CURLE_OK, @@ -3040,15 +3055,15 @@ } // TODO: expose `purpose` and `sockaddr` inside of `address` -extern fn opensocket_cb(data: *mut c_void, - _purpose: curl_sys::curlsocktype, - address: *mut curl_sys::curl_sockaddr) - -> curl_sys::curl_socket_t -{ +extern "C" fn opensocket_cb( + data: *mut c_void, + _purpose: curl_sys::curlsocktype, + address: *mut curl_sys::curl_sockaddr, +) -> curl_sys::curl_socket_t { let res = panic::catch(|| unsafe { - (*(data as *mut Inner)).handler.open_socket((*address).family, - (*address).socktype, - (*address).protocol) + (*(data as *mut Inner)) + .handler + .open_socket((*address).family, (*address).socktype, (*address).protocol) .unwrap_or(curl_sys::CURL_SOCKET_BAD) }); res.unwrap_or(curl_sys::CURL_SOCKET_BAD) @@ -3179,13 +3194,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let bits = self.bits as c_ulong; f.debug_struct("Auth") - .field("basic", &(bits & curl_sys::CURLAUTH_BASIC != 0)) - .field("digest", &(bits & curl_sys::CURLAUTH_DIGEST != 0)) - .field("digest_ie", &(bits & curl_sys::CURLAUTH_DIGEST_IE != 0)) - .field("gssnegotiate", &(bits & curl_sys::CURLAUTH_GSSNEGOTIATE != 0)) - .field("ntlm", &(bits & curl_sys::CURLAUTH_NTLM != 0)) - .field("ntlm_wb", &(bits & curl_sys::CURLAUTH_NTLM_WB != 0)) - .finish() + .field("basic", &(bits & curl_sys::CURLAUTH_BASIC != 0)) + .field("digest", &(bits & curl_sys::CURLAUTH_DIGEST != 0)) + .field("digest_ie", &(bits & curl_sys::CURLAUTH_DIGEST_IE != 0)) + .field( + "gssnegotiate", + &(bits & curl_sys::CURLAUTH_GSSNEGOTIATE != 0), + ) + .field("ntlm", &(bits & curl_sys::CURLAUTH_NTLM != 0)) + .field("ntlm_wb", &(bits & curl_sys::CURLAUTH_NTLM_WB != 0)) + .finish() } } @@ -3234,8 +3252,14 @@ impl fmt::Debug for SslOpt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("SslOpt") - .field("no_revoke", &(self.bits & curl_sys::CURLSSLOPT_NO_REVOKE != 0)) - .field("allow_beast", &(self.bits & curl_sys::CURLSSLOPT_ALLOW_BEAST != 0)) - .finish() + .field( + "no_revoke", + &(self.bits & curl_sys::CURLSSLOPT_NO_REVOKE != 0), + ) + .field( + "allow_beast", + &(self.bits & curl_sys::CURLSSLOPT_ALLOW_BEAST != 0), + ) + .finish() } } diff -Nru cargo-0.33.0/vendor/curl/src/easy/handle.rs cargo-0.35.0/vendor/curl/src/easy/handle.rs --- cargo-0.33.0/vendor/curl/src/easy/handle.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/handle.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,12 +9,12 @@ use curl_sys; use libc::c_void; -use Error; -use easy::{Form, List}; -use easy::handler::{self, InfoType, SeekResult, ReadError, WriteError}; -use easy::handler::{TimeCondition, IpResolve, HttpVersion, SslVersion}; -use easy::handler::{SslOpt, NetRc, Auth, ProxyType}; +use easy::handler::{self, InfoType, ReadError, SeekResult, WriteError}; +use easy::handler::{Auth, NetRc, ProxyType, SslOpt}; +use easy::handler::{HttpVersion, IpResolve, SslVersion, TimeCondition}; use easy::{Easy2, Handler}; +use easy::{Form, List}; +use Error; /// Raw bindings to a libcurl "easy session". /// @@ -232,7 +232,8 @@ /// transfer.perform().unwrap(); /// ``` pub fn write_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&[u8]) -> Result + Send + 'static + where + F: FnMut(&[u8]) -> Result + Send + 'static, { self.inner.get_mut().owned.write = Some(Box::new(f)); Ok(()) @@ -303,7 +304,8 @@ /// transfer.perform().unwrap(); /// ``` pub fn read_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&mut [u8]) -> Result + Send + 'static + where + F: FnMut(&mut [u8]) -> Result + Send + 'static, { self.inner.get_mut().owned.read = Some(Box::new(f)); Ok(()) @@ -334,7 +336,8 @@ /// `transfer` method and then using `seek_function` to configure a /// callback that can reference stack-local data. pub fn seek_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(SeekFrom) -> SeekResult + Send + 'static + where + F: FnMut(SeekFrom) -> SeekResult + Send + 'static, { self.inner.get_mut().owned.seek = Some(Box::new(f)); Ok(()) @@ -377,7 +380,8 @@ /// `transfer` method and then using `progress_function` to configure a /// callback that can reference stack-local data. pub fn progress_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(f64, f64, f64, f64) -> bool + Send + 'static + where + F: FnMut(f64, f64, f64, f64) -> bool + Send + 'static, { self.inner.get_mut().owned.progress = Some(Box::new(f)); Ok(()) @@ -413,7 +417,8 @@ /// `transfer` method and then using `progress_function` to configure a /// callback that can reference stack-local data. pub fn ssl_ctx_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'static + where + F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'static, { self.inner.get_mut().owned.ssl_ctx = Some(Box::new(f)); Ok(()) @@ -433,7 +438,8 @@ /// `transfer` method and then using `debug_function` to configure a /// callback that can reference stack-local data. pub fn debug_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(InfoType, &[u8]) + Send + 'static + where + F: FnMut(InfoType, &[u8]) + Send + 'static, { self.inner.get_mut().owned.debug = Some(Box::new(f)); Ok(()) @@ -517,7 +523,8 @@ /// println!("{:?}", headers); /// ``` pub fn header_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&[u8]) -> bool + Send + 'static + where + F: FnMut(&[u8]) -> bool + Send + 'static, { self.inner.get_mut().owned.header = Some(Box::new(f)); Ok(()) @@ -586,6 +593,11 @@ self.inner.local_port_range(range) } + /// Same as [`Easy2::dns_servers`](struct.Easy2.html#method.dns_servers) + pub fn dns_servers(&mut self, servers: &str) -> Result<(), Error> { + self.inner.dns_servers(servers) + } + /// Same as [`Easy2::dns_cache_timeout`](struct.Easy2.html#method.dns_cache_timeout) pub fn dns_cache_timeout(&mut self, dur: Duration) -> Result<(), Error> { self.inner.dns_cache_timeout(dur) @@ -1144,7 +1156,7 @@ } /// Same as [`Easy2::pipewait`](struct.Easy2.html#method.pipewait) - pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> { + pub fn pipewait(&mut self, wait: bool) -> Result<(), Error> { self.inner.pipewait(wait) } @@ -1162,7 +1174,7 @@ // invoking `FnMut`closures behind a `&self` pointer. This flag acts as // our own `RefCell` borrow flag sorta. if self.inner.get_ref().running.get() { - return Err(Error::new(curl_sys::CURLE_FAILED_INIT)) + return Err(Error::new(curl_sys::CURLE_FAILED_INIT)); } self.inner.get_ref().running.set(true); @@ -1266,13 +1278,14 @@ /// Basically this is just intended to acquire a callback, invoke it, and /// then stop. Nothing else. Super unsafe. unsafe fn callback<'a, T, F>(&'a mut self, f: F) -> Option<&'a mut T> - where F: for<'b> Fn(&'b mut Callbacks<'static>) -> &'b mut Option, + where + F: for<'b> Fn(&'b mut Callbacks<'static>) -> &'b mut Option, { let ptr = self.borrowed.get(); if !ptr.is_null() { let val = f(&mut *ptr); if val.is_some() { - return val.as_mut() + return val.as_mut(); } } f(&mut self.owned).as_mut() @@ -1325,11 +1338,7 @@ } } - fn progress(&mut self, - dltotal: f64, - dlnow: f64, - ultotal: f64, - ulnow: f64) -> bool { + fn progress(&mut self, dltotal: f64, dlnow: f64, ultotal: f64, ulnow: f64) -> bool { unsafe { match self.callback(|s| &mut s.progress) { Some(progress) => progress(dltotal, dlnow, ultotal, ulnow), @@ -1358,7 +1367,8 @@ /// Same as `Easy::write_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn write_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&[u8]) -> Result + 'data + where + F: FnMut(&[u8]) -> Result + 'data, { self.data.write = Some(Box::new(f)); Ok(()) @@ -1367,7 +1377,8 @@ /// Same as `Easy::read_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn read_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&mut [u8]) -> Result + 'data + where + F: FnMut(&mut [u8]) -> Result + 'data, { self.data.read = Some(Box::new(f)); Ok(()) @@ -1376,7 +1387,8 @@ /// Same as `Easy::seek_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn seek_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(SeekFrom) -> SeekResult + 'data + where + F: FnMut(SeekFrom) -> SeekResult + 'data, { self.data.seek = Some(Box::new(f)); Ok(()) @@ -1385,7 +1397,8 @@ /// Same as `Easy::progress_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn progress_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(f64, f64, f64, f64) -> bool + 'data + where + F: FnMut(f64, f64, f64, f64) -> bool + 'data, { self.data.progress = Some(Box::new(f)); Ok(()) @@ -1394,7 +1407,8 @@ /// Same as `Easy::ssl_ctx_function`, just takes a non `'static` /// lifetime corresponding to the lifetime of this transfer. pub fn ssl_ctx_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'data + where + F: FnMut(*mut c_void) -> Result<(), Error> + Send + 'data, { self.data.ssl_ctx = Some(Box::new(f)); Ok(()) @@ -1403,7 +1417,8 @@ /// Same as `Easy::debug_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn debug_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(InfoType, &[u8]) + 'data + where + F: FnMut(InfoType, &[u8]) + 'data, { self.data.debug = Some(Box::new(f)); Ok(()) @@ -1412,7 +1427,8 @@ /// Same as `Easy::header_function`, just takes a non `'static` lifetime /// corresponding to the lifetime of this transfer. pub fn header_function(&mut self, f: F) -> Result<(), Error> - where F: FnMut(&[u8]) -> bool + 'data + where + F: FnMut(&[u8]) -> bool + 'data, { self.data.header = Some(Box::new(f)); Ok(()) @@ -1458,8 +1474,8 @@ impl<'easy, 'data> fmt::Debug for Transfer<'easy, 'data> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Transfer") - .field("easy", &self.easy) - .finish() + .field("easy", &self.easy) + .finish() } } diff -Nru cargo-0.33.0/vendor/curl/src/easy/list.rs cargo-0.35.0/vendor/curl/src/easy/list.rs --- cargo-0.33.0/vendor/curl/src/easy/list.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/list.rs 2019-05-15 11:26:24.000000000 +0000 @@ -45,15 +45,18 @@ /// Returns an iterator over the nodes in this list. pub fn iter(&self) -> Iter { - Iter { _me: self, cur: self.raw } + Iter { + _me: self, + cur: self.raw, + } } } impl fmt::Debug for List { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() - .entries(self.iter().map(String::from_utf8_lossy)) - .finish() + .entries(self.iter().map(String::from_utf8_lossy)) + .finish() } } @@ -68,9 +71,7 @@ impl Drop for List { fn drop(&mut self) { - unsafe { - curl_sys::curl_slist_free_all(self.raw) - } + unsafe { curl_sys::curl_slist_free_all(self.raw) } } } @@ -79,13 +80,13 @@ fn next(&mut self) -> Option<&'a [u8]> { if self.cur.is_null() { - return None + return None; } unsafe { let ret = Some(CStr::from_ptr((*self.cur).data).to_bytes()); self.cur = (*self.cur).next; - return ret + return ret; } } } @@ -93,7 +94,7 @@ impl<'a> fmt::Debug for Iter<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_list() - .entries(self.clone().map(String::from_utf8_lossy)) - .finish() + .entries(self.clone().map(String::from_utf8_lossy)) + .finish() } } diff -Nru cargo-0.33.0/vendor/curl/src/easy/mod.rs cargo-0.35.0/vendor/curl/src/easy/mod.rs --- cargo-0.33.0/vendor/curl/src/easy/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,16 +7,16 @@ //! Most simple usage of libcurl will likely use the `Easy` structure here, and //! you can find more docs about its usage on that struct. -mod list; mod form; mod handle; mod handler; +mod list; mod windows; -pub use self::list::{List, Iter}; pub use self::form::{Form, Part}; pub use self::handle::{Easy, Transfer}; +pub use self::handler::{Auth, NetRc, ProxyType, SslOpt}; pub use self::handler::{Easy2, Handler}; -pub use self::handler::{InfoType, SeekResult, ReadError, WriteError}; -pub use self::handler::{TimeCondition, IpResolve, HttpVersion, SslVersion}; -pub use self::handler::{SslOpt, NetRc, Auth, ProxyType}; +pub use self::handler::{HttpVersion, IpResolve, SslVersion, TimeCondition}; +pub use self::handler::{InfoType, ReadError, SeekResult, WriteError}; +pub use self::list::{Iter, List}; diff -Nru cargo-0.33.0/vendor/curl/src/easy/windows.rs cargo-0.35.0/vendor/curl/src/easy/windows.rs --- cargo-0.33.0/vendor/curl/src/easy/windows.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/easy/windows.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,21 +4,21 @@ #[cfg(target_env = "msvc")] mod win { + use kernel32; + use schannel::cert_context::ValidUses; + use schannel::cert_store::CertStore; use std::ffi::CString; use std::mem; use std::ptr; - use schannel::cert_context::ValidUses; - use schannel::cert_store::CertStore; - use winapi::{self, c_void, c_uchar, c_long, c_int}; - use winapi::um::libloaderapi::{GetModuleHandleW, GetProcAddress}; + use winapi::{self, c_int, c_long, c_uchar, c_void}; fn lookup(module: &str, symbol: &str) -> Option<*const c_void> { unsafe { let symbol = CString::new(symbol).unwrap(); let mut mod_buf: Vec = module.encode_utf16().collect(); mod_buf.push(0); - let handle = GetModuleHandleW(mod_buf.as_mut_ptr()); - let n = GetProcAddress(handle, symbol.as_ptr()); + let handle = kernel32::GetModuleHandleW(mod_buf.as_mut_ptr()); + let n = kernel32::GetProcAddress(handle, symbol.as_ptr()); if n == ptr::null() { None } else { @@ -37,10 +37,9 @@ length: c_long, ) -> *mut X509; type X509_free_fn = unsafe extern "C" fn(x: *mut X509); - type X509_STORE_add_cert_fn = unsafe extern "C" fn(store: *mut X509_STORE, x: *mut X509) - -> c_int; - type SSL_CTX_get_cert_store_fn = unsafe extern "C" fn(ctx: *const SSL_CTX) - -> *mut X509_STORE; + type X509_STORE_add_cert_fn = + unsafe extern "C" fn(store: *mut X509_STORE, x: *mut X509) -> c_int; + type SSL_CTX_get_cert_store_fn = unsafe extern "C" fn(ctx: *const SSL_CTX) -> *mut X509_STORE; struct OpenSSL { d2i_X509: d2i_X509_fn, @@ -49,9 +48,7 @@ SSL_CTX_get_cert_store: SSL_CTX_get_cert_store_fn, } - unsafe fn lookup_functions(crypto_module: &str, ssl_module: &str) - -> Option - { + unsafe fn lookup_functions(crypto_module: &str, ssl_module: &str) -> Option { macro_rules! get { ($(let $sym:ident in $module:expr;)*) => ($( let $sym = match lookup($module, stringify!($sym)) { @@ -108,15 +105,13 @@ ValidUses::Oids(ref oids) => { let oid = winapi::wincrypt::szOID_PKIX_KP_SERVER_AUTH.to_owned(); if !oids.contains(&oid) { - continue + continue; } } } let der = cert.to_der(); - let x509 = (openssl.d2i_X509)(ptr::null_mut(), - &mut der.as_ptr(), - der.len() as c_long); + let x509 = (openssl.d2i_X509)(ptr::null_mut(), &mut der.as_ptr(), der.len() as c_long); if !x509.is_null() { (openssl.X509_STORE_add_cert)(openssl_store, x509); (openssl.X509_free)(x509); diff -Nru cargo-0.33.0/vendor/curl/src/error.rs cargo-0.35.0/vendor/curl/src/error.rs --- cargo-0.33.0/vendor/curl/src/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,8 @@ use std::error; use std::ffi::{self, CStr}; use std::fmt; -use std::str; use std::io; +use std::str; use curl_sys; @@ -283,6 +283,16 @@ self.code == curl_sys::CURLE_CHUNK_FAILED } + /// Returns whether this error corresponds to CURLE_HTTP2. + pub fn is_http2_error(&self) -> bool { + self.code == curl_sys::CURLE_HTTP2 + } + + /// Returns whether this error corresponds to CURLE_HTTP2_STREAM. + pub fn is_http2_stream_error(&self) -> bool { + self.code == curl_sys::CURLE_HTTP2_STREAM + } + // /// Returns whether this error corresponds to CURLE_NO_CONNECTION_AVAILABLE. // pub fn is_no_connection_available(&self) -> bool { // self.code == curl_sys::CURLE_NO_CONNECTION_AVAILABLE @@ -312,10 +322,10 @@ impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Error") - .field("description", &error::Error::description(self)) - .field("code", &self.code) - .field("extra", &self.extra) - .finish() + .field("description", &error::Error::description(self)) + .field("code", &self.code) + .field("extra", &self.extra) + .finish() } } @@ -382,9 +392,12 @@ impl fmt::Debug for ShareError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ShareError {{ description: {:?}, code: {} }}", - error::Error::description(self), - self.code) + write!( + f, + "ShareError {{ description: {:?}, code: {} }}", + error::Error::description(self), + self.code + ) } } @@ -466,9 +479,12 @@ impl fmt::Debug for MultiError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "MultiError {{ description: {:?}, code: {} }}", - error::Error::description(self), - self.code) + write!( + f, + "MultiError {{ description: {:?}, code: {} }}", + error::Error::description(self), + self.code + ) } } @@ -482,7 +498,6 @@ } } - /// An error from "form add" operations. /// /// THis structure wraps a `CURLFORMcode`. @@ -546,9 +561,12 @@ impl fmt::Debug for FormError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FormError {{ description: {:?}, code: {} }}", - error::Error::description(self), - self.code) + write!( + f, + "FormError {{ description: {:?}, code: {} }}", + error::Error::description(self), + self.code + ) } } @@ -571,7 +589,10 @@ impl From for Error { fn from(_: ffi::NulError) -> Error { - Error { code: curl_sys::CURLE_CONV_FAILED, extra: None } + Error { + code: curl_sys::CURLE_CONV_FAILED, + extra: None, + } } } diff -Nru cargo-0.33.0/vendor/curl/src/lib.rs cargo-0.35.0/vendor/curl/src/lib.rs --- cargo-0.33.0/vendor/curl/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -54,29 +54,32 @@ extern crate libc; extern crate socket2; -#[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] -extern crate openssl_sys; -#[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] +#[cfg(need_openssl_probe)] extern crate openssl_probe; +#[cfg(need_openssl_init)] +extern crate openssl_sys; + #[cfg(windows)] extern crate winapi; #[cfg(target_env = "msvc")] +extern crate kernel32; +#[cfg(target_env = "msvc")] extern crate schannel; use std::ffi::CStr; use std::str; use std::sync::{Once, ONCE_INIT}; -pub use error::{Error, ShareError, MultiError, FormError}; +pub use error::{Error, FormError, MultiError, ShareError}; mod error; -pub use version::{Version, Protocols}; +pub use version::{Protocols, Version}; mod version; -mod panic; pub mod easy; pub mod multi; +mod panic; /// Initializes the underlying libcurl library. /// @@ -101,12 +104,12 @@ // function. }); - #[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] + #[cfg(need_openssl_init)] fn platform_init() { openssl_sys::init(); } - #[cfg(not(all(unix, not(target_os = "macos"), feature = "ssl")))] + #[cfg(not(need_openssl_init))] fn platform_init() {} } diff -Nru cargo-0.33.0/vendor/curl/src/multi.rs cargo-0.35.0/vendor/curl/src/multi.rs --- cargo-0.33.0/vendor/curl/src/multi.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/multi.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,17 +4,17 @@ use std::marker; use std::time::Duration; -use libc::{c_int, c_char, c_void, c_long, c_short}; use curl_sys; +use libc::{c_char, c_int, c_long, c_short, c_void}; -#[cfg(windows)] -use winapi::um::winsock2::fd_set; #[cfg(unix)] -use libc::{fd_set, pollfd, POLLIN, POLLPRI, POLLOUT}; +use libc::{fd_set, pollfd, POLLIN, POLLOUT, POLLPRI}; +#[cfg(windows)] +use winapi::winsock2::fd_set; -use {MultiError, Error}; use easy::{Easy, Easy2}; use panic; +use {Error, MultiError}; /// A multi handle for initiating multiple connections simultaneously. /// @@ -126,30 +126,34 @@ /// The third `usize` parameter is a custom value set by the `assign` method /// below. pub fn socket_function(&mut self, f: F) -> Result<(), MultiError> - where F: FnMut(Socket, SocketEvents, usize) + Send + 'static, + where + F: FnMut(Socket, SocketEvents, usize) + Send + 'static, { self._socket_function(Box::new(f)) } - fn _socket_function(&mut self, - f: Box) - -> Result<(), MultiError> - { + fn _socket_function( + &mut self, + f: Box, + ) -> Result<(), MultiError> { self.data.socket = f; let cb: curl_sys::curl_socket_callback = cb; - try!(self.setopt_ptr(curl_sys::CURLMOPT_SOCKETFUNCTION, - cb as usize as *const c_char)); + try!(self.setopt_ptr( + curl_sys::CURLMOPT_SOCKETFUNCTION, + cb as usize as *const c_char + )); let ptr = &*self.data as *const _; - try!(self.setopt_ptr(curl_sys::CURLMOPT_SOCKETDATA, - ptr as *const c_char)); + try!(self.setopt_ptr(curl_sys::CURLMOPT_SOCKETDATA, ptr as *const c_char)); return Ok(()); // TODO: figure out how to expose `_easy` - extern fn cb(_easy: *mut curl_sys::CURL, - socket: curl_sys::curl_socket_t, - what: c_int, - userptr: *mut c_void, - socketp: *mut c_void) -> c_int { + extern "C" fn cb( + _easy: *mut curl_sys::CURL, + socket: curl_sys::curl_socket_t, + what: c_int, + userptr: *mut c_void, + socketp: *mut c_void, + ) -> c_int { panic::catch(|| unsafe { let f = &mut (*(userptr as *mut MultiData)).socket; f(socket, SocketEvents { bits: what }, socketp as usize) @@ -190,12 +194,13 @@ /// particular data so that when we get updates about this same socket /// again, we don't have to find the struct associated with this socket by /// ourselves. - pub fn assign(&self, - socket: Socket, - token: usize) -> Result<(), MultiError> { + pub fn assign(&self, socket: Socket, token: usize) -> Result<(), MultiError> { unsafe { - try!(cvt(curl_sys::curl_multi_assign(self.raw, socket, - token as *mut _))); + try!(cvt(curl_sys::curl_multi_assign( + self.raw, + socket, + token as *mut _ + ))); Ok(()) } } @@ -220,28 +225,32 @@ /// error. This callback can be used instead of, or in addition to, /// `get_timeout`. pub fn timer_function(&mut self, f: F) -> Result<(), MultiError> - where F: FnMut(Option) -> bool + Send + 'static, + where + F: FnMut(Option) -> bool + Send + 'static, { self._timer_function(Box::new(f)) } - fn _timer_function(&mut self, - f: Box) -> bool + Send>) - -> Result<(), MultiError> - { + fn _timer_function( + &mut self, + f: Box) -> bool + Send>, + ) -> Result<(), MultiError> { self.data.timer = f; let cb: curl_sys::curl_multi_timer_callback = cb; - try!(self.setopt_ptr(curl_sys::CURLMOPT_TIMERFUNCTION, - cb as usize as *const c_char)); + try!(self.setopt_ptr( + curl_sys::CURLMOPT_TIMERFUNCTION, + cb as usize as *const c_char + )); let ptr = &*self.data as *const _; - try!(self.setopt_ptr(curl_sys::CURLMOPT_TIMERDATA, - ptr as *const c_char)); + try!(self.setopt_ptr(curl_sys::CURLMOPT_TIMERDATA, ptr as *const c_char)); return Ok(()); // TODO: figure out how to expose `_multi` - extern fn cb(_multi: *mut curl_sys::CURLM, - timeout_ms: c_long, - user: *mut c_void) -> c_int { + extern "C" fn cb( + _multi: *mut curl_sys::CURLM, + timeout_ms: c_long, + user: *mut c_void, + ) -> c_int { let keep_going = panic::catch(|| unsafe { let f = &mut (*(user as *mut MultiData)).timer; if timeout_ms == -1 { @@ -249,8 +258,13 @@ } else { f(Some(Duration::from_millis(timeout_ms as u64))) } - }).unwrap_or(false); - if keep_going {0} else {-1} + }) + .unwrap_or(false); + if keep_going { + 0 + } else { + -1 + } } } @@ -266,7 +280,12 @@ /// request multiplexed over that at the same time as other transfers are /// already using that single connection. pub fn pipelining(&mut self, http_1: bool, multiplex: bool) -> Result<(), MultiError> { - let bitmask = if http_1 { curl_sys::CURLPIPE_HTTP1 } else { 0 } | if multiplex { curl_sys::CURLPIPE_MULTIPLEX } else { 0 }; + let bitmask = if http_1 { curl_sys::CURLPIPE_HTTP1 } else { 0 } + | if multiplex { + curl_sys::CURLPIPE_MULTIPLEX + } else { + 0 + }; self.setopt_long(curl_sys::CURLMOPT_PIPELINING, bitmask) } @@ -291,20 +310,16 @@ self.setopt_long(curl_sys::CURLMOPT_MAX_PIPELINE_LENGTH, val as c_long) } - fn setopt_long(&mut self, - opt: curl_sys::CURLMoption, - val: c_long) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) - } + fn setopt_long(&mut self, opt: curl_sys::CURLMoption, val: c_long) -> Result<(), MultiError> { + unsafe { cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) } } - fn setopt_ptr(&mut self, - opt: curl_sys::CURLMoption, - val: *const c_char) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) - } + fn setopt_ptr( + &mut self, + opt: curl_sys::CURLMoption, + val: *const c_char, + ) -> Result<(), MultiError> { + unsafe { cvt(curl_sys::curl_multi_setopt(self.raw, opt, val)) } } /// Add an easy handle to a multi session @@ -364,8 +379,10 @@ /// All other easy handles and transfers will remain unaffected. pub fn remove(&self, easy: EasyHandle) -> Result { unsafe { - try!(cvt(curl_sys::curl_multi_remove_handle(self.raw, - easy.easy.raw()))); + try!(cvt(curl_sys::curl_multi_remove_handle( + self.raw, + easy.easy.raw() + ))); } Ok(easy.easy) } @@ -373,8 +390,10 @@ /// Same as `remove`, but for `Easy2Handle`. pub fn remove2(&self, easy: Easy2Handle) -> Result, MultiError> { unsafe { - try!(cvt(curl_sys::curl_multi_remove_handle(self.raw, - easy.easy.raw()))); + try!(cvt(curl_sys::curl_multi_remove_handle( + self.raw, + easy.easy.raw() + ))); } Ok(easy.easy) } @@ -385,7 +404,10 @@ /// individual transfers. Messages may include informationals such as an /// error code from the transfer or just the fact that a transfer is /// completed. More details on these should be written down as well. - pub fn messages(&self, mut f: F) where F: FnMut(Message) { + pub fn messages(&self, mut f: F) + where + F: FnMut(Message), + { self._messages(&mut f) } @@ -395,9 +417,12 @@ loop { let ptr = curl_sys::curl_multi_info_read(self.raw, &mut queue); if ptr.is_null() { - break + break; } - f(Message { ptr: ptr, _multi: self }) + f(Message { + ptr: ptr, + _multi: self, + }) } } } @@ -423,14 +448,15 @@ /// the socket callback function set with the `socket_function` method. They /// update the status with changes since the previous time the callback was /// called. - pub fn action(&self, socket: Socket, events: &Events) - -> Result { + pub fn action(&self, socket: Socket, events: &Events) -> Result { let mut remaining = 0; unsafe { - try!(cvt(curl_sys::curl_multi_socket_action(self.raw, - socket, - events.bits, - &mut remaining))); + try!(cvt(curl_sys::curl_multi_socket_action( + self.raw, + socket, + events.bits, + &mut remaining + ))); Ok(remaining as u32) } } @@ -453,10 +479,12 @@ pub fn timeout(&self) -> Result { let mut remaining = 0; unsafe { - try!(cvt(curl_sys::curl_multi_socket_action(self.raw, - curl_sys::CURL_SOCKET_BAD, - 0, - &mut remaining))); + try!(cvt(curl_sys::curl_multi_socket_action( + self.raw, + curl_sys::CURL_SOCKET_BAD, + 0, + &mut remaining + ))); Ok(remaining as u32) } } @@ -515,8 +543,7 @@ /// m.wait(&mut [], Duration::from_secs(1)).unwrap(); /// } /// ``` - pub fn wait(&self, waitfds: &mut [WaitFd], timeout: Duration) - -> Result { + pub fn wait(&self, waitfds: &mut [WaitFd], timeout: Duration) -> Result { let timeout_ms = { let secs = timeout.as_secs(); if secs > (i32::max_value() / 1000) as u64 { @@ -528,11 +555,13 @@ }; unsafe { let mut ret = 0; - try!(cvt(curl_sys::curl_multi_wait(self.raw, - waitfds.as_mut_ptr() as *mut _, - waitfds.len() as u32, - timeout_ms, - &mut ret))); + try!(cvt(curl_sys::curl_multi_wait( + self.raw, + waitfds.as_mut_ptr() as *mut _, + waitfds.len() as u32, + timeout_ms, + &mut ret + ))); Ok(ret as u32) } } @@ -616,20 +645,20 @@ /// of bounds write which can cause crashes, or worse. The effect of NOT /// storing it will possibly save you from the crash, but will make your /// program NOT wait for sockets it should wait for... - pub fn fdset2(&self, - read: Option<&mut curl_sys::fd_set>, - write: Option<&mut curl_sys::fd_set>, - except: Option<&mut curl_sys::fd_set>) -> Result, MultiError> { + pub fn fdset2( + &self, + read: Option<&mut curl_sys::fd_set>, + write: Option<&mut curl_sys::fd_set>, + except: Option<&mut curl_sys::fd_set>, + ) -> Result, MultiError> { unsafe { let mut ret = 0; let read = read.map(|r| r as *mut _).unwrap_or(0 as *mut _); let write = write.map(|r| r as *mut _).unwrap_or(0 as *mut _); let except = except.map(|r| r as *mut _).unwrap_or(0 as *mut _); - try!(cvt(curl_sys::curl_multi_fdset(self.raw, - read, - write, - except, - &mut ret))); + try!(cvt(curl_sys::curl_multi_fdset( + self.raw, read, write, except, &mut ret + ))); if ret == -1 { Ok(None) } else { @@ -640,20 +669,24 @@ #[doc(hidden)] #[deprecated(note = "renamed to fdset2")] - pub fn fdset(&self, - read: Option<&mut fd_set>, - write: Option<&mut fd_set>, - except: Option<&mut fd_set>) -> Result, MultiError> { + pub fn fdset( + &self, + read: Option<&mut fd_set>, + write: Option<&mut fd_set>, + except: Option<&mut fd_set>, + ) -> Result, MultiError> { unsafe { let mut ret = 0; let read = read.map(|r| r as *mut _).unwrap_or(0 as *mut _); let write = write.map(|r| r as *mut _).unwrap_or(0 as *mut _); let except = except.map(|r| r as *mut _).unwrap_or(0 as *mut _); - try!(cvt(curl_sys::curl_multi_fdset(self.raw, - read as *mut _, - write as *mut _, - except as *mut _, - &mut ret))); + try!(cvt(curl_sys::curl_multi_fdset( + self.raw, + read as *mut _, + write as *mut _, + except as *mut _, + &mut ret + ))); if ret == -1 { Ok(None) } else { @@ -668,9 +701,7 @@ /// individual easy handles in any way - they still need to be closed /// individually. pub fn close(&self) -> Result<(), MultiError> { - unsafe { - cvt(curl_sys::curl_multi_cleanup(self.raw)) - } + unsafe { cvt(curl_sys::curl_multi_cleanup(self.raw)) } } } @@ -684,9 +715,7 @@ impl fmt::Debug for Multi { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Multi") - .field("raw", &self.raw) - .finish() + f.debug_struct("Multi").field("raw", &self.raw).finish() } } @@ -703,9 +732,11 @@ /// easy handle. pub fn set_token(&mut self, token: usize) -> Result<(), Error> { unsafe { - ::cvt(curl_sys::curl_easy_setopt(self.easy.raw(), - curl_sys::CURLOPT_PRIVATE, - token)) + ::cvt(curl_sys::curl_easy_setopt( + self.easy.raw(), + curl_sys::CURLOPT_PRIVATE, + token, + )) } } @@ -758,9 +789,11 @@ /// Same as `EasyHandle::set_token` pub fn set_token(&mut self, token: usize) -> Result<(), Error> { unsafe { - ::cvt(curl_sys::curl_easy_setopt(self.easy.raw(), - curl_sys::CURLOPT_PRIVATE, - token)) + ::cvt(curl_sys::curl_easy_setopt( + self.easy.raw(), + curl_sys::CURLOPT_PRIVATE, + token, + )) } } @@ -826,7 +859,7 @@ /// returned error. pub fn result_for(&self, handle: &EasyHandle) -> Option> { if !self.is_for(handle) { - return None + return None; } let mut err = self.result(); if let Some(Err(e)) = &mut err { @@ -834,7 +867,7 @@ e.set_extra(s); } } - return err + return err; } /// Same as `result`, except only returns `Some` for the specified handle. @@ -844,7 +877,7 @@ /// returned error. pub fn result_for2(&self, handle: &Easy2Handle) -> Option> { if !self.is_for2(handle) { - return None + return None; } let mut err = self.result(); if let Some(Err(e)) = &mut err { @@ -852,7 +885,7 @@ e.set_extra(s); } } - return err + return err; } /// Returns whether this easy message was for the specified easy handle or @@ -875,9 +908,11 @@ pub fn token(&self) -> Result { unsafe { let mut p = 0usize; - try!(::cvt(curl_sys::curl_easy_getinfo((*self.ptr).easy_handle, - curl_sys::CURLINFO_PRIVATE, - &mut p))); + try!(::cvt(curl_sys::curl_easy_getinfo( + (*self.ptr).easy_handle, + curl_sys::CURLINFO_PRIVATE, + &mut p + ))); Ok(p) } } @@ -885,9 +920,7 @@ impl<'a> fmt::Debug for Message<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Message") - .field("ptr", &self.ptr) - .finish() + f.debug_struct("Message").field("ptr", &self.ptr).finish() } } @@ -926,10 +959,10 @@ impl fmt::Debug for Events { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Events") - .field("input", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .field("output", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .field("error", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) - .finish() + .field("input", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) + .field("output", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) + .field("error", &(self.bits & curl_sys::CURL_CSELECT_IN != 0)) + .finish() } } @@ -959,10 +992,10 @@ impl fmt::Debug for SocketEvents { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Events") - .field("input", &self.input()) - .field("output", &self.output()) - .field("remove", &self.remove()) - .finish() + .field("input", &self.input()) + .field("output", &self.output()) + .field("remove", &self.remove()) + .finish() } } @@ -974,7 +1007,7 @@ fd: 0, events: 0, revents: 0, - } + }, } } @@ -1053,7 +1086,7 @@ fd: pfd.fd, events: events, revents: 0, - } + }, } } } @@ -1061,9 +1094,9 @@ impl fmt::Debug for WaitFd { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("WaitFd") - .field("fd", &self.inner.fd) - .field("events", &self.inner.fd) - .field("revents", &self.inner.fd) - .finish() + .field("fd", &self.inner.fd) + .field("events", &self.inner.fd) + .field("revents", &self.inner.fd) + .finish() } } diff -Nru cargo-0.33.0/vendor/curl/src/panic.rs cargo-0.35.0/vendor/curl/src/panic.rs --- cargo-0.33.0/vendor/curl/src/panic.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/panic.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,7 +7,7 @@ }); pub fn catch T>(f: F) -> Option { - match LAST_ERROR.try_with(|slot| slot.borrow().is_some()) { + match LAST_ERROR.try_with(|slot| slot.borrow().is_some()) { Ok(true) => return None, Ok(false) => {} // we're in thread shutdown, so we're for sure not panicking and diff -Nru cargo-0.33.0/vendor/curl/src/version.rs cargo-0.35.0/vendor/curl/src/version.rs --- cargo-0.33.0/vendor/curl/src/version.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/src/version.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ use std::str; use curl_sys; -use libc::{c_int, c_char}; +use libc::{c_char, c_int}; /// Version information about libcurl and the capabilities that it supports. pub struct Version { @@ -40,9 +40,7 @@ /// Returns the human readable version string, pub fn version(&self) -> &str { - unsafe { - ::opt_str((*self.inner).version).unwrap() - } + unsafe { ::opt_str((*self.inner).version).unwrap() } } /// Returns a numeric representation of the version number @@ -50,18 +48,14 @@ /// This is a 24 bit number made up of the major number, minor, and then /// patch number. For example 7.9.8 will return 0x070908. pub fn version_num(&self) -> u32 { - unsafe { - (*self.inner).version_num as u32 - } + unsafe { (*self.inner).version_num as u32 } } /// Returns a human readable string of the host libcurl is built for. /// /// This is discovered as part of the build environment. pub fn host(&self) -> &str { - unsafe { - ::opt_str((*self.inner).host).unwrap() - } + unsafe { ::opt_str((*self.inner).host).unwrap() } } /// Returns whether libcurl supports IPv6 @@ -148,32 +142,29 @@ } fn flag(&self, flag: c_int) -> bool { - unsafe { - (*self.inner).features & flag != 0 - } + unsafe { (*self.inner).features & flag != 0 } } /// Returns the version of OpenSSL that is used, or None if there is no SSL /// support. pub fn ssl_version(&self) -> Option<&str> { - unsafe { - ::opt_str((*self.inner).ssl_version) - } + unsafe { ::opt_str((*self.inner).ssl_version) } } /// Returns the version of libz that is used, or None if there is no libz /// support. pub fn libz_version(&self) -> Option<&str> { - unsafe { - ::opt_str((*self.inner).libz_version) - } + unsafe { ::opt_str((*self.inner).libz_version) } } /// Returns an iterator over the list of protocols that this build of /// libcurl supports. pub fn protocols(&self) -> Protocols { unsafe { - Protocols { _inner: self, cur: (*self.inner).protocols } + Protocols { + _inner: self, + cur: (*self.inner).protocols, + } } } @@ -222,7 +213,7 @@ } } - /// If available, the version of iconv libcurl is linked against. + /// If available, the version of libssh that libcurl is linked against. pub fn libssh_version(&self) -> Option<&str> { unsafe { if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH { @@ -260,22 +251,22 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut f = f.debug_struct("Version"); f.field("version", &self.version()) - .field("host", &self.host()) - .field("feature_ipv6", &self.feature_ipv6()) - .field("feature_ssl", &self.feature_ssl()) - .field("feature_libz", &self.feature_libz()) - .field("feature_ntlm", &self.feature_ntlm()) - .field("feature_gss_negotiate", &self.feature_gss_negotiate()) - .field("feature_debug", &self.feature_debug()) - .field("feature_spnego", &self.feature_debug()) - .field("feature_largefile", &self.feature_debug()) - .field("feature_idn", &self.feature_debug()) - .field("feature_sspi", &self.feature_debug()) - .field("feature_async_dns", &self.feature_debug()) - .field("feature_conv", &self.feature_debug()) - .field("feature_tlsauth_srp", &self.feature_debug()) - .field("feature_ntlm_wb", &self.feature_debug()) - .field("feature_unix_domain_socket", &self.feature_debug()); + .field("host", &self.host()) + .field("feature_ipv6", &self.feature_ipv6()) + .field("feature_ssl", &self.feature_ssl()) + .field("feature_libz", &self.feature_libz()) + .field("feature_ntlm", &self.feature_ntlm()) + .field("feature_gss_negotiate", &self.feature_gss_negotiate()) + .field("feature_debug", &self.feature_debug()) + .field("feature_spnego", &self.feature_debug()) + .field("feature_largefile", &self.feature_debug()) + .field("feature_idn", &self.feature_debug()) + .field("feature_sspi", &self.feature_debug()) + .field("feature_async_dns", &self.feature_debug()) + .field("feature_conv", &self.feature_debug()) + .field("feature_tlsauth_srp", &self.feature_debug()) + .field("feature_ntlm_wb", &self.feature_debug()) + .field("feature_unix_domain_socket", &self.feature_debug()); if let Some(s) = self.ssl_version() { f.field("ssl_version", &s); @@ -308,7 +299,7 @@ fn next(&mut self) -> Option<&'a str> { unsafe { if (*self.cur).is_null() { - return None + return None; } let ret = ::opt_str(*self.cur).unwrap(); self.cur = self.cur.offset(1); @@ -319,8 +310,6 @@ impl<'a> fmt::Debug for Protocols<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list() - .entries(self.clone()) - .finish() + f.debug_list().entries(self.clone()).finish() } } diff -Nru cargo-0.33.0/vendor/curl/tests/atexit.rs cargo-0.35.0/vendor/curl/tests/atexit.rs --- cargo-0.33.0/vendor/curl/tests/atexit.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/tests/atexit.rs 2019-05-15 11:26:24.000000000 +0000 @@ -6,15 +6,15 @@ pub extern "C" fn hook() { let mut easy = Easy::new(); easy.url("google.com").unwrap(); - easy.write_function(|data| { - Ok(data.len()) - }).unwrap(); + easy.write_function(|data| Ok(data.len())).unwrap(); easy.perform().unwrap(); } fn main() { curl::init(); hook(); - unsafe { libc::atexit(hook); } + unsafe { + libc::atexit(hook); + } println!("Finishing...") } diff -Nru cargo-0.33.0/vendor/curl/tests/easy.rs cargo-0.35.0/vendor/curl/tests/easy.rs --- cargo-0.33.0/vendor/curl/tests/easy.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/tests/easy.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,19 +1,21 @@ extern crate curl; -use std::cell::{RefCell, Cell}; +use std::cell::{Cell, RefCell}; use std::io::Read; use std::rc::Rc; use std::str; use std::time::Duration; macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - }) + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {:?}", stringify!($e), e), + } + }; } -use curl::easy::{Easy, List, WriteError, ReadError, Transfer}; +use curl::easy::{Easy, List, ReadError, Transfer, WriteError}; use server::Server; mod server; @@ -21,7 +23,7 @@ fn handle() -> Easy { let mut e = Easy::new(); t!(e.timeout(Duration::new(20, 0))); - return e + return e; } fn sink(data: &[u8]) -> Result { @@ -31,11 +33,13 @@ #[test] fn get_smoke() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut handle = handle(); @@ -46,11 +50,13 @@ #[test] fn get_path() { let s = Server::new(); - s.receive("\ -GET /foo HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET /foo HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut handle = handle(); @@ -61,11 +67,13 @@ #[test] fn write_callback() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\nhello!"); let mut all = Vec::::new(); @@ -85,11 +93,13 @@ #[test] fn resolve() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: example.com:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: example.com:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut list = List::new(); @@ -103,11 +113,13 @@ #[test] fn progress() { let s = Server::new(); - s.receive("\ -GET /foo HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET /foo HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\nHello!"); let mut hits = 0; @@ -133,17 +145,21 @@ #[test] fn headers() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ HTTP/1.1 200 OK\r\n\ Foo: bar\r\n\ Bar: baz\r\n\ \r\n -Hello!"); +Hello!", + ); let mut headers = Vec::new(); { @@ -158,25 +174,32 @@ t!(handle.write_function(sink)); t!(handle.perform()); } - assert_eq!(headers, vec![ - "HTTP/1.1 200 OK\r\n".to_string(), - "Foo: bar\r\n".to_string(), - "Bar: baz\r\n".to_string(), - "\r\n".to_string(), - ]); + assert_eq!( + headers, + vec![ + "HTTP/1.1 200 OK\r\n".to_string(), + "Foo: bar\r\n".to_string(), + "Bar: baz\r\n".to_string(), + "\r\n".to_string(), + ] + ); } #[test] fn fail_on_error() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 401 Not so good\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 401 Not so good\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -184,14 +207,18 @@ assert!(h.perform().is_err()); let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 401 Not so good\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 401 Not so good\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -202,14 +229,18 @@ #[test] fn port() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: localhost:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: localhost:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url("http://localhost/")); @@ -220,14 +251,18 @@ #[test] fn proxy() { let s = Server::new(); - s.receive("\ -GET http://example.com/ HTTP/1.1\r\n\ -Host: example.com\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET http://example.com/ HTTP/1.1\r\n\ + Host: example.com\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url("http://example.com/")); @@ -239,14 +274,18 @@ #[ignore] // fails on newer curl versions? seems benign fn noproxy() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -267,17 +306,32 @@ } #[test] +fn dns_servers() { + let mut h = handle(); + // Tests are not using a libcurl with c-ares, so this + // always fails. Test anyway to make sure it returns + // an error instead of panicing. + assert!(h.dns_servers("").is_err()); + assert!(h.dns_servers("nonsense").is_err()); + assert!(h.dns_servers("8.8.8.8,8.8.4.4").is_err()); +} + +#[test] fn userpass() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Authorization: Basic YmFyOg==\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Authorization: Basic YmFyOg==\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -289,15 +343,19 @@ #[test] fn accept_encoding() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Accept-Encoding: gzip\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Accept-Encoding: gzip\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -309,24 +367,33 @@ fn follow_location() { let s1 = Server::new(); let s2 = Server::new(); - s1.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s1.send(&format!("\ -HTTP/1.1 301 Moved Permanently\r\n\ -Location: http://{}/foo\r\n\ -\r\n", s2.addr())); - - s2.receive("\ -GET /foo HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s2.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s1.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s1.send(&format!( + "\ + HTTP/1.1 301 Moved Permanently\r\n\ + Location: http://{}/foo\r\n\ + \r\n", + s2.addr() + )); + + s2.receive( + "\ + GET /foo HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s2.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s1.url("/"))); @@ -337,16 +404,20 @@ #[test] fn put() { let s = Server::new(); - s.receive("\ -PUT / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 5\r\n\ -\r\n\ -data\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + PUT / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 5\r\n\ + \r\n\ + data\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut data = "data\n".as_bytes(); let mut list = List::new(); @@ -358,26 +429,28 @@ t!(h.upload(true)); t!(h.http_headers(list)); let mut h = h.transfer(); - t!(h.read_function(|buf| { - Ok(data.read(buf).unwrap()) - })); + t!(h.read_function(|buf| Ok(data.read(buf).unwrap()))); t!(h.perform()); } #[test] fn post1() { let s = Server::new(); - s.receive("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 5\r\n\ -Content-Type: application/x-www-form-urlencoded\r\n\ -\r\n\ -data\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 5\r\n\ + Content-Type: application/x-www-form-urlencoded\r\n\ + \r\n\ + data\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -389,17 +462,21 @@ #[test] fn post2() { let s = Server::new(); - s.receive("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 5\r\n\ -Content-Type: application/x-www-form-urlencoded\r\n\ -\r\n\ -data\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 5\r\n\ + Content-Type: application/x-www-form-urlencoded\r\n\ + \r\n\ + data\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -412,17 +489,21 @@ #[test] fn post3() { let s = Server::new(); - s.receive("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 5\r\n\ -Content-Type: application/x-www-form-urlencoded\r\n\ -\r\n\ -data\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 5\r\n\ + Content-Type: application/x-www-form-urlencoded\r\n\ + \r\n\ + data\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut data = "data\n".as_bytes(); let mut h = handle(); @@ -430,24 +511,26 @@ t!(h.post(true)); t!(h.post_field_size(5)); let mut h = h.transfer(); - t!(h.read_function(|buf| { - Ok(data.read(buf).unwrap()) - })); + t!(h.read_function(|buf| Ok(data.read(buf).unwrap()))); t!(h.perform()); } #[test] fn referer() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Referer: foo\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Referer: foo\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -458,15 +541,19 @@ #[test] fn useragent() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -User-Agent: foo\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + User-Agent: foo\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -477,14 +564,18 @@ #[test] fn custom_headers() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Foo: bar\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Foo: bar\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut custom = List::new(); t!(custom.append("Foo: bar")); @@ -498,15 +589,19 @@ #[test] fn cookie() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Cookie: foo\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Cookie: foo\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -532,14 +627,18 @@ #[test] fn getters() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -564,14 +663,18 @@ #[should_panic] fn panic_in_callback() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -582,15 +685,19 @@ #[test] fn abort_read() { let s = Server::new(); - s.receive("\ -PUT / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 2\r\n\ -\r\n"); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive( + "\ + PUT / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 2\r\n\ + \r\n", + ); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -607,16 +714,20 @@ #[test] fn pause_write_then_resume() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ HTTP/1.1 200 OK\r\n\ \r\n a\n -b"); +b", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -635,40 +746,46 @@ }); let h2 = h.clone(); - t!(h.transfer.borrow_mut().write_function(move |data| { - if h2.unpaused.get() { + t!(h.transfer + .borrow_mut() + .write_function(move |data| if h2.unpaused.get() { h2.unpaused.set(false); Ok(data.len()) } else { h2.paused.set(true); Err(WriteError::Pause) - } - })); + })); let h2 = h.clone(); - t!(h.transfer.borrow_mut().progress_function(move |_, _, _, _| { - if h2.paused.get() { - h2.paused.set(false); - h2.unpaused.set(true); - t!(h2.transfer.borrow().unpause_write()); - } - true - })); + t!(h.transfer + .borrow_mut() + .progress_function(move |_, _, _, _| { + if h2.paused.get() { + h2.paused.set(false); + h2.unpaused.set(true); + t!(h2.transfer.borrow().unpause_write()); + } + true + })); t!(h.transfer.borrow().perform()); } #[test] fn perform_in_perform_is_bad() { let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); - s.send("\ + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); + s.send( + "\ HTTP/1.1 200 OK\r\n\ \r\n a\n -b"); +b", + ); let mut h = handle(); t!(h.url(&s.url("/"))); @@ -690,4 +807,3 @@ let mut h = handle(); h.unix_socket("/var/something.socks").is_ok(); } - diff -Nru cargo-0.33.0/vendor/curl/tests/multi.rs cargo-0.35.0/vendor/curl/tests/multi.rs --- cargo-0.33.0/vendor/curl/tests/multi.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/tests/multi.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,17 +5,19 @@ extern crate mio_extras; use std::collections::HashMap; -use std::io::{Read, Cursor}; +use std::io::{Cursor, Read}; use std::time::Duration; use curl::easy::{Easy, List}; use curl::multi::Multi; macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - }) + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {:?}", stringify!($e), e), + } + }; } use server::Server; @@ -27,11 +29,13 @@ let mut e = Easy::new(); let s = Server::new(); - s.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); t!(e.url(&s.url("/"))); @@ -46,19 +50,23 @@ let m = Multi::new(); let s1 = Server::new(); - s1.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s1.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s1.send("HTTP/1.1 200 OK\r\n\r\n"); let s2 = Server::new(); - s2.receive("\ -GET / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -\r\n"); + s2.receive( + "\ + GET / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + \r\n", + ); s2.send("HTTP/1.1 200 OK\r\n\r\n"); let mut e1 = Easy::new(); @@ -82,7 +90,7 @@ #[test] fn upload_lots() { - use curl::multi::{Socket, SocketEvents, Events}; + use curl::multi::{Events, Socket, SocketEvents}; #[derive(Debug)] enum Message { @@ -103,16 +111,21 @@ })); let s = Server::new(); - s.receive(&format!("\ -PUT / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 131072\r\n\ -\r\n\ -{}\n", vec!["a"; 128 * 1024 - 1].join(""))); - s.send("\ -HTTP/1.1 200 OK\r\n\ -\r\n"); + s.receive(&format!( + "\ + PUT / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 131072\r\n\ + \r\n\ + {}\n", + vec!["a"; 128 * 1024 - 1].join("") + )); + s.send( + "\ + HTTP/1.1 200 OK\r\n\ + \r\n", + ); let mut data = vec![b'a'; 128 * 1024 - 1]; data.push(b'\n'); @@ -122,17 +135,12 @@ let mut h = Easy::new(); t!(h.url(&s.url("/"))); t!(h.put(true)); - t!(h.read_function(move |buf| { - Ok(data.read(buf).unwrap()) - })); + t!(h.read_function(move |buf| Ok(data.read(buf).unwrap()))); t!(h.in_filesize(128 * 1024)); t!(h.upload(true)); t!(h.http_headers(list)); - t!(poll.register(&rx, - mio::Token(0), - mio::Ready::all(), - mio::PollOpt::level())); + t!(poll.register(&rx, mio::Token(0), mio::Ready::all(), mio::PollOpt::level())); let e = t!(m.add(h)); @@ -173,15 +181,19 @@ next_token += 1; t!(m.assign(socket, token)); token_map.insert(token, socket); - t!(poll.register(&evented, - mio::Token(token), - e, - mio::PollOpt::level())); + t!(poll.register( + &evented, + mio::Token(token), + e, + mio::PollOpt::level() + )); } else { - t!(poll.reregister(&evented, - mio::Token(token), - e, - mio::PollOpt::level())); + t!(poll.reregister( + &evented, + mio::Token(token), + e, + mio::PollOpt::level() + )); } } } @@ -190,7 +202,7 @@ } if event.token() == mio::Token(0) { - continue + continue; } let token = event.token(); @@ -229,20 +241,24 @@ #[cfg(target_os = "linux")] #[test] fn waitfds() { + use curl::multi::WaitFd; use std::fs::File; use std::os::unix::io::AsRawFd; - use curl::multi::WaitFd; let filenames = ["/dev/null", "/dev/zero", "/dev/urandom"]; - let files: Vec = filenames.iter() + let files: Vec = filenames + .iter() .map(|filename| File::open(filename).unwrap()) .collect(); - let mut waitfds: Vec = files.iter().map(|f| { - let mut waitfd = WaitFd::new(); - waitfd.set_fd(f.as_raw_fd()); - waitfd.poll_on_read(true); - waitfd - }).collect(); + let mut waitfds: Vec = files + .iter() + .map(|f| { + let mut waitfd = WaitFd::new(); + waitfd.set_fd(f.as_raw_fd()); + waitfd.poll_on_read(true); + waitfd + }) + .collect(); let m = Multi::new(); let events = t!(m.wait(&mut waitfds, Duration::from_secs(1))); diff -Nru cargo-0.33.0/vendor/curl/tests/post.rs cargo-0.35.0/vendor/curl/tests/post.rs --- cargo-0.33.0/vendor/curl/tests/post.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/tests/post.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,13 +3,15 @@ use std::time::Duration; macro_rules! t { - ($e:expr) => (match $e { - Ok(e) => e, - Err(e) => panic!("{} failed with {:?}", stringify!($e), e), - }) + ($e:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {:?}", stringify!($e), e), + } + }; } -use curl::easy::{Easy, List, Form}; +use curl::easy::{Easy, Form, List}; use server::Server; mod server; @@ -20,24 +22,26 @@ let mut list = List::new(); t!(list.append("Expect:")); t!(e.http_headers(list)); - return e + return e; } #[test] fn custom() { let s = Server::new(); - s.receive("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 142\r\n\ -Content-Type: multipart/form-data; boundary=--[..]\r\n\ -\r\n\ ---[..]\r\n\ -Content-Disposition: form-data; name=\"foo\"\r\n\ -\r\n\ -1234\r\n\ ---[..]\r\n"); + s.receive( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 142\r\n\ + Content-Type: multipart/form-data; boundary=--[..]\r\n\ + \r\n\ + --[..]\r\n\ + Content-Disposition: form-data; name=\"foo\"\r\n\ + \r\n\ + 1234\r\n\ + --[..]\r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut handle = handle(); @@ -51,27 +55,30 @@ #[test] fn buffer() { let s = Server::new(); - s.receive("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: 181\r\n\ -Content-Type: multipart/form-data; boundary=--[..]\r\n\ -\r\n\ ---[..]\r\n\ -Content-Disposition: form-data; name=\"foo\"; filename=\"bar\"\r\n\ -Content-Type: foo/bar\r\n\ -\r\n\ -1234\r\n\ ---[..]\r\n"); + s.receive( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: 181\r\n\ + Content-Type: multipart/form-data; boundary=--[..]\r\n\ + \r\n\ + --[..]\r\n\ + Content-Disposition: form-data; name=\"foo\"; filename=\"bar\"\r\n\ + Content-Type: foo/bar\r\n\ + \r\n\ + 1234\r\n\ + --[..]\r\n", + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut handle = handle(); let mut form = Form::new(); - t!(form.part("foo") - .buffer("bar", b"1234".to_vec()) - .content_type("foo/bar") - .add()); + t!(form + .part("foo") + .buffer("bar", b"1234".to_vec()) + .content_type("foo/bar") + .add()); t!(handle.url(&s.url("/"))); t!(handle.httppost(form)); t!(handle.perform()); @@ -81,27 +88,32 @@ fn file() { let s = Server::new(); let formdata = include_str!("formdata"); - s.receive(format!("\ -POST / HTTP/1.1\r\n\ -Host: 127.0.0.1:$PORT\r\n\ -Accept: */*\r\n\ -Content-Length: {}\r\n\ -Content-Type: multipart/form-data; boundary=--[..]\r\n\ -\r\n\ ---[..]\r\n\ -Content-Disposition: form-data; name=\"foo\"; filename=\"formdata\"\r\n\ -Content-Type: application/octet-stream\r\n\ -\r\n\ -{}\ -\r\n\ ---[..]\r\n", 199 + formdata.len(), formdata).as_str()); + s.receive( + format!( + "\ + POST / HTTP/1.1\r\n\ + Host: 127.0.0.1:$PORT\r\n\ + Accept: */*\r\n\ + Content-Length: {}\r\n\ + Content-Type: multipart/form-data; boundary=--[..]\r\n\ + \r\n\ + --[..]\r\n\ + Content-Disposition: form-data; name=\"foo\"; filename=\"formdata\"\r\n\ + Content-Type: application/octet-stream\r\n\ + \r\n\ + {}\ + \r\n\ + --[..]\r\n", + 199 + formdata.len(), + formdata + ) + .as_str(), + ); s.send("HTTP/1.1 200 OK\r\n\r\n"); let mut handle = handle(); let mut form = Form::new(); - t!(form.part("foo") - .file("tests/formdata") - .add()); + t!(form.part("foo").file("tests/formdata").add()); t!(handle.url(&s.url("/"))); t!(handle.httppost(form)); t!(handle.perform()); diff -Nru cargo-0.33.0/vendor/curl/tests/server/mod.rs cargo-0.35.0/vendor/curl/tests/server/mod.rs --- cargo-0.33.0/vendor/curl/tests/server/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl/tests/server/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,11 @@ #![allow(dead_code)] use std::collections::HashSet; -use std::net::{TcpListener, SocketAddr, TcpStream}; use std::io::prelude::*; -use std::thread; -use std::sync::mpsc::{Sender, Receiver, channel}; use std::io::BufReader; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread; pub struct Server { messages: Option>, @@ -30,7 +30,7 @@ expected = &expected[i + 1..]; expected_headers.insert(line); if line == "\r\n" { - break + break; } } @@ -44,25 +44,27 @@ } // various versions of libcurl do different things here if actual == "Proxy-Connection: Keep-Alive\r\n" { - continue + continue; } if expected_headers.remove(&actual[..]) { - continue + continue; } let mut found = None; for header in expected_headers.iter() { if lines_match(header, &actual) { found = Some(header.clone()); - break + break; } } if let Some(found) = found { expected_headers.remove(&found); - continue + continue; } - panic!("unexpected header: {:?} (remaining headers {:?})", - actual, expected_headers); + panic!( + "unexpected header: {:?} (remaining headers {:?})", + actual, expected_headers + ); } for header in expected_headers { panic!("expected header but not found: {:?}", header); @@ -77,7 +79,7 @@ line.truncate(0); t!(socket.read_line(&mut line)); if line.len() == 0 { - break + break; } if expected.len() == 0 { panic!("unexpected line: {:?}", line); @@ -86,11 +88,14 @@ let expected_line = &expected[..i + 1]; expected = &expected[i + 1..]; if lines_match(expected_line, &line) { - continue + continue; } - panic!("lines didn't match:\n\ - expected: {:?}\n\ - actual: {:?}\n", expected_line, line) + panic!( + "lines didn't match:\n\ + expected: {:?}\n\ + actual: {:?}\n", + expected_line, line + ) } if expected.len() != 0 { println!("didn't get expected data: {:?}", expected); @@ -98,7 +103,7 @@ } Message::Write(ref to_write) => { t!(socket.get_mut().write_all(to_write.as_bytes())); - return + return; } } } @@ -113,13 +118,11 @@ match actual.find(part) { Some(j) => { if i == 0 && j != 0 { - return false + return false; } actual = &actual[j + part.len()..]; } - None => { - return false - } + None => return false, } } actual.is_empty() || expected.ends_with("[..]") diff -Nru cargo-0.33.0/vendor/curl-sys/build.rs cargo-0.35.0/vendor/curl-sys/build.rs --- cargo-0.33.0/vendor/curl-sys/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl-sys/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,11 @@ +extern crate cc; extern crate pkg_config; #[cfg(target_env = "msvc")] extern crate vcpkg; -extern crate cc; use std::env; use std::fs; -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; use std::process::Command; fn main() { @@ -32,18 +32,19 @@ // Next, fall back and try to use pkg-config if its available. if windows { if try_vcpkg() { - return + return; } } else { if try_pkg_config() { - return + return; } } } if !Path::new("curl/.git").exists() { - let _ = Command::new("git").args(&["submodule", "update", "--init"]) - .status(); + let _ = Command::new("git") + .args(&["submodule", "update", "--init"]) + .status(); } let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -54,14 +55,30 @@ println!("cargo:static=1"); fs::create_dir_all(include.join("curl")).unwrap(); fs::copy("curl/include/curl/curl.h", include.join("curl/curl.h")).unwrap(); - fs::copy("curl/include/curl/curlver.h", include.join("curl/curlver.h")).unwrap(); + fs::copy( + "curl/include/curl/curlver.h", + include.join("curl/curlver.h"), + ) + .unwrap(); fs::copy("curl/include/curl/easy.h", include.join("curl/easy.h")).unwrap(); - fs::copy("curl/include/curl/mprintf.h", include.join("curl/mprintf.h")).unwrap(); + fs::copy( + "curl/include/curl/mprintf.h", + include.join("curl/mprintf.h"), + ) + .unwrap(); fs::copy("curl/include/curl/multi.h", include.join("curl/multi.h")).unwrap(); - fs::copy("curl/include/curl/stdcheaders.h", include.join("curl/stdcheaders.h")).unwrap(); + fs::copy( + "curl/include/curl/stdcheaders.h", + include.join("curl/stdcheaders.h"), + ) + .unwrap(); fs::copy("curl/include/curl/system.h", include.join("curl/system.h")).unwrap(); fs::copy("curl/include/curl/urlapi.h", include.join("curl/urlapi.h")).unwrap(); - fs::copy("curl/include/curl/typecheck-gcc.h", include.join("curl/typecheck-gcc.h")).unwrap(); + fs::copy( + "curl/include/curl/typecheck-gcc.h", + include.join("curl/typecheck-gcc.h"), + ) + .unwrap(); let pkgconfig = dst.join("lib/pkgconfig"); fs::create_dir_all(&pkgconfig).unwrap(); @@ -78,7 +95,8 @@ .replace("@SUPPORT_FEATURES@", "") .replace("@SUPPORT_PROTOCOLS@", "") .replace("@CURLVERSION@", "7.61.1"), - ).unwrap(); + ) + .unwrap(); let mut cfg = cc::Build::new(); cfg.out_dir(&build) @@ -105,7 +123,6 @@ .define("OS", "\"unknown\"") // TODO .define("HAVE_ZLIB_H", None) .define("HAVE_LIBZ", None) - .file("curl/lib/asyn-thread.c") .file("curl/lib/base64.c") .file("curl/lib/conncache.c") @@ -169,21 +186,21 @@ .file("curl/lib/vtls/vtls.c") .file("curl/lib/warnless.c") .file("curl/lib/wildcard.c") - .define("HAVE_GETADDRINFO", None) - .warnings(false); if cfg!(feature = "http2") { cfg.define("USE_NGHTTP2", None) .define("NGHTTP2_STATICLIB", None); + println!("cargo:rustc-cfg=link_libnghttp2"); if let Some(path) = env::var_os("DEP_NGHTTP2_ROOT") { let path = PathBuf::from(path); cfg.include(path.join("include")); } } + println!("cargo:rustc-cfg=link_libz"); if let Some(path) = env::var_os("DEP_Z_INCLUDE") { cfg.include(path); } @@ -250,8 +267,8 @@ if cfg!(feature = "ssl") { if target.contains("-apple-") { - cfg.define("USE_DARWINSSL", None) - .file("curl/lib/vtls/darwinssl.c"); + cfg.define("USE_SECTRANSP", None) + .file("curl/lib/vtls/sectransp.c"); if xcode_major_version().map_or(true, |v| v >= 9) { // On earlier Xcode versions (<9), defining HAVE_BUILTIN_AVAILABLE // would cause __bultin_available() to fail to compile due to @@ -263,6 +280,7 @@ cfg.define("USE_OPENSSL", None) .file("curl/lib/vtls/openssl.c"); + println!("cargo:rustc-cfg=link_openssl"); if let Some(path) = env::var_os("DEP_OPENSSL_INCLUDE") { cfg.include(path); } @@ -316,21 +334,25 @@ #[cfg(target_env = "msvc")] fn try_vcpkg() -> bool { - // the import library for the dll is called libcurl_imp - let mut successful_probe_details = - match vcpkg::Config::new().lib_names("libcurl_imp", "libcurl") - .emit_includes(true).probe("curl") { - Ok(details) => Some(details), - Err(e) => { - println!("first run of vcpkg did not find libcurl: {}", e); - None - } - }; + let mut successful_probe_details = match vcpkg::Config::new() + .lib_names("libcurl_imp", "libcurl") + .emit_includes(true) + .probe("curl") + { + Ok(details) => Some(details), + Err(e) => { + println!("first run of vcpkg did not find libcurl: {}", e); + None + } + }; if successful_probe_details.is_none() { - match vcpkg::Config::new().lib_name("libcurl") - .emit_includes(true).probe("curl") { + match vcpkg::Config::new() + .lib_name("libcurl") + .emit_includes(true) + .probe("curl") + { Ok(details) => successful_probe_details = Some(details), Err(e) => println!("second run of vcpkg did not find libcurl: {}", e), } @@ -344,13 +366,15 @@ vcpkg::Config::new() .lib_name("libeay32") .lib_name("ssleay32") - .probe("openssl").ok(); + .probe("openssl") + .ok(); vcpkg::probe_package("libssh2").ok(); vcpkg::Config::new() .lib_names("zlib", "zlib1") - .probe("zlib").ok(); + .probe("zlib") + .ok(); println!("cargo:rustc-link-lib=crypt32"); println!("cargo:rustc-link-lib=gdi32"); @@ -367,40 +391,39 @@ let lib = match cfg.probe("libcurl") { Ok(lib) => lib, Err(e) => { - println!("Couldn't find libcurl from pkgconfig ({:?}), \ - compiling it from source...", e); - return false + println!( + "Couldn't find libcurl from pkgconfig ({:?}), \ + compiling it from source...", + e + ); + return false; } }; // Not all system builds of libcurl have http2 features enabled, so if we've // got a http2-requested build then we may fall back to a build from source. if cfg!(feature = "http2") && !curl_config_reports_http2() { - return false + return false; } // Re-find the library to print cargo's metadata, then print some extra // metadata as well. - cfg.cargo_metadata(true) - .probe("libcurl") - .unwrap(); + cfg.cargo_metadata(true).probe("libcurl").unwrap(); for path in lib.include_paths.iter() { println!("cargo:include={}", path.display()); } - return true + return true; } fn xcode_major_version() -> Option { - let output = Command::new("xcodebuild") - .arg("-version") - .output() - .ok()?; + let output = Command::new("xcodebuild").arg("-version").output().ok()?; if output.status.success() { let stdout = String::from_utf8_lossy(&output.stdout); + println!("xcode version: {}", stdout); let mut words = stdout.split_whitespace(); if words.next()? == "Xcode" { let version = words.next()?; - return version[..version.find('.')?].parse().ok() + return version[..version.find('.')?].parse().ok(); } } println!("unable to determine Xcode version, assuming >= 9"); @@ -408,26 +431,26 @@ } fn curl_config_reports_http2() -> bool { - let output = Command::new("curl-config") - .arg("--features") - .output(); + let output = Command::new("curl-config").arg("--features").output(); let output = match output { Ok(out) => out, Err(e) => { println!("failed to run curl-config ({}), building from source", e); - return false + return false; } }; if !output.status.success() { println!("curl-config failed: {}", output.status); - return false + return false; } let stdout = String::from_utf8_lossy(&output.stdout); if !stdout.contains("HTTP2") { - println!("failed to find http-2 feature enabled in pkg-config-found \ - libcurl, building from source"); - return false + println!( + "failed to find http-2 feature enabled in pkg-config-found \ + libcurl, building from source" + ); + return false; } - return true + return true; } diff -Nru cargo-0.33.0/vendor/curl-sys/.cargo-checksum.json cargo-0.35.0/vendor/curl-sys/.cargo-checksum.json --- cargo-0.33.0/vendor/curl-sys/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl-sys/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"ca79238a79fb294be6173b4057c95b22a718c94c4e38475d5faa82b8383f3502"} \ No newline at end of file +{"files":{},"package":"9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/curl-sys/Cargo.toml cargo-0.35.0/vendor/curl-sys/Cargo.toml --- cargo-0.33.0/vendor/curl-sys/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl-sys/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "curl-sys" -version = "0.4.16" +version = "0.4.18" authors = ["Alex Crichton "] build = "build.rs" links = "curl" diff -Nru cargo-0.33.0/vendor/curl-sys/lib.rs cargo-0.35.0/vendor/curl-sys/lib.rs --- cargo-0.33.0/vendor/curl-sys/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/curl-sys/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,23 +2,24 @@ #![doc(html_root_url = "https://docs.rs/curl-sys/0.3")] extern crate libc; +#[cfg(link_libnghttp2)] +extern crate libnghttp2_sys; +#[cfg(link_libz)] extern crate libz_sys; -#[cfg(all(unix, not(target_os = "macos"), feature = "ssl"))] +#[cfg(link_openssl)] extern crate openssl_sys; #[cfg(windows)] extern crate winapi; -#[cfg(feature = "http2")] -extern crate libnghttp2_sys; -use libc::{c_int, c_char, c_uint, c_short, c_long, c_double, c_void, size_t, time_t}; use libc::c_ulong; +use libc::{c_char, c_double, c_int, c_long, c_short, c_uint, c_void, size_t, time_t}; #[cfg(unix)] pub use libc::fd_set; #[cfg(windows)] -pub use winapi::um::winsock2::fd_set; -#[cfg(windows)] use winapi::shared::ws2def::SOCKADDR; +#[cfg(windows)] +pub use winapi::um::winsock2::fd_set; #[cfg(target_env = "msvc")] #[doc(hidden)] @@ -48,20 +49,20 @@ pub enum curl_httppost { // Note that this changed in some versions of libcurl, so we currently don't - // bind the fields as they're apparently not stable. - // pub next: *mut curl_httppost, - // pub name: *mut c_char, - // pub namelength: c_long, - // pub contents: *mut c_char, - // pub contentslength: c_long, - // pub buffer: *mut c_char, - // pub bufferlength: c_long, - // pub contenttype: *mut c_char, - // pub contentheader: *mut curl_slist, - // pub more: *mut curl_httppost, - // pub flags: c_long, - // pub showfilename: *mut c_char, - // pub userp: *mut c_void, +// bind the fields as they're apparently not stable. +// pub next: *mut curl_httppost, +// pub name: *mut c_char, +// pub namelength: c_long, +// pub contents: *mut c_char, +// pub contentslength: c_long, +// pub buffer: *mut c_char, +// pub bufferlength: c_long, +// pub contenttype: *mut c_char, +// pub contentheader: *mut curl_slist, +// pub more: *mut curl_httppost, +// pub flags: c_long, +// pub showfilename: *mut c_char, +// pub userp: *mut c_void, } // pub const HTTPPOST_FILENAME: c_long = 1 << 0; @@ -72,11 +73,8 @@ // pub const HTTPPOST_PTRBUFFER: c_long = 1 << 5; // pub const HTTPPOST_CALLBACK: c_long = 1 << 6; -pub type curl_progress_callback = extern fn(*mut c_void, - c_double, - c_double, - c_double, - c_double) -> c_int; +pub type curl_progress_callback = + extern "C" fn(*mut c_void, c_double, c_double, c_double, c_double) -> c_int; // pub type curl_xferinfo_callback = extern fn(*mut c_void, // curl_off_t, // curl_off_t, @@ -85,10 +83,7 @@ pub const CURL_WRITEFUNC_PAUSE: size_t = 0x10000001; -pub type curl_write_callback = extern fn(*mut c_char, - size_t, - size_t, - *mut c_void) -> size_t; +pub type curl_write_callback = extern "C" fn(*mut c_char, size_t, size_t, *mut c_void) -> size_t; pub type curlfiletype = __enum_ty; pub const CURLFILETYPE_FILE: curlfiletype = 0; @@ -136,34 +131,25 @@ pub const CURL_CHUNK_BGN_FUNC_OK: c_long = 0; pub const CURL_CHUNK_BGN_FUNC_FAIL: c_long = 1; pub const CURL_CHUNK_BGN_FUNC_SKIP: c_long = 2; -pub type curl_chunk_bgn_callback = extern fn(*const c_void, - *mut c_void, - c_int) -> c_long; +pub type curl_chunk_bgn_callback = extern "C" fn(*const c_void, *mut c_void, c_int) -> c_long; pub const CURL_CHUNK_END_FUNC_OK: c_long = 0; pub const CURL_CHUNK_END_FUNC_FAIL: c_long = 1; -pub type curl_chunk_end_callback = extern fn(*mut c_void) -> c_long; +pub type curl_chunk_end_callback = extern "C" fn(*mut c_void) -> c_long; pub const CURL_FNMATCHFUNC_MATCH: c_int = 0; pub const CURL_FNMATCHFUNC_NOMATCH: c_int = 1; pub const CURL_FNMATCHFUNC_FAIL: c_int = 2; -pub type curl_fnmatch_callback = extern fn(*mut c_void, - *const c_char, - *const c_char) -> c_int; +pub type curl_fnmatch_callback = extern "C" fn(*mut c_void, *const c_char, *const c_char) -> c_int; pub const CURL_SEEKFUNC_OK: c_int = 0; pub const CURL_SEEKFUNC_FAIL: c_int = 1; pub const CURL_SEEKFUNC_CANTSEEK: c_int = 2; -pub type curl_seek_callback = extern fn(*mut c_void, - curl_off_t, - c_int) -> c_int; +pub type curl_seek_callback = extern "C" fn(*mut c_void, curl_off_t, c_int) -> c_int; pub const CURL_READFUNC_ABORT: size_t = 0x10000000; pub const CURL_READFUNC_PAUSE: size_t = 0x10000001; -pub type curl_read_callback = extern fn(*mut c_char, - size_t, - size_t, - *mut c_void) -> size_t; +pub type curl_read_callback = extern "C" fn(*mut c_char, size_t, size_t, *mut c_void) -> size_t; // pub const CURL_SOCKOPT_OK: c_int = 0; // pub const CURL_SOCKOPT_ERROR: c_int = 1; @@ -181,13 +167,13 @@ pub const CURLIOCMD_NOP: curliocmd = 0; pub const CURLIOCMD_RESTARTREAD: curliocmd = 1; -pub type curl_ioctl_callback = extern fn(*mut CURL, c_int, *mut c_void) -> curlioerr; +pub type curl_ioctl_callback = extern "C" fn(*mut CURL, c_int, *mut c_void) -> curlioerr; -pub type curl_malloc_callback = extern fn(size_t) -> *mut c_void; -pub type curl_free_callback = extern fn(*mut c_void); -pub type curl_realloc_callback = extern fn(*mut c_void, size_t) -> *mut c_void; -pub type curl_strdup_callback = extern fn(*const c_char) -> *mut c_char; -pub type curl_calloc_callback = extern fn(size_t, size_t) -> *mut c_void; +pub type curl_malloc_callback = extern "C" fn(size_t) -> *mut c_void; +pub type curl_free_callback = extern "C" fn(*mut c_void); +pub type curl_realloc_callback = extern "C" fn(*mut c_void, size_t) -> *mut c_void; +pub type curl_strdup_callback = extern "C" fn(*const c_char) -> *mut c_char; +pub type curl_calloc_callback = extern "C" fn(size_t, size_t) -> *mut c_void; pub type curl_infotype = __enum_ty; pub const CURLINFO_TEXT: curl_infotype = 0; @@ -198,11 +184,8 @@ pub const CURLINFO_SSL_DATA_IN: curl_infotype = 5; pub const CURLINFO_SSL_DATA_OUT: curl_infotype = 6; -pub type curl_debug_callback = extern fn(*mut CURL, - curl_infotype, - *mut c_char, - size_t, - *mut c_void) -> c_int; +pub type curl_debug_callback = + extern "C" fn(*mut CURL, curl_infotype, *mut c_char, size_t, *mut c_void) -> c_int; pub const CURLE_OK: CURLcode = 0; pub const CURLE_UNSUPPORTED_PROTOCOL: CURLcode = 1; @@ -220,7 +203,7 @@ pub const CURLE_FTP_WEIRD_PASV_REPLY: CURLcode = 13; pub const CURLE_FTP_WEIRD_227_FORMAT: CURLcode = 14; pub const CURLE_FTP_CANT_GET_HOST: CURLcode = 15; -pub const CURLE_OBSOLETE16: CURLcode = 16; +pub const CURLE_HTTP2: CURLcode = 16; pub const CURLE_FTP_COULDNT_SET_TYPE: CURLcode = 17; pub const CURLE_PARTIAL_FILE: CURLcode = 18; pub const CURLE_FTP_COULDNT_RETR_FILE: CURLcode = 19; @@ -251,9 +234,9 @@ pub const CURLE_OBSOLETE44: CURLcode = 44; pub const CURLE_INTERFACE_FAILED: CURLcode = 45; pub const CURLE_OBSOLETE46: CURLcode = 46; -pub const CURLE_TOO_MANY_REDIRECTS : CURLcode = 47; +pub const CURLE_TOO_MANY_REDIRECTS: CURLcode = 47; pub const CURLE_UNKNOWN_OPTION: CURLcode = 48; -pub const CURLE_TELNET_OPTION_SYNTAX : CURLcode = 49; +pub const CURLE_TELNET_OPTION_SYNTAX: CURLcode = 49; pub const CURLE_OBSOLETE50: CURLcode = 50; pub const CURLE_PEER_FAILED_VERIFICATION: CURLcode = 60; pub const CURLE_GOT_NOTHING: CURLcode = 52; @@ -293,12 +276,14 @@ pub const CURLE_RTSP_SESSION_ERROR: CURLcode = 86; pub const CURLE_FTP_BAD_FILE_LIST: CURLcode = 87; pub const CURLE_CHUNK_FAILED: CURLcode = 88; -// pub const CURLE_NO_CONNECTION_AVAILABLE: CURLcode = 89; +pub const CURLE_NO_CONNECTION_AVAILABLE: CURLcode = 89; +pub const CURLE_SSL_PINNEDPUBKEYNOTMATCH: CURLcode = 90; +pub const CURLE_SSL_INVALIDCERTSTATUS: CURLcode = 91; +pub const CURLE_HTTP2_STREAM: CURLcode = 92; +pub const CURLE_RECURSIVE_API_CALL: CURLcode = 93; -pub type curl_conv_callback = extern fn(*mut c_char, size_t) -> CURLcode; -pub type curl_ssl_ctx_callback = extern fn(*mut CURL, - *mut c_void, - *mut c_void) -> CURLcode; +pub type curl_conv_callback = extern "C" fn(*mut c_char, size_t) -> CURLcode; +pub type curl_ssl_ctx_callback = extern "C" fn(*mut CURL, *mut c_void, *mut c_void) -> CURLcode; pub type curl_proxytype = __enum_ty; pub const CURLPROXY_HTTP: curl_proxytype = 0; @@ -310,10 +295,10 @@ pub const CURLAUTH_NONE: c_ulong = 0; pub const CURLAUTH_BASIC: c_ulong = 1 << 0; -pub const CURLAUTH_DIGEST: c_ulong = 1 << 1; +pub const CURLAUTH_DIGEST: c_ulong = 1 << 1; pub const CURLAUTH_GSSNEGOTIATE: c_ulong = 1 << 2; pub const CURLAUTH_NTLM: c_ulong = 1 << 3; -pub const CURLAUTH_DIGEST_IE: c_ulong = 1 << 4; +pub const CURLAUTH_DIGEST_IE: c_ulong = 1 << 4; pub const CURLAUTH_NTLM_WB: c_ulong = 1 << 5; // pub const CURLAUTH_ONLY: c_ulong = 1 << 31; pub const CURLAUTH_ANY: c_ulong = !CURLAUTH_DIGEST_IE; @@ -573,7 +558,7 @@ pub const CURLOPT_CLOSESOCKETFUNCTION: CURLoption = CURLOPTTYPE_FUNCTIONPOINT + 208; pub const CURLOPT_CLOSESOCKETDATA: CURLoption = CURLOPTTYPE_OBJECTPOINT + 209; pub const CURLOPT_GSSAPI_DELEGATION: CURLoption = CURLOPTTYPE_LONG + 210; -// pub const CURLOPT_DNS_SERVERS: CURLoption = CURLOPTTYPE_OBJECTPOINT + 211; +pub const CURLOPT_DNS_SERVERS: CURLoption = CURLOPTTYPE_OBJECTPOINT + 211; // pub const CURLOPT_ACCEPTTIMEOUT_MS: CURLoption = CURLOPTTYPE_LONG + 212; pub const CURLOPT_TCP_KEEPALIVE: CURLoption = CURLOPTTYPE_LONG + 213; pub const CURLOPT_TCP_KEEPIDLE: CURLoption = CURLOPTTYPE_LONG + 214; @@ -621,9 +606,10 @@ pub const CURL_SSLVERSION_TLSv1: CURLoption = 1; pub const CURL_SSLVERSION_SSLv2: CURLoption = 2; pub const CURL_SSLVERSION_SSLv3: CURLoption = 3; -// pub const CURL_SSLVERSION_TLSv1_0: CURLoption = 4; -// pub const CURL_SSLVERSION_TLSv1_1: CURLoption = 5; -// pub const CURL_SSLVERSION_TLSv1_2: CURLoption = 6; +pub const CURL_SSLVERSION_TLSv1_0: CURLoption = 4; +pub const CURL_SSLVERSION_TLSv1_1: CURLoption = 5; +pub const CURL_SSLVERSION_TLSv1_2: CURLoption = 6; +pub const CURL_SSLVERSION_TLSv1_3: CURLoption = 7; pub const CURLOPT_READDATA: CURLoption = CURLOPT_INFILE; pub const CURLOPT_WRITEDATA: CURLoption = CURLOPT_FILE; @@ -672,9 +658,7 @@ pub value: *const c_char, } -pub type curl_formget_callback = extern fn(*mut c_void, - *const c_char, - size_t) -> size_t; +pub type curl_formget_callback = extern "C" fn(*mut c_void, *const c_char, size_t) -> size_t; #[repr(C)] pub struct curl_slist { @@ -785,13 +769,9 @@ pub const CURL_LOCK_ACCESS_SHARED: curl_lock_access = 1; pub const CURL_LOCK_ACCESS_SINGLE: curl_lock_access = 2; -pub type curl_lock_function = extern fn(*mut CURL, - curl_lock_data, - curl_lock_access, - *mut c_void); -pub type curl_unlock_function = extern fn(*mut CURL, - curl_lock_data, - *mut c_void); +pub type curl_lock_function = + extern "C" fn(*mut CURL, curl_lock_data, curl_lock_access, *mut c_void); +pub type curl_unlock_function = extern "C" fn(*mut CURL, curl_lock_data, *mut c_void); pub enum CURLSH {} @@ -907,14 +887,9 @@ pub const CURL_CSELECT_ERR: c_int = 4; pub const CURL_SOCKET_TIMEOUT: curl_socket_t = CURL_SOCKET_BAD; -pub type curl_socket_callback = extern fn(*mut CURL, - curl_socket_t, - c_int, - *mut c_void, - *mut c_void) -> c_int; -pub type curl_multi_timer_callback = extern fn(*mut CURLM, - c_long, - *mut c_void) -> c_int; +pub type curl_socket_callback = + extern "C" fn(*mut CURL, curl_socket_t, c_int, *mut c_void, *mut c_void) -> c_int; +pub type curl_multi_timer_callback = extern "C" fn(*mut CURLM, c_long, *mut c_void) -> c_int; pub type CURLMoption = __enum_ty; pub const CURLMOPT_SOCKETFUNCTION: CURLMoption = CURLOPTTYPE_FUNCTIONPOINT + 1; @@ -938,9 +913,8 @@ pub const CURL_ERROR_SIZE: usize = 256; -pub type curl_opensocket_callback = extern fn(*mut c_void, - curlsocktype, - *mut curl_sockaddr) -> curl_socket_t; +pub type curl_opensocket_callback = + extern "C" fn(*mut c_void, curlsocktype, *mut curl_sockaddr) -> curl_socket_t; pub type curlsocktype = __enum_ty; pub const CURLSOCKTYPE_IPCXN: curlsocktype = 0; pub const CURLSOCKTYPE_ACCEPT: curlsocktype = 1; @@ -958,45 +932,49 @@ pub addr: SOCKADDR, } -extern { - pub fn curl_formadd(httppost: *mut *mut curl_httppost, - last_post: *mut *mut curl_httppost, - ...) -> CURLFORMcode; - pub fn curl_formget(form: *mut curl_httppost, - arg: *mut c_void, - append: curl_formget_callback) -> c_int; +extern "C" { + pub fn curl_formadd( + httppost: *mut *mut curl_httppost, + last_post: *mut *mut curl_httppost, + ... + ) -> CURLFORMcode; + pub fn curl_formget( + form: *mut curl_httppost, + arg: *mut c_void, + append: curl_formget_callback, + ) -> c_int; pub fn curl_formfree(form: *mut curl_httppost); pub fn curl_version() -> *mut c_char; - pub fn curl_easy_escape(handle: *mut CURL, - string: *const c_char, - length: c_int) -> *mut c_char; - pub fn curl_easy_unescape(handle: *mut CURL, - string: *const c_char, - length: c_int, - outlength: *mut c_int) -> *mut c_char; + pub fn curl_easy_escape(handle: *mut CURL, string: *const c_char, length: c_int) + -> *mut c_char; + pub fn curl_easy_unescape( + handle: *mut CURL, + string: *const c_char, + length: c_int, + outlength: *mut c_int, + ) -> *mut c_char; pub fn curl_free(p: *mut c_void); pub fn curl_global_init(flags: c_long) -> CURLcode; - pub fn curl_global_init_mem(flags: c_long, - m: curl_malloc_callback, - f: curl_free_callback, - r: curl_realloc_callback, - s: curl_strdup_callback, - c: curl_calloc_callback) -> CURLcode; + pub fn curl_global_init_mem( + flags: c_long, + m: curl_malloc_callback, + f: curl_free_callback, + r: curl_realloc_callback, + s: curl_strdup_callback, + c: curl_calloc_callback, + ) -> CURLcode; pub fn curl_global_cleanup(); - pub fn curl_slist_append(list: *mut curl_slist, - val: *const c_char) -> *mut curl_slist; + pub fn curl_slist_append(list: *mut curl_slist, val: *const c_char) -> *mut curl_slist; pub fn curl_slist_free_all(list: *mut curl_slist); pub fn curl_getdate(p: *const c_char, _: *const time_t) -> time_t; pub fn curl_share_init() -> *mut CURLSH; - pub fn curl_share_setopt(sh: *mut CURLSH, - opt: CURLSHoption, - ...) -> CURLSHcode; + pub fn curl_share_setopt(sh: *mut CURLSH, opt: CURLSHoption, ...) -> CURLSHcode; pub fn curl_share_cleanup(sh: *mut CURLSH) -> CURLSHcode; pub fn curl_version_info(t: CURLversion) -> *mut curl_version_info_data; @@ -1012,51 +990,63 @@ pub fn curl_easy_getinfo(curl: *mut CURL, info: CURLINFO, ...) -> CURLcode; pub fn curl_easy_duphandle(curl: *mut CURL) -> *mut CURL; pub fn curl_easy_reset(curl: *mut CURL); - pub fn curl_easy_recv(curl: *mut CURL, - buffer: *mut c_void, - buflen: size_t, - n: *mut size_t) -> CURLcode; - pub fn curl_easy_send(curl: *mut CURL, - buffer: *const c_void, - buflen: size_t, - n: *mut size_t) -> CURLcode; + pub fn curl_easy_recv( + curl: *mut CURL, + buffer: *mut c_void, + buflen: size_t, + n: *mut size_t, + ) -> CURLcode; + pub fn curl_easy_send( + curl: *mut CURL, + buffer: *const c_void, + buflen: size_t, + n: *mut size_t, + ) -> CURLcode; pub fn curl_multi_init() -> *mut CURLM; - pub fn curl_multi_add_handle(multi_handle: *mut CURLM, - curl_handle: *mut CURL) -> CURLMcode; - pub fn curl_multi_remove_handle(multi_handle: *mut CURLM, - curl_handle: *mut CURL) -> CURLMcode; - pub fn curl_multi_fdset(multi_handle: *mut CURLM, - read_fd_set: *mut fd_set, - write_fd_set: *mut fd_set, - exc_fd_set: *mut fd_set, - max_fd: *mut c_int) -> CURLMcode; - pub fn curl_multi_wait(multi_handle: *mut CURLM, - extra_fds: *mut curl_waitfd, - extra_nfds: c_uint, - timeout_ms: c_int, - ret: *mut c_int) -> CURLMcode; - pub fn curl_multi_perform(multi_handle: *mut CURLM, - running_handles: *mut c_int) -> CURLMcode; + pub fn curl_multi_add_handle(multi_handle: *mut CURLM, curl_handle: *mut CURL) -> CURLMcode; + pub fn curl_multi_remove_handle(multi_handle: *mut CURLM, curl_handle: *mut CURL) -> CURLMcode; + pub fn curl_multi_fdset( + multi_handle: *mut CURLM, + read_fd_set: *mut fd_set, + write_fd_set: *mut fd_set, + exc_fd_set: *mut fd_set, + max_fd: *mut c_int, + ) -> CURLMcode; + pub fn curl_multi_wait( + multi_handle: *mut CURLM, + extra_fds: *mut curl_waitfd, + extra_nfds: c_uint, + timeout_ms: c_int, + ret: *mut c_int, + ) -> CURLMcode; + pub fn curl_multi_perform(multi_handle: *mut CURLM, running_handles: *mut c_int) -> CURLMcode; pub fn curl_multi_cleanup(multi_handle: *mut CURLM) -> CURLMcode; - pub fn curl_multi_info_read(multi_handle: *mut CURLM, - msgs_in_queue: *mut c_int) -> *mut CURLMsg; + pub fn curl_multi_info_read( + multi_handle: *mut CURLM, + msgs_in_queue: *mut c_int, + ) -> *mut CURLMsg; pub fn curl_multi_strerror(code: CURLMcode) -> *const c_char; - pub fn curl_multi_socket(multi_handle: *mut CURLM, - s: curl_socket_t, - running_handles: *mut c_int) -> CURLMcode; - pub fn curl_multi_socket_action(multi_handle: *mut CURLM, - s: curl_socket_t, - ev_bitmask: c_int, - running_handles: *mut c_int) -> CURLMcode; - pub fn curl_multi_socket_all(multi_handle: *mut CURLM, - running_handles: *mut c_int) -> CURLMcode; - pub fn curl_multi_timeout(multi_handle: *mut CURLM, - milliseconds: *mut c_long) -> CURLMcode; - pub fn curl_multi_setopt(multi_handle: *mut CURLM, - option: CURLMoption, - ...) -> CURLMcode; - pub fn curl_multi_assign(multi_handle: *mut CURLM, - sockfd: curl_socket_t, - sockp: *mut c_void) -> CURLMcode; + pub fn curl_multi_socket( + multi_handle: *mut CURLM, + s: curl_socket_t, + running_handles: *mut c_int, + ) -> CURLMcode; + pub fn curl_multi_socket_action( + multi_handle: *mut CURLM, + s: curl_socket_t, + ev_bitmask: c_int, + running_handles: *mut c_int, + ) -> CURLMcode; + pub fn curl_multi_socket_all( + multi_handle: *mut CURLM, + running_handles: *mut c_int, + ) -> CURLMcode; + pub fn curl_multi_timeout(multi_handle: *mut CURLM, milliseconds: *mut c_long) -> CURLMcode; + pub fn curl_multi_setopt(multi_handle: *mut CURLM, option: CURLMoption, ...) -> CURLMcode; + pub fn curl_multi_assign( + multi_handle: *mut CURLM, + sockfd: curl_socket_t, + sockp: *mut c_void, + ) -> CURLMcode; } diff -Nru cargo-0.33.0/vendor/env_logger/.cargo-checksum.json cargo-0.35.0/vendor/env_logger/.cargo-checksum.json --- cargo-0.33.0/vendor/env_logger/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"} \ No newline at end of file +{"files":{},"package":"b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/env_logger/Cargo.toml cargo-0.35.0/vendor/env_logger/Cargo.toml --- cargo-0.33.0/vendor/env_logger/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "env_logger" -version = "0.6.0" +version = "0.6.1" authors = ["The Rust Project Developers"] description = "A logging implementation for `log` which is configured via an environment\nvariable.\n" documentation = "https://docs.rs/env_logger" diff -Nru cargo-0.33.0/vendor/env_logger/README.md cargo-0.35.0/vendor/env_logger/README.md --- cargo-0.33.0/vendor/env_logger/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -16,7 +16,7 @@ ```toml [dependencies] log = "0.4.0" -env_logger = "0.6.0" +env_logger = "0.6.1" ``` `env_logger` must be initialized as early as possible in the project. After it's initialized, you can use the `log` macros to do actual logging. @@ -52,7 +52,7 @@ log = "0.4.0" [dev-dependencies] -env_logger = { version = "0.6.0", default-features = false } +env_logger = "0.6.1" ``` ```rust @@ -69,16 +69,22 @@ use super::*; extern crate env_logger; + fn init() { + let _ = env_logger::builder().is_test(true).try_init(); + } + #[test] fn it_adds_one() { - let _ = env_logger::try_init(); + init(); + info!("can log from the test too"); assert_eq!(3, add_one(2)); } #[test] fn it_handles_negative_numbers() { - let _ = env_logger::try_init(); + init(); + info!("logging from another test"); assert_eq!(-7, add_one(-8)); } diff -Nru cargo-0.33.0/vendor/env_logger/src/filter/mod.rs cargo-0.35.0/vendor/env_logger/src/filter/mod.rs --- cargo-0.33.0/vendor/env_logger/src/filter/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/src/filter/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -306,8 +306,8 @@ let mods = parts.next(); let filter = parts.next(); if parts.next().is_some() { - println!("warning: invalid logging spec '{}', \ - ignoring it (too many '/'s)", spec); + eprintln!("warning: invalid logging spec '{}', \ + ignoring it (too many '/'s)", spec); return (dirs, None); } mods.map(|m| { for s in m.split(',') { @@ -327,15 +327,15 @@ match part1.parse() { Ok(num) => (num, Some(part0)), _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", part1); + eprintln!("warning: invalid logging spec '{}', \ + ignoring it", part1); continue } } }, _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", s); + eprintln!("warning: invalid logging spec '{}', \ + ignoring it", s); continue } }; @@ -349,7 +349,7 @@ match inner::Filter::new(filter) { Ok(re) => Some(re), Err(e) => { - println!("warning: invalid regex filter - {}", e); + eprintln!("warning: invalid regex filter - {}", e); None } } diff -Nru cargo-0.33.0/vendor/env_logger/src/fmt/writer/mod.rs cargo-0.35.0/vendor/env_logger/src/fmt/writer/mod.rs --- cargo-0.33.0/vendor/env_logger/src/fmt/writer/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/src/fmt/writer/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -70,21 +70,23 @@ pub(crate) struct Builder { target: Target, write_style: WriteStyle, + is_test: bool, built: bool, } impl Builder { /// Initialize the writer builder with defaults. - pub fn new() -> Self { + pub(crate) fn new() -> Self { Builder { target: Default::default(), write_style: Default::default(), + is_test: false, built: false, } } /// Set the target to write to. - pub fn target(&mut self, target: Target) -> &mut Self { + pub(crate) fn target(&mut self, target: Target) -> &mut Self { self.target = target; self } @@ -94,18 +96,24 @@ /// See the [Disabling colors] section for more details. /// /// [Disabling colors]: ../index.html#disabling-colors - pub fn parse(&mut self, write_style: &str) -> &mut Self { + pub(crate) fn parse_write_style(&mut self, write_style: &str) -> &mut Self { self.write_style(parse_write_style(write_style)) } /// Whether or not to print style characters when writing. - pub fn write_style(&mut self, write_style: WriteStyle) -> &mut Self { + pub(crate) fn write_style(&mut self, write_style: WriteStyle) -> &mut Self { self.write_style = write_style; self } + /// Whether or not to capture logs for `cargo test`. + pub(crate) fn is_test(&mut self, is_test: bool) -> &mut Self { + self.is_test = is_test; + self + } + /// Build a terminal writer. - pub fn build(&mut self) -> Writer { + pub(crate) fn build(&mut self) -> Writer { assert!(!self.built, "attempt to re-use consumed builder"); self.built = true; @@ -124,8 +132,8 @@ }; let writer = match self.target { - Target::Stderr => BufferWriter::stderr(color_choice), - Target::Stdout => BufferWriter::stdout(color_choice), + Target::Stderr => BufferWriter::stderr(self.is_test, color_choice), + Target::Stdout => BufferWriter::stdout(self.is_test, color_choice), }; Writer { diff -Nru cargo-0.33.0/vendor/env_logger/src/fmt/writer/termcolor/extern_impl.rs cargo-0.35.0/vendor/env_logger/src/fmt/writer/termcolor/extern_impl.rs --- cargo-0.33.0/vendor/env_logger/src/fmt/writer/termcolor/extern_impl.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/src/fmt/writer/termcolor/extern_impl.rs 2019-05-15 11:26:24.000000000 +0000 @@ -8,7 +8,7 @@ use termcolor::{self, ColorChoice, ColorSpec, WriteColor}; use ::WriteStyle; -use ::fmt::Formatter; +use ::fmt::{Formatter, Target}; pub(in ::fmt::writer) mod glob { pub use super::*; @@ -69,51 +69,98 @@ } } -pub(in ::fmt::writer) struct BufferWriter(termcolor::BufferWriter); -pub(in ::fmt) struct Buffer(termcolor::Buffer); +pub(in ::fmt::writer) struct BufferWriter { + inner: termcolor::BufferWriter, + test_target: Option, +} + +pub(in ::fmt) struct Buffer { + inner: termcolor::Buffer, + test_target: Option, +} impl BufferWriter { - pub(in ::fmt::writer) fn stderr(write_style: WriteStyle) -> Self { - BufferWriter(termcolor::BufferWriter::stderr(write_style.into_color_choice())) + pub(in ::fmt::writer) fn stderr(is_test: bool, write_style: WriteStyle) -> Self { + BufferWriter { + inner: termcolor::BufferWriter::stderr(write_style.into_color_choice()), + test_target: if is_test { + Some(Target::Stderr) + } else { + None + }, + } } - pub(in ::fmt::writer) fn stdout(write_style: WriteStyle) -> Self { - BufferWriter(termcolor::BufferWriter::stdout(write_style.into_color_choice())) + pub(in ::fmt::writer) fn stdout(is_test: bool, write_style: WriteStyle) -> Self { + BufferWriter { + inner: termcolor::BufferWriter::stdout(write_style.into_color_choice()), + test_target: if is_test { + Some(Target::Stdout) + } else { + None + }, + } } pub(in ::fmt::writer) fn buffer(&self) -> Buffer { - Buffer(self.0.buffer()) + Buffer { + inner: self.inner.buffer(), + test_target: self.test_target, + } } pub(in ::fmt::writer) fn print(&self, buf: &Buffer) -> io::Result<()> { - self.0.print(&buf.0) + if let Some(target) = self.test_target { + // This impl uses the `eprint` and `print` macros + // instead of `termcolor`'s buffer. + // This is so their output can be captured by `cargo test` + let log = String::from_utf8_lossy(buf.bytes()); + + match target { + Target::Stderr => eprint!("{}", log), + Target::Stdout => print!("{}", log), + } + + Ok(()) + } else { + self.inner.print(&buf.inner) + } } } impl Buffer { pub(in ::fmt) fn clear(&mut self) { - self.0.clear() + self.inner.clear() } pub(in ::fmt) fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) + self.inner.write(buf) } pub(in ::fmt) fn flush(&mut self) -> io::Result<()> { - self.0.flush() + self.inner.flush() } - #[cfg(test)] pub(in ::fmt) fn bytes(&self) -> &[u8] { - self.0.as_slice() + self.inner.as_slice() } fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { - self.0.set_color(spec) + // Ignore styles for test captured logs because they can't be printed + if self.test_target.is_none() { + self.inner.set_color(spec) + } else { + Ok(()) + } } fn reset(&mut self) -> io::Result<()> { - self.0.reset() + // Ignore styles for test captured logs because they can't be printed + if self.test_target.is_none() { + self.inner.reset() + } else { + Ok(()) + } } } diff -Nru cargo-0.33.0/vendor/env_logger/src/fmt/writer/termcolor/shim_impl.rs cargo-0.35.0/vendor/env_logger/src/fmt/writer/termcolor/shim_impl.rs --- cargo-0.33.0/vendor/env_logger/src/fmt/writer/termcolor/shim_impl.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/src/fmt/writer/termcolor/shim_impl.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,13 +13,13 @@ pub(in ::fmt) struct Buffer(Vec); impl BufferWriter { - pub(in ::fmt::writer) fn stderr(_: WriteStyle) -> Self { + pub(in ::fmt::writer) fn stderr(_is_test: bool, _write_style: WriteStyle) -> Self { BufferWriter { target: Target::Stderr, } } - pub(in ::fmt::writer) fn stdout(_: WriteStyle) -> Self { + pub(in ::fmt::writer) fn stdout(_is_test: bool, _write_style: WriteStyle) -> Self { BufferWriter { target: Target::Stdout, } diff -Nru cargo-0.33.0/vendor/env_logger/src/lib.rs cargo-0.35.0/vendor/env_logger/src/lib.rs --- cargo-0.33.0/vendor/env_logger/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -139,6 +139,33 @@ //! * `error,hello=warn/[0-9]scopes` turn on global error logging and also //! warn for hello. In both cases the log message must include a single digit //! number followed by 'scopes'. +//! +//! ## Capturing logs in tests +//! +//! Records logged during `cargo test` will not be captured by the test harness by default. +//! The [`Builder::is_test`] method can be used in unit tests to ensure logs will be captured: +//! +//! ``` +//! # #[macro_use] extern crate log; +//! # extern crate env_logger; +//! # fn main() {} +//! #[cfg(test)] +//! mod tests { +//! fn init() { +//! let _ = env_logger::builder().is_test(true).try_init(); +//! } +//! +//! #[test] +//! fn it_works() { +//! info!("This record will be captured by `cargo test`"); +//! +//! assert_eq!(2, 1 + 1); +//! } +//! } +//! ``` +//! +//! Enabling test capturing comes at the expense of color and other style support +//! and may have performance implications. //! //! ## Disabling colors //! @@ -157,9 +184,7 @@ //! The following example excludes the timestamp from the log output: //! //! ``` -//! use env_logger::Builder; -//! -//! Builder::from_default_env() +//! env_logger::builder() //! .default_format_timestamp(false) //! .init(); //! ``` @@ -180,9 +205,8 @@ //! //! ``` //! use std::io::Write; -//! use env_logger::Builder; //! -//! Builder::from_default_env() +//! env_logger::builder() //! .format(|buf, record| { //! writeln!(buf, "{}: {}", record.level(), record.args()) //! }) @@ -199,19 +223,20 @@ //! isn't set: //! //! ``` -//! use env_logger::{Builder, Env}; +//! use env_logger::Env; //! -//! Builder::from_env(Env::default().default_filter_or("warn")).init(); +//! env_logger::from_env(Env::default().default_filter_or("warn")).init(); //! ``` //! //! [log-crate-url]: https://docs.rs/log/ //! [`Builder`]: struct.Builder.html +//! [`Builder::is_test`]: struct.Builder.html#method.is_test //! [`Env`]: struct.Env.html //! [`fmt`]: fmt/index.html -#![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 = "https://docs.rs/env_logger/0.6.0")] +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://www.rust-lang.org/static/images/favicon.ico", + html_root_url = "https://docs.rs/env_logger/0.6.1")] #![cfg_attr(test, deny(warnings))] // When compiled for the rustc compiler itself we want to make sure that this is @@ -404,7 +429,7 @@ let env = env.into(); if let Some(s) = env.get_filter() { - builder.parse(&s); + builder.parse_filters(&s); } if let Some(s) = env.get_write_style() { @@ -579,7 +604,16 @@ /// environment variable. /// /// See the module documentation for more details. + #[deprecated(since = "0.6.1", note = "use `parse_filters` instead.")] pub fn parse(&mut self, filters: &str) -> &mut Self { + self.parse_filters(filters) + } + + /// Parses the directives string in the same form as the `RUST_LOG` + /// environment variable. + /// + /// See the module documentation for more details. + pub fn parse_filters(&mut self, filters: &str) -> &mut Self { self.filter.parse(filters); self } @@ -630,7 +664,16 @@ /// /// See the module documentation for more details. pub fn parse_write_style(&mut self, write_style: &str) -> &mut Self { - self.writer.parse(write_style); + self.writer.parse_write_style(write_style); + self + } + + /// Sets whether or not the logger will be used in unit tests. + /// + /// If `is_test` is `true` then the logger will allow the testing framework to + /// capture log records rather than printing them to the terminal directly. + pub fn is_test(&mut self, is_test: bool) -> &mut Self { + self.writer.is_test(is_test); self } @@ -1068,6 +1111,23 @@ try_init_from_env(env).expect("env_logger::init_from_env should not be called after logger initialized"); } +/// Create a new builder with the default environment variables. +/// +/// The builder can be configured before being initialized. +pub fn builder() -> Builder { + Builder::from_default_env() +} + +/// Create a builder from the given environment variables. +/// +/// The builder can be configured before being initialized. +pub fn from_env<'a, E>(env: E) -> Builder +where + E: Into> +{ + Builder::from_env(env) +} + #[cfg(test)] mod tests { use super::*; diff -Nru cargo-0.33.0/vendor/env_logger/tests/init-twice-retains-filter.rs cargo-0.35.0/vendor/env_logger/tests/init-twice-retains-filter.rs --- cargo-0.33.0/vendor/env_logger/tests/init-twice-retains-filter.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger/tests/init-twice-retains-filter.rs 2019-05-15 11:26:24.000000000 +0000 @@ -15,7 +15,7 @@ // Init again using a different max level // This shouldn't clobber the level that was previously set env_logger::Builder::new() - .parse("info") + .parse_filters("info") .try_init() .unwrap_err(); diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/.cargo-checksum.json cargo-0.35.0/vendor/env_logger-0.5.13/.cargo-checksum.json --- cargo-0.33.0/vendor/env_logger-0.5.13/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -{"files":{},"package":"15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/Cargo.toml cargo-0.35.0/vendor/env_logger-0.5.13/Cargo.toml --- cargo-0.33.0/vendor/env_logger-0.5.13/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "env_logger" -version = "0.5.13" -authors = ["The Rust Project Developers"] -description = "A logging implementation for `log` which is configured via an environment\nvariable.\n" -documentation = "https://docs.rs/env_logger" -readme = "README.md" -keywords = ["logging", "log", "logger"] -categories = ["development-tools::debugging"] -license = "MIT/Apache-2.0" -repository = "https://github.com/sebasmagri/env_logger/" - -[[test]] -name = "regexp_filter" -harness = false - -[[test]] -name = "log-in-log" -harness = false -[dependencies.atty] -version = "0.2.5" - -[dependencies.humantime] -version = "1.1" - -[dependencies.log] -version = "0.4" -features = ["std"] - -[dependencies.regex] -version = "1.0.3" -optional = true - -[dependencies.termcolor] -version = "1" - -[features] -default = ["regex"] diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_default_format.rs cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_default_format.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_default_format.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_default_format.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/*! -Disabling parts of the default format. - -Before running this example, try setting the `MY_LOG_LEVEL` environment variable to `info`: - -```no_run,shell -$ export MY_LOG_LEVEL='info' -``` - -Also try setting the `MY_LOG_STYLE` environment variable to `never` to disable colors -or `auto` to enable them: - -```no_run,shell -$ export MY_LOG_STYLE=never -``` - -If you want to control the logging output completely, see the `custom_logger` example. -*/ - -#[macro_use] -extern crate log; -extern crate env_logger; - -use env_logger::{Env, Builder}; - -fn init_logger() { - let env = Env::default() - .filter("MY_LOG_LEVEL") - .write_style("MY_LOG_STYLE"); - - let mut builder = Builder::from_env(env); - - builder - .default_format_level(false) - .default_format_timestamp_nanos(true); - - builder.init(); -} - -fn main() { - init_logger(); - - info!("a log from `MyLogger`"); -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_format.rs cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_format.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_format.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_format.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/*! -Changing the default logging format. - -Before running this example, try setting the `MY_LOG_LEVEL` environment variable to `info`: - -```no_run,shell -$ export MY_LOG_LEVEL='info' -``` - -Also try setting the `MY_LOG_STYLE` environment variable to `never` to disable colors -or `auto` to enable them: - -```no_run,shell -$ export MY_LOG_STYLE=never -``` - -If you want to control the logging output completely, see the `custom_logger` example. -*/ - -#[macro_use] -extern crate log; -extern crate env_logger; - -use std::io::Write; - -use env_logger::{Env, Builder, fmt}; - -fn init_logger() { - let env = Env::default() - .filter("MY_LOG_LEVEL") - .write_style("MY_LOG_STYLE"); - - let mut builder = Builder::from_env(env); - - // Use a different format for writing log records - builder.format(|buf, record| { - let mut style = buf.style(); - style.set_bg(fmt::Color::Yellow).set_bold(true); - - let timestamp = buf.timestamp(); - - writeln!(buf, "My formatted log ({}): {}", timestamp, style.value(record.args())) - }); - - builder.init(); -} - -fn main() { - init_logger(); - - info!("a log from `MyLogger`"); -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_logger.rs cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_logger.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/examples/custom_logger.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/examples/custom_logger.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/*! -Using `env_logger` to drive a custom logger. - -Before running this example, try setting the `MY_LOG_LEVEL` environment variable to `info`: - -```no_run,shell -$ export MY_LOG_LEVEL='info' -``` - -If you only want to change the way logs are formatted, look at the `custom_format` example. -*/ - -#[macro_use] -extern crate log; -extern crate env_logger; -use env_logger::filter::Filter; -use log::{Log, Metadata, Record, SetLoggerError}; - -struct MyLogger { - inner: Filter -} - -impl MyLogger { - fn new() -> MyLogger { - use env_logger::filter::Builder; - let mut builder = Builder::from_env("MY_LOG_LEVEL"); - - MyLogger { - inner: builder.build() - } - } - - fn init() -> Result<(), SetLoggerError> { - let logger = Self::new(); - - log::set_max_level(logger.inner.filter()); - log::set_boxed_logger(Box::new(logger)) - } -} - -impl Log for MyLogger { - fn enabled(&self, metadata: &Metadata) -> bool { - self.inner.enabled(metadata) - } - - fn log(&self, record: &Record) { - // Check if the record is matched by the logger before logging - if self.inner.matches(record) { - println!("{} - {}", record.level(), record.args()); - } - } - - fn flush(&self) { } -} - -fn main() { - MyLogger::init().unwrap(); - - info!("a log from `MyLogger`"); -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/examples/default.rs cargo-0.35.0/vendor/env_logger-0.5.13/examples/default.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/examples/default.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/examples/default.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/*! -Using `env_logger`. - -Before running this example, try setting the `MY_LOG_LEVEL` environment variable to `info`: - -```no_run,shell -$ export MY_LOG_LEVEL='info' -``` - -Also try setting the `MY_LOG_STYLE` environment variable to `never` to disable colors -or `auto` to enable them: - -```no_run,shell -$ export MY_LOG_STYLE=never -``` -*/ - -#[macro_use] -extern crate log; -extern crate env_logger; - -use env_logger::Env; - -fn main() { - let env = Env::default() - .filter_or("MY_LOG_LEVEL", "trace") - .write_style_or("MY_LOG_STYLE", "always"); - - env_logger::init_from_env(env); - - trace!("some trace log"); - debug!("some debug log"); - info!("some information log"); - warn!("some warning log"); - error!("some error log"); -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/examples/direct_logger.rs cargo-0.35.0/vendor/env_logger-0.5.13/examples/direct_logger.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/examples/direct_logger.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/examples/direct_logger.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/*! -Using `env_logger::Logger` and the `log::Log` trait directly. - -This example doesn't rely on environment variables, or having a static logger installed. -*/ - -extern crate log; -extern crate env_logger; - -fn record() -> log::Record<'static> { - let error_metadata = log::MetadataBuilder::new() - .target("myApp") - .level(log::Level::Error) - .build(); - - log::Record::builder() - .metadata(error_metadata) - .args(format_args!("Error!")) - .line(Some(433)) - .file(Some("app.rs")) - .module_path(Some("server")) - .build() -} - -fn main() { - use log::Log; - - let stylish_logger = env_logger::Builder::new() - .filter(None, log::LevelFilter::Error) - .write_style(env_logger::WriteStyle::Always) - .build(); - - let unstylish_logger = env_logger::Builder::new() - .filter(None, log::LevelFilter::Error) - .write_style(env_logger::WriteStyle::Never) - .build(); - - stylish_logger.log(&record()); - unstylish_logger.log(&record()); -} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/LICENSE-APACHE cargo-0.35.0/vendor/env_logger-0.5.13/LICENSE-APACHE --- cargo-0.33.0/vendor/env_logger-0.5.13/LICENSE-APACHE 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/LICENSE-MIT cargo-0.35.0/vendor/env_logger-0.5.13/LICENSE-MIT --- cargo-0.33.0/vendor/env_logger-0.5.13/LICENSE-MIT 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Copyright (c) 2014 The Rust Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/README.md cargo-0.35.0/vendor/env_logger-0.5.13/README.md --- cargo-0.33.0/vendor/env_logger-0.5.13/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/README.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -env_logger [![Build Status](https://travis-ci.org/sebasmagri/env_logger.svg?branch=master)](https://travis-ci.org/sebasmagri/env_logger) [![Maintenance](https://img.shields.io/badge/maintenance-actively%20maintained-brightgreen.svg)](https://github.com/sebasmagri/env_logger) [![crates.io](https://img.shields.io/crates/v/env_logger.svg)](https://crates.io/crates/env_logger) [![Documentation](https://img.shields.io/badge/docs-current-blue.svg)](https://docs.rs/env_logger) -========== - -Implements a logger that can be configured via environment variables. - -## Usage - -### In libraries - -`env_logger` makes sense when used in executables (binary projects). Libraries should use the [`log`](https://doc.rust-lang.org/log) crate instead. - -### In executables - -It must be added along with `log` to the project dependencies: - -```toml -[dependencies] -log = "0.4.0" -env_logger = "0.5.13" -``` - -`env_logger` must be initialized as early as possible in the project. After it's initialized, you can use the `log` macros to do actual logging. - -```rust -#[macro_use] -extern crate log; -extern crate env_logger; - -fn main() { - env_logger::init(); - - info!("starting up"); - - // ... -} -``` - -Then when running the executable, specify a value for the `RUST_LOG` -environment variable that corresponds with the log messages you want to show. - -```bash -$ RUST_LOG=info ./main -INFO: 2017-11-09T02:12:24Z: main: starting up -``` - -### In tests - -Tests can use the `env_logger` crate to see log messages generated during that test: - -```toml -[dependencies] -log = "0.4.0" - -[dev-dependencies] -env_logger = "0.5.13" -``` - -```rust -#[macro_use] -extern crate log; - -fn add_one(num: i32) -> i32 { - info!("add_one called with {}", num); - num + 1 -} - -#[cfg(test)] -mod tests { - use super::*; - extern crate env_logger; - - #[test] - fn it_adds_one() { - let _ = env_logger::try_init(); - info!("can log from the test too"); - assert_eq!(3, add_one(2)); - } - - #[test] - fn it_handles_negative_numbers() { - let _ = env_logger::try_init(); - info!("logging from another test"); - assert_eq!(-7, add_one(-8)); - } -} -``` - -Assuming the module under test is called `my_lib`, running the tests with the -`RUST_LOG` filtering to info messages from this module looks like: - -```bash -$ RUST_LOG=my_lib=info cargo test - Running target/debug/my_lib-... - -running 2 tests -INFO: 2017-11-09T02:12:24Z: my_lib::tests: logging from another test -INFO: 2017-11-09T02:12:24Z: my_lib: add_one called with -8 -test tests::it_handles_negative_numbers ... ok -INFO: 2017-11-09T02:12:24Z: my_lib::tests: can log from the test too -INFO: 2017-11-09T02:12:24Z: my_lib: add_one called with 2 -test tests::it_adds_one ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured -``` - -Note that `env_logger::try_init()` needs to be called in each test in which you -want to enable logging. Additionally, the default behavior of tests to -run in parallel means that logging output may be interleaved with test output. -Either run tests in a single thread by specifying `RUST_TEST_THREADS=1` or by -running one test by specifying its name as an argument to the test binaries as -directed by the `cargo test` help docs: - -```bash -$ RUST_LOG=my_lib=info cargo test it_adds_one - Running target/debug/my_lib-... - -running 1 test -INFO: 2017-11-09T02:12:24Z: my_lib::tests: can log from the test too -INFO: 2017-11-09T02:12:24Z: my_lib: add_one called with 2 -test tests::it_adds_one ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured -``` - -## Configuring log target - -By default, `env_logger` logs to stderr. If you want to log to stdout instead, -you can use the `Builder` to change the log target: - -```rust -use std::env; -use env_logger::{Builder, Target}; - -let mut builder = Builder::new(); -builder.target(Target::Stdout); -if env::var("RUST_LOG").is_ok() { - builder.parse(&env::var("RUST_LOG").unwrap()); -} -builder.init(); -``` diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/mod.rs cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/mod.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,568 +0,0 @@ -//! Filtering for log records. -//! -//! This module contains the log filtering used by `env_logger` to match records. -//! You can use the `Filter` type in your own logger implementation to use the same -//! filter parsing and matching as `env_logger`. For more details about the format -//! for directive strings see [Enabling Logging]. -//! -//! ## Using `env_logger` in your own logger -//! -//! You can use `env_logger`'s filtering functionality with your own logger. -//! Call [`Builder::parse`] to parse directives from a string when constructing -//! your logger. Call [`Filter::matches`] to check whether a record should be -//! logged based on the parsed filters when log records are received. -//! -//! ``` -//! extern crate log; -//! extern crate env_logger; -//! use env_logger::filter::Filter; -//! use log::{Log, Metadata, Record}; -//! -//! struct MyLogger { -//! filter: Filter -//! } -//! -//! impl MyLogger { -//! fn new() -> MyLogger { -//! use env_logger::filter::Builder; -//! let mut builder = Builder::new(); -//! -//! // Parse a directives string from an environment variable -//! if let Ok(ref filter) = std::env::var("MY_LOG_LEVEL") { -//! builder.parse(filter); -//! } -//! -//! MyLogger { -//! filter: builder.build() -//! } -//! } -//! } -//! -//! impl Log for MyLogger { -//! fn enabled(&self, metadata: &Metadata) -> bool { -//! self.filter.enabled(metadata) -//! } -//! -//! fn log(&self, record: &Record) { -//! // Check if the record is matched by the filter -//! if self.filter.matches(record) { -//! println!("{:?}", record); -//! } -//! } -//! -//! fn flush(&self) {} -//! } -//! # fn main() {} -//! ``` -//! -//! [Enabling Logging]: ../index.html#enabling-logging -//! [`Builder::parse`]: struct.Builder.html#method.parse -//! [`Filter::matches`]: struct.Filter.html#method.matches - -use std::env; -use std::mem; -use std::fmt; -use log::{Level, LevelFilter, Record, Metadata}; - -#[cfg(feature = "regex")] -#[path = "regex.rs"] -mod inner; - -#[cfg(not(feature = "regex"))] -#[path = "string.rs"] -mod inner; - -/// A log filter. -/// -/// This struct can be used to determine whether or not a log record -/// should be written to the output. -/// Use the [`Builder`] type to parse and construct a `Filter`. -/// -/// [`Builder`]: struct.Builder.html -pub struct Filter { - directives: Vec, - filter: Option, -} - -/// A builder for a log filter. -/// -/// It can be used to parse a set of directives from a string before building -/// a [`Filter`] instance. -/// -/// ## Example -/// -/// ``` -/// #[macro_use] -/// extern crate log; -/// extern crate env_logger; -/// -/// use std::env; -/// use std::io; -/// use env_logger::filter::Builder; -/// -/// fn main() { -/// let mut builder = Builder::new(); -/// -/// // Parse a logging filter from an environment variable. -/// if let Ok(rust_log) = env::var("RUST_LOG") { -/// builder.parse(&rust_log); -/// } -/// -/// let filter = builder.build(); -/// } -/// ``` -/// -/// [`Filter`]: struct.Filter.html -pub struct Builder { - directives: Vec, - filter: Option, -} - -#[derive(Debug)] -struct Directive { - name: Option, - level: LevelFilter, -} - -impl Filter { - /// Returns the maximum `LevelFilter` that this filter instance is - /// configured to output. - /// - /// # Example - /// - /// ```rust - /// extern crate log; - /// extern crate env_logger; - /// - /// use log::LevelFilter; - /// use env_logger::filter::Builder; - /// - /// fn main() { - /// let mut builder = Builder::new(); - /// builder.filter(Some("module1"), LevelFilter::Info); - /// builder.filter(Some("module2"), LevelFilter::Error); - /// - /// let filter = builder.build(); - /// assert_eq!(filter.filter(), LevelFilter::Info); - /// } - /// ``` - pub fn filter(&self) -> LevelFilter { - self.directives.iter() - .map(|d| d.level) - .max() - .unwrap_or(LevelFilter::Off) - } - - /// Checks if this record matches the configured filter. - pub fn matches(&self, record: &Record) -> bool { - if !self.enabled(record.metadata()) { - return false; - } - - if let Some(filter) = self.filter.as_ref() { - if !filter.is_match(&*record.args().to_string()) { - return false; - } - } - - true - } - - /// Determines if a log message with the specified metadata would be logged. - pub fn enabled(&self, metadata: &Metadata) -> bool { - let level = metadata.level(); - let target = metadata.target(); - - enabled(&self.directives, level, target) - } -} - -impl Builder { - /// Initializes the filter builder with defaults. - pub fn new() -> Builder { - Builder { - directives: Vec::new(), - filter: None, - } - } - - /// Initializes the filter builder from an environment. - pub fn from_env(env: &str) -> Builder { - let mut builder = Builder::new(); - - if let Ok(s) = env::var(env) { - builder.parse(&s); - } - - builder - } - - /// Adds a directive to the filter for a specific module. - pub fn filter_module(&mut self, module: &str, level: LevelFilter) -> &mut Self { - self.filter(Some(module), level) - } - - /// Adds a directive to the filter for all modules. - pub fn filter_level(&mut self, level: LevelFilter) -> &mut Self { - self.filter(None, level) - } - - /// Adds a directive to the filter. - /// - /// The given module (if any) will log at most the specified level provided. - /// If no module is provided then the filter will apply to all log messages. - pub fn filter(&mut self, - module: Option<&str>, - level: LevelFilter) -> &mut Self { - self.directives.push(Directive { - name: module.map(|s| s.to_string()), - level, - }); - self - } - - /// Parses the directives string. - /// - /// See the [Enabling Logging] section for more details. - /// - /// [Enabling Logging]: ../index.html#enabling-logging - pub fn parse(&mut self, filters: &str) -> &mut Self { - let (directives, filter) = parse_spec(filters); - - self.filter = filter; - - for directive in directives { - self.directives.push(directive); - } - self - } - - /// Build a log filter. - pub fn build(&mut self) -> Filter { - if self.directives.is_empty() { - // Adds the default filter if none exist - self.directives.push(Directive { - name: None, - level: LevelFilter::Error, - }); - } else { - // Sort the directives by length of their name, this allows a - // little more efficient lookup at runtime. - self.directives.sort_by(|a, b| { - let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0); - let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0); - alen.cmp(&blen) - }); - } - - Filter { - directives: mem::replace(&mut self.directives, Vec::new()), - filter: mem::replace(&mut self.filter, None), - } - } -} - -impl Default for Builder { - fn default() -> Self { - Builder::new() - } -} - -impl fmt::Debug for Filter { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Filter") - .field("filter", &self.filter) - .field("directives", &self.directives) - .finish() - } -} - -impl fmt::Debug for Builder { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Filter") - .field("filter", &self.filter) - .field("directives", &self.directives) - .finish() - } -} - -/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=error/foo") -/// and return a vector with log directives. -fn parse_spec(spec: &str) -> (Vec, Option) { - let mut dirs = Vec::new(); - - let mut parts = spec.split('/'); - let mods = parts.next(); - let filter = parts.next(); - if parts.next().is_some() { - println!("warning: invalid logging spec '{}', \ - ignoring it (too many '/'s)", spec); - return (dirs, None); - } - mods.map(|m| { for s in m.split(',') { - if s.len() == 0 { continue } - let mut parts = s.split('='); - let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) { - (Some(part0), None, None) => { - // if the single argument is a log-level string or number, - // treat that as a global fallback - match part0.parse() { - Ok(num) => (num, None), - Err(_) => (LevelFilter::max(), Some(part0)), - } - } - (Some(part0), Some(""), None) => (LevelFilter::max(), Some(part0)), - (Some(part0), Some(part1), None) => { - match part1.parse() { - Ok(num) => (num, Some(part0)), - _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", part1); - continue - } - } - }, - _ => { - println!("warning: invalid logging spec '{}', \ - ignoring it", s); - continue - } - }; - dirs.push(Directive { - name: name.map(|s| s.to_string()), - level: log_level, - }); - }}); - - let filter = filter.map_or(None, |filter| { - match inner::Filter::new(filter) { - Ok(re) => Some(re), - Err(e) => { - println!("warning: invalid regex filter - {}", e); - None - } - } - }); - - return (dirs, filter); -} - - -// Check whether a level and target are enabled by the set of directives. -fn enabled(directives: &[Directive], level: Level, target: &str) -> bool { - // Search for the longest match, the vector is assumed to be pre-sorted. - for directive in directives.iter().rev() { - match directive.name { - Some(ref name) if !target.starts_with(&**name) => {}, - Some(..) | None => { - return level <= directive.level - } - } - } - false -} - -#[cfg(test)] -mod tests { - use log::{Level, LevelFilter}; - - use super::{Builder, Filter, Directive, parse_spec, enabled}; - - fn make_logger_filter(dirs: Vec) -> Filter { - let mut logger = Builder::new().build(); - logger.directives = dirs; - logger - } - - #[test] - fn filter_info() { - let logger = Builder::new().filter(None, LevelFilter::Info).build(); - assert!(enabled(&logger.directives, Level::Info, "crate1")); - assert!(!enabled(&logger.directives, Level::Debug, "crate1")); - } - - #[test] - fn filter_beginning_longest_match() { - let logger = Builder::new() - .filter(Some("crate2"), LevelFilter::Info) - .filter(Some("crate2::mod"), LevelFilter::Debug) - .filter(Some("crate1::mod1"), LevelFilter::Warn) - .build(); - assert!(enabled(&logger.directives, Level::Debug, "crate2::mod1")); - assert!(!enabled(&logger.directives, Level::Debug, "crate2")); - } - - #[test] - fn parse_default() { - let logger = Builder::new().parse("info,crate1::mod1=warn").build(); - assert!(enabled(&logger.directives, Level::Warn, "crate1::mod1")); - assert!(enabled(&logger.directives, Level::Info, "crate2::mod2")); - } - - #[test] - fn match_full_path() { - let logger = make_logger_filter(vec![ - Directive { - name: Some("crate2".to_string()), - level: LevelFilter::Info - }, - Directive { - name: Some("crate1::mod1".to_string()), - level: LevelFilter::Warn - } - ]); - assert!(enabled(&logger.directives, Level::Warn, "crate1::mod1")); - assert!(!enabled(&logger.directives, Level::Info, "crate1::mod1")); - assert!(enabled(&logger.directives, Level::Info, "crate2")); - assert!(!enabled(&logger.directives, Level::Debug, "crate2")); - } - - #[test] - fn no_match() { - let logger = make_logger_filter(vec![ - Directive { name: Some("crate2".to_string()), level: LevelFilter::Info }, - Directive { name: Some("crate1::mod1".to_string()), level: LevelFilter::Warn } - ]); - assert!(!enabled(&logger.directives, Level::Warn, "crate3")); - } - - #[test] - fn match_beginning() { - let logger = make_logger_filter(vec![ - Directive { name: Some("crate2".to_string()), level: LevelFilter::Info }, - Directive { name: Some("crate1::mod1".to_string()), level: LevelFilter::Warn } - ]); - assert!(enabled(&logger.directives, Level::Info, "crate2::mod1")); - } - - #[test] - fn match_beginning_longest_match() { - let logger = make_logger_filter(vec![ - Directive { name: Some("crate2".to_string()), level: LevelFilter::Info }, - Directive { name: Some("crate2::mod".to_string()), level: LevelFilter::Debug }, - Directive { name: Some("crate1::mod1".to_string()), level: LevelFilter::Warn } - ]); - assert!(enabled(&logger.directives, Level::Debug, "crate2::mod1")); - assert!(!enabled(&logger.directives, Level::Debug, "crate2")); - } - - #[test] - fn match_default() { - let logger = make_logger_filter(vec![ - Directive { name: None, level: LevelFilter::Info }, - Directive { name: Some("crate1::mod1".to_string()), level: LevelFilter::Warn } - ]); - assert!(enabled(&logger.directives, Level::Warn, "crate1::mod1")); - assert!(enabled(&logger.directives, Level::Info, "crate2::mod2")); - } - - #[test] - fn zero_level() { - let logger = make_logger_filter(vec![ - Directive { name: None, level: LevelFilter::Info }, - Directive { name: Some("crate1::mod1".to_string()), level: LevelFilter::Off } - ]); - assert!(!enabled(&logger.directives, Level::Error, "crate1::mod1")); - assert!(enabled(&logger.directives, Level::Info, "crate2::mod2")); - } - - #[test] - fn parse_spec_valid() { - let (dirs, filter) = parse_spec("crate1::mod1=error,crate1::mod2,crate2=debug"); - assert_eq!(dirs.len(), 3); - assert_eq!(dirs[0].name, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Error); - - assert_eq!(dirs[1].name, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::max()); - - assert_eq!(dirs[2].name, Some("crate2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::Debug); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_invalid_crate() { - // test parse_spec with multiple = in specification - let (dirs, filter) = parse_spec("crate1::mod1=warn=info,crate2=debug"); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Debug); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_invalid_level() { - // test parse_spec with 'noNumber' as log level - let (dirs, filter) = parse_spec("crate1::mod1=noNumber,crate2=debug"); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Debug); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_string_level() { - // test parse_spec with 'warn' as log level - let (dirs, filter) = parse_spec("crate1::mod1=wrong,crate2=warn"); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Warn); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_empty_level() { - // test parse_spec with '' as log level - let (dirs, filter) = parse_spec("crate1::mod1=wrong,crate2="); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::max()); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_global() { - // test parse_spec with no crate - let (dirs, filter) = parse_spec("warn,crate2=debug"); - assert_eq!(dirs.len(), 2); - assert_eq!(dirs[0].name, None); - assert_eq!(dirs[0].level, LevelFilter::Warn); - assert_eq!(dirs[1].name, Some("crate2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::Debug); - assert!(filter.is_none()); - } - - #[test] - fn parse_spec_valid_filter() { - let (dirs, filter) = parse_spec("crate1::mod1=error,crate1::mod2,crate2=debug/abc"); - assert_eq!(dirs.len(), 3); - assert_eq!(dirs[0].name, Some("crate1::mod1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Error); - - assert_eq!(dirs[1].name, Some("crate1::mod2".to_string())); - assert_eq!(dirs[1].level, LevelFilter::max()); - - assert_eq!(dirs[2].name, Some("crate2".to_string())); - assert_eq!(dirs[2].level, LevelFilter::Debug); - assert!(filter.is_some() && filter.unwrap().to_string() == "abc"); - } - - #[test] - fn parse_spec_invalid_crate_filter() { - let (dirs, filter) = parse_spec("crate1::mod1=error=warn,crate2=debug/a.c"); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate2".to_string())); - assert_eq!(dirs[0].level, LevelFilter::Debug); - assert!(filter.is_some() && filter.unwrap().to_string() == "a.c"); - } - - #[test] - fn parse_spec_empty_with_filter() { - let (dirs, filter) = parse_spec("crate1/a*c"); - assert_eq!(dirs.len(), 1); - assert_eq!(dirs[0].name, Some("crate1".to_string())); - assert_eq!(dirs[0].level, LevelFilter::max()); - assert!(filter.is_some() && filter.unwrap().to_string() == "a*c"); - } -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/regex.rs cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/regex.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/regex.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/regex.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -extern crate regex; - -use std::fmt; - -use self::regex::Regex; - -#[derive(Debug)] -pub struct Filter { - inner: Regex, -} - -impl Filter { - pub fn new(spec: &str) -> Result { - match Regex::new(spec){ - Ok(r) => Ok(Filter { inner: r }), - Err(e) => Err(e.to_string()), - } - } - - pub fn is_match(&self, s: &str) -> bool { - self.inner.is_match(s) - } -} - -impl fmt::Display for Filter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.inner.fmt(f) - } -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/string.rs cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/string.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/src/filter/string.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/src/filter/string.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -use std::fmt; - -#[derive(Debug)] -pub struct Filter { - inner: String, -} - -impl Filter { - pub fn new(spec: &str) -> Result { - Ok(Filter { inner: spec.to_string() }) - } - - pub fn is_match(&self, s: &str) -> bool { - s.contains(&self.inner) - } -} - -impl fmt::Display for Filter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.inner.fmt(f) - } -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/src/fmt.rs cargo-0.35.0/vendor/env_logger-0.5.13/src/fmt.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/src/fmt.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/src/fmt.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,844 +0,0 @@ -//! Formatting for log records. -//! -//! This module contains a [`Formatter`] that can be used to format log records -//! into without needing temporary allocations. Usually you won't need to worry -//! about the contents of this module and can use the `Formatter` like an ordinary -//! [`Write`]. -//! -//! # Formatting log records -//! -//! The format used to print log records can be customised using the [`Builder::format`] -//! method. -//! Custom formats can apply different color and weight to printed values using -//! [`Style`] builders. -//! -//! ``` -//! use std::io::Write; -//! use env_logger::fmt::Color; -//! -//! let mut builder = env_logger::Builder::new(); -//! -//! builder.format(|buf, record| { -//! let mut level_style = buf.style(); -//! -//! level_style.set_color(Color::Red).set_bold(true); -//! -//! writeln!(buf, "{}: {}", -//! level_style.value(record.level()), -//! record.args()) -//! }); -//! ``` -//! -//! [`Formatter`]: struct.Formatter.html -//! [`Style`]: struct.Style.html -//! [`Builder::format`]: ../struct.Builder.html#method.format -//! [`Write`]: https://doc.rust-lang.org/stable/std/io/trait.Write.html - -use std::io::prelude::*; -use std::{io, fmt}; -use std::rc::Rc; -use std::str::FromStr; -use std::error::Error; -use std::cell::RefCell; -use std::time::SystemTime; - -use log::Level; -use termcolor::{self, ColorSpec, ColorChoice, Buffer, BufferWriter, WriteColor}; -use atty; -use humantime::{format_rfc3339_seconds, format_rfc3339_nanos}; - -/// A formatter to write logs into. -/// -/// `Formatter` implements the standard [`Write`] trait for writing log records. -/// It also supports terminal colors, through the [`style`] method. -/// -/// # Examples -/// -/// Use the [`writeln`] macro to easily format a log record: -/// -/// ``` -/// use std::io::Write; -/// -/// let mut builder = env_logger::Builder::new(); -/// -/// builder.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args())); -/// ``` -/// -/// [`Write`]: https://doc.rust-lang.org/stable/std/io/trait.Write.html -/// [`writeln`]: https://doc.rust-lang.org/stable/std/macro.writeln.html -/// [`style`]: #method.style -pub struct Formatter { - buf: Rc>, - write_style: WriteStyle, -} - -/// A set of styles to apply to the terminal output. -/// -/// Call [`Formatter::style`] to get a `Style` and use the builder methods to -/// set styling properties, like [color] and [weight]. -/// To print a value using the style, wrap it in a call to [`value`] when the log -/// record is formatted. -/// -/// # Examples -/// -/// Create a bold, red colored style and use it to print the log level: -/// -/// ``` -/// use std::io::Write; -/// use env_logger::fmt::Color; -/// -/// let mut builder = env_logger::Builder::new(); -/// -/// builder.format(|buf, record| { -/// let mut level_style = buf.style(); -/// -/// level_style.set_color(Color::Red).set_bold(true); -/// -/// writeln!(buf, "{}: {}", -/// level_style.value(record.level()), -/// record.args()) -/// }); -/// ``` -/// -/// Styles can be re-used to output multiple values: -/// -/// ``` -/// use std::io::Write; -/// use env_logger::fmt::Color; -/// -/// let mut builder = env_logger::Builder::new(); -/// -/// builder.format(|buf, record| { -/// let mut bold = buf.style(); -/// -/// bold.set_bold(true); -/// -/// writeln!(buf, "{}: {} {}", -/// bold.value(record.level()), -/// bold.value("some bold text"), -/// record.args()) -/// }); -/// ``` -/// -/// [`Formatter::style`]: struct.Formatter.html#method.style -/// [color]: #method.set_color -/// [weight]: #method.set_bold -/// [`value`]: #method.value -#[derive(Clone)] -pub struct Style { - buf: Rc>, - spec: ColorSpec, -} - -/// A value that can be printed using the given styles. -/// -/// It is the result of calling [`Style::value`]. -/// -/// [`Style::value`]: struct.Style.html#method.value -pub struct StyledValue<'a, T> { - style: &'a Style, - value: T, -} - -/// An [RFC3339] formatted timestamp. -/// -/// The timestamp implements [`Display`] and can be written to a [`Formatter`]. -/// -/// [RFC3339]: https://www.ietf.org/rfc/rfc3339.txt -/// [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html -/// [`Formatter`]: struct.Formatter.html -pub struct Timestamp(SystemTime); - -/// An [RFC3339] formatted timestamp with nanos -#[derive(Debug)] -pub struct PreciseTimestamp(SystemTime); - -/// Log target, either `stdout` or `stderr`. -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub enum Target { - /// Logs will be sent to standard output. - Stdout, - /// Logs will be sent to standard error. - Stderr, -} - -impl Default for Target { - fn default() -> Self { - Target::Stderr - } -} - -/// Whether or not to print styles to the target. -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub enum WriteStyle { - /// Try to print styles, but don't force the issue. - Auto, - /// Try very hard to print styles. - Always, - /// Never print styles. - Never, -} - -impl Default for WriteStyle { - fn default() -> Self { - WriteStyle::Auto - } -} - -/// A terminal target with color awareness. -pub(crate) struct Writer { - inner: BufferWriter, - write_style: WriteStyle, -} - -impl Writer { - pub(crate) fn write_style(&self) -> WriteStyle { - self.write_style - } -} - -/// A builder for a terminal writer. -/// -/// The target and style choice can be configured before building. -pub(crate) struct Builder { - target: Target, - write_style: WriteStyle, -} - -impl Builder { - /// Initialize the writer builder with defaults. - pub fn new() -> Self { - Builder { - target: Default::default(), - write_style: Default::default(), - } - } - - /// Set the target to write to. - pub fn target(&mut self, target: Target) -> &mut Self { - self.target = target; - self - } - - /// Parses a style choice string. - /// - /// See the [Disabling colors] section for more details. - /// - /// [Disabling colors]: ../index.html#disabling-colors - pub fn parse(&mut self, write_style: &str) -> &mut Self { - self.write_style(parse_write_style(write_style)) - } - - /// Whether or not to print style characters when writing. - pub fn write_style(&mut self, write_style: WriteStyle) -> &mut Self { - self.write_style = write_style; - self - } - - /// Build a terminal writer. - pub fn build(&mut self) -> Writer { - let color_choice = match self.write_style { - WriteStyle::Auto => { - if atty::is(match self.target { - Target::Stderr => atty::Stream::Stderr, - Target::Stdout => atty::Stream::Stdout, - }) { - ColorChoice::Auto - } else { - ColorChoice::Never - } - }, - WriteStyle::Always => ColorChoice::Always, - WriteStyle::Never => ColorChoice::Never, - }; - - let writer = match self.target { - Target::Stderr => BufferWriter::stderr(color_choice), - Target::Stdout => BufferWriter::stdout(color_choice), - }; - - Writer { - inner: writer, - write_style: self.write_style, - } - } -} - -impl Default for Builder { - fn default() -> Self { - Builder::new() - } -} - -impl Style { - /// Set the text color. - /// - /// # Examples - /// - /// Create a style with red text: - /// - /// ``` - /// use std::io::Write; - /// use env_logger::fmt::Color; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut style = buf.style(); - /// - /// style.set_color(Color::Red); - /// - /// writeln!(buf, "{}", style.value(record.args())) - /// }); - /// ``` - pub fn set_color(&mut self, color: Color) -> &mut Style { - self.spec.set_fg(color.into_termcolor()); - self - } - - /// Set the text weight. - /// - /// If `yes` is true then text will be written in bold. - /// If `yes` is false then text will be written in the default weight. - /// - /// # Examples - /// - /// Create a style with bold text: - /// - /// ``` - /// use std::io::Write; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut style = buf.style(); - /// - /// style.set_bold(true); - /// - /// writeln!(buf, "{}", style.value(record.args())) - /// }); - /// ``` - pub fn set_bold(&mut self, yes: bool) -> &mut Style { - self.spec.set_bold(yes); - self - } - - /// Set the text intensity. - /// - /// If `yes` is true then text will be written in a brighter color. - /// If `yes` is false then text will be written in the default color. - /// - /// # Examples - /// - /// Create a style with intense text: - /// - /// ``` - /// use std::io::Write; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut style = buf.style(); - /// - /// style.set_intense(true); - /// - /// writeln!(buf, "{}", style.value(record.args())) - /// }); - /// ``` - pub fn set_intense(&mut self, yes: bool) -> &mut Style { - self.spec.set_intense(yes); - self - } - - /// Set the background color. - /// - /// # Examples - /// - /// Create a style with a yellow background: - /// - /// ``` - /// use std::io::Write; - /// use env_logger::fmt::Color; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut style = buf.style(); - /// - /// style.set_bg(Color::Yellow); - /// - /// writeln!(buf, "{}", style.value(record.args())) - /// }); - /// ``` - pub fn set_bg(&mut self, color: Color) -> &mut Style { - self.spec.set_bg(color.into_termcolor()); - self - } - - /// Wrap a value in the style. - /// - /// The same `Style` can be used to print multiple different values. - /// - /// # Examples - /// - /// Create a bold, red colored style and use it to print the log level: - /// - /// ``` - /// use std::io::Write; - /// use env_logger::fmt::Color; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut style = buf.style(); - /// - /// style.set_color(Color::Red).set_bold(true); - /// - /// writeln!(buf, "{}: {}", - /// style.value(record.level()), - /// record.args()) - /// }); - /// ``` - pub fn value(&self, value: T) -> StyledValue { - StyledValue { - style: &self, - value - } - } -} - -impl Formatter { - pub(crate) fn new(writer: &Writer) -> Self { - Formatter { - buf: Rc::new(RefCell::new(writer.inner.buffer())), - write_style: writer.write_style(), - } - } - - pub(crate) fn write_style(&self) -> WriteStyle { - self.write_style - } - - /// Begin a new [`Style`]. - /// - /// # Examples - /// - /// Create a bold, red colored style and use it to print the log level: - /// - /// ``` - /// use std::io::Write; - /// use env_logger::fmt::Color; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let mut level_style = buf.style(); - /// - /// level_style.set_color(Color::Red).set_bold(true); - /// - /// writeln!(buf, "{}: {}", - /// level_style.value(record.level()), - /// record.args()) - /// }); - /// ``` - /// - /// [`Style`]: struct.Style.html - pub fn style(&self) -> Style { - Style { - buf: self.buf.clone(), - spec: ColorSpec::new(), - } - } - - /// Get the default [`Style`] for the given level. - pub fn default_level_style(&self, level: Level) -> Style { - let mut level_style = self.style(); - match level { - Level::Trace => level_style.set_color(Color::White), - Level::Debug => level_style.set_color(Color::Blue), - Level::Info => level_style.set_color(Color::Green), - Level::Warn => level_style.set_color(Color::Yellow), - Level::Error => level_style.set_color(Color::Red).set_bold(true), - }; - level_style - } - - /// Get a [`Timestamp`] for the current date and time in UTC. - /// - /// # Examples - /// - /// Include the current timestamp with the log record: - /// - /// ``` - /// use std::io::Write; - /// - /// let mut builder = env_logger::Builder::new(); - /// - /// builder.format(|buf, record| { - /// let ts = buf.timestamp(); - /// - /// writeln!(buf, "{}: {}: {}", ts, record.level(), record.args()) - /// }); - /// ``` - /// - /// [`Timestamp`]: struct.Timestamp.html - pub fn timestamp(&self) -> Timestamp { - Timestamp(SystemTime::now()) - } - - /// Get a [`PreciseTimestamp`] for the current date and time in UTC with nanos. - pub fn precise_timestamp(&self) -> PreciseTimestamp { - PreciseTimestamp(SystemTime::now()) - } - - pub(crate) fn print(&self, writer: &Writer) -> io::Result<()> { - writer.inner.print(&self.buf.borrow()) - } - - pub(crate) fn clear(&mut self) { - self.buf.borrow_mut().clear() - } -} - -impl Write for Formatter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.buf.borrow_mut().write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.buf.borrow_mut().flush() - } -} - -impl<'a, T> StyledValue<'a, T> { - fn write_fmt(&self, f: F) -> fmt::Result - where - F: FnOnce() -> fmt::Result, - { - self.style.buf.borrow_mut().set_color(&self.style.spec).map_err(|_| fmt::Error)?; - - // Always try to reset the terminal style, even if writing failed - let write = f(); - let reset = self.style.buf.borrow_mut().reset().map_err(|_| fmt::Error); - - write.and(reset) - } -} - -impl fmt::Debug for Timestamp { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - /// A `Debug` wrapper for `Timestamp` that uses the `Display` implementation. - struct TimestampValue<'a>(&'a Timestamp); - - impl<'a> fmt::Debug for TimestampValue<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) - } - } - - f.debug_tuple("Timestamp") - .field(&TimestampValue(&self)) - .finish() - } -} - -impl fmt::Debug for Writer { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Writer").finish() - } -} - -impl fmt::Debug for Formatter { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Formatter").finish() - } -} - -impl fmt::Debug for Builder { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Logger") - .field("target", &self.target) - .field("write_style", &self.write_style) - .finish() - } -} - -impl fmt::Debug for Style { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Style").field("spec", &self.spec).finish() - } -} - -macro_rules! impl_styled_value_fmt { - ($($fmt_trait:path),*) => { - $( - impl<'a, T: $fmt_trait> $fmt_trait for StyledValue<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - self.write_fmt(|| T::fmt(&self.value, f)) - } - } - )* - }; -} - -impl_styled_value_fmt!( - fmt::Debug, - fmt::Display, - fmt::Pointer, - fmt::Octal, - fmt::Binary, - fmt::UpperHex, - fmt::LowerHex, - fmt::UpperExp, - fmt::LowerExp); - -impl fmt::Display for Timestamp { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - format_rfc3339_seconds(self.0).fmt(f) - } -} - -impl fmt::Display for PreciseTimestamp { - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - format_rfc3339_nanos(self.0).fmt(f) - } -} - -// The `Color` type is copied from https://github.com/BurntSushi/ripgrep/tree/master/termcolor - -/// The set of available colors for the terminal foreground/background. -/// -/// The `Ansi256` and `Rgb` colors will only output the correct codes when -/// paired with the `Ansi` `WriteColor` implementation. -/// -/// The `Ansi256` and `Rgb` color types are not supported when writing colors -/// on Windows using the console. If they are used on Windows, then they are -/// silently ignored and no colors will be emitted. -/// -/// This set may expand over time. -/// -/// This type has a `FromStr` impl that can parse colors from their human -/// readable form. The format is as follows: -/// -/// 1. Any of the explicitly listed colors in English. They are matched -/// case insensitively. -/// 2. A single 8-bit integer, in either decimal or hexadecimal format. -/// 3. A triple of 8-bit integers separated by a comma, where each integer is -/// in decimal or hexadecimal format. -/// -/// Hexadecimal numbers are written with a `0x` prefix. -#[allow(missing_docs)] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Color { - Black, - Blue, - Green, - Red, - Cyan, - Magenta, - Yellow, - White, - Ansi256(u8), - Rgb(u8, u8, u8), - #[doc(hidden)] - __Nonexhaustive, -} - -/// An error from parsing an invalid color specification. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ParseColorError(ParseColorErrorKind); - -#[derive(Clone, Debug, Eq, PartialEq)] -enum ParseColorErrorKind { - /// An error originating from `termcolor`. - TermColor(termcolor::ParseColorError), - /// An error converting the `termcolor` color to a `env_logger::Color`. - /// - /// This variant should only get reached if a user uses a new spec that's - /// valid for `termcolor`, but not recognised in `env_logger` yet. - Unrecognized { - given: String, - } -} - -impl ParseColorError { - fn termcolor(err: termcolor::ParseColorError) -> Self { - ParseColorError(ParseColorErrorKind::TermColor(err)) - } - - fn unrecognized(given: String) -> Self { - ParseColorError(ParseColorErrorKind::Unrecognized { given }) - } - - /// Return the string that couldn't be parsed as a valid color. - pub fn invalid(&self) -> &str { - match self.0 { - ParseColorErrorKind::TermColor(ref err) => err.invalid(), - ParseColorErrorKind::Unrecognized { ref given, .. } => given, - } - } -} - -impl Error for ParseColorError { - fn description(&self) -> &str { - match self.0 { - ParseColorErrorKind::TermColor(ref err) => err.description(), - ParseColorErrorKind::Unrecognized { .. } => "unrecognized color value", - } - } -} - -impl fmt::Display for ParseColorError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - ParseColorErrorKind::TermColor(ref err) => fmt::Display::fmt(err, f), - ParseColorErrorKind::Unrecognized { ref given, .. } => { - write!(f, "unrecognized color value '{}'", given) - } - } - } -} - -impl Color { - fn into_termcolor(self) -> Option { - match self { - Color::Black => Some(termcolor::Color::Black), - Color::Blue => Some(termcolor::Color::Blue), - Color::Green => Some(termcolor::Color::Green), - Color::Red => Some(termcolor::Color::Red), - Color::Cyan => Some(termcolor::Color::Cyan), - Color::Magenta => Some(termcolor::Color::Magenta), - Color::Yellow => Some(termcolor::Color::Yellow), - Color::White => Some(termcolor::Color::White), - Color::Ansi256(value) => Some(termcolor::Color::Ansi256(value)), - Color::Rgb(r, g, b) => Some(termcolor::Color::Rgb(r, g, b)), - _ => None, - } - } - - fn from_termcolor(color: termcolor::Color) -> Option { - match color { - termcolor::Color::Black => Some(Color::Black), - termcolor::Color::Blue => Some(Color::Blue), - termcolor::Color::Green => Some(Color::Green), - termcolor::Color::Red => Some(Color::Red), - termcolor::Color::Cyan => Some(Color::Cyan), - termcolor::Color::Magenta => Some(Color::Magenta), - termcolor::Color::Yellow => Some(Color::Yellow), - termcolor::Color::White => Some(Color::White), - termcolor::Color::Ansi256(value) => Some(Color::Ansi256(value)), - termcolor::Color::Rgb(r, g, b) => Some(Color::Rgb(r, g, b)), - _ => None, - } - } -} - -impl FromStr for Color { - type Err = ParseColorError; - - fn from_str(s: &str) -> Result { - let tc = termcolor::Color::from_str(s).map_err(ParseColorError::termcolor)?; - Color::from_termcolor(tc).ok_or_else(|| ParseColorError::unrecognized(s.into())) - } -} - -fn parse_write_style(spec: &str) -> WriteStyle { - match spec { - "auto" => WriteStyle::Auto, - "always" => WriteStyle::Always, - "never" => WriteStyle::Never, - _ => Default::default(), - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_write_style_valid() { - let inputs = vec![ - ("auto", WriteStyle::Auto), - ("always", WriteStyle::Always), - ("never", WriteStyle::Never), - ]; - - for (input, expected) in inputs { - assert_eq!(expected, parse_write_style(input)); - } - } - - #[test] - fn parse_write_style_invalid() { - let inputs = vec![ - "", - "true", - "false", - "NEVER!!" - ]; - - for input in inputs { - assert_eq!(WriteStyle::Auto, parse_write_style(input)); - } - } - - #[test] - fn parse_color_name_valid() { - let inputs = vec![ - "black", - "blue", - "green", - "red", - "cyan", - "magenta", - "yellow", - "white", - ]; - - for input in inputs { - assert!(Color::from_str(input).is_ok()); - } - } - - #[test] - fn parse_color_ansi_valid() { - let inputs = vec![ - "7", - "32", - "0xFF", - ]; - - for input in inputs { - assert!(Color::from_str(input).is_ok()); - } - } - - #[test] - fn parse_color_rgb_valid() { - let inputs = vec![ - "0,0,0", - "0,128,255", - "0x0,0x0,0x0", - "0x33,0x66,0xFF", - ]; - - for input in inputs { - assert!(Color::from_str(input).is_ok()); - } - } - - #[test] - fn parse_color_invalid() { - let inputs = vec![ - "not_a_color", - "256", - "0,0", - "0,0,256", - ]; - - for input in inputs { - let err = Color::from_str(input).unwrap_err(); - assert_eq!(input, err.invalid()); - } - } -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/src/lib.rs cargo-0.35.0/vendor/env_logger-0.5.13/src/lib.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1125 +0,0 @@ -// Copyright 2014-2015 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A simple logger configured via environment variables which writes -//! to stdout or stderr, for use with the logging facade exposed by the -//! [`log` crate][log-crate-url]. -//! -//! ## Example -//! -//! ``` -//! #[macro_use] extern crate log; -//! extern crate env_logger; -//! -//! use log::Level; -//! -//! fn main() { -//! env_logger::init(); -//! -//! debug!("this is a debug {}", "message"); -//! error!("this is printed by default"); -//! -//! if log_enabled!(Level::Info) { -//! let x = 3 * 4; // expensive computation -//! info!("the answer was: {}", x); -//! } -//! } -//! ``` -//! -//! Assumes the binary is `main`: -//! -//! ```{.bash} -//! $ RUST_LOG=error ./main -//! ERROR: 2017-11-09T02:12:24Z: main: this is printed by default -//! ``` -//! -//! ```{.bash} -//! $ RUST_LOG=info ./main -//! ERROR: 2017-11-09T02:12:24Z: main: this is printed by default -//! INFO: 2017-11-09T02:12:24Z: main: the answer was: 12 -//! ``` -//! -//! ```{.bash} -//! $ RUST_LOG=debug ./main -//! DEBUG: 2017-11-09T02:12:24Z: main: this is a debug message -//! ERROR: 2017-11-09T02:12:24Z: main: this is printed by default -//! INFO: 2017-11-09T02:12:24Z: main: the answer was: 12 -//! ``` -//! -//! You can also set the log level on a per module basis: -//! -//! ```{.bash} -//! $ RUST_LOG=main=info ./main -//! ERROR: 2017-11-09T02:12:24Z: main: this is printed by default -//! INFO: 2017-11-09T02:12:24Z: main: the answer was: 12 -//! ``` -//! -//! And enable all logging: -//! -//! ```{.bash} -//! $ RUST_LOG=main ./main -//! DEBUG: 2017-11-09T02:12:24Z: main: this is a debug message -//! ERROR: 2017-11-09T02:12:24Z: main: this is printed by default -//! INFO: 2017-11-09T02:12:24Z: main: the answer was: 12 -//! ``` -//! -//! If the binary name contains hyphens, you will need to replace -//! them with underscores: -//! -//! ```{.bash} -//! $ RUST_LOG=my_app ./my-app -//! DEBUG: 2017-11-09T02:12:24Z: my_app: this is a debug message -//! ERROR: 2017-11-09T02:12:24Z: my_app: this is printed by default -//! INFO: 2017-11-09T02:12:24Z: my_app: the answer was: 12 -//! ``` -//! -//! This is because Rust modules and crates cannot contain hyphens -//! in their name, although `cargo` continues to accept them. -//! -//! See the documentation for the [`log` crate][log-crate-url] for more -//! information about its API. -//! -//! ## Enabling logging -//! -//! Log levels are controlled on a per-module basis, and by default all logging -//! is disabled except for `error!`. Logging is controlled via the `RUST_LOG` -//! environment variable. The value of this environment variable is a -//! comma-separated list of logging directives. A logging directive is of the -//! form: -//! -//! ```text -//! path::to::module=level -//! ``` -//! -//! The path to the module is rooted in the name of the crate it was compiled -//! for, so if your program is contained in a file `hello.rs`, for example, to -//! turn on logging for this file you would use a value of `RUST_LOG=hello`. -//! Furthermore, this path is a prefix-search, so all modules nested in the -//! specified module will also have logging enabled. -//! -//! The actual `level` is optional to specify. If omitted, all logging will -//! be enabled. If specified, it must be one of the strings `debug`, `error`, -//! `info`, `warn`, or `trace`. -//! -//! As the log level for a module is optional, the module to enable logging for -//! is also optional. If only a `level` is provided, then the global log -//! level for all modules is set to this value. -//! -//! Some examples of valid values of `RUST_LOG` are: -//! -//! * `hello` turns on all logging for the 'hello' module -//! * `info` turns on all info logging -//! * `hello=debug` turns on debug logging for 'hello' -//! * `hello,std::option` turns on hello, and std's option logging -//! * `error,hello=warn` turn on global error logging and also warn for hello -//! -//! ## Filtering results -//! -//! A `RUST_LOG` directive may include a regex filter. The syntax is to append `/` -//! followed by a regex. Each message is checked against the regex, and is only -//! logged if it matches. Note that the matching is done after formatting the -//! log string but before adding any logging meta-data. There is a single filter -//! for all modules. -//! -//! Some examples: -//! -//! * `hello/foo` turns on all logging for the 'hello' module where the log -//! message includes 'foo'. -//! * `info/f.o` turns on all info logging where the log message includes 'foo', -//! 'f1o', 'fao', etc. -//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the log -//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc. -//! * `error,hello=warn/[0-9]scopes` turn on global error logging and also -//! warn for hello. In both cases the log message must include a single digit -//! number followed by 'scopes'. -//! -//! ## Disabling colors -//! -//! Colors and other styles can be configured with the `RUST_LOG_STYLE` -//! environment variable. It accepts the following values: -//! -//! * `auto` (default) will attempt to print style characters, but don't force the issue. -//! If the console isn't available on Windows, or if TERM=dumb, for example, then don't print colors. -//! * `always` will always print style characters even if they aren't supported by the terminal. -//! This includes emitting ANSI colors on Windows if the console API is unavailable. -//! * `never` will never print style characters. -//! -//! ## Tweaking the default format -//! -//! Parts of the default format can be excluded from the log output using the [`Builder`]. -//! The following example excludes the timestamp from the log output: -//! -//! ``` -//! #[macro_use] extern crate log; -//! extern crate env_logger; -//! -//! use log::Level; -//! -//! fn main() { -//! env_logger::Builder::from_default_env() -//! .default_format_timestamp(false) -//! .init(); -//! -//! debug!("this is a debug {}", "message"); -//! error!("this is printed by default"); -//! -//! if log_enabled!(Level::Info) { -//! let x = 3 * 4; // expensive computation -//! info!("the answer was: {}", x); -//! } -//! } -//! ``` -//! -//! ## Specifying defaults for environment variables -//! -//! `env_logger` can read configuration from environment variables. -//! If these variables aren't present, the default value to use can be tweaked with the [`Env`] type. -//! The following example defaults to log `warn` and above if the `RUST_LOG` environment variable -//! isn't set: -//! -//! ``` -//! #[macro_use] extern crate log; -//! extern crate env_logger; -//! -//! use log::Level; -//! -//! fn main() { -//! let env = env_logger::Env::default() -//! .filter_or(env_logger::DEFAULT_FILTER_ENV, "warn"); -//! -//! env_logger::Builder::from_env(env).init(); -//! } -//! ``` -//! -//! [log-crate-url]: https://docs.rs/log/ -//! [`Builder`]: struct.Builder.html -//! [`Env`]: struct.Env.html - -#![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 = "https://docs.rs/env_logger/0.5.13")] -#![cfg_attr(test, deny(warnings))] - -// When compiled for the rustc compiler itself we want to make sure that this is -// an unstable crate -#![cfg_attr(rustbuild, feature(staged_api, rustc_private))] -#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] - -#![deny(missing_debug_implementations, missing_docs, warnings)] - -extern crate log; -extern crate termcolor; -extern crate humantime; -extern crate atty; - -use std::env; -use std::borrow::Cow; -use std::io::prelude::*; -use std::io; -use std::mem; -use std::cell::RefCell; - -use log::{Log, LevelFilter, Record, SetLoggerError, Metadata}; - -pub mod filter; -pub mod fmt; - -pub use self::fmt::{Target, WriteStyle, Color, Formatter}; - -/// The default name for the environment variable to read filters from. -pub const DEFAULT_FILTER_ENV: &'static str = "RUST_LOG"; - -/// The default name for the environment variable to read style preferences from. -pub const DEFAULT_WRITE_STYLE_ENV: &'static str = "RUST_LOG_STYLE"; - -/// Set of environment variables to configure from. -/// -/// # Default environment variables -/// -/// By default, the `Env` will read the following environment variables: -/// -/// - `RUST_LOG`: the level filter -/// - `RUST_LOG_STYLE`: whether or not to print styles with records. -/// -/// These sources can be configured using the builder methods on `Env`. -#[derive(Debug)] -pub struct Env<'a> { - filter: Var<'a>, - write_style: Var<'a>, -} - -#[derive(Debug)] -struct Var<'a> { - name: Cow<'a, str>, - default: Option>, -} - -/// The env logger. -/// -/// This struct implements the `Log` trait from the [`log` crate][log-crate-url], -/// which allows it to act as a logger. -/// -/// The [`init()`], [`try_init()`], [`Builder::init()`] and [`Builder::try_init()`] -/// methods will each construct a `Logger` and immediately initialize it as the -/// default global logger. -/// -/// If you'd instead need access to the constructed `Logger`, you can use -/// the associated [`Builder`] and install it with the -/// [`log` crate][log-crate-url] directly. -/// -/// [log-crate-url]: https://docs.rs/log/ -/// [`init()`]: fn.init.html -/// [`try_init()`]: fn.try_init.html -/// [`Builder::init()`]: struct.Builder.html#method.init -/// [`Builder::try_init()`]: struct.Builder.html#method.try_init -/// [`Builder`]: struct.Builder.html -pub struct Logger { - writer: fmt::Writer, - filter: filter::Filter, - format: Box io::Result<()> + Sync + Send>, -} - -struct Format { - default_format_timestamp: bool, - default_format_module_path: bool, - default_format_level: bool, - default_format_timestamp_nanos: bool, - custom_format: Option io::Result<()> + Sync + Send>>, -} - -impl Default for Format { - fn default() -> Self { - Format { - default_format_timestamp: true, - default_format_module_path: true, - default_format_level: true, - default_format_timestamp_nanos: false, - custom_format: None, - } - } -} - -impl Format { - /// Convert the format into a callable function. - /// - /// If the `custom_format` is `Some`, then any `default_format` switches are ignored. - /// If the `custom_format` is `None`, then a default format is returned. - /// Any `default_format` switches set to `false` won't be written by the format. - fn into_boxed_fn(self) -> Box io::Result<()> + Sync + Send> { - if let Some(fmt) = self.custom_format { - fmt - } - else { - Box::new(move |buf, record| { - let write_level = if self.default_format_level { - let level = record.level(); - let level_style = buf.default_level_style(level); - write!(buf, "{:>5} ", level_style.value(level)) - } else { - Ok(()) - }; - - let write_ts = if self.default_format_timestamp { - if self.default_format_timestamp_nanos { - let ts_nanos = buf.precise_timestamp(); - write!(buf, "{}: ", ts_nanos) - } else { - let ts = buf.timestamp(); - write!(buf, "{}: ", ts) - } - } else { - Ok(()) - }; - - let default_format_module_path = (self.default_format_module_path, record.module_path()); - let write_module_path = if let (true, Some(module_path)) = default_format_module_path { - write!(buf, "{}: ", module_path) - } else { - Ok(()) - }; - - let write_args = writeln!(buf, "{}", record.args()); - - write_level.and(write_ts).and(write_module_path).and(write_args) - }) - } - } -} - -/// `Builder` acts as builder for initializing a `Logger`. -/// -/// It can be used to customize the log format, change the environment variable used -/// to provide the logging directives and also set the default log level filter. -/// -/// # Examples -/// -/// ``` -/// #[macro_use] -/// extern crate log; -/// extern crate env_logger; -/// -/// use std::env; -/// use std::io::Write; -/// use log::LevelFilter; -/// use env_logger::Builder; -/// -/// fn main() { -/// let mut builder = Builder::from_default_env(); -/// -/// builder.format(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args())) -/// .filter(None, LevelFilter::Info) -/// .init(); -/// -/// error!("error message"); -/// info!("info message"); -/// } -/// ``` -#[derive(Default)] -pub struct Builder { - filter: filter::Builder, - writer: fmt::Builder, - format: Format, -} - -impl Builder { - /// Initializes the log builder with defaults. - /// - /// **NOTE:** This method won't read from any environment variables. - /// Use the [`filter`] and [`write_style`] methods to configure the builder - /// or use [`from_env`] or [`from_default_env`] instead. - /// - /// # Examples - /// - /// Create a new builder and configure filters and style: - /// - /// ``` - /// # extern crate log; - /// # extern crate env_logger; - /// # fn main() { - /// use log::LevelFilter; - /// use env_logger::{Builder, WriteStyle}; - /// - /// let mut builder = Builder::new(); - /// - /// builder.filter(None, LevelFilter::Info) - /// .write_style(WriteStyle::Always) - /// .init(); - /// # } - /// ``` - /// - /// [`filter`]: #method.filter - /// [`write_style`]: #method.write_style - /// [`from_env`]: #method.from_env - /// [`from_default_env`]: #method.from_default_env - pub fn new() -> Builder { - Default::default() - } - - /// Initializes the log builder from the environment. - /// - /// The variables used to read configuration from can be tweaked before - /// passing in. - /// - /// # Examples - /// - /// Initialise a logger reading the log filter from an environment variable - /// called `MY_LOG`: - /// - /// ``` - /// use env_logger::Builder; - /// - /// let mut builder = Builder::from_env("MY_LOG"); - /// builder.init(); - /// ``` - /// - /// Initialise a logger using the `MY_LOG` variable for filtering and - /// `MY_LOG_STYLE` for whether or not to write styles: - /// - /// ``` - /// use env_logger::{Builder, Env}; - /// - /// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); - /// - /// let mut builder = Builder::from_env(env); - /// builder.init(); - /// ``` - pub fn from_env<'a, E>(env: E) -> Self - where - E: Into> - { - let mut builder = Builder::new(); - let env = env.into(); - - if let Some(s) = env.get_filter() { - builder.parse(&s); - } - - if let Some(s) = env.get_write_style() { - builder.parse_write_style(&s); - } - - builder - } - - /// Initializes the log builder from the environment using default variable names. - /// - /// This method is a convenient way to call `from_env(Env::default())` without - /// having to use the `Env` type explicitly. The builder will use the - /// [default environment variables]. - /// - /// # Examples - /// - /// Initialise a logger using the default environment variables: - /// - /// ``` - /// use env_logger::Builder; - /// - /// let mut builder = Builder::from_default_env(); - /// builder.init(); - /// ``` - /// - /// [default environment variables]: struct.Env.html#default-environment-variables - pub fn from_default_env() -> Self { - Self::from_env(Env::default()) - } - - /// Sets the format function for formatting the log output. - /// - /// This function is called on each record logged and should format the - /// log record and output it to the given [`Formatter`]. - /// - /// The format function is expected to output the string directly to the - /// `Formatter` so that implementations can use the [`std::fmt`] macros - /// to format and output without intermediate heap allocations. The default - /// `env_logger` formatter takes advantage of this. - /// - /// # Examples - /// - /// Use a custom format to write only the log message: - /// - /// ``` - /// use std::io::Write; - /// use env_logger::Builder; - /// - /// let mut builder = Builder::new(); - /// - /// builder.format(|buf, record| write!(buf, "{}", record.args())); - /// ``` - /// - /// [`Formatter`]: fmt/struct.Formatter.html - /// [`String`]: https://doc.rust-lang.org/stable/std/string/struct.String.html - /// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html - pub fn format(&mut self, format: F) -> &mut Self - where F: Fn(&mut Formatter, &Record) -> io::Result<()> + Sync + Send - { - self.format.custom_format = Some(Box::new(format)); - self - } - - /// Use the default format. - /// - /// This method will clear any custom format set on the builder. - pub fn default_format(&mut self) -> &mut Self { - self.format.custom_format = None; - self - } - - /// Whether or not to write the level in the default format. - pub fn default_format_level(&mut self, write: bool) -> &mut Self { - self.format.default_format_level = write; - self - } - - /// Whether or not to write the module path in the default format. - pub fn default_format_module_path(&mut self, write: bool) -> &mut Self { - self.format.default_format_module_path = write; - self - } - - /// Whether or not to write the timestamp in the default format. - pub fn default_format_timestamp(&mut self, write: bool) -> &mut Self { - self.format.default_format_timestamp = write; - self - } - - /// Whether or not to write the timestamp with nanos. - pub fn default_format_timestamp_nanos(&mut self, write: bool) -> &mut Self { - self.format.default_format_timestamp_nanos = write; - self - } - - /// Adds a directive to the filter for a specific module. - /// - /// # Examples - /// - /// Only include messages for warning and above for logs in `path::to::module`: - /// - /// ``` - /// # extern crate log; - /// # extern crate env_logger; - /// # fn main() { - /// use log::LevelFilter; - /// use env_logger::Builder; - /// - /// let mut builder = Builder::new(); - /// - /// builder.filter_module("path::to::module", LevelFilter::Info); - /// # } - /// ``` - pub fn filter_module(&mut self, module: &str, level: LevelFilter) -> &mut Self { - self.filter.filter_module(module, level); - self - } - - /// Adds a directive to the filter for all modules. - /// - /// # Examples - /// - /// Only include messages for warning and above for logs in `path::to::module`: - /// - /// ``` - /// # extern crate log; - /// # extern crate env_logger; - /// # fn main() { - /// use log::LevelFilter; - /// use env_logger::Builder; - /// - /// let mut builder = Builder::new(); - /// - /// builder.filter_level(LevelFilter::Info); - /// # } - /// ``` - pub fn filter_level(&mut self, level: LevelFilter) -> &mut Self { - self.filter.filter_level(level); - self - } - - /// Adds filters to the logger. - /// - /// The given module (if any) will log at most the specified level provided. - /// If no module is provided then the filter will apply to all log messages. - /// - /// # Examples - /// - /// Only include messages for warning and above for logs in `path::to::module`: - /// - /// ``` - /// # extern crate log; - /// # extern crate env_logger; - /// # fn main() { - /// use log::LevelFilter; - /// use env_logger::Builder; - /// - /// let mut builder = Builder::new(); - /// - /// builder.filter(Some("path::to::module"), LevelFilter::Info); - /// # } - /// ``` - pub fn filter(&mut self, - module: Option<&str>, - level: LevelFilter) -> &mut Self { - self.filter.filter(module, level); - self - } - - /// Parses the directives string in the same form as the `RUST_LOG` - /// environment variable. - /// - /// See the module documentation for more details. - pub fn parse(&mut self, filters: &str) -> &mut Self { - self.filter.parse(filters); - self - } - - /// Sets the target for the log output. - /// - /// Env logger can log to either stdout or stderr. The default is stderr. - /// - /// # Examples - /// - /// Write log message to `stdout`: - /// - /// ``` - /// use env_logger::{Builder, Target}; - /// - /// let mut builder = Builder::new(); - /// - /// builder.target(Target::Stdout); - /// ``` - pub fn target(&mut self, target: fmt::Target) -> &mut Self { - self.writer.target(target); - self - } - - /// Sets whether or not styles will be written. - /// - /// This can be useful in environments that don't support control characters - /// for setting colors. - /// - /// # Examples - /// - /// Never attempt to write styles: - /// - /// ``` - /// use env_logger::{Builder, WriteStyle}; - /// - /// let mut builder = Builder::new(); - /// - /// builder.write_style(WriteStyle::Never); - /// ``` - pub fn write_style(&mut self, write_style: fmt::WriteStyle) -> &mut Self { - self.writer.write_style(write_style); - self - } - - /// Parses whether or not to write styles in the same form as the `RUST_LOG_STYLE` - /// environment variable. - /// - /// See the module documentation for more details. - pub fn parse_write_style(&mut self, write_style: &str) -> &mut Self { - self.writer.parse(write_style); - self - } - - /// Initializes the global logger with the built env logger. - /// - /// This should be called early in the execution of a Rust program. Any log - /// events that occur before initialization will be ignored. - /// - /// # Errors - /// - /// This function will fail if it is called more than once, or if another - /// library has already initialized a global logger. - pub fn try_init(&mut self) -> Result<(), SetLoggerError> { - let logger = self.build(); - - log::set_max_level(logger.filter()); - log::set_boxed_logger(Box::new(logger)) - } - - /// Initializes the global logger with the built env logger. - /// - /// This should be called early in the execution of a Rust program. Any log - /// events that occur before initialization will be ignored. - /// - /// # Panics - /// - /// This function will panic if it is called more than once, or if another - /// library has already initialized a global logger. - pub fn init(&mut self) { - self.try_init().expect("Builder::init should not be called after logger initialized"); - } - - /// Build an env logger. - /// - /// The returned logger implements the `Log` trait and can be installed manually - /// or nested within another logger. - pub fn build(&mut self) -> Logger { - Logger { - writer: self.writer.build(), - filter: self.filter.build(), - format: mem::replace(&mut self.format, Default::default()).into_boxed_fn(), - } - } -} - -impl Logger { - /// Creates the logger from the environment. - /// - /// The variables used to read configuration from can be tweaked before - /// passing in. - /// - /// # Examples - /// - /// Create a logger reading the log filter from an environment variable - /// called `MY_LOG`: - /// - /// ``` - /// use env_logger::Logger; - /// - /// let logger = Logger::from_env("MY_LOG"); - /// ``` - /// - /// Create a logger using the `MY_LOG` variable for filtering and - /// `MY_LOG_STYLE` for whether or not to write styles: - /// - /// ``` - /// use env_logger::{Logger, Env}; - /// - /// let env = Env::new().filter_or("MY_LOG", "info").write_style_or("MY_LOG_STYLE", "always"); - /// - /// let logger = Logger::from_env(env); - /// ``` - pub fn from_env<'a, E>(env: E) -> Self - where - E: Into> - { - Builder::from_env(env).build() - } - - /// Creates the logger from the environment using default variable names. - /// - /// This method is a convenient way to call `from_env(Env::default())` without - /// having to use the `Env` type explicitly. The logger will use the - /// [default environment variables]. - /// - /// # Examples - /// - /// Creates a logger using the default environment variables: - /// - /// ``` - /// use env_logger::Logger; - /// - /// let logger = Logger::from_default_env(); - /// ``` - /// - /// [default environment variables]: struct.Env.html#default-environment-variables - pub fn from_default_env() -> Self { - Builder::from_default_env().build() - } - - /// Returns the maximum `LevelFilter` that this env logger instance is - /// configured to output. - pub fn filter(&self) -> LevelFilter { - self.filter.filter() - } - - /// Checks if this record matches the configured filter. - pub fn matches(&self, record: &Record) -> bool { - self.filter.matches(record) - } -} - -impl Log for Logger { - fn enabled(&self, metadata: &Metadata) -> bool { - self.filter.enabled(metadata) - } - - fn log(&self, record: &Record) { - if self.matches(record) { - // Log records are written to a thread-local buffer before being printed - // to the terminal. We clear these buffers afterwards, but they aren't shrinked - // so will always at least have capacity for the largest log record formatted - // on that thread. - // - // If multiple `Logger`s are used by the same threads then the thread-local - // formatter might have different color support. If this is the case the - // formatter and its buffer are discarded and recreated. - - thread_local! { - static FORMATTER: RefCell> = RefCell::new(None); - } - - FORMATTER.with(|tl_buf| { - // It's possible for implementations to sometimes - // log-while-logging (e.g. a `std::fmt` implementation logs - // internally) but it's super rare. If this happens make sure we - // at least don't panic and ship some output to the screen. - let mut a; - let mut b = None; - let tl_buf = match tl_buf.try_borrow_mut() { - Ok(f) => { - a = f; - &mut *a - } - Err(_) => &mut b, - }; - - // Check the buffer style. If it's different from the logger's - // style then drop the buffer and recreate it. - match *tl_buf { - Some(ref mut formatter) => { - if formatter.write_style() != self.writer.write_style() { - *formatter = Formatter::new(&self.writer) - } - }, - ref mut tl_buf => *tl_buf = Some(Formatter::new(&self.writer)) - } - - // The format is guaranteed to be `Some` by this point - let mut formatter = tl_buf.as_mut().unwrap(); - - let _ = (self.format)(&mut formatter, record).and_then(|_| formatter.print(&self.writer)); - - // Always clear the buffer afterwards - formatter.clear(); - }); - } - } - - fn flush(&self) {} -} - -impl<'a> Env<'a> { - /// Get a default set of environment variables. - pub fn new() -> Self { - Self::default() - } - - /// Specify an environment variable to read the filter from. - pub fn filter(mut self, filter_env: E) -> Self - where - E: Into> - { - self.filter = Var::new(filter_env); - - self - } - - /// Specify an environment variable to read the filter from. - /// - /// If the variable is not set, the default value will be used. - pub fn filter_or(mut self, filter_env: E, default: V) -> Self - where - E: Into>, - V: Into>, - { - self.filter = Var::new_with_default(filter_env, default); - - self - } - - fn get_filter(&self) -> Option { - self.filter.get() - } - - /// Specify an environment variable to read the style from. - pub fn write_style(mut self, write_style_env: E) -> Self - where - E: Into> - { - self.write_style = Var::new(write_style_env); - - self - } - - /// Specify an environment variable to read the style from. - /// - /// If the variable is not set, the default value will be used. - pub fn write_style_or(mut self, write_style_env: E, default: V) -> Self - where - E: Into>, - V: Into>, - { - self.write_style = Var::new_with_default(write_style_env, default); - - self - } - - fn get_write_style(&self) -> Option { - self.write_style.get() - } -} - -impl<'a> Var<'a> { - fn new(name: E) -> Self - where - E: Into>, - { - Var { - name: name.into(), - default: None, - } - } - - fn new_with_default(name: E, default: V) -> Self - where - E: Into>, - V: Into>, - { - Var { - name: name.into(), - default: Some(default.into()), - } - } - - fn get(&self) -> Option { - env::var(&*self.name) - .ok() - .or_else(|| self.default - .to_owned() - .map(|v| v.into_owned())) - } -} - -impl<'a, T> From for Env<'a> -where - T: Into> -{ - fn from(filter_env: T) -> Self { - Env::default().filter(filter_env.into()) - } -} - -impl<'a> Default for Env<'a> { - fn default() -> Self { - Env { - filter: Var::new(DEFAULT_FILTER_ENV), - write_style: Var::new(DEFAULT_WRITE_STYLE_ENV), - } - } -} - -mod std_fmt_impls { - use std::fmt; - use super::*; - - impl fmt::Debug for Logger{ - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Logger") - .field("filter", &self.filter) - .finish() - } - } - - impl fmt::Debug for Builder{ - fn fmt(&self, f: &mut fmt::Formatter)->fmt::Result { - f.debug_struct("Logger") - .field("filter", &self.filter) - .field("writer", &self.writer) - .finish() - } - } -} - -/// Attempts to initialize the global logger with an env logger. -/// -/// This should be called early in the execution of a Rust program. Any log -/// events that occur before initialization will be ignored. -/// -/// # Errors -/// -/// This function will fail if it is called more than once, or if another -/// library has already initialized a global logger. -pub fn try_init() -> Result<(), SetLoggerError> { - try_init_from_env(Env::default()) -} - -/// Initializes the global logger with an env logger. -/// -/// This should be called early in the execution of a Rust program. Any log -/// events that occur before initialization will be ignored. -/// -/// # Panics -/// -/// This function will panic if it is called more than once, or if another -/// library has already initialized a global logger. -pub fn init() { - try_init().expect("env_logger::init should not be called after logger initialized"); -} - -/// Attempts to initialize the global logger with an env logger from the given -/// environment variables. -/// -/// This should be called early in the execution of a Rust program. Any log -/// events that occur before initialization will be ignored. -/// -/// # Examples -/// -/// Initialise a logger using the `MY_LOG` environment variable for filters -/// and `MY_LOG_STYLE` for writing colors: -/// -/// ``` -/// # extern crate env_logger; -/// use env_logger::{Builder, Env}; -/// -/// # fn run() -> Result<(), Box<::std::error::Error>> { -/// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); -/// -/// env_logger::try_init_from_env(env)?; -/// -/// Ok(()) -/// # } -/// # fn main() { run().unwrap(); } -/// ``` -/// -/// # Errors -/// -/// This function will fail if it is called more than once, or if another -/// library has already initialized a global logger. -pub fn try_init_from_env<'a, E>(env: E) -> Result<(), SetLoggerError> -where - E: Into> -{ - let mut builder = Builder::from_env(env); - - builder.try_init() -} - -/// Initializes the global logger with an env logger from the given environment -/// variables. -/// -/// This should be called early in the execution of a Rust program. Any log -/// events that occur before initialization will be ignored. -/// -/// # Examples -/// -/// Initialise a logger using the `MY_LOG` environment variable for filters -/// and `MY_LOG_STYLE` for writing colors: -/// -/// ``` -/// use env_logger::{Builder, Env}; -/// -/// let env = Env::new().filter("MY_LOG").write_style("MY_LOG_STYLE"); -/// -/// env_logger::init_from_env(env); -/// ``` -/// -/// # Panics -/// -/// This function will panic if it is called more than once, or if another -/// library has already initialized a global logger. -pub fn init_from_env<'a, E>(env: E) -where - E: Into> -{ - try_init_from_env(env).expect("env_logger::init_from_env should not be called after logger initialized"); -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn env_get_filter_reads_from_var_if_set() { - env::set_var("env_get_filter_reads_from_var_if_set", "from var"); - - let env = Env::new().filter_or("env_get_filter_reads_from_var_if_set", "from default"); - - assert_eq!(Some("from var".to_owned()), env.get_filter()); - } - - #[test] - fn env_get_filter_reads_from_default_if_var_not_set() { - env::remove_var("env_get_filter_reads_from_default_if_var_not_set"); - - let env = Env::new().filter_or("env_get_filter_reads_from_default_if_var_not_set", "from default"); - - assert_eq!(Some("from default".to_owned()), env.get_filter()); - } - - #[test] - fn env_get_write_style_reads_from_var_if_set() { - env::set_var("env_get_write_style_reads_from_var_if_set", "from var"); - - let env = Env::new().write_style_or("env_get_write_style_reads_from_var_if_set", "from default"); - - assert_eq!(Some("from var".to_owned()), env.get_write_style()); - } - - #[test] - fn env_get_write_style_reads_from_default_if_var_not_set() { - env::remove_var("env_get_write_style_reads_from_default_if_var_not_set"); - - let env = Env::new().write_style_or("env_get_write_style_reads_from_default_if_var_not_set", "from default"); - - assert_eq!(Some("from default".to_owned()), env.get_write_style()); - } -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/tests/log-in-log.rs cargo-0.35.0/vendor/env_logger-0.5.13/tests/log-in-log.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/tests/log-in-log.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/tests/log-in-log.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#[macro_use] extern crate log; -extern crate env_logger; - -use std::process; -use std::fmt; -use std::env; -use std::str; - -struct Foo; - -impl fmt::Display for Foo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - info!("test"); - f.write_str("bar") - } -} - -fn main() { - env_logger::init(); - if env::var("YOU_ARE_TESTING_NOW").is_ok() { - return info!("{}", Foo); - } - - let exe = env::current_exe().unwrap(); - let out = process::Command::new(exe) - .env("YOU_ARE_TESTING_NOW", "1") - .env("RUST_LOG", "debug") - .output() - .unwrap_or_else(|e| panic!("Unable to start child process: {}", e)); - if out.status.success() { - return - } - - println!("test failed: {}", out.status); - println!("--- stdout\n{}", str::from_utf8(&out.stdout).unwrap()); - println!("--- stderr\n{}", str::from_utf8(&out.stderr).unwrap()); - process::exit(1); -} diff -Nru cargo-0.33.0/vendor/env_logger-0.5.13/tests/regexp_filter.rs cargo-0.35.0/vendor/env_logger-0.5.13/tests/regexp_filter.rs --- cargo-0.33.0/vendor/env_logger-0.5.13/tests/regexp_filter.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/env_logger-0.5.13/tests/regexp_filter.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -#[macro_use] extern crate log; -extern crate env_logger; - -use std::process; -use std::env; -use std::str; - -fn main() { - if env::var("LOG_REGEXP_TEST").ok() == Some(String::from("1")) { - child_main(); - } else { - parent_main() - } -} - -fn child_main() { - env_logger::init(); - info!("XYZ Message"); -} - -fn run_child(rust_log: String) -> bool { - let exe = env::current_exe().unwrap(); - let out = process::Command::new(exe) - .env("LOG_REGEXP_TEST", "1") - .env("RUST_LOG", rust_log) - .output() - .unwrap_or_else(|e| panic!("Unable to start child process: {}", e)); - str::from_utf8(out.stderr.as_ref()).unwrap().contains("XYZ Message") -} - -fn assert_message_printed(rust_log: &str) { - if !run_child(rust_log.to_string()) { - panic!("RUST_LOG={} should allow the test log message", rust_log) - } -} - -fn assert_message_not_printed(rust_log: &str) { - if run_child(rust_log.to_string()) { - panic!("RUST_LOG={} should not allow the test log message", rust_log) - } -} - -fn parent_main() { - // test normal log severity levels - assert_message_printed("info"); - assert_message_not_printed("warn"); - - // test of regular expression filters - assert_message_printed("info/XYZ"); - assert_message_not_printed("info/XXX"); -} diff -Nru cargo-0.33.0/vendor/filetime/.cargo-checksum.json cargo-0.35.0/vendor/filetime/.cargo-checksum.json --- cargo-0.33.0/vendor/filetime/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646"} \ No newline at end of file +{"files":{},"package":"2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/filetime/Cargo.toml cargo-0.35.0/vendor/filetime/Cargo.toml --- cargo-0.33.0/vendor/filetime/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "filetime" -version = "0.2.4" +version = "0.2.5" authors = ["Alex Crichton "] description = "Platform-agnostic accessors of timestamps in File metadata\n" homepage = "https://github.com/alexcrichton/filetime" diff -Nru cargo-0.33.0/vendor/filetime/README.md cargo-0.35.0/vendor/filetime/README.md --- cargo-0.33.0/vendor/filetime/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -5,7 +5,7 @@ [Documentation](https://docs.rs/filetime) -A helper library for inspecting the various timestamps of files in Rust. This +A helper library for inspecting and setting the various timestamps of files in Rust. This library takes into account cross-platform differences in terms of where the timestamps are located, what they are called, and how to convert them into a platform-independent representation. @@ -16,6 +16,12 @@ filetime = "0.2" ``` +# Advantages over using `std::fs::Metadata` + +This library includes the ability to set this data, which std does not. + +This library, when built with `RUSTFLAGS=--cfg emulate_second_only_system` set, will return all times rounded down to the second. This emulates the behavior of some file systems, mostly [HFS](https://en.wikipedia.org/wiki/HFS_Plus), allowing debugging on other hardware. + # License This project is licensed under either of @@ -30,5 +36,5 @@ ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be +for inclusion in Filetime by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. diff -Nru cargo-0.33.0/vendor/filetime/src/lib.rs cargo-0.35.0/vendor/filetime/src/lib.rs --- cargo-0.33.0/vendor/filetime/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -50,6 +50,9 @@ } else if #[cfg(windows)] { #[path = "windows.rs"] mod imp; + } else if #[cfg(target_arch = "wasm32")] { + #[path = "wasm.rs"] + mod imp; } else { #[path = "unix/mod.rs"] mod imp; @@ -75,6 +78,14 @@ FileTime { seconds: 0, nanos: 0 } } + fn emulate_second_only_system(self) -> FileTime { + if cfg!(emulate_second_only_system) { + FileTime {seconds: self.seconds, nanos: 0} + } else { + self + } + } + /// Creates a new instance of `FileTime` with a number of seconds and /// nanoseconds relative to the Unix epoch, 1970-01-01T00:00:00Z. /// @@ -89,7 +100,7 @@ FileTime { seconds: seconds + if cfg!(windows) {11644473600} else {0}, nanos, - } + }.emulate_second_only_system() } /// Creates a new timestamp from the last modification time listed in the @@ -98,7 +109,7 @@ /// The returned value corresponds to the `mtime` field of `stat` on Unix /// platforms and the `ftLastWriteTime` field on Windows platforms. pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime { - imp::from_last_modification_time(meta) + imp::from_last_modification_time(meta).emulate_second_only_system() } /// Creates a new timestamp from the last access time listed in the @@ -107,7 +118,7 @@ /// The returned value corresponds to the `atime` field of `stat` on Unix /// platforms and the `ftLastAccessTime` field on Windows platforms. pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime { - imp::from_last_access_time(meta) + imp::from_last_access_time(meta).emulate_second_only_system() } /// Creates a new timestamp from the creation time listed in the specified @@ -118,7 +129,7 @@ /// that not all Unix platforms have this field available and may return /// `None` in some circumstances. pub fn from_creation_time(meta: &fs::Metadata) -> Option { - imp::from_creation_time(meta) + imp::from_creation_time(meta).map(|x| x.emulate_second_only_system()) } /// Creates a new timestamp from the given SystemTime. @@ -149,7 +160,7 @@ seconds: -1 * until_epoch.as_secs() as i64 + sec_offset, nanos } - }) + }).emulate_second_only_system() } /// Returns the whole number of seconds represented by this timestamp. diff -Nru cargo-0.33.0/vendor/filetime/src/unix/mod.rs cargo-0.35.0/vendor/filetime/src/unix/mod.rs --- cargo-0.33.0/vendor/filetime/src/unix/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/src/unix/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -15,12 +15,11 @@ if #[cfg(target_os = "linux")] { mod linux; pub use self::linux::*; - // netbsd, openbsd and freebsd should use utimensat, but the call is not - // in the latest rust libc (0.2.43). as soon as a new version is available - // these target_os'es should be added back in. } else if #[cfg(any(target_os = "android", target_os = "solaris", target_os = "emscripten", + target_os = "freebsd", + target_os = "netbsd", target_os = "openbsd"))] { mod utimensat; pub use self::utimensat::*; diff -Nru cargo-0.33.0/vendor/filetime/src/wasm.rs cargo-0.35.0/vendor/filetime/src/wasm.rs --- cargo-0.33.0/vendor/filetime/src/wasm.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/filetime/src/wasm.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,26 @@ +#![allow(unused_variables)] +#![allow(bad_style)] + +use std::path::Path; +use std::{fs, io}; +use FileTime; + +pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "Wasm not implemented")) +} + +pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, "Wasm not implemented")) +} + +pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime { + unimplemented!() +} + +pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime { + unimplemented!() +} + +pub fn from_creation_time(meta: &fs::Metadata) -> Option { + unimplemented!() +} diff -Nru cargo-0.33.0/vendor/flate2/appveyor.yml cargo-0.35.0/vendor/flate2/appveyor.yml --- cargo-0.33.0/vendor/flate2/appveyor.yml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -environment: - matrix: - - TARGET: x86_64-pc-windows-msvc - - TARGET: x86_64-pc-windows-gnu - - TARGET: i686-pc-windows-msvc - - TARGET: i686-pc-windows-gnu -install: - - ps: >- - If ($Env:TARGET -eq 'x86_64-pc-windows-gnu') { - $Env:PATH += ';C:\msys64\mingw64\bin' - } ElseIf ($Env:TARGET -eq 'i686-pc-windows-gnu') { - $Env:PATH += ';C:\MinGW\bin' - } - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" - - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin - - rustc -V - - cargo -V - -build: false - -test_script: - - cargo test --target %TARGET% - - cargo test --target %TARGET% --features tokio - -branches: - only: - - master diff -Nru cargo-0.33.0/vendor/flate2/azure-pipelines.yml cargo-0.35.0/vendor/flate2/azure-pipelines.yml --- cargo-0.33.0/vendor/flate2/azure-pipelines.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/azure-pipelines.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,52 @@ +trigger: + - master + +jobs: +- template: ci/azure-job-test-all.yml + parameters: + name: Linux_stable +- template: ci/azure-job-test-all.yml + parameters: + vmImage: macOS-10.13 + name: Darwin_stable +- template: ci/azure-job-test-all.yml + parameters: + toolchain: beta + name: Linux_beta +- template: ci/azure-job-test-all.yml + parameters: + toolchain: nightly + name: Linux_nightly +- template: ci/azure-job-test-all.yml + parameters: + vmImage: vs2017-win2016 + name: Windows_stable +- template: ci/azure-job-test-all.yml + parameters: + vmImage: vs2017-win2016 + toolchain: stable-x86_64-gnu + name: Windows_stable_MinGW +- job: systest + steps: + - template: ci/azure-install-rust.yml + - script: cargo run --manifest-path systest/Cargo.toml +- job: wasm + steps: + - template: ci/azure-install-rust.yml + - script: rustup target add wasm32-unknown-unknown + - script: cargo build --target wasm32-unknown-unknown +- job: rust_backend + steps: + - template: ci/azure-install-rust.yml + - script: cargo test --features rust_backend + continueOnError: true + - script: cargo test --features rust_backend --no-default-features + continueOnError: true +- job: docs + steps: + - template: ci/azure-install-rust.yml + - script: cargo doc --no-deps --all-features + - script: curl -LsSf https://git.io/fhJ8n | rustc - && (cd target/doc && ../../rust_out) + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + env: + GITHUB_DEPLOY_KEY: $(GITHUB_DEPLOY_KEY) diff -Nru cargo-0.33.0/vendor/flate2/.cargo-checksum.json cargo-0.35.0/vendor/flate2/.cargo-checksum.json --- cargo-0.33.0/vendor/flate2/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4"} \ No newline at end of file +{"files":{},"package":"f87e68aa82b2de08a6e037f1385455759df6e445a8df5e005b4297191dbf18aa"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/flate2/Cargo.toml cargo-0.35.0/vendor/flate2/Cargo.toml --- cargo-0.33.0/vendor/flate2/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "flate2" -version = "1.0.6" +version = "1.0.7" authors = ["Alex Crichton "] description = "Bindings to miniz.c for DEFLATE compression and decompression exposed as\nReader/Writer streams. Contains bindings for zlib, deflate, and gzip-based\nstreams.\n" homepage = "https://github.com/alexcrichton/flate2-rs" @@ -26,7 +26,7 @@ version = "1.1" [dependencies.futures] -version = "0.1" +version = "0.1.25" optional = true [dependencies.libc] @@ -37,8 +37,11 @@ optional = true [dependencies.tokio-io] -version = "0.1" +version = "0.1.11" optional = true +[dev-dependencies.futures] +version = "0.1" + [dev-dependencies.quickcheck] version = "0.7" default-features = false @@ -46,8 +49,14 @@ [dev-dependencies.rand] version = "0.6" -[dev-dependencies.tokio-core] -version = "0.1" +[dev-dependencies.tokio-io] +version = "0.1.11" + +[dev-dependencies.tokio-tcp] +version = "0.1.3" + +[dev-dependencies.tokio-threadpool] +version = "0.1.10" [features] default = ["zlib"] diff -Nru cargo-0.33.0/vendor/flate2/ci/azure-install-rust.yml cargo-0.35.0/vendor/flate2/ci/azure-install-rust.yml --- cargo-0.33.0/vendor/flate2/ci/azure-install-rust.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/ci/azure-install-rust.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,25 @@ +parameters: + toolchain: 'stable' + +steps: + - bash: | + curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $TOOLCHAIN + echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" + displayName: Install rust + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + env: + TOOLCHAIN: ${{ parameters.toolchain }} + + - script: | + curl -sSf -o rustup-init.exe https://win.rustup.rs + rustup-init.exe -y --default-toolchain %TOOLCHAIN% + echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin" + displayName: Install rust + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + env: + TOOLCHAIN: ${{ parameters.toolchain }} + + - script: | + rustc -Vv + cargo -V + displayName: Query rust and cargo versions diff -Nru cargo-0.33.0/vendor/flate2/ci/azure-job-test-all.yml cargo-0.35.0/vendor/flate2/ci/azure-job-test-all.yml --- cargo-0.33.0/vendor/flate2/ci/azure-job-test-all.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/ci/azure-job-test-all.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,20 @@ +parameters: + toolchain: 'stable' + vmImage: 'ubuntu-16.04' + name: '' + +jobs: +- job: ${{ parameters.name }} + pool: + vmImage: ${{ parameters.vmImage }} + steps: + - template: azure-install-rust.yml + parameters: + toolchain: ${{ parameters.toolchain }} + - script: cargo build + - script: rustdoc --test README.md -L target/debug/deps --extern flate2=target/debug/libflate2.rlib + - script: cargo test + - script: cargo test --features zlib + - script: cargo test --features tokio + - script: cargo test --features "tokio zlib" + - script: cargo test --features zlib --no-default-features diff -Nru cargo-0.33.0/vendor/flate2/examples/deflatedecoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/deflatedecoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/deflatedecoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflatedecoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::DeflateEncoder; use flate2::bufread::DeflateDecoder; +use flate2::write::DeflateEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/deflatedecoder-read.rs cargo-0.35.0/vendor/flate2/examples/deflatedecoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/deflatedecoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflatedecoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::DeflateEncoder; use flate2::read::DeflateDecoder; +use flate2::write::DeflateEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/deflatedecoder-write.rs cargo-0.35.0/vendor/flate2/examples/deflatedecoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/deflatedecoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflatedecoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::DeflateEncoder; use flate2::write::DeflateDecoder; +use flate2::write::DeflateEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/deflateencoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/deflateencoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/deflateencoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflateencoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; use flate2::bufread::DeflateEncoder; +use flate2::Compression; use std::fs::File; +use std::io; +use std::io::prelude::*; use std::io::BufReader; // Open file and debug print the contents compressed with Deflate diff -Nru cargo-0.33.0/vendor/flate2/examples/deflateencoder-read.rs cargo-0.35.0/vendor/flate2/examples/deflateencoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/deflateencoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflateencoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; use flate2::read::DeflateEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Print the Deflate compressed representation of hello world fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/deflateencoder-write.rs cargo-0.35.0/vendor/flate2/examples/deflateencoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/deflateencoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/deflateencoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,8 @@ extern crate flate2; -use std::io::prelude::*; -use flate2::Compression; use flate2::write::DeflateEncoder; +use flate2::Compression; +use std::io::prelude::*; // Vec implements Write to print the compressed bytes of sample string fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzbuilder.rs cargo-0.35.0/vendor/flate2/examples/gzbuilder.rs --- cargo-0.33.0/vendor/flate2/examples/gzbuilder.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzbuilder.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use std::fs::File; -use flate2::GzBuilder; use flate2::Compression; +use flate2::GzBuilder; +use std::fs::File; +use std::io; +use std::io::prelude::*; // Open file and debug print the contents compressed with gzip fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzdecoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/gzdecoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/gzdecoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzdecoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::GzEncoder; use flate2::bufread::GzDecoder; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzdecoder-read.rs cargo-0.35.0/vendor/flate2/examples/gzdecoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/gzdecoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzdecoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::GzEncoder; use flate2::read::GzDecoder; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzdecoder-write.rs cargo-0.35.0/vendor/flate2/examples/gzdecoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/gzdecoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzdecoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; +use flate2::write::{GzDecoder, GzEncoder}; use flate2::Compression; -use flate2::write::{GzEncoder, GzDecoder}; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzencoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/gzencoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/gzencoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzencoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; use flate2::bufread::GzEncoder; +use flate2::Compression; use std::fs::File; +use std::io; +use std::io::prelude::*; use std::io::BufReader; // Open file and debug print the contents compressed with gzip diff -Nru cargo-0.33.0/vendor/flate2/examples/gzencoder-read.rs cargo-0.35.0/vendor/flate2/examples/gzencoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/gzencoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzencoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; use flate2::read::GzEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Print the GZ compressed representation of hello world fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzencoder-write.rs cargo-0.35.0/vendor/flate2/examples/gzencoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/gzencoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzencoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,8 @@ extern crate flate2; -use std::io::prelude::*; -use flate2::Compression; use flate2::write::GzEncoder; +use flate2::Compression; +use std::io::prelude::*; // Vec implements Write to print the compressed bytes of sample string fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzmultidecoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/gzmultidecoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/gzmultidecoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzmultidecoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::GzEncoder; use flate2::bufread::MultiGzDecoder; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/gzmultidecoder-read.rs cargo-0.35.0/vendor/flate2/examples/gzmultidecoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/gzmultidecoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/gzmultidecoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::GzEncoder; use flate2::read::MultiGzDecoder; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibdecoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/zlibdecoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/zlibdecoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibdecoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::ZlibEncoder; use flate2::bufread::ZlibDecoder; +use flate2::write::ZlibEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibdecoder-read.rs cargo-0.35.0/vendor/flate2/examples/zlibdecoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/zlibdecoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibdecoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::ZlibEncoder; use flate2::read::ZlibDecoder; +use flate2::write::ZlibEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibdecoder-write.rs cargo-0.35.0/vendor/flate2/examples/zlibdecoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/zlibdecoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibdecoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; -use flate2::write::ZlibEncoder; use flate2::write::ZlibDecoder; +use flate2::write::ZlibEncoder; +use flate2::Compression; +use std::io; +use std::io::prelude::*; // Compress a sample string and print it after transformation. fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibencoder-bufread.rs cargo-0.35.0/vendor/flate2/examples/zlibencoder-bufread.rs --- cargo-0.33.0/vendor/flate2/examples/zlibencoder-bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibencoder-bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,10 @@ extern crate flate2; -use std::io::prelude::*; -use std::io; -use flate2::Compression; use flate2::bufread::ZlibEncoder; +use flate2::Compression; use std::fs::File; +use std::io; +use std::io::prelude::*; use std::io::BufReader; // Open file and debug print the contents compressed with zlib diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibencoder-read.rs cargo-0.35.0/vendor/flate2/examples/zlibencoder-read.rs --- cargo-0.33.0/vendor/flate2/examples/zlibencoder-read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibencoder-read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,9 @@ extern crate flate2; -use std::io::prelude::*; -use flate2::Compression; use flate2::read::ZlibEncoder; +use flate2::Compression; use std::fs::File; +use std::io::prelude::*; // Open file and debug print the compressed contents fn main() { diff -Nru cargo-0.33.0/vendor/flate2/examples/zlibencoder-write.rs cargo-0.35.0/vendor/flate2/examples/zlibencoder-write.rs --- cargo-0.33.0/vendor/flate2/examples/zlibencoder-write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/examples/zlibencoder-write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,8 @@ extern crate flate2; -use std::io::prelude::*; -use flate2::Compression; use flate2::write::ZlibEncoder; +use flate2::Compression; +use std::io::prelude::*; // Vec implements Write to print the compressed bytes of sample string fn main() { diff -Nru cargo-0.33.0/vendor/flate2/.pc/disable-miniz.patch/Cargo.toml cargo-0.35.0/vendor/flate2/.pc/disable-miniz.patch/Cargo.toml --- cargo-0.33.0/vendor/flate2/.pc/disable-miniz.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/.pc/disable-miniz.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "flate2" -version = "1.0.6" +version = "1.0.7" authors = ["Alex Crichton "] description = "Bindings to miniz.c for DEFLATE compression and decompression exposed as\nReader/Writer streams. Contains bindings for zlib, deflate, and gzip-based\nstreams.\n" homepage = "https://github.com/alexcrichton/flate2-rs" @@ -26,7 +26,7 @@ version = "1.1" [dependencies.futures] -version = "0.1" +version = "0.1.25" optional = true [dependencies.libc] @@ -46,8 +46,11 @@ optional = true [dependencies.tokio-io] -version = "0.1" +version = "0.1.11" optional = true +[dev-dependencies.futures] +version = "0.1" + [dev-dependencies.quickcheck] version = "0.7" default-features = false @@ -55,8 +58,14 @@ [dev-dependencies.rand] version = "0.6" -[dev-dependencies.tokio-core] -version = "0.1" +[dev-dependencies.tokio-io] +version = "0.1.11" + +[dev-dependencies.tokio-tcp] +version = "0.1.3" + +[dev-dependencies.tokio-threadpool] +version = "0.1.10" [features] default = ["miniz-sys"] diff -Nru cargo-0.33.0/vendor/flate2/README.md cargo-0.35.0/vendor/flate2/README.md --- cargo-0.33.0/vendor/flate2/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,6 @@ # flate2 -[![Build Status](https://travis-ci.org/alexcrichton/flate2-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/flate2-rs) -[![Build status](https://ci.appveyor.com/api/projects/status/9tatexq47i3ee13k?svg=true)](https://ci.appveyor.com/project/alexcrichton/flate2-rs) +[![Build Status](https://dev.azure.com/alexcrichton/flate2-rs/_apis/build/status/alexcrichton.flate2-rs?branchName=master)](https://dev.azure.com/alexcrichton/flate2-rs/_build/latest?definitionId=1&branchName=master) [![Crates.io](https://img.shields.io/crates/v/flate2.svg?maxAge=2592000)](https://crates.io/crates/flate2) [![Documentation](https://docs.rs/flate2/badge.svg)](https://docs.rs/flate2) diff -Nru cargo-0.33.0/vendor/flate2/src/crc.rs cargo-0.35.0/vendor/flate2/src/crc.rs --- cargo-0.33.0/vendor/flate2/src/crc.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/crc.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,7 @@ //! Simple CRC bindings backed by miniz.c -use std::io::prelude::*; use std::io; +use std::io::prelude::*; use crc32fast::Hasher; @@ -26,7 +26,10 @@ impl Crc { /// Create a new CRC. pub fn new() -> Crc { - Crc { amt: 0, hasher: Hasher::new() } + Crc { + amt: 0, + hasher: Hasher::new(), + } } /// Returns the current crc32 checksum. diff -Nru cargo-0.33.0/vendor/flate2/src/deflate/bufread.rs cargo-0.35.0/vendor/flate2/src/deflate/bufread.rs --- cargo-0.33.0/vendor/flate2/src/deflate/bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/deflate/bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,5 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; use std::mem; #[cfg(feature = "tokio")] diff -Nru cargo-0.33.0/vendor/flate2/src/deflate/read.rs cargo-0.35.0/vendor/flate2/src/deflate/read.rs --- cargo-0.33.0/vendor/flate2/src/deflate/read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/deflate/read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,13 +1,13 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; #[cfg(feature = "tokio")] use futures::Poll; #[cfg(feature = "tokio")] use tokio_io::{AsyncRead, AsyncWrite}; -use bufreader::BufReader; use super::bufread; +use bufreader::BufReader; /// A DEFLATE encoder, or compressor. /// diff -Nru cargo-0.33.0/vendor/flate2/src/deflate/write.rs cargo-0.35.0/vendor/flate2/src/deflate/write.rs --- cargo-0.33.0/vendor/flate2/src/deflate/write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/deflate/write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,5 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; #[cfg(feature = "tokio")] use futures::Poll; @@ -169,7 +169,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for DeflateEncoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.inner.finish()); + self.inner.finish()?; self.inner.get_mut().shutdown() } } @@ -334,7 +334,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for DeflateDecoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.inner.finish()); + self.inner.finish()?; self.inner.get_mut().shutdown() } } diff -Nru cargo-0.33.0/vendor/flate2/src/ffi.rs cargo-0.35.0/vendor/flate2/src/ffi.rs --- cargo-0.33.0/vendor/flate2/src/ffi.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/ffi.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,17 +4,17 @@ #[allow(bad_style)] mod imp { extern crate libz_sys as z; + use libc::{c_char, c_int}; use std::mem; use std::ops::{Deref, DerefMut}; - use libc::{c_char, c_int}; - pub use self::z::*; + pub use self::z::deflate as mz_deflate; pub use self::z::deflateEnd as mz_deflateEnd; - pub use self::z::inflateEnd as mz_inflateEnd; pub use self::z::deflateReset as mz_deflateReset; - pub use self::z::deflate as mz_deflate; pub use self::z::inflate as mz_inflate; + pub use self::z::inflateEnd as mz_inflateEnd; pub use self::z::z_stream as mz_stream; + pub use self::z::*; pub use self::z::Z_BLOCK as MZ_BLOCK; pub use self::z::Z_BUF_ERROR as MZ_BUF_ERROR; @@ -23,13 +23,13 @@ pub use self::z::Z_DEFLATED as MZ_DEFLATED; pub use self::z::Z_FINISH as MZ_FINISH; pub use self::z::Z_FULL_FLUSH as MZ_FULL_FLUSH; + pub use self::z::Z_NEED_DICT as MZ_NEED_DICT; pub use self::z::Z_NO_FLUSH as MZ_NO_FLUSH; pub use self::z::Z_OK as MZ_OK; pub use self::z::Z_PARTIAL_FLUSH as MZ_PARTIAL_FLUSH; pub use self::z::Z_STREAM_END as MZ_STREAM_END; - pub use self::z::Z_SYNC_FLUSH as MZ_SYNC_FLUSH; pub use self::z::Z_STREAM_ERROR as MZ_STREAM_ERROR; - pub use self::z::Z_NEED_DICT as MZ_NEED_DICT; + pub use self::z::Z_SYNC_FLUSH as MZ_SYNC_FLUSH; pub const MZ_DEFAULT_WINDOW_BITS: c_int = 15; @@ -96,13 +96,16 @@ } } -#[cfg(any(all(not(feature = "zlib"), feature = "rust_backend"), all(target_arch = "wasm32", not(target_os = "emscripten"))))] +#[cfg(any( + all(not(feature = "zlib"), feature = "rust_backend"), + all(target_arch = "wasm32", not(target_os = "emscripten")) +))] mod imp { extern crate miniz_oxide_c_api; use std::ops::{Deref, DerefMut}; - pub use self::miniz_oxide_c_api::*; pub use self::miniz_oxide_c_api::lib_oxide::*; + pub use self::miniz_oxide_c_api::*; #[derive(Debug, Default)] pub struct StreamWrapper { @@ -124,7 +127,11 @@ } } -#[cfg(all(not(feature = "zlib"), not(feature = "rust_backend"), not(all(target_arch = "wasm32", not(target_os = "emscripten")))))] +#[cfg(all( + not(feature = "zlib"), + not(feature = "rust_backend"), + not(all(target_arch = "wasm32", not(target_os = "emscripten"))) +))] mod imp { extern crate miniz_sys; use std::mem; @@ -164,4 +171,3 @@ } } } - diff -Nru cargo-0.33.0/vendor/flate2/src/gz/bufread.rs cargo-0.35.0/vendor/flate2/src/gz/bufread.rs --- cargo-0.33.0/vendor/flate2/src/gz/bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/gz/bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,6 +3,11 @@ use std::io::prelude::*; use std::mem; +#[cfg(feature = "tokio")] +use futures::Poll; +#[cfg(feature = "tokio")] +use tokio_io::{AsyncRead, AsyncWrite}; + use super::{GzBuilder, GzHeader}; use super::{FCOMMENT, FEXTRA, FHCRC, FNAME}; use crc::CrcReader; @@ -211,6 +216,19 @@ } } +#[inline] +fn finish(buf: &[u8; 8]) -> (u32, u32) { + let crc = ((buf[0] as u32) << 0) + | ((buf[1] as u32) << 8) + | ((buf[2] as u32) << 16) + | ((buf[3] as u32) << 24); + let amt = ((buf[4] as u32) << 0) + | ((buf[5] as u32) << 8) + | ((buf[6] as u32) << 16) + | ((buf[7] as u32) << 24); + (crc, amt) +} + impl Read for GzEncoder { fn read(&mut self, mut into: &mut [u8]) -> io::Result { let mut amt = 0; @@ -280,69 +298,101 @@ /// ``` #[derive(Debug)] pub struct GzDecoder { - inner: CrcReader>, - header: Option>, - finished: bool, + inner: GzState, + header: Option, + reader: CrcReader>, + multi: bool +} + +#[derive(Debug)] +enum GzState { + Header(Vec), + Body, + Finished(usize, [u8; 8]), + Err(io::Error), + End +} + +/// A small adapter which reads data originally from `buf` and then reads all +/// further data from `reader`. This will also buffer all data read from +/// `reader` into `buf` for reuse on a further call. +struct Buffer<'a, T: 'a> { + buf: &'a mut Vec, + buf_cur: usize, + buf_max: usize, + reader: &'a mut T +} + +impl<'a, T> Buffer<'a, T> { + fn new(buf: &'a mut Vec, reader: &'a mut T) -> Buffer<'a, T> { + Buffer { + reader, + buf_cur: 0, + buf_max: buf.len(), + buf, + } + } +} + +impl<'a, T: Read> Read for Buffer<'a, T> { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if self.buf_cur == self.buf_max { + let len = self.reader.read(buf)?; + self.buf.extend_from_slice(&buf[..len]); + Ok(len) + } else { + let len = (&self.buf[self.buf_cur..self.buf_max]).read(buf)?; + self.buf_cur += len; + Ok(len) + } + } } impl GzDecoder { /// Creates a new decoder from the given reader, immediately parsing the /// gzip header. pub fn new(mut r: R) -> GzDecoder { - let header = read_gz_header(&mut r); + let mut buf = Vec::with_capacity(10); // minimum header length + let mut header = None; + + let result = { + let mut reader = Buffer::new(&mut buf, &mut r); + read_gz_header(&mut reader) + }; + + let state = match result { + Ok(hdr) => { + header = Some(hdr); + GzState::Body + }, + Err(ref err) if io::ErrorKind::WouldBlock == err.kind() + => GzState::Header(buf), + Err(err) => GzState::Err(err) + }; - let flate = deflate::bufread::DeflateDecoder::new(r); GzDecoder { - inner: CrcReader::new(flate), - header: Some(header), - finished: false, + inner: state, + reader: CrcReader::new(deflate::bufread::DeflateDecoder::new(r)), + multi: false, + header } } - fn finish(&mut self) -> io::Result<()> { - if self.finished { - return Ok(()); - } - let ref mut buf = [0u8; 8]; - { - let mut len = 0; - - while len < buf.len() { - match self.inner.get_mut().get_mut().read(&mut buf[len..])? { - 0 => return Err(corrupt()), - n => len += n, - } - } - } - - let crc = ((buf[0] as u32) << 0) - | ((buf[1] as u32) << 8) - | ((buf[2] as u32) << 16) - | ((buf[3] as u32) << 24); - let amt = ((buf[4] as u32) << 0) - | ((buf[5] as u32) << 8) - | ((buf[6] as u32) << 16) - | ((buf[7] as u32) << 24); - if crc != self.inner.crc().sum() { - return Err(corrupt()); - } - if amt != self.inner.crc().amount() { - return Err(corrupt()); - } - self.finished = true; - Ok(()) + fn multi(mut self, flag: bool) -> GzDecoder { + self.multi = flag; + self } } impl GzDecoder { /// Returns the header associated with this stream, if it was valid pub fn header(&self) -> Option<&GzHeader> { - self.header.as_ref().and_then(|h| h.as_ref().ok()) + self.header.as_ref() } /// Acquires a reference to the underlying reader. pub fn get_ref(&self) -> &R { - self.inner.get_ref().get_ref() + self.reader.get_ref().get_ref() } /// Acquires a mutable reference to the underlying stream. @@ -350,38 +400,116 @@ /// Note that mutation of the stream may result in surprising results if /// this encoder is continued to be used. pub fn get_mut(&mut self) -> &mut R { - self.inner.get_mut().get_mut() + self.reader.get_mut().get_mut() } /// Consumes this decoder, returning the underlying reader. pub fn into_inner(self) -> R { - self.inner.into_inner().into_inner() + self.reader.into_inner().into_inner() } } impl Read for GzDecoder { fn read(&mut self, into: &mut [u8]) -> io::Result { - match self.header { - None => return Ok(0), // error already returned, - Some(Ok(_)) => {} - Some(Err(_)) => match self.header.take().unwrap() { - Ok(_) => panic!(), - Err(e) => return Err(e), - }, - } - if into.is_empty() { - return Ok(0); - } - match self.inner.read(into)? { - 0 => { - self.finish()?; - Ok(0) - } - n => Ok(n), + let GzDecoder { inner, header, reader, multi } = self; + + loop { + *inner = match mem::replace(inner, GzState::End) { + GzState::Header(mut buf) => { + let result = { + let mut reader = Buffer::new(&mut buf, reader.get_mut().get_mut()); + read_gz_header(&mut reader) + }; + let hdr = result + .map_err(|err| { + if io::ErrorKind::WouldBlock == err.kind() { + *inner = GzState::Header(buf); + } + + err + })?; + *header = Some(hdr); + GzState::Body + }, + GzState::Body => { + if into.is_empty() { + *inner = GzState::Body; + return Ok(0); + } + + let n = reader.read(into) + .map_err(|err| { + if io::ErrorKind::WouldBlock == err.kind() { + *inner = GzState::Body; + } + + err + })?; + + match n { + 0 => GzState::Finished(0, [0; 8]), + n => { + *inner = GzState::Body; + return Ok(n); + } + } + }, + GzState::Finished(pos, mut buf) => if pos < buf.len() { + let n = reader.get_mut().get_mut() + .read(&mut buf[pos..]) + .and_then(|n| if n == 0 { + Err(io::ErrorKind::UnexpectedEof.into()) + } else { + Ok(n) + }) + .map_err(|err| { + if io::ErrorKind::WouldBlock == err.kind() { + *inner = GzState::Finished(pos, buf); + } + + err + })?; + + GzState::Finished(pos + n, buf) + } else { + let (crc, amt) = finish(&buf); + + if crc != reader.crc().sum() || amt != reader.crc().amount() { + return Err(corrupt()); + } else if *multi { + let is_eof = reader.get_mut().get_mut() + .fill_buf() + .map(|buf| buf.is_empty()) + .map_err(|err| { + if io::ErrorKind::WouldBlock == err.kind() { + *inner = GzState::Finished(pos, buf); + } + + err + })?; + + if is_eof { + GzState::End + } else { + reader.reset(); + reader.get_mut().reset_data(); + header.take(); + GzState::Header(Vec::with_capacity(10)) + } + } else { + GzState::End + } + }, + GzState::Err(err) => return Err(err), + GzState::End => return Ok(0) + }; } } } +#[cfg(feature = "tokio")] +impl AsyncRead for GzDecoder {} + impl Write for GzDecoder { fn write(&mut self, buf: &[u8]) -> io::Result { self.get_mut().write(buf) @@ -392,6 +520,13 @@ } } +#[cfg(feature = "tokio")] +impl AsyncWrite for GzDecoder { + fn shutdown(&mut self) -> Poll<(), io::Error> { + self.get_mut().shutdown() + } +} + /// A gzip streaming decoder that decodes all members of a multistream /// /// A gzip member consists of a header, compressed data and a trailer. The [gzip @@ -433,85 +568,26 @@ /// } /// ``` #[derive(Debug)] -pub struct MultiGzDecoder { - inner: CrcReader>, - header: io::Result, - finished: bool, -} +pub struct MultiGzDecoder(GzDecoder); impl MultiGzDecoder { /// Creates a new decoder from the given reader, immediately parsing the /// (first) gzip header. If the gzip stream contains multiple members all will /// be decoded. - pub fn new(mut r: R) -> MultiGzDecoder { - let header = read_gz_header(&mut r); - - let flate = deflate::bufread::DeflateDecoder::new(r); - MultiGzDecoder { - inner: CrcReader::new(flate), - header: header, - finished: false, - } - } - - fn finish_member(&mut self) -> io::Result { - if self.finished { - return Ok(0); - } - let ref mut buf = [0u8; 8]; - { - let mut len = 0; - - while len < buf.len() { - match self.inner.get_mut().get_mut().read(&mut buf[len..])? { - 0 => return Err(corrupt()), - n => len += n, - } - } - } - - let crc = ((buf[0] as u32) << 0) - | ((buf[1] as u32) << 8) - | ((buf[2] as u32) << 16) - | ((buf[3] as u32) << 24); - let amt = ((buf[4] as u32) << 0) - | ((buf[5] as u32) << 8) - | ((buf[6] as u32) << 16) - | ((buf[7] as u32) << 24); - if crc != self.inner.crc().sum() as u32 { - return Err(corrupt()); - } - if amt != self.inner.crc().amount() { - return Err(corrupt()); - } - let remaining = match self.inner.get_mut().get_mut().fill_buf() { - Ok(b) => if b.is_empty() { - self.finished = true; - return Ok(0); - } else { - b.len() - }, - Err(e) => return Err(e), - }; - - let next_header = read_gz_header(self.inner.get_mut().get_mut()); - drop(mem::replace(&mut self.header, next_header)); - self.inner.reset(); - self.inner.get_mut().reset_data(); - - Ok(remaining) + pub fn new(r: R) -> MultiGzDecoder { + MultiGzDecoder(GzDecoder::new(r).multi(true)) } } impl MultiGzDecoder { /// Returns the current header associated with this stream, if it's valid pub fn header(&self) -> Option<&GzHeader> { - self.header.as_ref().ok() + self.0.header() } /// Acquires a reference to the underlying reader. pub fn get_ref(&self) -> &R { - self.inner.get_ref().get_ref() + self.0.get_ref() } /// Acquires a mutable reference to the underlying stream. @@ -519,32 +595,24 @@ /// Note that mutation of the stream may result in surprising results if /// this encoder is continued to be used. pub fn get_mut(&mut self) -> &mut R { - self.inner.get_mut().get_mut() + self.0.get_mut() } /// Consumes this decoder, returning the underlying reader. pub fn into_inner(self) -> R { - self.inner.into_inner().into_inner() + self.0.into_inner() } } impl Read for MultiGzDecoder { fn read(&mut self, into: &mut [u8]) -> io::Result { - if let Err(ref mut e) = self.header { - let another_error = io::ErrorKind::Other.into(); - return Err(mem::replace(e, another_error)); - } - match self.inner.read(into)? { - 0 => match self.finish_member() { - Ok(0) => Ok(0), - Ok(_) => self.read(into), - Err(e) => Err(e), - }, - n => Ok(n), - } + self.0.read(into) } } +#[cfg(feature = "tokio")] +impl AsyncRead for MultiGzDecoder {} + impl Write for MultiGzDecoder { fn write(&mut self, buf: &[u8]) -> io::Result { self.get_mut().write(buf) @@ -554,3 +622,10 @@ self.get_mut().flush() } } + +#[cfg(feature = "tokio")] +impl AsyncWrite for MultiGzDecoder { + fn shutdown(&mut self) -> Poll<(), io::Error> { + self.get_mut().shutdown() + } +} diff -Nru cargo-0.33.0/vendor/flate2/src/gz/mod.rs cargo-0.35.0/vendor/flate2/src/gz/mod.rs --- cargo-0.33.0/vendor/flate2/src/gz/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/gz/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,8 @@ use std::io::prelude::*; use std::time; -use Compression; use bufreader::BufReader; +use Compression; pub static FHCRC: u8 = 1 << 1; pub static FEXTRA: u8 = 1 << 2; @@ -18,7 +18,7 @@ /// /// The header can contain metadata about the file that was compressed, if /// present. -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Clone, Debug, Default)] pub struct GzHeader { extra: Option>, filename: Option>, @@ -257,8 +257,8 @@ use std::io::prelude::*; use super::{read, write, GzBuilder}; - use Compression; use rand::{thread_rng, Rng}; + use Compression; #[test] fn roundtrip() { diff -Nru cargo-0.33.0/vendor/flate2/src/gz/read.rs cargo-0.35.0/vendor/flate2/src/gz/read.rs --- cargo-0.33.0/vendor/flate2/src/gz/read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/gz/read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,15 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; +#[cfg(feature = "tokio")] +use futures::Poll; +#[cfg(feature = "tokio")] +use tokio_io::{AsyncRead, AsyncWrite}; + +use super::bufread; use super::{GzBuilder, GzHeader}; -use Compression; use bufreader::BufReader; -use super::bufread; +use Compression; /// A gzip streaming encoder /// @@ -170,6 +175,9 @@ } } +#[cfg(feature = "tokio")] +impl AsyncRead for GzDecoder {} + impl Write for GzDecoder { fn write(&mut self, buf: &[u8]) -> io::Result { self.get_mut().write(buf) @@ -180,6 +188,13 @@ } } +#[cfg(feature = "tokio")] +impl AsyncWrite for GzDecoder { + fn shutdown(&mut self) -> Poll<(), io::Error> { + self.get_mut().shutdown() + } +} + /// A gzip streaming decoder that decodes all members of a multistream /// /// A gzip member consists of a header, compressed data and a trailer. The [gzip @@ -267,6 +282,9 @@ } } +#[cfg(feature = "tokio")] +impl AsyncRead for MultiGzDecoder {} + impl Write for MultiGzDecoder { fn write(&mut self, buf: &[u8]) -> io::Result { self.get_mut().write(buf) @@ -276,3 +294,10 @@ self.get_mut().flush() } } + +#[cfg(feature = "tokio")] +impl AsyncWrite for MultiGzDecoder { + fn shutdown(&mut self) -> Poll<(), io::Error> { + self.get_mut().shutdown() + } +} diff -Nru cargo-0.33.0/vendor/flate2/src/gz/write.rs cargo-0.35.0/vendor/flate2/src/gz/write.rs --- cargo-0.33.0/vendor/flate2/src/gz/write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/gz/write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -161,7 +161,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for GzEncoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.try_finish()); + self.try_finish()?; self.get_mut().shutdown() } } @@ -388,7 +388,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for GzDecoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.try_finish()); + self.try_finish()?; self.inner.get_mut().get_mut().shutdown() } } diff -Nru cargo-0.33.0/vendor/flate2/src/lib.rs cargo-0.35.0/vendor/flate2/src/lib.rs --- cargo-0.33.0/vendor/flate2/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -89,7 +89,6 @@ #[cfg(test)] extern crate rand; #[cfg(feature = "tokio")] -#[macro_use] extern crate tokio_io; // These must currently agree with here -- @@ -108,19 +107,19 @@ pub type size_t = usize; } +pub use crc::{Crc, CrcReader, CrcWriter}; pub use gz::GzBuilder; pub use gz::GzHeader; pub use mem::{Compress, CompressError, Decompress, DecompressError, Status}; pub use mem::{FlushCompress, FlushDecompress}; -pub use crc::{Crc, CrcReader, CrcWriter}; mod bufreader; mod crc; mod deflate; mod ffi; mod gz; -mod zio; mod mem; +mod zio; mod zlib; /// Types which operate over [`Read`] streams, both encoders and decoders for @@ -128,13 +127,13 @@ /// /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html pub mod read { - pub use deflate::read::DeflateEncoder; pub use deflate::read::DeflateDecoder; - pub use zlib::read::ZlibEncoder; - pub use zlib::read::ZlibDecoder; - pub use gz::read::GzEncoder; + pub use deflate::read::DeflateEncoder; pub use gz::read::GzDecoder; + pub use gz::read::GzEncoder; pub use gz::read::MultiGzDecoder; + pub use zlib::read::ZlibDecoder; + pub use zlib::read::ZlibEncoder; } /// Types which operate over [`Write`] streams, both encoders and decoders for @@ -142,12 +141,12 @@ /// /// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html pub mod write { - pub use deflate::write::DeflateEncoder; pub use deflate::write::DeflateDecoder; - pub use zlib::write::ZlibEncoder; - pub use zlib::write::ZlibDecoder; - pub use gz::write::GzEncoder; + pub use deflate::write::DeflateEncoder; pub use gz::write::GzDecoder; + pub use gz::write::GzEncoder; + pub use zlib::write::ZlibDecoder; + pub use zlib::write::ZlibEncoder; } /// Types which operate over [`BufRead`] streams, both encoders and decoders for @@ -155,13 +154,13 @@ /// /// [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html pub mod bufread { - pub use deflate::bufread::DeflateEncoder; pub use deflate::bufread::DeflateDecoder; - pub use zlib::bufread::ZlibEncoder; - pub use zlib::bufread::ZlibDecoder; - pub use gz::bufread::GzEncoder; + pub use deflate::bufread::DeflateEncoder; pub use gz::bufread::GzDecoder; + pub use gz::bufread::GzEncoder; pub use gz::bufread::MultiGzDecoder; + pub use zlib::bufread::ZlibDecoder; + pub use zlib::bufread::ZlibEncoder; } fn _assert_send_sync() { @@ -228,8 +227,8 @@ #[cfg(test)] fn random_bytes() -> impl Iterator { - use std::iter; use rand::Rng; + use std::iter; iter::repeat(()).map(|_| rand::thread_rng().gen()) } diff -Nru cargo-0.33.0/vendor/flate2/src/mem.rs cargo-0.35.0/vendor/flate2/src/mem.rs --- cargo-0.33.0/vendor/flate2/src/mem.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/mem.rs 2019-05-15 11:26:24.000000000 +0000 @@ -614,10 +614,9 @@ let mut d = Decompress::new(false); // decompressed whole deflate stream - assert!( - d.decompress_vec(&data[10..], &mut decoded, FlushDecompress::Finish) - .is_ok() - ); + assert!(d + .decompress_vec(&data[10..], &mut decoded, FlushDecompress::Finish) + .is_ok()); // decompress data that has nothing to do with the deflate stream (this // used to panic) diff -Nru cargo-0.33.0/vendor/flate2/src/zlib/bufread.rs cargo-0.35.0/vendor/flate2/src/zlib/bufread.rs --- cargo-0.33.0/vendor/flate2/src/zlib/bufread.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/zlib/bufread.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,5 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; use std::mem; #[cfg(feature = "tokio")] diff -Nru cargo-0.33.0/vendor/flate2/src/zlib/mod.rs cargo-0.35.0/vendor/flate2/src/zlib/mod.rs --- cargo-0.33.0/vendor/flate2/src/zlib/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/zlib/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,8 +4,8 @@ #[cfg(test)] mod tests { - use std::io::prelude::*; use std::io; + use std::io::prelude::*; use rand::{thread_rng, Rng}; diff -Nru cargo-0.33.0/vendor/flate2/src/zlib/read.rs cargo-0.35.0/vendor/flate2/src/zlib/read.rs --- cargo-0.33.0/vendor/flate2/src/zlib/read.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/zlib/read.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,13 +1,13 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; #[cfg(feature = "tokio")] use futures::Poll; #[cfg(feature = "tokio")] use tokio_io::{AsyncRead, AsyncWrite}; -use bufreader::BufReader; use super::bufread; +use bufreader::BufReader; /// A ZLIB encoder, or compressor. /// diff -Nru cargo-0.33.0/vendor/flate2/src/zlib/write.rs cargo-0.35.0/vendor/flate2/src/zlib/write.rs --- cargo-0.33.0/vendor/flate2/src/zlib/write.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/src/zlib/write.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,5 @@ -use std::io::prelude::*; use std::io; +use std::io::prelude::*; #[cfg(feature = "tokio")] use futures::Poll; @@ -169,7 +169,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for ZlibEncoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.try_finish()); + self.try_finish()?; self.get_mut().shutdown() } } @@ -333,7 +333,7 @@ #[cfg(feature = "tokio")] impl AsyncWrite for ZlibDecoder { fn shutdown(&mut self) -> Poll<(), io::Error> { - try_nb!(self.inner.finish()); + self.inner.finish()?; self.inner.get_mut().shutdown() } } diff -Nru cargo-0.33.0/vendor/flate2/tests/async-reader.rs cargo-0.35.0/vendor/flate2/tests/async-reader.rs --- cargo-0.33.0/vendor/flate2/tests/async-reader.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/tests/async-reader.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,94 @@ +extern crate flate2; +extern crate tokio_io; +extern crate futures; + +use flate2::read::{GzDecoder, MultiGzDecoder}; +use std::cmp; +use std::fs::File; +use std::io::{self, Read}; +use tokio_io::AsyncRead; +use tokio_io::io::read_to_end; +use futures::prelude::*; +use futures::task; + + +struct BadReader { + reader: T, + x: bool +} + +impl BadReader { + fn new(reader: T) -> BadReader { + BadReader { reader, x: true } + } +} + +impl Read for BadReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if self.x { + self.x = false; + let len = cmp::min(buf.len(), 1); + self.reader.read(&mut buf[..len]) + } else { + self.x = true; + Err(io::ErrorKind::WouldBlock.into()) + } + } +} + +struct AssertAsync(T); + +impl Read for AssertAsync { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } +} + +impl AsyncRead for AssertAsync {} + +struct AlwaysNotify(T); + +impl Future for AlwaysNotify { + type Item = T::Item; + type Error = T::Error; + + fn poll(&mut self) -> Poll { + let ret = self.0.poll(); + if let Ok(Async::NotReady) = &ret { + task::current().notify(); + } + ret + } +} + +#[test] +fn test_gz_asyncread() { + let f = File::open("tests/good-file.gz").unwrap(); + + let fut = read_to_end(AssertAsync(GzDecoder::new(BadReader::new(f))), Vec::new()); + let (_, content) = AlwaysNotify(fut).wait().unwrap(); + + let mut expected = Vec::new(); + File::open("tests/good-file.txt") + .unwrap() + .read_to_end(&mut expected) + .unwrap(); + + assert_eq!(content, expected); +} + +#[test] +fn test_multi_gz_asyncread() { + let f = File::open("tests/multi.gz").unwrap(); + + let fut = read_to_end(AssertAsync(MultiGzDecoder::new(BadReader::new(f))), Vec::new()); + let (_, content) = AlwaysNotify(fut).wait().unwrap(); + + let mut expected = Vec::new(); + File::open("tests/multi.txt") + .unwrap() + .read_to_end(&mut expected) + .unwrap(); + + assert_eq!(content, expected); +} diff -Nru cargo-0.33.0/vendor/flate2/tests/early-flush.rs cargo-0.35.0/vendor/flate2/tests/early-flush.rs --- cargo-0.33.0/vendor/flate2/tests/early-flush.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/tests/early-flush.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,8 @@ use std::io::{Read, Write}; -use flate2::write::GzEncoder; use flate2::read::GzDecoder; +use flate2::write::GzEncoder; #[test] fn smoke() { diff -Nru cargo-0.33.0/vendor/flate2/tests/gunzip.rs cargo-0.35.0/vendor/flate2/tests/gunzip.rs --- cargo-0.33.0/vendor/flate2/tests/gunzip.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/tests/gunzip.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,11 @@ extern crate flate2; +use flate2::read::GzDecoder; +use flate2::read::MultiGzDecoder; use std::fs::File; use std::io::prelude::*; use std::io::{self, BufReader}; use std::path::Path; -use flate2::read::GzDecoder; -use flate2::read::MultiGzDecoder; // test extraction of a gzipped file #[test] diff -Nru cargo-0.33.0/vendor/flate2/tests/tokio.rs cargo-0.35.0/vendor/flate2/tests/tokio.rs --- cargo-0.33.0/vendor/flate2/tests/tokio.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/flate2/tests/tokio.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,30 +3,29 @@ extern crate flate2; extern crate futures; extern crate rand; -extern crate tokio_core; extern crate tokio_io; +extern crate tokio_tcp; +extern crate tokio_threadpool; use std::io::{Read, Write}; use std::iter; use std::net::{Shutdown, TcpListener}; use std::thread; -use flate2::Compression; use flate2::read; use flate2::write; +use flate2::Compression; use futures::Future; use rand::{thread_rng, Rng}; -use tokio_core::net::TcpStream; -use tokio_core::reactor::Core; -use tokio_io::AsyncRead; use tokio_io::io::{copy, shutdown}; +use tokio_io::AsyncRead; +use tokio_tcp::TcpStream; #[test] fn tcp_stream_echo_pattern() { const N: u8 = 16; const M: usize = 16 * 1024; - let mut core = Core::new().unwrap(); let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = listener.local_addr().unwrap(); let t = thread::spawn(move || { @@ -56,8 +55,7 @@ t.join().unwrap(); }); - let handle = core.handle(); - let stream = TcpStream::connect(&addr, &handle); + let stream = TcpStream::connect(&addr); let copy = stream .and_then(|s| { let (a, b) = s.split(); @@ -69,9 +67,12 @@ let (amt, _a, b) = result.unwrap(); assert_eq!(amt, (N as u64) * (M as u64)); shutdown(b).map(|_| ()) - }); + }) + .map_err(|err| panic!("{}", err)); - core.run(copy).unwrap(); + let threadpool = tokio_threadpool::Builder::new().build(); + threadpool.spawn(copy); + threadpool.shutdown().wait().unwrap(); t.join().unwrap(); } @@ -81,7 +82,6 @@ .take(1024 * 1024) .map(|()| thread_rng().gen::()) .collect::>(); - let mut core = Core::new().unwrap(); let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = listener.local_addr().unwrap(); let v2 = v.clone(); @@ -111,8 +111,7 @@ t.join().unwrap(); }); - let handle = core.handle(); - let stream = TcpStream::connect(&addr, &handle); + let stream = TcpStream::connect(&addr); let copy = stream .and_then(|s| { let (a, b) = s.split(); @@ -120,12 +119,15 @@ let b = write::DeflateEncoder::new(b, Compression::default()); copy(a, b) }) - .then(|result| { + .then(move |result| { let (amt, _a, b) = result.unwrap(); assert_eq!(amt, v.len() as u64); shutdown(b).map(|_| ()) - }); + }) + .map_err(|err| panic!("{}", err)); - core.run(copy).unwrap(); + let threadpool = tokio_threadpool::Builder::new().build(); + threadpool.spawn(copy); + threadpool.shutdown().wait().unwrap(); t.join().unwrap(); } diff -Nru cargo-0.33.0/vendor/git2/.cargo-checksum.json cargo-0.35.0/vendor/git2/.cargo-checksum.json --- cargo-0.33.0/vendor/git2/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71"} \ No newline at end of file +{"files":{},"package":"c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/git2/Cargo.toml cargo-0.35.0/vendor/git2/Cargo.toml --- cargo-0.33.0/vendor/git2/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "git2" -version = "0.7.5" +version = "0.8.0" authors = ["Alex Crichton "] description = "Bindings to libgit2 for interoperating with git repositories. This library is\nboth threadsafe and memory safe and allows both reading and writing git\nrepositories.\n" homepage = "https://github.com/alexcrichton/git2-rs" @@ -29,7 +29,7 @@ version = "0.2" [dependencies.libgit2-sys] -version = "0.7.7" +version = "0.7.11" [dependencies.log] version = "0.4" @@ -61,6 +61,7 @@ ssh = ["libgit2-sys/ssh"] ssh_key_from_memory = ["libgit2-sys/ssh_key_from_memory"] unstable = [] +vendored-openssl = ["openssl-sys/vendored"] [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies.openssl-probe] version = "0.1" optional = true diff -Nru cargo-0.33.0/vendor/git2/README.md cargo-0.35.0/vendor/git2/README.md --- cargo-0.33.0/vendor/git2/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -20,8 +20,6 @@ ## Building git2-rs -First, you'll need to install _CMake_. Afterwards, just run: - ```sh $ git clone https://github.com/alexcrichton/git2-rs $ cd git2-rs @@ -42,14 +40,9 @@ ## Building on OSX 10.10+ -Currently libssh2 requires linking against OpenSSL, and to compile libssh2 it -also needs to find the OpenSSL headers. On OSX 10.10+ the OpenSSL headers have -been removed, but if you're using Homebrew you can install them via: - -```sh -brew install openssl -``` - +If the `ssh` feature is enabled (and it is by default) then this library depends +on libssh2 which depends on OpenSSL. To get OpenSSL working follow the +[`openssl` crate's instructions](https://github.com/sfackler/rust-openssl#macos). # License diff -Nru cargo-0.33.0/vendor/git2/src/build.rs cargo-0.35.0/vendor/git2/src/build.rs --- cargo-0.33.0/vendor/git2/src/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -59,8 +59,9 @@ /// /// The callback must return a bool specifying whether the checkout should /// continue. -pub type Notify<'a> = FnMut(CheckoutNotificationType, Option<&Path>, DiffFile, - DiffFile, DiffFile) -> bool + 'a; +pub type Notify<'a> = FnMut(CheckoutNotificationType, Option<&Path>, + Option, Option, + Option) -> bool + 'a; impl<'cb> Default for RepoBuilder<'cb> { @@ -506,8 +507,8 @@ /// Callbacks are invoked prior to modifying any files on disk. /// Returning `false` from the callback will cancel the checkout. pub fn notify(&mut self, cb: F) -> &mut CheckoutBuilder<'cb> - where F: FnMut(CheckoutNotificationType, Option<&Path>, DiffFile, - DiffFile, DiffFile) -> bool + 'cb + where F: FnMut(CheckoutNotificationType, Option<&Path>, Option, + Option, Option) -> bool + 'cb { self.notify = Some(Box::new(cb) as Box>); self @@ -593,12 +594,26 @@ Some(util::bytes2path(CStr::from_ptr(path).to_bytes())) }; + let baseline = if baseline.is_null() { + None + } else { + Some(DiffFile::from_raw(baseline)) + }; + + let target = if target.is_null() { + None + } else { + Some(DiffFile::from_raw(target)) + }; + + let workdir = if workdir.is_null() { + None + } else { + Some(DiffFile::from_raw(workdir)) + }; + let why = CheckoutNotificationType::from_bits_truncate(why as u32); - let keep_going = callback(why, - path, - DiffFile::from_raw(baseline), - DiffFile::from_raw(target), - DiffFile::from_raw(workdir)); + let keep_going = callback(why, path, baseline, target, workdir); if keep_going {0} else {1} }).unwrap_or(2) } @@ -608,8 +623,8 @@ use std::fs; use std::path::Path; use tempdir::TempDir; - use super::RepoBuilder; - use Repository; + use super::{CheckoutBuilder, RepoBuilder}; + use {CheckoutNotificationType, Repository}; #[test] fn smoke() { @@ -635,4 +650,52 @@ .clone(&url, &dst).is_err()); } + /// Issue regression test #365 + #[test] + fn notify_callback() { + let td = TempDir::new("test").unwrap(); + let cd = TempDir::new("external-checkout").unwrap(); + + { + let repo = Repository::init(&td.path()).unwrap(); + + let mut config = repo.config().unwrap(); + config.set_str("user.name", "name").unwrap(); + config.set_str("user.email", "email").unwrap(); + + let mut index = repo.index().unwrap(); + let p = Path::new(td.path()).join("file"); + println!("using path {:?}", p); + fs::File::create(&p).unwrap(); + index.add_path(&Path::new("file")).unwrap(); + let id = index.write_tree().unwrap(); + + let tree = repo.find_tree(id).unwrap(); + let sig = repo.signature().unwrap(); + repo.commit(Some("HEAD"), &sig, &sig, "initial", + &tree, &[]).unwrap(); + } + + let repo = Repository::open_bare(&td.path().join(".git")).unwrap(); + let tree = repo + .revparse_single(&"master") + .unwrap() + .peel_to_tree() + .unwrap(); + let mut index = repo.index().unwrap(); + index.read_tree(&tree).unwrap(); + + let mut checkout_opts = CheckoutBuilder::new(); + checkout_opts.target_dir(&cd.path()); + checkout_opts.notify_on(CheckoutNotificationType::all()); + checkout_opts.notify(|_notif, _path, baseline, target, workdir| { + assert!(baseline.is_none()); + assert_eq!(target.unwrap().path(), Some(Path::new("file"))); + assert!(workdir.is_none()); + true + }); + repo.checkout_index(Some(&mut index), Some(&mut checkout_opts)) + .unwrap(); + } + } diff -Nru cargo-0.33.0/vendor/git2/src/commit.rs cargo-0.35.0/vendor/git2/src/commit.rs --- cargo-0.33.0/vendor/git2/src/commit.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/commit.rs 2019-05-15 11:26:24.000000000 +0000 @@ -17,12 +17,16 @@ } /// An iterator over the parent commits of a commit. +/// +/// Aborts iteration when a commit cannot be found pub struct Parents<'commit, 'repo: 'commit> { range: Range, commit: &'commit Commit<'repo>, } /// An iterator over the parent commits' ids of a commit. +/// +/// Aborts iteration when a commit cannot be found pub struct ParentIds<'commit> { range: Range, commit: &'commit Commit<'commit>, @@ -79,9 +83,9 @@ /// `None` will be returned if the encoding is not known pub fn message_encoding(&self) -> Option<&str> { let bytes = unsafe { - ::opt_bytes(self, raw::git_commit_message(&*self.raw)) + ::opt_bytes(self, raw::git_commit_message_encoding(&*self.raw)) }; - bytes.map(|b| str::from_utf8(b).unwrap()) + bytes.and_then(|b| str::from_utf8(b).ok()) } /// Get the full raw message of a commit. @@ -147,14 +151,12 @@ /// Creates a new iterator over the parents of this commit. pub fn parents<'a>(&'a self) -> Parents<'a, 'repo> { - let max = unsafe { raw::git_commit_parentcount(&*self.raw) as usize }; - Parents { range: 0..max, commit: self } + Parents { range: 0..self.parent_count(), commit: self } } /// Creates a new iterator over the parents of this commit. pub fn parent_ids(&self) -> ParentIds { - let max = unsafe { raw::git_commit_parentcount(&*self.raw) as usize }; - ParentIds { range: 0..max, commit: self } + ParentIds { range: 0..self.parent_count(), commit: self } } /// Get the author of this commit. @@ -206,6 +208,13 @@ } } + /// Get the number of parents of this commit. + /// + /// Use the `parents` iterator to return an iterator over all parents. + pub fn parent_count(&self) -> usize { + unsafe { raw::git_commit_parentcount(&*self.raw) as usize } + } + /// Get the specified parent of the commit. /// /// Use the `parents` iterator to return an iterator over all parents. @@ -273,33 +282,37 @@ } } +/// Aborts iteration when a commit cannot be found impl<'repo, 'commit> Iterator for Parents<'commit, 'repo> { type Item = Commit<'repo>; fn next(&mut self) -> Option> { - self.range.next().map(|i| self.commit.parent(i).unwrap()) + self.range.next().and_then(|i| self.commit.parent(i).ok()) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } } +/// Aborts iteration when a commit cannot be found impl<'repo, 'commit> DoubleEndedIterator for Parents<'commit, 'repo> { fn next_back(&mut self) -> Option> { - self.range.next_back().map(|i| self.commit.parent(i).unwrap()) + self.range.next_back().and_then(|i| self.commit.parent(i).ok()) } } impl<'repo, 'commit> ExactSizeIterator for Parents<'commit, 'repo> {} +/// Aborts iteration when a commit cannot be found impl<'commit> Iterator for ParentIds<'commit> { type Item = Oid; fn next(&mut self) -> Option { - self.range.next().map(|i| self.commit.parent_id(i).unwrap()) + self.range.next().and_then(|i| self.commit.parent_id(i).ok()) } fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } } +/// Aborts iteration when a commit cannot be found impl<'commit> DoubleEndedIterator for ParentIds<'commit> { fn next_back(&mut self) -> Option { - self.range.next_back().map(|i| self.commit.parent_id(i).unwrap()) + self.range.next_back().and_then(|i| self.commit.parent_id(i).ok()) } } diff -Nru cargo-0.33.0/vendor/git2/src/cred.rs cargo-0.35.0/vendor/git2/src/cred.rs --- cargo-0.33.0/vendor/git2/src/cred.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/cred.rs 2019-05-15 11:26:24.000000000 +0000 @@ -418,7 +418,7 @@ use {Cred, Config, CredentialHelper, ConfigLevel}; - macro_rules! cfg( ($($k:expr => $v:expr),*) => ({ + macro_rules! test_cfg( ($($k:expr => $v:expr),*) => ({ let td = TempDir::new("git2-rs").unwrap(); let mut cfg = Config::new().unwrap(); cfg.add_file(&td.path().join("cfg"), ConfigLevel::Highest, false).unwrap(); @@ -433,7 +433,7 @@ #[test] fn credential_helper1() { - let cfg = cfg! { + let cfg = test_cfg! { "credential.helper" => "!f() { echo username=a; echo password=b; }; f" }; let (u, p) = CredentialHelper::new("https://example.com/foo/bar") @@ -445,7 +445,7 @@ #[test] fn credential_helper2() { - let cfg = cfg! {}; + let cfg = test_cfg! {}; assert!(CredentialHelper::new("https://example.com/foo/bar") .config(&cfg) .execute().is_none()); @@ -453,7 +453,7 @@ #[test] fn credential_helper3() { - let cfg = cfg! { + let cfg = test_cfg! { "credential.https://example.com.helper" => "!f() { echo username=c; }; f", "credential.helper" => "!f() { echo username=a; echo password=b; }; f" @@ -474,7 +474,7 @@ echo username=c ").unwrap(); chmod(&path); - let cfg = cfg! { + let cfg = test_cfg! { "credential.https://example.com.helper" => &path.display().to_string()[..], "credential.helper" => "!f() { echo username=a; echo password=b; }; f" @@ -501,7 +501,7 @@ .chain(path.parent().map(|p| p.to_path_buf()).into_iter()); env::set_var("PATH", &env::join_paths(paths).unwrap()); - let cfg = cfg! { + let cfg = test_cfg! { "credential.https://example.com.helper" => "script", "credential.helper" => "!f() { echo username=a; echo password=b; }; f" }; @@ -514,7 +514,7 @@ #[test] fn credential_helper6() { - let cfg = cfg! { + let cfg = test_cfg! { "credential.helper" => "" }; assert!(CredentialHelper::new("https://example.com/foo/bar") diff -Nru cargo-0.33.0/vendor/git2/src/describe.rs cargo-0.35.0/vendor/git2/src/describe.rs --- cargo-0.33.0/vendor/git2/src/describe.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/describe.rs 2019-05-15 11:26:24.000000000 +0000 @@ -124,7 +124,7 @@ /// Sets the reference lookup strategy /// - /// This behaves like the `--tags` option to git-decribe. + /// This behaves like the `--tags` option to git-describe. pub fn describe_tags(&mut self) -> &mut Self { self.raw.describe_strategy = raw::GIT_DESCRIBE_TAGS as c_uint; self @@ -132,7 +132,7 @@ /// Sets the reference lookup strategy /// - /// This behaves like the `--all` option to git-decribe. + /// This behaves like the `--all` option to git-describe. pub fn describe_all(&mut self) -> &mut Self { self.raw.describe_strategy = raw::GIT_DESCRIBE_ALL as c_uint; self diff -Nru cargo-0.33.0/vendor/git2/src/index.rs cargo-0.35.0/vendor/git2/src/index.rs --- cargo-0.33.0/vendor/git2/src/index.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/index.rs 2019-05-15 11:26:24.000000000 +0000 @@ -127,6 +127,66 @@ } } + /// Add or update an index entry from a buffer in memory + /// + /// This method will create a blob in the repository that owns the index and + /// then add the index entry to the index. The path of the entry represents + /// the position of the blob relative to the repository's root folder. + /// + /// If a previous index entry exists that has the same path as the given + /// 'entry', it will be replaced. Otherwise, the 'entry' will be added. + /// The id and the file_size of the 'entry' are updated with the real value + /// of the blob. + /// + /// This forces the file to be added to the index, not looking at gitignore + /// rules. + /// + /// If this file currently is the result of a merge conflict, this file will + /// no longer be marked as conflicting. The data about the conflict will be + /// moved to the "resolve undo" (REUC) section. + pub fn add_frombuffer(&mut self, entry: &IndexEntry, data: &[u8]) -> Result<(), Error> { + let path = try!(CString::new(&entry.path[..])); + + // libgit2 encodes the length of the path in the lower bits of the + // `flags` entry, so mask those out and recalculate here to ensure we + // don't corrupt anything. + let mut flags = entry.flags & !raw::GIT_IDXENTRY_NAMEMASK; + + if entry.path.len() < raw::GIT_IDXENTRY_NAMEMASK as usize { + flags |= entry.path.len() as u16; + } else { + flags |= raw::GIT_IDXENTRY_NAMEMASK; + } + + unsafe { + let raw = raw::git_index_entry { + dev: entry.dev, + ino: entry.ino, + mode: entry.mode, + uid: entry.uid, + gid: entry.gid, + file_size: entry.file_size, + id: *entry.id.raw(), + flags: flags, + flags_extended: entry.flags_extended, + path: path.as_ptr(), + mtime: raw::git_index_time { + seconds: entry.mtime.seconds(), + nanoseconds: entry.mtime.nanoseconds(), + }, + ctime: raw::git_index_time { + seconds: entry.ctime.seconds(), + nanoseconds: entry.ctime.nanoseconds(), + }, + }; + + let ptr = data.as_ptr() as *const c_void; + let len = data.len() as size_t; + try_call!(raw::git_index_add_frombuffer(self.raw, &raw, ptr, len)); + Ok(()) + } + } + /// Add or update an index entry from a file on disk /// /// The file path must be relative to the repository's working folder and @@ -615,6 +675,22 @@ assert_eq!(e.path.len(), 6); } + #[test] + fn add_frombuffer_then_read() { + let (_td, repo) = ::test::repo_init(); + let mut index = repo.index().unwrap(); + + let mut e = entry(); + e.path = b"foobar".to_vec(); + let content = b"the contents"; + index.add_frombuffer(&e, content).unwrap(); + let e = index.get(0).unwrap(); + assert_eq!(e.path.len(), 6); + + let b = repo.find_blob(e.id).unwrap(); + assert_eq!(b.content(), content); + } + fn entry() -> IndexEntry { IndexEntry { ctime: IndexTime::new(0, 0), diff -Nru cargo-0.33.0/vendor/git2/src/lib.rs cargo-0.35.0/vendor/git2/src/lib.rs --- cargo-0.33.0/vendor/git2/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -103,6 +103,7 @@ pub use pathspec::{PathspecDiffEntries, PathspecEntries}; pub use patch::Patch; pub use proxy_options::ProxyOptions; +pub use rebase::{Rebase, RebaseOptions, RebaseOperation, RebaseOperationType}; pub use reference::{Reference, References, ReferenceNames}; pub use reflog::{Reflog, ReflogEntry, ReflogIter}; pub use refspec::Refspec; @@ -118,7 +119,7 @@ pub use submodule::{Submodule, SubmoduleUpdateOptions}; pub use tag::Tag; pub use time::{Time, IndexTime}; -pub use tree::{Tree, TreeEntry, TreeIter}; +pub use tree::{Tree, TreeEntry, TreeIter, TreeWalkMode, TreeWalkResult}; pub use treebuilder::TreeBuilder; pub use odb::{Odb, OdbObject, OdbReader, OdbWriter}; pub use util::IntoCString; @@ -377,8 +378,8 @@ /// change at any time. This is the default sorting for new walkers. const NONE = raw::GIT_SORT_NONE as u32; - /// Sort the repository contents in topological order (parents before - /// children). + /// Sort the repository contents in topological order (children before + /// parents). /// /// This sorting mode can be combined with time sorting. const TOPOLOGICAL = raw::GIT_SORT_TOPOLOGICAL as u32; @@ -657,6 +658,7 @@ mod pathspec; mod patch; mod proxy_options; +mod rebase; mod reference; mod reflog; mod refspec; diff -Nru cargo-0.33.0/vendor/git2/src/merge.rs cargo-0.35.0/vendor/git2/src/merge.rs --- cargo-0.33.0/vendor/git2/src/merge.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/merge.rs 2019-05-15 11:26:24.000000000 +0000 @@ -46,16 +46,38 @@ opts } - /// Detect file renames - pub fn find_renames(&mut self, find: bool) -> &mut MergeOptions { - if find { - self.raw.flags |= raw::GIT_MERGE_FIND_RENAMES; + fn flag(&mut self, opt: raw::git_merge_flag_t, val: bool) -> &mut MergeOptions { + if val { + self.raw.flags |= opt; } else { - self.raw.flags &= !raw::GIT_MERGE_FIND_RENAMES; + self.raw.flags &= !opt; } self } + /// Detect file renames + pub fn find_renames(&mut self, find: bool) -> &mut MergeOptions { + self.flag(raw::GIT_MERGE_FIND_RENAMES, find) + } + + /// If a conflict occurs, exit immediately instead of attempting to continue + /// resolving conflicts + pub fn fail_on_conflict(&mut self, fail: bool) -> &mut MergeOptions { + self.flag(raw::GIT_MERGE_FAIL_ON_CONFLICT, fail) + } + + /// Do not write the REUC extension on the generated index + pub fn skip_reuc(&mut self, skip: bool) -> &mut MergeOptions { + self.flag(raw::GIT_MERGE_FAIL_ON_CONFLICT, skip) + } + + /// If the commits being merged have multiple merge bases, do not build a + /// recursive merge base (by merging the multiple merge bases), instead + /// simply use the first base. + pub fn no_recursive(&mut self, disable: bool) -> &mut MergeOptions { + self.flag(raw::GIT_MERGE_NO_RECURSIVE, disable) + } + /// Similarity to consider a file renamed (default 50) pub fn rename_threshold(&mut self, thresh: u32) -> &mut MergeOptions { self.raw.rename_threshold = thresh; @@ -86,7 +108,7 @@ self } - fn flag(&mut self, opt: raw::git_merge_file_flag_t, val: bool) -> &mut MergeOptions { + fn file_flag(&mut self, opt: raw::git_merge_file_flag_t, val: bool) -> &mut MergeOptions { if val { self.raw.file_flags |= opt; } else { @@ -97,42 +119,42 @@ /// Create standard conflicted merge files pub fn standard_style(&mut self, standard: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_STYLE_MERGE, standard) + self.file_flag(raw::GIT_MERGE_FILE_STYLE_MERGE, standard) } /// Create diff3-style file pub fn diff3_style(&mut self, diff3: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_STYLE_DIFF3, diff3) + self.file_flag(raw::GIT_MERGE_FILE_STYLE_DIFF3, diff3) } /// Condense non-alphanumeric regions for simplified diff file pub fn simplify_alnum(&mut self, simplify: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_SIMPLIFY_ALNUM, simplify) + self.file_flag(raw::GIT_MERGE_FILE_SIMPLIFY_ALNUM, simplify) } /// Ignore all whitespace pub fn ignore_whitespace(&mut self, ignore: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE, ignore) + self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE, ignore) } /// Ignore changes in amount of whitespace pub fn ignore_whitespace_change(&mut self, ignore: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE, ignore) + self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE, ignore) } /// Ignore whitespace at end of line pub fn ignore_whitespace_eol(&mut self, ignore: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL, ignore) + self.file_flag(raw::GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL, ignore) } /// Use the "patience diff" algorithm pub fn patience(&mut self, patience: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_DIFF_PATIENCE, patience) + self.file_flag(raw::GIT_MERGE_FILE_DIFF_PATIENCE, patience) } /// Take extra time to find minimal diff pub fn minimal(&mut self, minimal: bool) -> &mut MergeOptions { - self.flag(raw::GIT_MERGE_FILE_DIFF_MINIMAL, minimal) + self.file_flag(raw::GIT_MERGE_FILE_DIFF_MINIMAL, minimal) } /// Acquire a pointer to the underlying raw options. diff -Nru cargo-0.33.0/vendor/git2/src/rebase.rs cargo-0.35.0/vendor/git2/src/rebase.rs --- cargo-0.33.0/vendor/git2/src/rebase.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/rebase.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,354 @@ +use std::{marker, ptr, mem, str}; +use std::ffi::CString; + +use {raw, Oid, Error, Signature, MergeOptions, Index}; +use build::CheckoutBuilder; +use util::Binding; + +/// Rebase options +/// +/// Use to tell the rebase machinery how to operate. +pub struct RebaseOptions<'cb> { + raw: raw::git_rebase_options, + merge_options: Option, + checkout_options: Option>, +} + +impl<'cb> Default for RebaseOptions<'cb> { + fn default() -> Self { + Self::new() + } +} + +impl<'cb> RebaseOptions<'cb> { + /// Creates a new default set of rebase options. + pub fn new() -> RebaseOptions<'cb> { + let mut opts = RebaseOptions { + raw: unsafe { mem::zeroed() }, + merge_options: None, + checkout_options: None, + }; + assert_eq!(unsafe { + raw::git_rebase_init_options(&mut opts.raw, 1) + }, 0); + opts + } + + /// Used by `Repository::rebase`, this will instruct other clients working on this + /// rebase that you want a quiet rebase experience, which they may choose to + /// provide in an application-specific manner. This has no effect upon + /// libgit2 directly, but is provided for interoperability between Git + /// tools. + pub fn quiet(&mut self, quiet: bool) -> &mut RebaseOptions<'cb> { + self.raw.quiet = quiet as i32; + self + } + + /// Used by `Repository::rebase`, this will begin an in-memory rebase, + /// which will allow callers to step through the rebase operations and + /// commit the rebased changes, but will not rewind HEAD or update the + /// repository to be in a rebasing state. This will not interfere with + /// the working directory (if there is one). + pub fn inmemory(&mut self, inmemory: bool) -> &mut RebaseOptions<'cb> { + self.raw.inmemory = inmemory as i32; + self + } + + /// Used by `finish()`, this is the name of the notes reference + /// used to rewrite notes for rebased commits when finishing the rebase; + /// if NULL, the contents of the configuration option `notes.rewriteRef` + /// is examined, unless the configuration option `notes.rewrite.rebase` + /// is set to false. If `notes.rewriteRef` is also NULL, notes will + /// not be rewritten. + pub fn rewrite_notes_ref(&mut self, rewrite_notes_ref: &str) -> &mut RebaseOptions<'cb> { + let s = CString::new(rewrite_notes_ref).unwrap().as_ptr(); + self.raw.rewrite_notes_ref = s; + self + } + + /// Options to control how trees are merged during `next()`. + pub fn merge_options(&mut self, opts: MergeOptions) -> &mut RebaseOptions<'cb> { + self.merge_options = Some(opts); + self + } + + /// Options to control how files are written during `Repository::rebase`, + /// `next()` and `abort()`. Note that a minimum strategy of + /// `GIT_CHECKOUT_SAFE` is defaulted in `init` and `next`, and a minimum + /// strategy of `GIT_CHECKOUT_FORCE` is defaulted in `abort` to match git + /// semantics. + pub fn checkout_options(&mut self, opts: CheckoutBuilder<'cb>) -> &mut RebaseOptions<'cb> { + self.checkout_options = Some(opts); + self + } + + /// Acquire a pointer to the underlying raw options. + pub fn raw(&mut self) -> *const raw::git_rebase_options { + unsafe { + if let Some(opts) = self.merge_options.as_mut().take() { + ptr::copy_nonoverlapping(opts.raw(), &mut self.raw.merge_options, 1); + mem::forget(opts); + } + if let Some(opts) = self.checkout_options.as_mut() { + opts.configure(&mut self.raw.checkout_options); + } + } + &self.raw + } + +} + +/// Representation of a rebase +pub struct Rebase<'repo> { + raw: *mut raw::git_rebase, + _marker: marker::PhantomData<&'repo raw::git_rebase>, +} + +impl <'repo> Rebase<'repo> { + /// Gets the count of rebase operations that are to be applied. + pub fn len(&self) -> usize { + unsafe { raw::git_rebase_operation_entrycount(self.raw) } + } + + /// Gets the rebase operation specified by the given index. + pub fn nth(&mut self, n: usize) -> Option { + unsafe { + let op = raw::git_rebase_operation_byindex(self.raw, n); + if op.is_null() { + None + } else { + Some(RebaseOperation::from_raw(op)) + } + } + } + + /// Gets the index of the rebase operation that is currently being applied. + /// If the first operation has not yet been applied (because you have called + /// `init` but not yet `next`) then this returns None. + pub fn operation_current(&mut self) -> Option { + let cur = unsafe { raw::git_rebase_operation_current(self.raw) }; + if cur == raw::GIT_REBASE_NO_OPERATION { + None + } else { + Some(cur) + } + } + + /// Gets the index produced by the last operation, which is the result of + /// `next()` and which will be committed by the next invocation of + /// `commit()`. This is useful for resolving conflicts in an in-memory + /// rebase before committing them. + /// + /// This is only applicable for in-memory rebases; for rebases within a + /// working directory, the changes were applied to the repository's index. + pub fn inmemory_index(&mut self) -> Result { + let mut idx = ptr::null_mut(); + unsafe { + try_call!(raw::git_rebase_inmemory_index(&mut idx, self.raw)); + Ok(Binding::from_raw(idx)) + } + } + + /// Commits the current patch. You must have resolved any conflicts that + /// were introduced during the patch application from the `git_rebase_next` + /// invocation. + pub fn commit(&mut self, author: &Signature, committer: &Signature, message: &str) -> Result { + let mut id: raw::git_oid = unsafe { mem::zeroed() }; + let message = try!(CString::new(message)); + unsafe { + try_call!(raw::git_rebase_commit(&mut id, self.raw, author.raw(), committer.raw(), ptr::null(), message)); + Ok(Binding::from_raw(&id as *const _)) + } + } + + /// Aborts a rebase that is currently in progress, resetting the repository + /// and working directory to their state before rebase began. + pub fn abort(&mut self) -> Result<(), Error> { + unsafe { + try_call!(raw::git_rebase_abort(self.raw)); + } + + Ok(()) + } + + /// Finishes a rebase that is currently in progress once all patches have + /// been applied. + pub fn finish(&mut self, signature: &Signature) -> Result<(), Error> { + unsafe { + try_call!(raw::git_rebase_finish(self.raw, signature.raw())); + } + + Ok(()) + } +} + +impl <'rebase> Iterator for Rebase<'rebase> { + type Item = Result, Error>; + + /// Performs the next rebase operation and returns the information about it. + /// If the operation is one that applies a patch (which is any operation except + /// GitRebaseOperation::Exec) then the patch will be applied and the index and + /// working directory will be updated with the changes. If there are conflicts, + /// you will need to address those before committing the changes. + fn next(&mut self) -> Option, Error>> { + let mut out = ptr::null_mut(); + unsafe { + try_call_iter!(raw::git_rebase_next(&mut out, self.raw)); + Some(Ok(RebaseOperation::from_raw(out))) + } + } +} + + +impl<'repo> Binding for Rebase<'repo> { + type Raw = *mut raw::git_rebase; + unsafe fn from_raw(raw: *mut raw::git_rebase) + -> Rebase<'repo> { + Rebase { + raw: raw, + _marker: marker::PhantomData, + } + } + fn raw(&self) -> *mut raw::git_rebase { self.raw } +} + + +impl<'repo> Drop for Rebase<'repo> { + fn drop(&mut self) { + unsafe { raw::git_rebase_free(self.raw) } + } +} + +/// A rebase operation +/// +/// Describes a single instruction/operation to be performed during the +/// rebase. +#[derive(Debug, PartialEq)] +pub enum RebaseOperationType { + /// The given commit is to be cherry-picked. The client should commit the + /// changes and continue if there are no conflicts. + Pick, + + /// The given commit is to be cherry-picked, but the client should prompt + /// the user to provide an updated commit message. + Reword, + + /// The given commit is to be cherry-picked, but the client should stop to + /// allow the user to edit the changes before committing them. + Edit, + + /// The given commit is to be squashed into the previous commit. The commit + /// message will be merged with the previous message. + Squash, + + /// The given commit is to be squashed into the previous commit. The commit + /// message from this commit will be discarded. + Fixup, + + /// No commit will be cherry-picked. The client should run the given command + /// and (if successful) continue. + Exec, +} + +impl RebaseOperationType { + /// Convert from the int into an enum. Returns None if invalid. + pub fn from_raw(raw: raw::git_rebase_operation_t) -> Option { + match raw { + raw::GIT_REBASE_OPERATION_PICK => Some(RebaseOperationType::Pick), + raw::GIT_REBASE_OPERATION_REWORD => Some(RebaseOperationType::Reword), + raw::GIT_REBASE_OPERATION_EDIT => Some(RebaseOperationType::Edit), + raw::GIT_REBASE_OPERATION_SQUASH => Some(RebaseOperationType::Squash), + raw::GIT_REBASE_OPERATION_FIXUP => Some(RebaseOperationType::Fixup), + raw::GIT_REBASE_OPERATION_EXEC => Some(RebaseOperationType::Exec), + _ => None, + } + } +} + +/// A rebase operation +/// +/// Describes a single instruction/operation to be performed during the +/// rebase. +#[derive(Debug)] +pub struct RebaseOperation<'rebase> { + raw: *const raw::git_rebase_operation, + _marker: marker::PhantomData>, +} + +impl<'rebase> RebaseOperation<'rebase> { + /// The type of rebase operation + pub fn kind(&self) -> Option { + unsafe { + RebaseOperationType::from_raw((*self.raw).kind) + } + } + + /// The commit ID being cherry-picked. This will be populated for all + /// operations except those of type `GIT_REBASE_OPERATION_EXEC`. + pub fn id(&self) -> Oid { + unsafe { + Binding::from_raw(&(*self.raw).id as *const _) + } + } + + ///The executable the user has requested be run. This will only + /// be populated for operations of type RebaseOperationType::Exec + pub fn exec(&self) -> Option<&str> { + unsafe { + str::from_utf8(::opt_bytes(self, (*self.raw).exec).unwrap()).ok() + } + } +} + +impl<'rebase> Binding for RebaseOperation<'rebase> { + type Raw = *const raw::git_rebase_operation; + unsafe fn from_raw(raw: *const raw::git_rebase_operation) -> RebaseOperation<'rebase> { + RebaseOperation { + raw: raw, + _marker: marker::PhantomData, + } + } + fn raw(&self) -> *const raw::git_rebase_operation { self.raw } +} + +#[cfg(test)] +mod tests { + use {RebaseOptions, RebaseOperationType}; + + #[test] + fn smoke() { + let (_td, repo) = ::test::repo_init(); + let head_target = repo.head().unwrap().target().unwrap(); + let tip = repo.find_commit(head_target).unwrap(); + let sig = tip.author(); + let tree = tip.tree().unwrap(); + + // We just want to see the iteration work so we can create commits with + // no changes + let c1 = repo.commit(Some("refs/heads/master"), &sig, &sig, "foo", &tree, &[&tip]).unwrap(); + let c1 = repo.find_commit(c1).unwrap(); + let c2 = repo.commit(Some("refs/heads/master"), &sig, &sig, "foo", &tree, &[&c1]).unwrap(); + + let branch = repo.find_annotated_commit(c2).unwrap(); + let upstream = repo .find_annotated_commit(tip.id()).unwrap(); + let mut opts: RebaseOptions = Default::default(); + opts.inmemory(true); + let mut rebase = repo.rebase(Some(&branch), Some(&upstream), None, Some(&mut opts)).unwrap(); + + assert_eq!(rebase.len(), 2); + { + let op = rebase.next().unwrap().unwrap(); + assert_eq!(op.kind(), Some(RebaseOperationType::Pick)); + assert_eq!(op.id(), c1.id()); + } + { + let op = rebase.next().unwrap().unwrap(); + assert_eq!(op.kind(), Some(RebaseOperationType::Pick)); + assert_eq!(op.id(), c2); + } + { + let op = rebase.next(); + assert!(op.is_none()); + } + } +} diff -Nru cargo-0.33.0/vendor/git2/src/reflog.rs cargo-0.35.0/vendor/git2/src/reflog.rs --- cargo-0.33.0/vendor/git2/src/reflog.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/reflog.rs 2019-05-15 11:26:24.000000000 +0000 @@ -115,7 +115,7 @@ /// Get the old oid pub fn id_old(&self) -> Oid { - unsafe { Binding::from_raw(raw::git_reflog_entry_id_new(self.raw)) } + unsafe { Binding::from_raw(raw::git_reflog_entry_id_old(self.raw)) } } /// Get the log message, returning `None` on invalid UTF-8. diff -Nru cargo-0.33.0/vendor/git2/src/remote_callbacks.rs cargo-0.35.0/vendor/git2/src/remote_callbacks.rs --- cargo-0.33.0/vendor/git2/src/remote_callbacks.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/remote_callbacks.rs 2019-05-15 11:26:24.000000000 +0000 @@ -115,7 +115,7 @@ /// Textual progress from the remote. /// /// Text sent over the progress side-band will be passed to this function - /// (this is the 'counting objects' output. + /// (this is the 'counting objects' output). pub fn sideband_progress(&mut self, cb: F) -> &mut RemoteCallbacks<'a> where F: FnMut(&[u8]) -> bool + 'a { self.sideband_progress = Some(Box::new(cb) as Box>); diff -Nru cargo-0.33.0/vendor/git2/src/repo.rs cargo-0.35.0/vendor/git2/src/repo.rs --- cargo-0.33.0/vendor/git2/src/repo.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/repo.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,6 +14,7 @@ use {ObjectType, Tag, Note, Notes, StatusOptions, Statuses, Status, Revwalk}; use {RevparseMode, RepositoryInitMode, Reflog, IntoCString, Describe}; use {DescribeOptions, TreeBuilder, Diff, DiffOptions, PackBuilder, Odb}; +use {Rebase, RebaseOptions}; use build::{RepoBuilder, CheckoutBuilder}; use stash::{StashApplyOptions, StashCbData, stash_cb}; use string_array::StringArray; @@ -171,9 +172,9 @@ Repository::init_opts(path, RepositoryInitOptions::new().bare(true)) } - /// Creates a new `--bare` repository in the specified folder. + /// Creates a new repository in the specified folder with the given options. /// - /// The folder must exist prior to invoking this function. + /// See `RepositoryInitOptions` struct for more information. pub fn init_opts>(path: P, opts: &RepositoryInitOptions) -> Result { init(); @@ -1574,6 +1575,42 @@ } } + /// Initializes a rebase operation to rebase the changes in `branch` + /// relative to `upstream` onto another branch. To begin the rebase process, + /// call `next()`. + pub fn rebase(&self, + branch: Option<&AnnotatedCommit>, + upstream: Option<&AnnotatedCommit>, + onto: Option<&AnnotatedCommit>, + opts: Option<&mut RebaseOptions>) -> Result { + + let mut rebase: *mut raw::git_rebase = ptr::null_mut(); + unsafe { + try_call!(raw::git_rebase_init( + &mut rebase, + self.raw(), + branch.map(|c| c.raw()), + upstream.map(|c| c.raw()), + onto.map(|c| c.raw()), + opts.map(|o| o.raw()).unwrap_or(ptr::null()))); + + Ok(Rebase::from_raw(rebase)) + } + } + + /// Opens an existing rebase that was previously started by either an + /// invocation of `rebase()` or by another client. + pub fn open_rebase(&self, opts: Option<&mut RebaseOptions>) -> Result { + let mut rebase: *mut raw::git_rebase = ptr::null_mut(); + unsafe { + try_call!(raw::git_rebase_open(&mut rebase, self.raw(), opts.map(|o| o.raw()).unwrap_or(ptr::null()))); + Ok(Rebase::from_raw(rebase)) + + } + } + + + /// Add a note for an object /// /// The `notes_ref` argument is the canonical name of the reference to use, diff -Nru cargo-0.33.0/vendor/git2/src/submodule.rs cargo-0.35.0/vendor/git2/src/submodule.rs --- cargo-0.33.0/vendor/git2/src/submodule.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/submodule.rs 2019-05-15 11:26:24.000000000 +0000 @@ -37,13 +37,26 @@ /// Get the submodule's url. /// - /// Returns `None` if the url is not valid utf-8 - pub fn url(&self) -> Option<&str> { str::from_utf8(self.url_bytes()).ok() } + /// Returns `None` if the url is not valid utf-8 or if the URL isn't present + pub fn url(&self) -> Option<&str> { + self.opt_url_bytes().and_then(|b| str::from_utf8(b).ok()) + } /// Get the url for the submodule. + #[doc(hidden)] + #[deprecated(note = "renamed to `opt_url_bytes`")] pub fn url_bytes(&self) -> &[u8] { + self.opt_url_bytes().unwrap() + } + + /// Get the url for the submodule. + /// + /// Returns `None` if the URL isn't present + // TODO: delete this method and fix the signature of `url_bytes` on next + // major version bump + pub fn opt_url_bytes(&self) -> Option<&[u8]> { unsafe { - ::opt_bytes(self, raw::git_submodule_url(self.raw)).unwrap() + ::opt_bytes(self, raw::git_submodule_url(self.raw)) } } diff -Nru cargo-0.33.0/vendor/git2/src/tree.rs cargo-0.35.0/vendor/git2/src/tree.rs --- cargo-0.33.0/vendor/git2/src/tree.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2/src/tree.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,14 +1,14 @@ use std::mem; use std::cmp::Ordering; -use std::ffi::CString; +use std::ffi::{CStr, CString}; use std::ops::Range; use std::marker; use std::path::Path; use std::ptr; use std::str; -use libc; +use libc::{self, c_int, c_char, c_void}; -use {raw, Oid, Repository, Error, Object, ObjectType}; +use {panic, raw, Oid, Repository, Error, Object, ObjectType}; use util::{Binding, IntoCString}; /// A structure to represent a git [tree][1] @@ -33,6 +33,43 @@ tree: &'tree Tree<'tree>, } +/// A binary indicator of whether a tree walk should be performed in pre-order +/// or post-order. +pub enum TreeWalkMode { + /// Runs the traversal in pre order. + PreOrder = 0, + /// Runs the traversal in post order. + PostOrder = 1, +} + +/// Possible return codes for tree walking callback functions. +#[repr(i32)] +pub enum TreeWalkResult { + /// Continue with the traversal as normal. + Ok = 0, + /// Skip the current node (in pre-order mode). + Skip = 1, + /// Completely stop the traversal. + Abort = raw::GIT_EUSER, +} + +impl Into for TreeWalkResult { + fn into(self) -> i32 { + self as i32 + } +} + +impl Into for TreeWalkMode { + #[cfg(target_env = "msvc")] + fn into(self) -> raw::git_treewalk_mode { + self as i32 + } + #[cfg(not(target_env = "msvc"))] + fn into(self) -> raw::git_treewalk_mode { + self as u32 + } +} + impl<'repo> Tree<'repo> { /// Get the id (SHA1) of a repository object pub fn id(&self) -> Oid { @@ -54,6 +91,49 @@ TreeIter { range: 0..self.len(), tree: self } } + /// Traverse the entries in a tree and its subtrees in post or pre order. + /// The callback function will be run on each node of the tree that's + /// walked. The return code of this function will determine how the walk + /// continues. + /// + /// libgit requires that the callback be an integer, where 0 indicates a + /// successful visit, 1 skips the node, and -1 aborts the traversal completely. + /// You may opt to use the enum [`TreeWalkResult`](TreeWalkResult) instead. + /// + /// ```ignore + /// let mut ct = 0; + /// tree.walk(TreeWalkMode::PreOrder, |_, entry| { + /// assert_eq!(entry.name(), Some("foo")); + /// ct += 1; + /// TreeWalkResult::Ok + /// }).unwrap(); + /// assert_eq!(ct, 1); + /// ``` + /// + /// See [libgit documentation][1] for more information. + /// + /// [1]: https://libgit2.org/libgit2/#HEAD/group/tree/git_tree_walk + pub fn walk(&self, mode: TreeWalkMode, mut callback: C) -> Result<(), Error> + where + C: FnMut(&str, &TreeEntry) -> T, + T: Into, + { + #[allow(unused)] + struct TreeWalkCbData<'a, T: 'a> { + pub callback: &'a mut TreeWalkCb<'a, T> + } + unsafe { + let mut data = TreeWalkCbData { callback: &mut callback }; + raw::git_tree_walk( + self.raw(), + mode.into(), + treewalk_cb::, + &mut data as *mut _ as *mut c_void, + ); + Ok(()) + } + } + /// Lookup a tree entry by SHA value. pub fn get_id(&self, id: Oid) -> Option { unsafe { @@ -119,6 +199,23 @@ } } +type TreeWalkCb<'a, T> = FnMut(&str, &TreeEntry) -> T + 'a; + +extern fn treewalk_cb>(root: *const c_char, entry: *const raw::git_tree_entry, payload: *mut c_void) -> c_int { + match panic::wrap(|| unsafe { + let root = match CStr::from_ptr(root).to_str() { + Ok(value) => value, + _ => return -1, + }; + let entry = entry_from_raw_const(entry); + let payload = payload as *mut &mut TreeWalkCb; + (*payload)(root, &entry).into() + }) { + Some(value) => value, + None => -1, + } +} + impl<'repo> Binding for Tree<'repo> { type Raw = *mut raw::git_tree; @@ -294,6 +391,7 @@ #[cfg(test)] mod tests { use {Repository,Tree,TreeEntry,ObjectType,Object}; + use super::{TreeWalkMode, TreeWalkResult}; use tempdir::TempDir; use std::fs::File; use std::io::prelude::*; @@ -403,4 +501,32 @@ repo.find_object(commit.tree_id(), None).unwrap().as_tree().unwrap(); repo.find_object(commit.tree_id(), None).unwrap().into_tree().ok().unwrap(); } + + #[test] + fn tree_walk() { + let (td, repo) = ::test::repo_init(); + + setup_repo(&td, &repo); + + let head = repo.head().unwrap(); + let target = head.target().unwrap(); + let commit = repo.find_commit(target).unwrap(); + let tree = repo.find_tree(commit.tree_id()).unwrap(); + + let mut ct = 0; + tree.walk(TreeWalkMode::PreOrder, |_, entry| { + assert_eq!(entry.name(), Some("foo")); + ct += 1; + 0 + }).unwrap(); + assert_eq!(ct, 1); + + let mut ct = 0; + tree.walk(TreeWalkMode::PreOrder, |_, entry| { + assert_eq!(entry.name(), Some("foo")); + ct += 1; + TreeWalkResult::Ok + }).unwrap(); + assert_eq!(ct, 1); + } } diff -Nru cargo-0.33.0/vendor/git2-curl/.cargo-checksum.json cargo-0.35.0/vendor/git2-curl/.cargo-checksum.json --- cargo-0.33.0/vendor/git2-curl/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2-curl/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"0173e317f8ba21f3fff0f71549fead5e42e67961dbd402bf69f42775f3cc78b4"} \ No newline at end of file +{"files":{},"package":"d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/git2-curl/Cargo.toml cargo-0.35.0/vendor/git2-curl/Cargo.toml --- cargo-0.33.0/vendor/git2-curl/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/git2-curl/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "git2-curl" -version = "0.8.2" +version = "0.9.0" authors = ["Alex Crichton "] description = "Backend for an HTTP transport in libgit2 powered by libcurl.\n\nIntended to be used with the git2 crate.\n" homepage = "https://github.com/alexcrichton/git2-rs" @@ -27,7 +27,7 @@ version = "0.4" [dependencies.git2] -version = "0.7" +version = "0.8" default-features = false [dependencies.log] diff -Nru cargo-0.33.0/vendor/globset/.cargo-checksum.json cargo-0.35.0/vendor/globset/.cargo-checksum.json --- cargo-0.33.0/vendor/globset/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/globset/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865"} \ No newline at end of file +{"files":{},"package":"ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/globset/Cargo.toml cargo-0.35.0/vendor/globset/Cargo.toml --- cargo-0.33.0/vendor/globset/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/globset/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "globset" -version = "0.4.2" +version = "0.4.3" authors = ["Andrew Gallant "] description = "Cross platform single glob and glob set matching. Glob set matching is the\nprocess of matching one or more glob patterns against a single candidate path\nsimultaneously, and returning all of the globs that matched.\n" homepage = "https://github.com/BurntSushi/ripgrep/tree/master/globset" @@ -26,7 +26,12 @@ name = "globset" bench = false [dependencies.aho-corasick] -version = "0.6.8" +version = "0.7.3" + +[dependencies.bstr] +version = "0.1.2" +features = ["std"] +default-features = false [dependencies.fnv] version = "1.0.6" @@ -34,13 +39,10 @@ [dependencies.log] version = "0.4.5" -[dependencies.memchr] -version = "2.0.2" - [dependencies.regex] -version = "1.0.5" +version = "1.1.5" [dev-dependencies.glob] -version = "0.2.11" +version = "0.3.0" [features] simd-accel = [] diff -Nru cargo-0.33.0/vendor/globset/src/glob.rs cargo-0.35.0/vendor/globset/src/glob.rs --- cargo-0.33.0/vendor/globset/src/glob.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/globset/src/glob.rs 2019-05-15 11:26:24.000000000 +0000 @@ -120,7 +120,7 @@ /// Tests whether the given path matches this pattern or not. pub fn is_match_candidate(&self, path: &Candidate) -> bool { - self.re.is_match(&path.path) + self.re.is_match(path.path.as_bytes()) } } @@ -145,7 +145,7 @@ /// Tests whether the given path matches this pattern or not. fn is_match_candidate(&self, candidate: &Candidate) -> bool { - let byte_path = &*candidate.path; + let byte_path = candidate.path.as_bytes(); match self.strategy { MatchStrategy::Literal(ref lit) => lit.as_bytes() == byte_path, @@ -837,40 +837,66 @@ fn parse_star(&mut self) -> Result<(), Error> { let prev = self.prev; - if self.chars.peek() != Some(&'*') { + if self.peek() != Some('*') { self.push_token(Token::ZeroOrMore)?; return Ok(()); } assert!(self.bump() == Some('*')); if !self.have_tokens()? { - self.push_token(Token::RecursivePrefix)?; - let next = self.bump(); - if !next.map(is_separator).unwrap_or(true) { - return Err(self.error(ErrorKind::InvalidRecursive)); + if !self.peek().map_or(true, is_separator) { + self.push_token(Token::ZeroOrMore)?; + self.push_token(Token::ZeroOrMore)?; + } else { + self.push_token(Token::RecursivePrefix)?; + assert!(self.bump().map_or(true, is_separator)); } return Ok(()); } - self.pop_token()?; + if !prev.map(is_separator).unwrap_or(false) { if self.stack.len() <= 1 - || (prev != Some(',') && prev != Some('{')) { - return Err(self.error(ErrorKind::InvalidRecursive)); - } - } - match self.chars.peek() { - None => { - assert!(self.bump().is_none()); - self.push_token(Token::RecursiveSuffix) + || (prev != Some(',') && prev != Some('{')) + { + self.push_token(Token::ZeroOrMore)?; + self.push_token(Token::ZeroOrMore)?; + return Ok(()); + } + } + let is_suffix = + match self.peek() { + None => { + assert!(self.bump().is_none()); + true + } + Some(',') | Some('}') if self.stack.len() >= 2 => { + true + } + Some(c) if is_separator(c) => { + assert!(self.bump().map(is_separator).unwrap_or(false)); + false + } + _ => { + self.push_token(Token::ZeroOrMore)?; + self.push_token(Token::ZeroOrMore)?; + return Ok(()); + } + }; + match self.pop_token()? { + Token::RecursivePrefix => { + self.push_token(Token::RecursivePrefix)?; } - Some(&',') | Some(&'}') if self.stack.len() >= 2 => { - self.push_token(Token::RecursiveSuffix) + Token::RecursiveSuffix => { + self.push_token(Token::RecursiveSuffix)?; } - Some(&c) if is_separator(c) => { - assert!(self.bump().map(is_separator).unwrap_or(false)); - self.push_token(Token::RecursiveZeroOrMore) + _ => { + if is_suffix { + self.push_token(Token::RecursiveSuffix)?; + } else { + self.push_token(Token::RecursiveZeroOrMore)?; + } } - _ => Err(self.error(ErrorKind::InvalidRecursive)), } + Ok(()) } fn parse_class(&mut self) -> Result<(), Error> { @@ -959,6 +985,10 @@ self.cur = self.chars.next(); self.cur } + + fn peek(&mut self) -> Option { + self.chars.peek().map(|&ch| ch) + } } #[cfg(test)] @@ -1144,13 +1174,6 @@ syntax!(cls20, "[^a]", vec![classn('a', 'a')]); syntax!(cls21, "[^a-z]", vec![classn('a', 'z')]); - syntaxerr!(err_rseq1, "a**", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq2, "**a", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq3, "a**b", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq4, "***", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq5, "/a**", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq6, "/**a", ErrorKind::InvalidRecursive); - syntaxerr!(err_rseq7, "/a**b", ErrorKind::InvalidRecursive); syntaxerr!(err_unclosed1, "[", ErrorKind::UnclosedClass); syntaxerr!(err_unclosed2, "[]", ErrorKind::UnclosedClass); syntaxerr!(err_unclosed3, "[!", ErrorKind::UnclosedClass); @@ -1194,8 +1217,30 @@ toregex!(re8, "[*]", r"^[\*]$"); toregex!(re9, "[+]", r"^[\+]$"); toregex!(re10, "+", r"^\+$"); - toregex!(re11, "**", r"^.*$"); - toregex!(re12, "☃", r"^\xe2\x98\x83$"); + toregex!(re11, "☃", r"^\xe2\x98\x83$"); + toregex!(re12, "**", r"^.*$"); + toregex!(re13, "**/", r"^.*$"); + toregex!(re14, "**/*", r"^(?:/?|.*/).*$"); + toregex!(re15, "**/**", r"^.*$"); + toregex!(re16, "**/**/*", r"^(?:/?|.*/).*$"); + toregex!(re17, "**/**/**", r"^.*$"); + toregex!(re18, "**/**/**/*", r"^(?:/?|.*/).*$"); + toregex!(re19, "a/**", r"^a(?:/?|/.*)$"); + toregex!(re20, "a/**/**", r"^a(?:/?|/.*)$"); + toregex!(re21, "a/**/**/**", r"^a(?:/?|/.*)$"); + toregex!(re22, "a/**/b", r"^a(?:/|/.*/)b$"); + toregex!(re23, "a/**/**/b", r"^a(?:/|/.*/)b$"); + toregex!(re24, "a/**/**/**/b", r"^a(?:/|/.*/)b$"); + toregex!(re25, "**/b", r"^(?:/?|.*/)b$"); + toregex!(re26, "**/**/b", r"^(?:/?|.*/)b$"); + toregex!(re27, "**/**/**/b", r"^(?:/?|.*/)b$"); + toregex!(re28, "a**", r"^a.*.*$"); + toregex!(re29, "**a", r"^.*.*a$"); + toregex!(re30, "a**b", r"^a.*.*b$"); + toregex!(re31, "***", r"^.*.*.*$"); + toregex!(re32, "/a**", r"^/a.*.*$"); + toregex!(re33, "/**a", r"^/.*.*a$"); + toregex!(re34, "/a**b", r"^/a.*.*b$"); matches!(match1, "a", "a"); matches!(match2, "a*b", "a_b"); diff -Nru cargo-0.33.0/vendor/globset/src/lib.rs cargo-0.35.0/vendor/globset/src/lib.rs --- cargo-0.33.0/vendor/globset/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/globset/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -104,27 +104,25 @@ #![deny(missing_docs)] extern crate aho_corasick; +extern crate bstr; extern crate fnv; #[macro_use] extern crate log; -extern crate memchr; extern crate regex; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap}; use std::error::Error as StdError; -use std::ffi::OsStr; use std::fmt; use std::hash; use std::path::Path; use std::str; -use aho_corasick::{Automaton, AcAutomaton, FullAcAutomaton}; +use aho_corasick::AhoCorasick; +use bstr::{B, BStr, BString}; use regex::bytes::{Regex, RegexBuilder, RegexSet}; -use pathutil::{ - file_name, file_name_ext, normalize_path, os_str_bytes, path_bytes, -}; +use pathutil::{file_name, file_name_ext, normalize_path}; use glob::MatchStrategy; pub use glob::{Glob, GlobBuilder, GlobMatcher}; @@ -143,8 +141,13 @@ /// The kind of error that can occur when parsing a glob pattern. #[derive(Clone, Debug, Eq, PartialEq)] pub enum ErrorKind { - /// Occurs when a use of `**` is invalid. Namely, `**` can only appear - /// adjacent to a path separator, or the beginning/end of a glob. + /// **DEPRECATED**. + /// + /// This error used to occur for consistency with git's glob specification, + /// but the specification now accepts all uses of `**`. When `**` does not + /// appear adjacent to a path separator or at the beginning/end of a glob, + /// it is now treated as two consecutive `*` patterns. As such, this error + /// is no longer used. InvalidRecursive, /// Occurs when a character class (e.g., `[abc]`) is not closed. UnclosedClass, @@ -289,6 +292,7 @@ impl GlobSet { /// Create an empty `GlobSet`. An empty set matches nothing. + #[inline] pub fn empty() -> GlobSet { GlobSet { len: 0, @@ -297,11 +301,13 @@ } /// Returns true if this set is empty, and therefore matches nothing. + #[inline] pub fn is_empty(&self) -> bool { self.len == 0 } /// Returns the number of globs in this set. + #[inline] pub fn len(&self) -> usize { self.len } @@ -484,24 +490,25 @@ /// path against multiple globs or sets of globs. #[derive(Clone, Debug)] pub struct Candidate<'a> { - path: Cow<'a, [u8]>, - basename: Cow<'a, [u8]>, - ext: Cow<'a, [u8]>, + path: Cow<'a, BStr>, + basename: Cow<'a, BStr>, + ext: Cow<'a, BStr>, } impl<'a> Candidate<'a> { /// Create a new candidate for matching from the given path. pub fn new + ?Sized>(path: &'a P) -> Candidate<'a> { - let path = path.as_ref(); - let basename = file_name(path).unwrap_or(OsStr::new("")); + let path = normalize_path(BString::from_path_lossy(path.as_ref())); + let basename = file_name(&path).unwrap_or(Cow::Borrowed(B(""))); + let ext = file_name_ext(&basename).unwrap_or(Cow::Borrowed(B(""))); Candidate { - path: normalize_path(path_bytes(path)), - basename: os_str_bytes(basename), - ext: file_name_ext(basename).unwrap_or(Cow::Borrowed(b"")), + path: path, + basename: basename, + ext: ext, } } - fn path_prefix(&self, max: usize) -> &[u8] { + fn path_prefix(&self, max: usize) -> &BStr { if self.path.len() <= max { &*self.path } else { @@ -509,7 +516,7 @@ } } - fn path_suffix(&self, max: usize) -> &[u8] { + fn path_suffix(&self, max: usize) -> &BStr { if self.path.len() <= max { &*self.path } else { @@ -570,12 +577,12 @@ } fn is_match(&self, candidate: &Candidate) -> bool { - self.0.contains_key(&*candidate.path) + self.0.contains_key(candidate.path.as_bytes()) } #[inline(never)] fn matches_into(&self, candidate: &Candidate, matches: &mut Vec) { - if let Some(hits) = self.0.get(&*candidate.path) { + if let Some(hits) = self.0.get(candidate.path.as_bytes()) { matches.extend(hits); } } @@ -597,7 +604,7 @@ if candidate.basename.is_empty() { return false; } - self.0.contains_key(&*candidate.basename) + self.0.contains_key(candidate.basename.as_bytes()) } #[inline(never)] @@ -605,7 +612,7 @@ if candidate.basename.is_empty() { return; } - if let Some(hits) = self.0.get(&*candidate.basename) { + if let Some(hits) = self.0.get(candidate.basename.as_bytes()) { matches.extend(hits); } } @@ -627,7 +634,7 @@ if candidate.ext.is_empty() { return false; } - self.0.contains_key(&*candidate.ext) + self.0.contains_key(candidate.ext.as_bytes()) } #[inline(never)] @@ -635,7 +642,7 @@ if candidate.ext.is_empty() { return; } - if let Some(hits) = self.0.get(&*candidate.ext) { + if let Some(hits) = self.0.get(candidate.ext.as_bytes()) { matches.extend(hits); } } @@ -643,7 +650,7 @@ #[derive(Clone, Debug)] struct PrefixStrategy { - matcher: FullAcAutomaton>, + matcher: AhoCorasick, map: Vec, longest: usize, } @@ -651,8 +658,8 @@ impl PrefixStrategy { fn is_match(&self, candidate: &Candidate) -> bool { let path = candidate.path_prefix(self.longest); - for m in self.matcher.find_overlapping(path) { - if m.start == 0 { + for m in self.matcher.find_overlapping_iter(path) { + if m.start() == 0 { return true; } } @@ -661,9 +668,9 @@ fn matches_into(&self, candidate: &Candidate, matches: &mut Vec) { let path = candidate.path_prefix(self.longest); - for m in self.matcher.find_overlapping(path) { - if m.start == 0 { - matches.push(self.map[m.pati]); + for m in self.matcher.find_overlapping_iter(path) { + if m.start() == 0 { + matches.push(self.map[m.pattern()]); } } } @@ -671,7 +678,7 @@ #[derive(Clone, Debug)] struct SuffixStrategy { - matcher: FullAcAutomaton>, + matcher: AhoCorasick, map: Vec, longest: usize, } @@ -679,8 +686,8 @@ impl SuffixStrategy { fn is_match(&self, candidate: &Candidate) -> bool { let path = candidate.path_suffix(self.longest); - for m in self.matcher.find_overlapping(path) { - if m.end == path.len() { + for m in self.matcher.find_overlapping_iter(path) { + if m.end() == path.len() { return true; } } @@ -689,9 +696,9 @@ fn matches_into(&self, candidate: &Candidate, matches: &mut Vec) { let path = candidate.path_suffix(self.longest); - for m in self.matcher.find_overlapping(path) { - if m.end == path.len() { - matches.push(self.map[m.pati]); + for m in self.matcher.find_overlapping_iter(path) { + if m.end() == path.len() { + matches.push(self.map[m.pattern()]); } } } @@ -705,11 +712,11 @@ if candidate.ext.is_empty() { return false; } - match self.0.get(&*candidate.ext) { + match self.0.get(candidate.ext.as_bytes()) { None => false, Some(regexes) => { for &(_, ref re) in regexes { - if re.is_match(&*candidate.path) { + if re.is_match(candidate.path.as_bytes()) { return true; } } @@ -723,9 +730,9 @@ if candidate.ext.is_empty() { return; } - if let Some(regexes) = self.0.get(&*candidate.ext) { + if let Some(regexes) = self.0.get(candidate.ext.as_bytes()) { for &(global_index, ref re) in regexes { - if re.is_match(&*candidate.path) { + if re.is_match(candidate.path.as_bytes()) { matches.push(global_index); } } @@ -741,11 +748,11 @@ impl RegexSetStrategy { fn is_match(&self, candidate: &Candidate) -> bool { - self.matcher.is_match(&*candidate.path) + self.matcher.is_match(candidate.path.as_bytes()) } fn matches_into(&self, candidate: &Candidate, matches: &mut Vec) { - for i in self.matcher.matches(&*candidate.path) { + for i in self.matcher.matches(candidate.path.as_bytes()) { matches.push(self.map[i]); } } @@ -776,18 +783,16 @@ } fn prefix(self) -> PrefixStrategy { - let it = self.literals.into_iter().map(|s| s.into_bytes()); PrefixStrategy { - matcher: AcAutomaton::new(it).into_full(), + matcher: AhoCorasick::new_auto_configured(&self.literals), map: self.map, longest: self.longest, } } fn suffix(self) -> SuffixStrategy { - let it = self.literals.into_iter().map(|s| s.into_bytes()); SuffixStrategy { - matcher: AcAutomaton::new(it).into_full(), + matcher: AhoCorasick::new_auto_configured(&self.literals), map: self.map, longest: self.longest, } diff -Nru cargo-0.33.0/vendor/globset/src/pathutil.rs cargo-0.35.0/vendor/globset/src/pathutil.rs --- cargo-0.33.0/vendor/globset/src/pathutil.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/globset/src/pathutil.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,41 +1,26 @@ use std::borrow::Cow; -use std::ffi::OsStr; -use std::path::Path; + +use bstr::BStr; /// The final component of the path, if it is a normal file. /// /// If the path terminates in ., .., or consists solely of a root of prefix, /// file_name will return None. -#[cfg(unix)] -pub fn file_name<'a, P: AsRef + ?Sized>( - path: &'a P, -) -> Option<&'a OsStr> { - use std::os::unix::ffi::OsStrExt; - use memchr::memrchr; - - let path = path.as_ref().as_os_str().as_bytes(); +pub fn file_name<'a>(path: &Cow<'a, BStr>) -> Option> { if path.is_empty() { return None; - } else if path.len() == 1 && path[0] == b'.' { - return None; - } else if path.last() == Some(&b'.') { - return None; - } else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] { + } else if path.last() == Some(b'.') { return None; } - let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0); - Some(OsStr::from_bytes(&path[last_slash..])) -} - -/// The final component of the path, if it is a normal file. -/// -/// If the path terminates in ., .., or consists solely of a root of prefix, -/// file_name will return None. -#[cfg(not(unix))] -pub fn file_name<'a, P: AsRef + ?Sized>( - path: &'a P, -) -> Option<&'a OsStr> { - path.as_ref().file_name() + let last_slash = path.rfind_byte(b'/').map(|i| i + 1).unwrap_or(0); + Some(match *path { + Cow::Borrowed(path) => Cow::Borrowed(&path[last_slash..]), + Cow::Owned(ref path) => { + let mut path = path.clone(); + path.drain_bytes(..last_slash); + Cow::Owned(path) + } + }) } /// Return a file extension given a path's file name. @@ -54,59 +39,28 @@ /// a pattern like `*.rs` is obviously trying to match files with a `rs` /// extension, but it also matches files like `.rs`, which doesn't have an /// extension according to std::path::Path::extension. -pub fn file_name_ext(name: &OsStr) -> Option> { +pub fn file_name_ext<'a>(name: &Cow<'a, BStr>) -> Option> { if name.is_empty() { return None; } - let name = os_str_bytes(name); - let last_dot_at = { - let result = name - .iter().enumerate().rev() - .find(|&(_, &b)| b == b'.') - .map(|(i, _)| i); - match result { - None => return None, - Some(i) => i, - } + let last_dot_at = match name.rfind_byte(b'.') { + None => return None, + Some(i) => i, }; - Some(match name { + Some(match *name { Cow::Borrowed(name) => Cow::Borrowed(&name[last_dot_at..]), - Cow::Owned(mut name) => { - name.drain(..last_dot_at); + Cow::Owned(ref name) => { + let mut name = name.clone(); + name.drain_bytes(..last_dot_at); Cow::Owned(name) } }) } -/// Return raw bytes of a path, transcoded to UTF-8 if necessary. -pub fn path_bytes(path: &Path) -> Cow<[u8]> { - os_str_bytes(path.as_os_str()) -} - -/// Return the raw bytes of the given OS string, possibly transcoded to UTF-8. -#[cfg(unix)] -pub fn os_str_bytes(s: &OsStr) -> Cow<[u8]> { - use std::os::unix::ffi::OsStrExt; - Cow::Borrowed(s.as_bytes()) -} - -/// Return the raw bytes of the given OS string, possibly transcoded to UTF-8. -#[cfg(not(unix))] -pub fn os_str_bytes(s: &OsStr) -> Cow<[u8]> { - // TODO(burntsushi): On Windows, OS strings are WTF-8, which is a superset - // of UTF-8, so even if we could get at the raw bytes, they wouldn't - // be useful. We *must* convert to UTF-8 before doing path matching. - // Unfortunate, but necessary. - match s.to_string_lossy() { - Cow::Owned(s) => Cow::Owned(s.into_bytes()), - Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()), - } -} - /// Normalizes a path to use `/` as a separator everywhere, even on platforms /// that recognize other characters as separators. #[cfg(unix)] -pub fn normalize_path(path: Cow<[u8]>) -> Cow<[u8]> { +pub fn normalize_path(path: Cow) -> Cow { // UNIX only uses /, so we're good. path } @@ -114,7 +68,7 @@ /// Normalizes a path to use `/` as a separator everywhere, even on platforms /// that recognize other characters as separators. #[cfg(not(unix))] -pub fn normalize_path(mut path: Cow<[u8]>) -> Cow<[u8]> { +pub fn normalize_path(mut path: Cow) -> Cow { use std::path::is_separator; for i in 0..path.len() { @@ -129,7 +83,8 @@ #[cfg(test)] mod tests { use std::borrow::Cow; - use std::ffi::OsStr; + + use bstr::{B, BString}; use super::{file_name_ext, normalize_path}; @@ -137,8 +92,9 @@ ($name:ident, $file_name:expr, $ext:expr) => { #[test] fn $name() { - let got = file_name_ext(OsStr::new($file_name)); - assert_eq!($ext.map(|s| Cow::Borrowed(s.as_bytes())), got); + let bs = BString::from($file_name); + let got = file_name_ext(&Cow::Owned(bs)); + assert_eq!($ext.map(|s| Cow::Borrowed(B(s))), got); } }; } @@ -153,7 +109,8 @@ ($name:ident, $path:expr, $expected:expr) => { #[test] fn $name() { - let got = normalize_path(Cow::Owned($path.to_vec())); + let bs = BString::from_slice($path); + let got = normalize_path(Cow::Owned(bs)); assert_eq!($expected.to_vec(), got.into_owned()); } }; diff -Nru cargo-0.33.0/vendor/http/benches/header_map/basic.rs cargo-0.35.0/vendor/http/benches/header_map/basic.rs --- cargo-0.33.0/vendor/http/benches/header_map/basic.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/benches/header_map/basic.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,586 @@ +macro_rules! bench { + ($name:ident($map:ident, $b:ident) $body:expr) => { + mod $name { + #[allow(unused_imports)] + use test::{self, Bencher}; + use seahash::SeaHasher; + use fnv::FnvHasher; + use std::hash::BuildHasherDefault; + use http::header::*; + #[allow(unused_imports)] + use super::custom_hdr; + + #[bench] + fn header_map($b: &mut Bencher) { + let $map = || HeaderMap::default(); + $body + } + + #[bench] + fn order_map_fnv($b: &mut Bencher) { + use indexmap::IndexMap; + let $map = || IndexMap::<_, _, BuildHasherDefault>::default(); + $body + } + + #[bench] + fn vec_map($b: &mut Bencher) { + use vec_map::VecMap; + + let $map = || VecMap::with_capacity(0); + $body + } + + #[bench] + fn order_map_seahash($b: &mut Bencher) { + use indexmap::IndexMap; + let $map = || IndexMap::<_, _, BuildHasherDefault>::default(); + $body + } + + /* + #[bench] + fn order_map_siphash($b: &mut Bencher) { + use indexmap::IndexMap; + let $map = || IndexMap::new(); + $body + } + + #[bench] + fn std_map_siphash($b: &mut Bencher) { + use std::collections::HashMap; + let $map = || HashMap::new(); + $body + } + */ + } + }; +} + +bench!(new_insert_get_host(new_map, b) { + b.iter(|| { + let mut h = new_map(); + h.insert(HOST, "hyper.rs"); + test::black_box(h.get(&HOST)); + }) +}); + +bench!(insert_4_std_get_30(new_map, b) { + + b.iter(|| { + let mut h = new_map(); + + for i in 0..4 { + h.insert(super::STD[i].clone(), "foo"); + } + + for i in 0..30 { + test::black_box(h.get(&super::STD[i % 4])); + } + }) +}); + +bench!(insert_6_std_get_6(new_map, b) { + + b.iter(|| { + let mut h = new_map(); + + for i in 0..6 { + h.insert(super::STD[i].clone(), "foo"); + } + + for i in 0..6 { + test::black_box(h.get(&super::STD[i % 4])); + } + }) +}); + +/* +bench!(insert_remove_host(new_map, b) { + let mut h = new_map(); + + b.iter(|| { + test::black_box(h.insert(HOST, "hyper.rs")); + test::black_box(h.remove(&HOST)); + }) +}); + +bench!(insert_insert_host(new_map, b) { + let mut h = new_map(); + + b.iter(|| { + test::black_box(h.insert(HOST, "hyper.rs")); + test::black_box(h.insert(HOST, "hyper.rs")); + }) +}); +*/ + +bench!(get_10_of_20_std(new_map, b) { + let mut h = new_map(); + + for hdr in super::STD[10..30].iter() { + h.insert(hdr.clone(), hdr.as_str().to_string()); + } + + b.iter(|| { + for hdr in &super::STD[10..20] { + test::black_box(h.get(hdr)); + } + }) +}); + +bench!(get_100_std(new_map, b) { + let mut h = new_map(); + + for hdr in super::STD.iter() { + h.insert(hdr.clone(), hdr.as_str().to_string()); + } + + b.iter(|| { + for i in 0..100 { + test::black_box(h.get(&super::STD[i % super::STD.len()])); + } + }) +}); + +bench!(set_8_get_1_std(new_map, b) { + b.iter(|| { + let mut h = new_map(); + + for hdr in &super::STD[0..8] { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&super::STD[0])); + }) +}); + +bench!(set_10_get_1_std(new_map, b) { + b.iter(|| { + let mut h = new_map(); + + for hdr in &super::STD[0..10] { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&super::STD[0])); + }) +}); + +bench!(set_20_get_1_std(new_map, b) { + b.iter(|| { + let mut h = new_map(); + + for hdr in &super::STD[0..20] { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&super::STD[0])); + }) +}); + +bench!(get_10_custom_short(new_map, b) { + let hdrs = custom_hdr(20); + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), hdr.as_str().to_string()); + } + + b.iter(|| { + for hdr in &hdrs[..10] { + test::black_box(h.get(hdr)); + } + }) +}); + +bench!(set_10_get_1_custom_short(new_map, b) { + let hdrs = custom_hdr(10); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + + +bench!(set_10_get_1_custom_med(new_map, b) { + let hdrs = super::med_custom_hdr(10); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_10_get_1_custom_long(new_map, b) { + let hdrs = super::long_custom_hdr(10); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_10_get_1_custom_very_long(new_map, b) { + let hdrs = super::very_long_custom_hdr(10); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_20_get_1_custom_short(new_map, b) { + let hdrs = custom_hdr(20); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_20_get_1_custom_med(new_map, b) { + let hdrs = super::med_custom_hdr(20); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_20_get_1_custom_long(new_map, b) { + let hdrs = super::long_custom_hdr(20); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(set_20_get_1_custom_very_long(new_map, b) { + let hdrs = super::very_long_custom_hdr(20); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + + test::black_box(h.get(&hdrs[0])); + }) +}); + +bench!(insert_all_std_headers(new_map, b) { + b.iter(|| { + let mut h = new_map(); + + for hdr in super::STD { + test::black_box(h.insert(hdr.clone(), "foo")); + } + }) +}); + +bench!(insert_79_custom_std_headers(new_map, b) { + let hdrs = super::custom_std(79); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + h.insert(hdr.clone(), "foo"); + } + }) +}); + +bench!(insert_100_custom_headers(new_map, b) { + let hdrs = custom_hdr(100); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + test::black_box(h.insert(hdr.clone(), "foo")); + } + }) +}); + +bench!(insert_500_custom_headers(new_map, b) { + let hdrs = custom_hdr(500); + + b.iter(|| { + let mut h = new_map(); + + for hdr in &hdrs { + test::black_box(h.insert(hdr.clone(), "foo")); + } + }) +}); + +bench!(insert_one_15_char_header(new_map, b) { + let hdr: HeaderName = "abcd-abcd-abcde" + .parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + h.insert(hdr.clone(), "hello"); + test::black_box(h); + }) +}); + +bench!(insert_one_25_char_header(new_map, b) { + let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcde" + .parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + h.insert(hdr.clone(), "hello"); + test::black_box(h); + }) +}); + +bench!(insert_one_50_char_header(new_map, b) { + let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde" + .parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + h.insert(hdr.clone(), "hello"); + test::black_box(h); + }) +}); + +bench!(insert_one_100_char_header(new_map, b) { + let hdr: HeaderName = "abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcdeabcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcd-abcde" + .parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + h.insert(hdr.clone(), "hello"); + test::black_box(h); + }) +}); + +const HN_HDRS: [(&'static str, &'static str); 11] = [ + ("Date", "Fri, 27 Jan 2017 23:00:00 GMT"), + ("Content-Type", "text/html; charset=utf-8"), + ("Transfer-Encoding", "chunked"), + ("Connection", "keep-alive"), + ("Set-Cookie", "__cfduid=dbdfbbe3822b61cb8750ba37d894022151485558000; expires=Sat, 27-Jan-18 23:00:00 GMT; path=/; domain=.ycombinator.com; HttpOnly"), + ("Vary", "Accept-Encoding"), + ("Cache-Control", "private"), + ("X-Frame-Options", "DENY"), + ("Strict-Transport-Security", "max-age=31556900; includeSubDomains"), + ("Server", "cloudflare-nginx"), + ("CF-RAY", "327fd1809f3c1baf-SEA"), +]; + +bench!(hn_hdrs_set_8_get_many(new_map, b) { + let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter() + .map(|&(name, val)| (name.parse().unwrap(), val)) + .collect(); + + b.iter(|| { + let mut h = new_map(); + + for &(ref name, val) in hdrs.iter() { + h.insert(name.clone(), val); + } + + for _ in 0..15 { + test::black_box(h.get(&CONTENT_LENGTH)); + test::black_box(h.get(&VARY)); + } + }); +}); + +bench!(hn_hdrs_set_8_get_miss(new_map, b) { + let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS[..8].iter() + .map(|&(name, val)| (name.parse().unwrap(), val)) + .collect(); + + let miss: HeaderName = "x-wat".parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + + for &(ref name, val) in hdrs.iter() { + h.insert(name.clone(), val); + } + + test::black_box(h.get(&CONTENT_LENGTH)); + test::black_box(h.get(&miss)); + }); +}); + +bench!(hn_hdrs_set_11_get_with_miss(new_map, b) { + let hdrs: Vec<(HeaderName, &'static str)> = super::HN_HDRS.iter() + .map(|&(name, val)| (name.parse().unwrap(), val)) + .collect(); + + let miss: HeaderName = "x-wat".parse().unwrap(); + + b.iter(|| { + let mut h = new_map(); + + for &(ref name, val) in hdrs.iter() { + h.insert(name.clone(), val); + } + + for _ in 0..10 { + test::black_box(h.get(&CONTENT_LENGTH)); + test::black_box(h.get(&VARY)); + test::black_box(h.get(&miss)); + } + }); +}); + +use http::header::*; + +fn custom_hdr(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("x-custom-{}", i); + s.parse().unwrap() + }).collect() +} + +fn med_custom_hdr(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("content-length-{}", i); + s.parse().unwrap() + }).collect() +} + +fn long_custom_hdr(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("access-control-allow-headers-{}", i); + s.parse().unwrap() + }).collect() +} + +fn very_long_custom_hdr(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("access-control-allow-access-control-allow-headers-{}", i); + s.parse().unwrap() + }).collect() +} + +fn custom_std(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("{}-{}", STD[i % STD.len()].as_str(), i); + s.parse().unwrap() + }).collect() +} + +const STD: &'static [HeaderName] = &[ + ACCEPT, + ACCEPT_CHARSET, + ACCEPT_ENCODING, + ACCEPT_LANGUAGE, + ACCEPT_RANGES, + ACCESS_CONTROL_ALLOW_CREDENTIALS, + ACCESS_CONTROL_ALLOW_HEADERS, + ACCESS_CONTROL_ALLOW_METHODS, + ACCESS_CONTROL_ALLOW_ORIGIN, + ACCESS_CONTROL_EXPOSE_HEADERS, + ACCESS_CONTROL_MAX_AGE, + ACCESS_CONTROL_REQUEST_HEADERS, + ACCESS_CONTROL_REQUEST_METHOD, + AGE, + ALLOW, + ALT_SVC, + AUTHORIZATION, + CACHE_CONTROL, + CONNECTION, + CONTENT_DISPOSITION, + CONTENT_ENCODING, + CONTENT_LANGUAGE, + CONTENT_LENGTH, + CONTENT_LOCATION, + CONTENT_RANGE, + CONTENT_SECURITY_POLICY, + CONTENT_SECURITY_POLICY_REPORT_ONLY, + CONTENT_TYPE, + COOKIE, + DNT, + DATE, + ETAG, + EXPECT, + EXPIRES, + FORWARDED, + FROM, + HOST, + IF_MATCH, + IF_MODIFIED_SINCE, + IF_NONE_MATCH, + IF_RANGE, + IF_UNMODIFIED_SINCE, + LAST_MODIFIED, + LINK, + LOCATION, + MAX_FORWARDS, + ORIGIN, + PRAGMA, + PROXY_AUTHENTICATE, + PROXY_AUTHORIZATION, + PUBLIC_KEY_PINS, + PUBLIC_KEY_PINS_REPORT_ONLY, + RANGE, + REFERER, + REFERRER_POLICY, + REFRESH, + RETRY_AFTER, + SERVER, + SET_COOKIE, + STRICT_TRANSPORT_SECURITY, + TE, + TRAILER, + TRANSFER_ENCODING, + USER_AGENT, + UPGRADE, + UPGRADE_INSECURE_REQUESTS, + VARY, + VIA, + WARNING, + WWW_AUTHENTICATE, + X_CONTENT_TYPE_OPTIONS, + X_DNS_PREFETCH_CONTROL, + X_FRAME_OPTIONS, + X_XSS_PROTECTION, +]; diff -Nru cargo-0.33.0/vendor/http/benches/header_map/mod.rs cargo-0.35.0/vendor/http/benches/header_map/mod.rs --- cargo-0.33.0/vendor/http/benches/header_map/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/benches/header_map/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +#![feature(test)] + +extern crate http; +extern crate test; +extern crate indexmap; +extern crate seahash; +extern crate fnv; + +mod basic; +mod vec_map; diff -Nru cargo-0.33.0/vendor/http/benches/header_map/vec_map.rs cargo-0.35.0/vendor/http/benches/header_map/vec_map.rs --- cargo-0.33.0/vendor/http/benches/header_map/vec_map.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/benches/header_map/vec_map.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,103 @@ +#![allow(dead_code)] + +#[derive(Clone)] +pub struct VecMap { + vec: Vec<(K, V)>, +} + +impl VecMap { + #[inline] + pub fn with_capacity(cap: usize) -> VecMap { + VecMap { + vec: Vec::with_capacity(cap) + } + } + + #[inline] + pub fn insert(&mut self, key: K, value: V) { + match self.find(&key) { + Some(pos) => self.vec[pos] = (key, value), + None => self.vec.push((key, value)) + } + } + + #[inline] + pub fn entry(&mut self, key: K) -> Entry { + match self.find(&key) { + Some(pos) => Entry::Occupied(OccupiedEntry { + vec: self, + pos: pos, + }), + None => Entry::Vacant(VacantEntry { + vec: self, + key: key, + }) + } + } + + #[inline] + pub fn get + ?Sized>(&self, key: &K2) -> Option<&V> { + self.find(key).map(move |pos| &self.vec[pos].1) + } + + #[inline] + pub fn get_mut + ?Sized>(&mut self, key: &K2) -> Option<&mut V> { + self.find(key).map(move |pos| &mut self.vec[pos].1) + } + + #[inline] + pub fn contains_key + ?Sized>(&self, key: &K2) -> bool { + self.find(key).is_some() + } + + #[inline] + pub fn len(&self) -> usize { self.vec.len() } + + #[inline] + pub fn iter(&self) -> ::std::slice::Iter<(K, V)> { + self.vec.iter() + } + #[inline] + pub fn remove + ?Sized>(&mut self, key: &K2) -> Option { + self.find(key).map(|pos| self.vec.remove(pos)).map(|(_, v)| v) + } + #[inline] + pub fn clear(&mut self) { + self.vec.clear(); + } + + #[inline] + fn find + ?Sized>(&self, key: &K2) -> Option { + self.vec.iter().position(|entry| key == &entry.0) + } +} + +pub enum Entry<'a, K: 'a, V: 'a> { + Vacant(VacantEntry<'a, K, V>), + Occupied(OccupiedEntry<'a, K, V>) +} + +pub struct VacantEntry<'a, K: 'a, V: 'a> { + vec: &'a mut VecMap, + key: K, +} + +impl<'a, K, V> VacantEntry<'a, K, V> { + pub fn insert(self, val: V) -> &'a mut V { + let vec = self.vec; + vec.vec.push((self.key, val)); + let pos = vec.vec.len() - 1; + &mut vec.vec[pos].1 + } +} + +pub struct OccupiedEntry<'a, K: 'a, V: 'a> { + vec: &'a mut VecMap, + pos: usize, +} + +impl<'a, K, V> OccupiedEntry<'a, K, V> { + pub fn into_mut(self) -> &'a mut V { + &mut self.vec.vec[self.pos].1 + } +} diff -Nru cargo-0.33.0/vendor/http/benches/header_value.rs cargo-0.35.0/vendor/http/benches/header_value.rs --- cargo-0.33.0/vendor/http/benches/header_value.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/benches/header_value.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,54 @@ +#![feature(test)] + +extern crate bytes; +extern crate http; +extern crate test; + +use bytes::Bytes; +use http::header::HeaderValue; +use test::Bencher; + +static SHORT: &'static [u8] = b"localhost"; +static LONG: &'static [u8] = b"Mozilla/5.0 (X11; CrOS x86_64 9592.71.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.80 Safari/537.36"; + + +#[bench] +fn from_shared_short(b: &mut Bencher) { + b.bytes = SHORT.len() as u64; + let bytes = Bytes::from_static(SHORT); + b.iter(|| { + HeaderValue::from_shared(bytes.clone()).unwrap(); + }); +} + +#[bench] +fn from_shared_long(b: &mut Bencher) { + b.bytes = LONG.len() as u64; + let bytes = Bytes::from_static(LONG); + b.iter(|| { + HeaderValue::from_shared(bytes.clone()).unwrap(); + }); +} + + +#[bench] +fn from_shared_unchecked_short(b: &mut Bencher) { + b.bytes = SHORT.len() as u64; + let bytes = Bytes::from_static(SHORT); + b.iter(|| { + unsafe { + HeaderValue::from_shared_unchecked(bytes.clone()); + } + }); +} + +#[bench] +fn from_shared_unchecked_long(b: &mut Bencher) { + b.bytes = LONG.len() as u64; + let bytes = Bytes::from_static(LONG); + b.iter(|| { + unsafe { + HeaderValue::from_shared_unchecked(bytes.clone()); + } + }); +} diff -Nru cargo-0.33.0/vendor/http/benches/uri.rs cargo-0.35.0/vendor/http/benches/uri.rs --- cargo-0.33.0/vendor/http/benches/uri.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/benches/uri.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,33 @@ +#![feature(test)] + +extern crate http; +extern crate test; + +use http::Uri; +use test::Bencher; + +#[bench] +fn uri_parse_slash(b: &mut Bencher) { + b.bytes = 1; + b.iter(|| { + "/".parse::().unwrap(); + }); +} + +#[bench] +fn uri_parse_relative_medium(b: &mut Bencher) { + let s = "/wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg"; + b.bytes = s.len() as u64; + b.iter(|| { + s.parse::().unwrap(); + }); +} + +#[bench] +fn uri_parse_relative_query(b: &mut Bencher) { + let s = "/wp-content/uploads/2010/03/hello-kitty-darth-vader-pink.jpg?foo={bar}|baz%13%11quux"; + b.bytes = s.len() as u64; + b.iter(|| { + s.parse::().unwrap(); + }); +} diff -Nru cargo-0.33.0/vendor/http/.cargo-checksum.json cargo-0.35.0/vendor/http/.cargo-checksum.json --- cargo-0.33.0/vendor/http/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/http/Cargo.toml cargo-0.35.0/vendor/http/Cargo.toml --- cargo-0.33.0/vendor/http/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,61 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "http" +version = "0.1.17" +authors = ["Alex Crichton ", "Carl Lerche ", "Sean McArthur "] +description = "A set of types for representing HTTP requests and responses.\n" +homepage = "https://github.com/hyperium/http" +documentation = "https://docs.rs/http" +readme = "README.md" +keywords = ["http"] +categories = ["web-programming"] +license = "MIT/Apache-2.0" +repository = "https://github.com/hyperium/http" + +[[bench]] +name = "header_map" +path = "benches/header_map/mod.rs" + +[[bench]] +name = "header_value" +path = "benches/header_value.rs" + +[[bench]] +name = "uri" +path = "benches/uri.rs" +[dependencies.bytes] +version = "0.4" + +[dependencies.fnv] +version = "1.0.5" + +[dependencies.itoa] +version = "0.4.1" +[dev-dependencies.indexmap] +version = "1.0" + +[dev-dependencies.quickcheck] +version = "0.6" + +[dev-dependencies.rand] +version = "0.4" + +[dev-dependencies.seahash] +version = "3.0.5" + +[dev-dependencies.serde] +version = "1.0" + +[dev-dependencies.serde_json] +version = "1.0" diff -Nru cargo-0.33.0/vendor/http/CHANGELOG.md cargo-0.35.0/vendor/http/CHANGELOG.md --- cargo-0.33.0/vendor/http/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,106 @@ +# 0.1.17 (April 5, 2019) + +* Add `Error::inner_ref()` to view the kind of error (#303) +* Add `headers_ref()` and `headers_mut()` methods to `request::Builder` and `response::Builder` (#293) + +# 0.1.16 (February 19, 2019) + +* Fix `Uri` to permit more characters in the `path` (#296) + +# 0.1.15 (January 22, 2019) + +* Fix `Uri::host()` to include brackets of IPv6 literals (#292) +* Add `scheme_str` and `port_u16` methods to `Uri` (#287) +* Add `method_ref`, `uri_ref`, and `headers_ref` to `request::Builder` (#284) + +# 0.1.14 (November 21, 2018) + +* Add `Port` struct (#252, #255, #265) +* Introduce `Uri` builder (#219) +* Empty `Method` no longer considered valid (#262) +* Fix `Uri` equality when terminating question mark is present (#270) +* Allow % character in userinfo (#269) +* Support additional tokens for header names (#271) +* Export `http::headers::{IterMut, ValuesMut}` (#278) + +# 0.1.13 (September 14, 2018) + +* impl `fmt::Display` for `HeaderName` (#249) +* Fix `uri::Authority` parsing when there is no host after an `@` (#248) +* Fix `Uri` parsing to allow more characters in query strings (#247) + +# 0.1.12 (September 7, 2018) + +* Fix `HeaderValue` parsing to allow HTABs (#244) + +# 0.1.11 (September 5, 2018) + +* Add `From<&Self>` for `HeaderValue`, `Method`, and `StatusCode` (#238) +* Add `Uri::from_static` (#240) + +# 0.1.10 (August 8, 2018) + +* impl HttpTryFrom for HeaderValue (#236) + +# 0.1.9 (August 7, 2018) + +* Fix double percent encoding (#233) +* Add additional HttpTryFrom impls (#234) + +# 0.1.8 (July 23, 2018) + +* Add fuller set of `PartialEq` for `Method` (#221) +* Reduce size of `HeaderMap` by using `Box<[Entry]>` instea of `Vec` (#224) +* Reduce size of `Extensions` by storing as `Option>` (#227) +* Implement `Iterator::size_hint` for most iterators in `header` (#226) + +# 0.1.7 (June 22, 2018) + +* Add `From for HeaderValue` for most integer types (#218). +* Add `Uri::into_parts()` inherent method (same as `Parts::from(uri)`) (#214). +* Fix converting `Uri`s in authority-form to `Parts` and then back into `Uri` (#216). +* Fix `Authority` parsing to reject multiple port sections (#215). +* Fix parsing 1 character authority-form `Uri`s into illegal forms (#220). + +# 0.1.6 (June 13, 2018) + +* Add `HeaderName::from_static()` constructor (#195). +* Add `Authority::from_static()` constructor (#186). +* Implement `From` for `HeaderValue` (#184). +* Fix duplicate keys when iterating over `header::Keys` (#201). + +# 0.1.5 (February 28, 2018) + +* Add websocket handshake related header constants (#162). +* Parsing `Authority` with an empty string now returns an error (#164). +* Implement `PartialEq` for `StatusCode` (#153). +* Implement `HttpTryFrom<&Uri>` for `Uri` (#165). +* Implement `FromStr` for `Method` (#167). +* Implement `HttpTryFrom` for `Uri` (#171). +* Add `into_body` fns to `Request` and `Response` (#172). +* Fix `Request::options` (#177). + +# 0.1.4 (January 4, 2018) + +* Add PathAndQuery::from_static (#148). +* Impl PartialOrd / PartialEq for Authority and PathAndQuery (#150). +* Add `map` fn to `Request` and `Response` (#151). + +# 0.1.3 (December 11, 2017) + +* Add `Scheme` associated consts for common protos. + +# 0.1.2 (November 29, 2017) + +* Add Uri accessor for scheme part. +* Fix Uri parsing bug (#134) + +# 0.1.1 (October 9, 2017) + +* Provide Uri accessors for parts (#129) +* Add Request builder helpers. (#123) +* Misc performance improvements (#126) + +# 0.1.0 (September 8, 2017) + +* Initial release. diff -Nru cargo-0.33.0/vendor/http/LICENSE-APACHE cargo-0.35.0/vendor/http/LICENSE-APACHE --- cargo-0.33.0/vendor/http/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/LICENSE-APACHE 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2017 http-rs authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff -Nru cargo-0.33.0/vendor/http/LICENSE-MIT cargo-0.35.0/vendor/http/LICENSE-MIT --- cargo-0.33.0/vendor/http/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/LICENSE-MIT 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,25 @@ +Copyright (c) 2017 http-rs authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff -Nru cargo-0.33.0/vendor/http/README.md cargo-0.35.0/vendor/http/README.md --- cargo-0.33.0/vendor/http/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,80 @@ +# HTTP + +A general purpose library of common HTTP types + +[![Build Status](https://travis-ci.org/hyperium/http.svg?branch=master)](https://travis-ci.org/hyperium/http) +[![Crates.io](https://img.shields.io/crates/v/http.svg)](https://crates.io/crates/http) +[![Documentation](https://docs.rs/http/badge.svg)][dox] + +More information about this crate can be found in the [crate +documentation][dox]. + +[dox]: https://docs.rs/http + +## Usage + +To use `http`, first add this to your `Cargo.toml`: + +```toml +[dependencies] +http = "0.1" +``` + +Next, add this to your crate: + +```rust +extern crate http; + +use http::{Request, Response}; + +fn main() { + // ... +} +``` + +## Examples + +Create an HTTP request: + +```rust +extern crate http; + +use http::Request; + +fn main() { + let request = Request::builder() + .uri("https://www.rust-lang.org/") + .header("User-Agent", "awesome/1.0") + .body(()) + .unwrap(); +} +``` + +Create an HTTP response: + +```rust +extern crate http; + +use http::{Response, StatusCode}; + +fn main() { + let response = Response::builder() + .status(StatusCode::MOVED_PERMANENTLY) + .header("Location", "https://www.rust-lang.org/install.html") + .body(()) + .unwrap(); +} +``` + +# License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +# Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff -Nru cargo-0.33.0/vendor/http/src/byte_str.rs cargo-0.35.0/vendor/http/src/byte_str.rs --- cargo-0.33.0/vendor/http/src/byte_str.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/byte_str.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,61 @@ +use bytes::Bytes; + +use std::{ops, str}; + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub(crate) struct ByteStr { + bytes: Bytes, +} + +impl ByteStr { + #[inline] + pub fn new() -> ByteStr { + ByteStr { bytes: Bytes::new() } + } + + #[inline] + pub fn from_static(val: &'static str) -> ByteStr { + ByteStr { bytes: Bytes::from_static(val.as_bytes()) } + } + + #[inline] + pub unsafe fn from_utf8_unchecked(bytes: Bytes) -> ByteStr { + if cfg!(debug_assertions) { + match str::from_utf8(&bytes) { + Ok(_) => (), + Err(err) => panic!("ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}", err, bytes), + } + } + ByteStr { bytes: bytes } + } +} + +impl ops::Deref for ByteStr { + type Target = str; + + #[inline] + fn deref(&self) -> &str { + let b: &[u8] = self.bytes.as_ref(); + unsafe { str::from_utf8_unchecked(b) } + } +} + +impl From for ByteStr { + #[inline] + fn from(src: String) -> ByteStr { + ByteStr { bytes: Bytes::from(src) } + } +} + +impl<'a> From<&'a str> for ByteStr { + #[inline] + fn from(src: &'a str) -> ByteStr { + ByteStr { bytes: Bytes::from(src) } + } +} + +impl From for Bytes { + fn from(src: ByteStr) -> Self { + src.bytes + } +} diff -Nru cargo-0.33.0/vendor/http/src/convert.rs cargo-0.35.0/vendor/http/src/convert.rs --- cargo-0.33.0/vendor/http/src/convert.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/convert.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,64 @@ +use Error; +use header::{HeaderName, HeaderValue}; +use method::Method; +use sealed::Sealed; +use status::StatusCode; +use uri::{Scheme, Authority, PathAndQuery, Uri}; + +/// Private trait for the `http` crate to have generic methods with fallible +/// conversions. +/// +/// This trait is similar to the `TryFrom` trait proposed in the standard +/// library, except this is specialized for the `http` crate and isn't intended +/// for general consumption. +/// +/// This trait cannot be implemented types outside of the `http` crate, and is +/// only intended for use as a generic bound on methods in the `http` crate. +pub trait HttpTryFrom: Sized + Sealed { + /// Associated error with the conversion this implementation represents. + type Error: Into; + + #[doc(hidden)] + fn try_from(t: T) -> Result; +} + +pub(crate) trait HttpTryInto: Sized { + fn http_try_into(self) -> Result; +} + +#[doc(hidden)] +impl HttpTryInto for T +where + U: HttpTryFrom, + T: Sized, +{ + fn http_try_into(self) -> Result { + HttpTryFrom::try_from(self) + .map_err(|e: U::Error| e.into()) + } +} + +macro_rules! reflexive { + ($($t:ty,)*) => ($( + impl HttpTryFrom<$t> for $t { + type Error = Error; + + fn try_from(t: Self) -> Result { + Ok(t) + } + } + + impl Sealed for $t {} + )*) +} + +reflexive! { + Uri, + Method, + StatusCode, + HeaderName, + HeaderValue, + Scheme, + Authority, + PathAndQuery, +} diff -Nru cargo-0.33.0/vendor/http/src/error.rs cargo-0.35.0/vendor/http/src/error.rs --- cargo-0.33.0/vendor/http/src/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,195 @@ +use std::error; +use std::fmt; +use std::result; + +use header; +use method; +use status; +use uri; + +/// A generic "error" for HTTP connections +/// +/// This error type is less specific than the error returned from other +/// functions in this crate, but all other errors can be converted to this +/// error. Consumers of this crate can typically consume and work with this form +/// of error for conversions with the `?` operator. +#[derive(Debug)] +pub struct Error { + inner: ErrorKind, +} + +/// A `Result` typedef to use with the `http::Error` type +pub type Result = result::Result; + +#[derive(Debug)] +enum ErrorKind { + StatusCode(status::InvalidStatusCode), + Method(method::InvalidMethod), + Uri(uri::InvalidUri), + UriShared(uri::InvalidUriBytes), + UriParts(uri::InvalidUriParts), + HeaderName(header::InvalidHeaderName), + HeaderNameShared(header::InvalidHeaderNameBytes), + HeaderValue(header::InvalidHeaderValue), + HeaderValueShared(header::InvalidHeaderValueBytes), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + error::Error::description(self).fmt(f) + } +} + +impl Error { + /// Return true if the underlying error has the same type as T. + pub fn is(&self) -> bool { + self.get_ref().is::() + } + + /// Return a reference to the lower level, inner error. + pub fn get_ref(&self) -> &(error::Error + 'static) { + use self::ErrorKind::*; + + match self.inner { + StatusCode(ref e) => e, + Method(ref e) => e, + Uri(ref e) => e, + UriShared(ref e) => e, + UriParts(ref e) => e, + HeaderName(ref e) => e, + HeaderNameShared(ref e) => e, + HeaderValue(ref e) => e, + HeaderValueShared(ref e) => e, + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + use self::ErrorKind::*; + + match self.inner { + StatusCode(ref e) => e.description(), + Method(ref e) => e.description(), + Uri(ref e) => e.description(), + UriShared(ref e) => e.description(), + UriParts(ref e) => e.description(), + HeaderName(ref e) => e.description(), + HeaderNameShared(ref e) => e.description(), + HeaderValue(ref e) => e.description(), + HeaderValueShared(ref e) => e.description(), + } + } + + // Return any available cause from the inner error. Note the inner error is + // not itself the cause. + #[allow(deprecated)] + fn cause(&self) -> Option<&error::Error> { + self.get_ref().cause() + } +} + +impl From for Error { + fn from(err: status::InvalidStatusCode) -> Error { + Error { inner: ErrorKind::StatusCode(err) } + } +} + +impl From for Error { + fn from(err: method::InvalidMethod) -> Error { + Error { inner: ErrorKind::Method(err) } + } +} + +impl From for Error { + fn from(err: uri::InvalidUri) -> Error { + Error { inner: ErrorKind::Uri(err) } + } +} + +impl From for Error { + fn from(err: uri::InvalidUriBytes) -> Error { + Error { inner: ErrorKind::UriShared(err) } + } +} + +impl From for Error { + fn from(err: uri::InvalidUriParts) -> Error { + Error { inner: ErrorKind::UriParts(err) } + } +} + +impl From for Error { + fn from(err: header::InvalidHeaderName) -> Error { + Error { inner: ErrorKind::HeaderName(err) } + } +} + +impl From for Error { + fn from(err: header::InvalidHeaderNameBytes) -> Error { + Error { inner: ErrorKind::HeaderNameShared(err) } + } +} + +impl From for Error { + fn from(err: header::InvalidHeaderValue) -> Error { + Error { inner: ErrorKind::HeaderValue(err) } + } +} + +impl From for Error { + fn from(err: header::InvalidHeaderValueBytes) -> Error { + Error { inner: ErrorKind::HeaderValueShared(err) } + } +} + +// A crate-private type until we can use !. +// +// Being crate-private, we should be able to swap the type out in a +// backwards compatible way. +pub enum Never {} + +impl From for Error { + fn from(never: Never) -> Error { + match never {} + } +} + +impl fmt::Debug for Never { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match *self {} + } +} + +impl fmt::Display for Never { + fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { + match *self {} + } +} + +impl error::Error for Never { + fn description(&self) -> &str { + match *self {} + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn inner_error_is_invalid_status_code() { + if let Err(e) = status::StatusCode::from_u16(6666) { + let err: Error = e.into(); + let ie = err.get_ref(); + assert!(!ie.is::()); + assert!( ie.is::()); + ie.downcast_ref::().unwrap(); + + assert!(!err.is::()); + assert!( err.is::()); + } else { + panic!("Bad status allowed!"); + } + } +} diff -Nru cargo-0.33.0/vendor/http/src/extensions.rs cargo-0.35.0/vendor/http/src/extensions.rs --- cargo-0.33.0/vendor/http/src/extensions.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/extensions.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,195 @@ +use std::any::{Any, TypeId}; +use std::collections::HashMap; +use std::hash::{BuildHasherDefault, Hasher}; +use std::fmt; + +type AnyMap = HashMap, BuildHasherDefault>; + +// With TypeIds as keys, there's no need to hash them. They are already hashes +// themselves, coming from the compiler. The IdHasher just holds the u64 of +// the TypeId, and then returns it, instead of doing any bit fiddling. +#[derive(Default)] +struct IdHasher(u64); + +impl Hasher for IdHasher { + fn write(&mut self, _: &[u8]) { + unreachable!("TypeId calls write_u64"); + } + + #[inline] + fn write_u64(&mut self, id: u64) { + self.0 = id; + } + + #[inline] + fn finish(&self) -> u64 { + self.0 + } +} + + + +/// A type map of protocol extensions. +/// +/// `Extensions` can be used by `Request` and `Response` to store +/// extra data derived from the underlying protocol. +#[derive(Default)] +pub struct Extensions { + // If extensions are never used, no need to carry around an empty HashMap. + // That's 3 words. Instead, this is only 1 word. + map: Option>, +} + +impl Extensions { + /// Create an empty `Extensions`. + #[inline] + pub fn new() -> Extensions { + Extensions { + map: None, + } + } + + /// Insert a type into this `Extensions`. + /// + /// If a extension of this type already existed, it will + /// be returned. + /// + /// # Example + /// + /// ``` + /// # use http::Extensions; + /// let mut ext = Extensions::new(); + /// assert!(ext.insert(5i32).is_none()); + /// assert!(ext.insert(4u8).is_none()); + /// assert_eq!(ext.insert(9i32), Some(5i32)); + /// ``` + pub fn insert(&mut self, val: T) -> Option { + self + .map + .get_or_insert_with(|| Box::new(HashMap::default())) + .insert(TypeId::of::(), Box::new(val)) + .and_then(|boxed| { + //TODO: we can use unsafe and remove double checking the type id + (boxed as Box) + .downcast() + .ok() + .map(|boxed| *boxed) + }) + } + + /// Get a reference to a type previously inserted on this `Extensions`. + /// + /// # Example + /// + /// ``` + /// # use http::Extensions; + /// let mut ext = Extensions::new(); + /// assert!(ext.get::().is_none()); + /// ext.insert(5i32); + /// + /// assert_eq!(ext.get::(), Some(&5i32)); + /// ``` + pub fn get(&self) -> Option<&T> { + self + .map + .as_ref() + .and_then(|map| map.get(&TypeId::of::())) + //TODO: we can use unsafe and remove double checking the type id + .and_then(|boxed| (&**boxed as &(Any + 'static)).downcast_ref()) + } + + /// Get a mutable reference to a type previously inserted on this `Extensions`. + /// + /// # Example + /// + /// ``` + /// # use http::Extensions; + /// let mut ext = Extensions::new(); + /// ext.insert(String::from("Hello")); + /// ext.get_mut::().unwrap().push_str(" World"); + /// + /// assert_eq!(ext.get::().unwrap(), "Hello World"); + /// ``` + pub fn get_mut(&mut self) -> Option<&mut T> { + self + .map + .as_mut() + .and_then(|map| map.get_mut(&TypeId::of::())) + //TODO: we can use unsafe and remove double checking the type id + .and_then(|boxed| (&mut **boxed as &mut (Any + 'static)).downcast_mut()) + } + + + /// Remove a type from this `Extensions`. + /// + /// If a extension of this type existed, it will be returned. + /// + /// # Example + /// + /// ``` + /// # use http::Extensions; + /// let mut ext = Extensions::new(); + /// ext.insert(5i32); + /// assert_eq!(ext.remove::(), Some(5i32)); + /// assert!(ext.get::().is_none()); + /// ``` + pub fn remove(&mut self) -> Option { + self + .map + .as_mut() + .and_then(|map| map.remove(&TypeId::of::())) + .and_then(|boxed| { + //TODO: we can use unsafe and remove double checking the type id + (boxed as Box) + .downcast() + .ok() + .map(|boxed| *boxed) + }) + } + + /// Clear the `Extensions` of all inserted extensions. + /// + /// # Example + /// + /// ``` + /// # use http::Extensions; + /// let mut ext = Extensions::new(); + /// ext.insert(5i32); + /// ext.clear(); + /// + /// assert!(ext.get::().is_none()); + /// ``` + #[inline] + pub fn clear(&mut self) { + if let Some(ref mut map) = self.map { + map.clear(); + } + } +} + +impl fmt::Debug for Extensions { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Extensions") + .finish() + } +} + +#[test] +fn test_extensions() { + #[derive(Debug, PartialEq)] + struct MyType(i32); + + let mut extensions = Extensions::new(); + + extensions.insert(5i32); + extensions.insert(MyType(10)); + + assert_eq!(extensions.get(), Some(&5i32)); + assert_eq!(extensions.get_mut(), Some(&mut 5i32)); + + assert_eq!(extensions.remove::(), Some(5i32)); + assert!(extensions.get::().is_none()); + + assert_eq!(extensions.get::(), None); + assert_eq!(extensions.get(), Some(&MyType(10))); +} diff -Nru cargo-0.33.0/vendor/http/src/header/map.rs cargo-0.35.0/vendor/http/src/header/map.rs --- cargo-0.33.0/vendor/http/src/header/map.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/header/map.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,3321 @@ +use super::HeaderValue; +use super::name::{HeaderName, HdrName, InvalidHeaderName}; + +use std::{fmt, mem, ops, ptr, vec}; +use std::collections::hash_map::RandomState; +use std::hash::{BuildHasher, Hasher, Hash}; +use std::iter::FromIterator; +use std::marker::PhantomData; + +pub use self::as_header_name::AsHeaderName; +pub use self::into_header_name::IntoHeaderName; + +/// A set of HTTP headers +/// +/// `HeaderMap` is an multimap of [`HeaderName`] to values. +/// +/// [`HeaderName`]: struct.HeaderName.html +/// +/// # Examples +/// +/// Basic usage +/// +/// ``` +/// # use http::HeaderMap; +/// # use http::header::{CONTENT_LENGTH, HOST, LOCATION}; +/// let mut headers = HeaderMap::new(); +/// +/// headers.insert(HOST, "example.com".parse().unwrap()); +/// headers.insert(CONTENT_LENGTH, "123".parse().unwrap()); +/// +/// assert!(headers.contains_key(HOST)); +/// assert!(!headers.contains_key(LOCATION)); +/// +/// assert_eq!(headers[HOST], "example.com"); +/// +/// headers.remove(HOST); +/// +/// assert!(!headers.contains_key(HOST)); +/// ``` +#[derive(Clone)] +pub struct HeaderMap { + // Used to mask values to get an index + mask: Size, + indices: Box<[Pos]>, + entries: Vec>, + extra_values: Vec>, + danger: Danger, +} + +// # Implementation notes +// +// Below, you will find a fairly large amount of code. Most of this is to +// provide the necessary functions to efficiently manipulate the header +// multimap. The core hashing table is based on robin hood hashing [1]. While +// this is the same hashing algorithm used as part of Rust's `HashMap` in +// stdlib, many implementation details are different. The two primary reasons +// for this divergence are that `HeaderMap` is a multimap and the structure has +// been optimized to take advantage of the characteristics of HTTP headers. +// +// ## Structure Layout +// +// Most of the data contained by `HeaderMap` is *not* stored in the hash table. +// Instead, pairs of header name and *first* associated header value are stored +// in the `entries` vector. If the header name has more than one associated +// header value, then additional values are stored in `extra_values`. The actual +// hash table (`indices`) only maps hash codes to indices in `entries`. This +// means that, when an eviction happens, the actual header name and value stay +// put and only a tiny amount of memory has to be copied. +// +// Extra values associated with a header name are tracked using a linked list. +// Links are formed with offsets into `extra_values` and not pointers. +// +// [1]: https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing + +/// `HeaderMap` entry iterator. +/// +/// Yields `(&HeaderName, &value)` tuples. The same header name may be yielded +/// more than once if it has more than one associated value. +#[derive(Debug)] +pub struct Iter<'a, T: 'a> { + inner: IterMut<'a, T>, +} + +/// `HeaderMap` mutable entry iterator +/// +/// Yields `(&HeaderName, &mut value)` tuples. The same header name may be +/// yielded more than once if it has more than one associated value. +#[derive(Debug)] +pub struct IterMut<'a, T: 'a> { + map: *mut HeaderMap, + entry: usize, + cursor: Option, + lt: PhantomData<&'a mut HeaderMap>, +} + +/// An owning iterator over the entries of a `HeaderMap`. +/// +/// This struct is created by the `into_iter` method on `HeaderMap`. +#[derive(Debug)] +pub struct IntoIter { + // If None, pull from `entries` + next: Option, + entries: vec::IntoIter>, + extra_values: Vec>, +} + +/// An iterator over `HeaderMap` keys. +/// +/// Each header name is yielded only once, even if it has more than one +/// associated value. +#[derive(Debug)] +pub struct Keys<'a, T: 'a> { + inner: ::std::slice::Iter<'a, Bucket>, +} + +/// `HeaderMap` value iterator. +/// +/// Each value contained in the `HeaderMap` will be yielded. +#[derive(Debug)] +pub struct Values<'a, T: 'a> { + inner: Iter<'a, T>, +} + +/// `HeaderMap` mutable value iterator +#[derive(Debug)] +pub struct ValuesMut<'a, T: 'a> { + inner: IterMut<'a, T>, +} + +/// A drain iterator for `HeaderMap`. +#[derive(Debug)] +pub struct Drain<'a, T: 'a> { + idx: usize, + map: *mut HeaderMap, + lt: PhantomData<&'a mut HeaderMap>, +} + +/// A view to all values stored in a single entry. +/// +/// This struct is returned by `HeaderMap::get_all`. +#[derive(Debug)] +pub struct GetAll<'a, T: 'a> { + map: &'a HeaderMap, + index: Option, +} + +/// A view into a single location in a `HeaderMap`, which may be vacant or occupied. +#[derive(Debug)] +pub enum Entry<'a, T: 'a> { + /// An occupied entry + Occupied(OccupiedEntry<'a, T>), + + /// A vacant entry + Vacant(VacantEntry<'a, T>), +} + +/// A view into a single empty location in a `HeaderMap`. +/// +/// This struct is returned as part of the `Entry` enum. +#[derive(Debug)] +pub struct VacantEntry<'a, T: 'a> { + map: &'a mut HeaderMap, + key: HeaderName, + hash: HashValue, + probe: usize, + danger: bool, +} + +/// A view into a single occupied location in a `HeaderMap`. +/// +/// This struct is returned as part of the `Entry` enum. +#[derive(Debug)] +pub struct OccupiedEntry<'a, T: 'a> { + map: &'a mut HeaderMap, + probe: usize, + index: usize, +} + +/// An iterator of all values associated with a single header name. +#[derive(Debug)] +pub struct ValueIter<'a, T: 'a> { + map: &'a HeaderMap, + index: usize, + front: Option, + back: Option, +} + +/// A mutable iterator of all values associated with a single header name. +#[derive(Debug)] +pub struct ValueIterMut<'a, T: 'a> { + map: *mut HeaderMap, + index: usize, + front: Option, + back: Option, + lt: PhantomData<&'a mut HeaderMap>, +} + +/// An drain iterator of all values associated with a single header name. +#[derive(Debug)] +pub struct ValueDrain<'a, T: 'a> { + map: *mut HeaderMap, + first: Option, + next: Option, + lt: PhantomData<&'a mut HeaderMap>, +} + +/// Tracks the value iterator state +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +enum Cursor { + Head, + Values(usize), +} + +/// Type used for representing the size of a HeaderMap value. +/// +/// 32,768 is more than enough entries for a single header map. Setting this +/// limit enables using `u16` to represent all offsets, which takes 2 bytes +/// instead of 8 on 64 bit processors. +/// +/// Setting this limit is especially benificial for `indices`, making it more +/// cache friendly. More hash codes can fit in a cache line. +/// +/// You may notice that `u16` may represent more than 32,768 values. This is +/// true, but 32,768 should be plenty and it allows us to reserve the top bit +/// for future usage. +type Size = usize; + +/// This limit falls out from above. +const MAX_SIZE: usize = (1 << 15); + +/// An entry in the hash table. This represents the full hash code for an entry +/// as well as the position of the entry in the `entries` vector. +#[derive(Copy, Clone)] +struct Pos { + // Index in the `entries` vec + index: Size, + // Full hash value for the entry. + hash: HashValue, +} + +/// Hash values are limited to u16 as well. While `fast_hash` and `Hasher` +/// return `usize` hash codes, limiting the effective hash code to the lower 16 +/// bits is fine since we know that the `indices` vector will never grow beyond +/// that size. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +struct HashValue(usize); + +/// Stores the data associated with a `HeaderMap` entry. Only the first value is +/// included in this struct. If a header name has more than one associated +/// value, all extra values are stored in the `extra_values` vector. A doubly +/// linked list of entries is maintained. The doubly linked list is used so that +/// removing a value is constant time. This also has the nice property of +/// enabling double ended iteration. +#[derive(Debug, Clone)] +struct Bucket { + hash: HashValue, + key: HeaderName, + value: T, + links: Option, +} + +/// The head and tail of the value linked list. +#[derive(Debug, Copy, Clone)] +struct Links { + next: usize, + tail: usize, +} + +/// Node in doubly-linked list of header value entries +#[derive(Debug, Clone)] +struct ExtraValue { + value: T, + prev: Link, + next: Link, +} + +/// A header value node is either linked to another node in the `extra_values` +/// list or it points to an entry in `entries`. The entry in `entries` is the +/// start of the list and holds the associated header name. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +enum Link { + Entry(usize), + Extra(usize), +} + +/// Tracks the header map danger level! This relates to the adaptive hashing +/// algorithm. A HeaderMap starts in the "green" state, when a large number of +/// collisions are detected, it transitions to the yellow state. At this point, +/// the header map will either grow and switch back to the green state OR it +/// will transition to the red state. +/// +/// When in the red state, a safe hashing algorithm is used and all values in +/// the header map have to be rehashed. +#[derive(Clone)] +enum Danger { + Green, + Yellow, + Red(RandomState), +} + +// Constants related to detecting DOS attacks. +// +// Displacement is the number of entries that get shifted when inserting a new +// value. Forward shift is how far the entry gets stored from the ideal +// position. +// +// The current constant values were picked from another implementation. It could +// be that there are different values better suited to the header map case. +const DISPLACEMENT_THRESHOLD: usize = 128; +const FORWARD_SHIFT_THRESHOLD: usize = 512; + +// The default strategy for handling the yellow danger state is to increase the +// header map capacity in order to (hopefully) reduce the number of collisions. +// If growing the hash map would cause the load factor to drop bellow this +// threshold, then instead of growing, the headermap is switched to the red +// danger state and safe hashing is used instead. +const LOAD_FACTOR_THRESHOLD: f32 = 0.2; + +// Macro used to iterate the hash table starting at a given point, looping when +// the end is hit. +macro_rules! probe_loop { + ($label:tt: $probe_var: ident < $len: expr, $body: expr) => { + debug_assert!($len > 0); + $label: + loop { + if $probe_var < $len { + $body + $probe_var += 1; + } else { + $probe_var = 0; + } + } + }; + ($probe_var: ident < $len: expr, $body: expr) => { + debug_assert!($len > 0); + loop { + if $probe_var < $len { + $body + $probe_var += 1; + } else { + $probe_var = 0; + } + } + }; +} + +// First part of the robinhood algorithm. Given a key, find the slot in which it +// will be inserted. This is done by starting at the "ideal" spot. Then scanning +// until the destination slot is found. A destination slot is either the next +// empty slot or the next slot that is occupied by an entry that has a lower +// displacement (displacement is the distance from the ideal spot). +// +// This is implemented as a macro instead of a function that takes a closure in +// order to guarantee that it is "inlined". There is no way to annotate closures +// to guarantee inlining. +macro_rules! insert_phase_one { + ($map:ident, + $key:expr, + $probe:ident, + $pos:ident, + $hash:ident, + $danger:ident, + $vacant:expr, + $occupied:expr, + $robinhood:expr) => + {{ + let $hash = hash_elem_using(&$map.danger, &$key); + let mut $probe = desired_pos($map.mask, $hash); + let mut dist = 0; + let ret; + + // Start at the ideal position, checking all slots + probe_loop!('probe: $probe < $map.indices.len(), { + if let Some(($pos, entry_hash)) = $map.indices[$probe].resolve() { + // The slot is already occupied, but check if it has a lower + // displacement. + let their_dist = probe_distance($map.mask, entry_hash, $probe); + + if their_dist < dist { + // The new key's distance is larger, so claim this spot and + // displace the current entry. + // + // Check if this insertion is above the danger threshold. + let $danger = + dist >= FORWARD_SHIFT_THRESHOLD && !$map.danger.is_red(); + + ret = $robinhood; + break 'probe; + } else if entry_hash == $hash && $map.entries[$pos].key == $key { + // There already is an entry with the same key. + ret = $occupied; + break 'probe; + } + } else { + // The entry is vacant, use it for this key. + let $danger = + dist >= FORWARD_SHIFT_THRESHOLD && !$map.danger.is_red(); + + ret = $vacant; + break 'probe; + } + + dist += 1; + }); + + ret + }} +} + +// ===== impl HeaderMap ===== + +impl HeaderMap { + /// Create an empty `HeaderMap`. + /// + /// The map will be created without any capacity. This function will not + /// allocate. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let map = HeaderMap::new(); + /// + /// assert!(map.is_empty()); + /// assert_eq!(0, map.capacity()); + /// ``` + pub fn new() -> Self { + HeaderMap::with_capacity(0) + } +} + +impl HeaderMap { + /// Create an empty `HeaderMap` with the specified capacity. + /// + /// The returned map will allocate internal storage in order to hold about + /// `capacity` elements without reallocating. However, this is a "best + /// effort" as there are usage patterns that could cause additional + /// allocations before `capacity` headers are stored in the map. + /// + /// More capacity than requested may be allocated. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let map: HeaderMap = HeaderMap::with_capacity(10); + /// + /// assert!(map.is_empty()); + /// assert_eq!(12, map.capacity()); + /// ``` + pub fn with_capacity(capacity: usize) -> HeaderMap { + assert!(capacity <= MAX_SIZE, "requested capacity too large"); + + if capacity == 0 { + HeaderMap { + mask: 0, + indices: Box::new([]), // as a ZST, this doesn't actually allocate anything + entries: Vec::new(), + extra_values: Vec::new(), + danger: Danger::Green, + } + } else { + let raw_cap = to_raw_capacity(capacity).next_power_of_two(); + debug_assert!(raw_cap > 0); + + HeaderMap { + mask: (raw_cap - 1) as Size, + indices: vec![Pos::none(); raw_cap].into_boxed_slice(), + entries: Vec::with_capacity(raw_cap), + extra_values: Vec::new(), + danger: Danger::Green, + } + } + } + + /// Returns the number of headers stored in the map. + /// + /// This number represents the total number of **values** stored in the map. + /// This number can be greater than or equal to the number of **keys** + /// stored given that a single key may have more than one associated value. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{ACCEPT, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// assert_eq!(0, map.len()); + /// + /// map.insert(ACCEPT, "text/plain".parse().unwrap()); + /// map.insert(HOST, "localhost".parse().unwrap()); + /// + /// assert_eq!(2, map.len()); + /// + /// map.append(ACCEPT, "text/html".parse().unwrap()); + /// + /// assert_eq!(3, map.len()); + /// ``` + pub fn len(&self) -> usize { + self.entries.len() + self.extra_values.len() + } + + /// Returns the number of keys stored in the map. + /// + /// This number will be less than or equal to `len()` as each key may have + /// more than one associated value. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{ACCEPT, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// assert_eq!(0, map.keys_len()); + /// + /// map.insert(ACCEPT, "text/plain".parse().unwrap()); + /// map.insert(HOST, "localhost".parse().unwrap()); + /// + /// assert_eq!(2, map.keys_len()); + /// + /// map.insert(ACCEPT, "text/html".parse().unwrap()); + /// + /// assert_eq!(2, map.keys_len()); + /// ``` + pub fn keys_len(&self) -> usize { + self.entries.len() + } + + /// Returns true if the map contains no elements. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// + /// assert!(map.is_empty()); + /// + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// assert!(!map.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.entries.len() == 0 + } + + /// Clears the map, removing all key-value pairs. Keeps the allocated memory + /// for reuse. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// map.clear(); + /// assert!(map.is_empty()); + /// assert!(map.capacity() > 0); + /// ``` + pub fn clear(&mut self) { + self.entries.clear(); + self.extra_values.clear(); + self.danger = Danger::Green; + + for e in self.indices.iter_mut() { + *e = Pos::none(); + } + } + + /// Returns the number of headers the map can hold without reallocating. + /// + /// This number is an approximation as certain usage patterns could cause + /// additional allocations before the returned capacity is filled. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// + /// assert_eq!(0, map.capacity()); + /// + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// assert_eq!(6, map.capacity()); + /// ``` + pub fn capacity(&self) -> usize { + usable_capacity(self.indices.len()) + } + + /// Reserves capacity for at least `additional` more headers to be inserted + /// into the `HeaderMap`. + /// + /// The header map may reserve more space to avoid frequent reallocations. + /// Like with `with_capacity`, this will be a "best effort" to avoid + /// allocations until `additional` more headers are inserted. Certain usage + /// patterns could cause additional allocations before the number is + /// reached. + /// + /// # Panics + /// + /// Panics if the new allocation size overflows `usize`. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// map.reserve(10); + /// # map.insert(HOST, "bar".parse().unwrap()); + /// ``` + pub fn reserve(&mut self, additional: usize) { + // TODO: This can't overflow if done properly... since the max # of + // elements is u16::MAX. + let cap = self.entries.len() + .checked_add(additional) + .expect("reserve overflow"); + + if cap > self.indices.len() { + let cap = cap.next_power_of_two(); + + if self.entries.len() == 0 { + self.mask = cap - 1; + self.indices = vec![Pos::none(); cap].into_boxed_slice(); + self.entries = Vec::with_capacity(usable_capacity(cap)); + } else { + self.grow(cap); + } + } + } + + /// Returns a reference to the value associated with the key. + /// + /// If there are multiple values associated with the key, then the first one + /// is returned. Use `get_all` to get all values associated with a given + /// key. Returns `None` if there are no values associated with the key. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// assert!(map.get("host").is_none()); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// assert_eq!(map.get(HOST).unwrap(), &"hello"); + /// assert_eq!(map.get("host").unwrap(), &"hello"); + /// + /// map.append(HOST, "world".parse().unwrap()); + /// assert_eq!(map.get("host").unwrap(), &"hello"); + /// ``` + pub fn get(&self, key: K) -> Option<&T> + where K: AsHeaderName + { + self.get2(&key) + } + + fn get2(&self, key: &K) -> Option<&T> + where K: AsHeaderName + { + match key.find(self) { + Some((_, found)) => { + let entry = &self.entries[found]; + Some(&entry.value) + } + None => None, + } + } + + /// Returns a mutable reference to the value associated with the key. + /// + /// If there are multiple values associated with the key, then the first one + /// is returned. Use `entry` to get all values associated with a given + /// key. Returns `None` if there are no values associated with the key. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::default(); + /// map.insert(HOST, "hello".to_string()); + /// map.get_mut("host").unwrap().push_str("-world"); + /// + /// assert_eq!(map.get(HOST).unwrap(), &"hello-world"); + /// ``` + pub fn get_mut(&mut self, key: K) -> Option<&mut T> + where K: AsHeaderName + { + match key.find(self) { + Some((_, found)) => { + let entry = &mut self.entries[found]; + Some(&mut entry.value) + } + None => None, + } + } + + /// Returns a view of all values associated with a key. + /// + /// The returned view does not incur any allocations and allows iterating + /// the values associated with the key. See [`GetAll`] for more details. + /// Returns `None` if there are no values associated with the key. + /// + /// [`GetAll`]: struct.GetAll.html + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// map.append(HOST, "goodbye".parse().unwrap()); + /// + /// let view = map.get_all("host"); + /// + /// let mut iter = view.iter(); + /// assert_eq!(&"hello", iter.next().unwrap()); + /// assert_eq!(&"goodbye", iter.next().unwrap()); + /// assert!(iter.next().is_none()); + /// ``` + pub fn get_all(&self, key: K) -> GetAll + where K: AsHeaderName + { + GetAll { + map: self, + index: key.find(self).map(|(_, i)| i), + } + } + + /// Returns true if the map contains a value for the specified key. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// assert!(!map.contains_key(HOST)); + /// + /// map.insert(HOST, "world".parse().unwrap()); + /// assert!(map.contains_key("host")); + /// ``` + pub fn contains_key(&self, key: K) -> bool + where K: AsHeaderName + { + key.find(self).is_some() + } + + /// An iterator visiting all key-value pairs. + /// + /// The iteration order is arbitrary, but consistent across platforms for + /// the same crate version. Each key will be yielded once per associated + /// value. So, if a key has 3 associated values, it will be yielded 3 times. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// map.append(HOST, "goodbye".parse().unwrap()); + /// map.insert(CONTENT_LENGTH, "123".parse().unwrap()); + /// + /// for (key, value) in map.iter() { + /// println!("{:?}: {:?}", key, value); + /// } + /// ``` + pub fn iter(&self) -> Iter { + Iter { + inner: IterMut { + map: self as *const _ as *mut _, + entry: 0, + cursor: self.entries.first().map(|_| Cursor::Head), + lt: PhantomData, + } + } + } + + /// An iterator visiting all key-value pairs, with mutable value references. + /// + /// The iterator order is arbitrary, but consistent across platforms for the + /// same crate version. Each key will be yielded once per associated value, + /// so if a key has 3 associated values, it will be yielded 3 times. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::default(); + /// + /// map.insert(HOST, "hello".to_string()); + /// map.append(HOST, "goodbye".to_string()); + /// map.insert(CONTENT_LENGTH, "123".to_string()); + /// + /// for (key, value) in map.iter_mut() { + /// value.push_str("-boop"); + /// } + /// ``` + pub fn iter_mut(&mut self) -> IterMut { + IterMut { + map: self as *mut _, + entry: 0, + cursor: self.entries.first().map(|_| Cursor::Head), + lt: PhantomData, + } + } + + /// An iterator visiting all keys. + /// + /// The iteration order is arbitrary, but consistent across platforms for + /// the same crate version. Each key will be yielded only once even if it + /// has multiple associated values. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// map.append(HOST, "goodbye".parse().unwrap()); + /// map.insert(CONTENT_LENGTH, "123".parse().unwrap()); + /// + /// for key in map.keys() { + /// println!("{:?}", key); + /// } + /// ``` + pub fn keys(&self) -> Keys { + Keys { inner: self.entries.iter() } + } + + /// An iterator visiting all values. + /// + /// The iteration order is arbitrary, but consistent across platforms for + /// the same crate version. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// map.append(HOST, "goodbye".parse().unwrap()); + /// map.insert(CONTENT_LENGTH, "123".parse().unwrap()); + /// + /// for value in map.values() { + /// println!("{:?}", value); + /// } + /// ``` + pub fn values(&self) -> Values { + Values { inner: self.iter() } + } + + /// An iterator visiting all values mutably. + /// + /// The iteration order is arbitrary, but consistent across platforms for + /// the same crate version. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::default(); + /// + /// map.insert(HOST, "hello".to_string()); + /// map.append(HOST, "goodbye".to_string()); + /// map.insert(CONTENT_LENGTH, "123".to_string()); + /// + /// for value in map.values_mut() { + /// value.push_str("-boop"); + /// } + /// ``` + pub fn values_mut(&mut self) -> ValuesMut { + ValuesMut { inner: self.iter_mut() } + } + + /// Clears the map, returning all entries as an iterator. + /// + /// The internal memory is kept for reuse. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::{CONTENT_LENGTH, HOST}; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(HOST, "hello".parse().unwrap()); + /// map.append(HOST, "goodbye".parse().unwrap()); + /// map.insert(CONTENT_LENGTH, "123".parse().unwrap()); + /// + /// let mut drain = map.drain(); + /// + /// let (key, mut vals) = drain.next().unwrap(); + /// + /// assert_eq!("host", key); + /// assert_eq!("hello", vals.next().unwrap()); + /// assert_eq!("goodbye", vals.next().unwrap()); + /// assert!(vals.next().is_none()); + /// + /// let (key, mut vals) = drain.next().unwrap(); + /// + /// assert_eq!("content-length", key); + /// assert_eq!("123", vals.next().unwrap()); + /// assert!(vals.next().is_none()); + /// ``` + pub fn drain(&mut self) -> Drain { + for i in self.indices.iter_mut() { + *i = Pos::none(); + } + + Drain { + idx: 0, + map: self as *mut _, + lt: PhantomData, + } + } + + fn value_iter(&self, idx: Option) -> ValueIter { + use self::Cursor::*; + + if let Some(idx) = idx { + let back = { + let entry = &self.entries[idx]; + + entry.links + .map(|l| Values(l.tail)) + .unwrap_or(Head) + }; + + ValueIter { + map: self, + index: idx, + front: Some(Head), + back: Some(back), + } + } else { + ValueIter { + map: self, + index: ::std::usize::MAX, + front: None, + back: None, + } + } + } + + fn value_iter_mut(&mut self, idx: usize) -> ValueIterMut { + use self::Cursor::*; + + let back = { + let entry = &self.entries[idx]; + + entry.links + .map(|l| Values(l.tail)) + .unwrap_or(Head) + }; + + ValueIterMut { + map: self as *mut _, + index: idx, + front: Some(Head), + back: Some(back), + lt: PhantomData, + } + } + + /// Gets the given key's corresponding entry in the map for in-place + /// manipulation. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let mut map: HeaderMap = HeaderMap::default(); + /// + /// let headers = &[ + /// "content-length", + /// "x-hello", + /// "Content-Length", + /// "x-world", + /// ]; + /// + /// for &header in headers { + /// let counter = map.entry(header).unwrap().or_insert(0); + /// *counter += 1; + /// } + /// + /// assert_eq!(map["content-length"], 2); + /// assert_eq!(map["x-hello"], 1); + /// ``` + pub fn entry(&mut self, key: K) -> Result, InvalidHeaderName> + where K: AsHeaderName, + { + key.entry(self) + } + + fn entry2(&mut self, key: K) -> Entry + where K: Hash + Into, + HeaderName: PartialEq, + { + // Ensure that there is space in the map + self.reserve_one(); + + insert_phase_one!( + self, + key, + probe, + pos, + hash, + danger, + Entry::Vacant(VacantEntry { + map: self, + hash: hash, + key: key.into(), + probe: probe, + danger: danger, + }), + Entry::Occupied(OccupiedEntry { + map: self, + index: pos, + probe: probe, + }), + Entry::Vacant(VacantEntry { + map: self, + hash: hash, + key: key.into(), + probe: probe, + danger: danger, + })) + } + + /// Inserts a key-value pair into the map. + /// + /// If the map did not previously have this key present, then `None` is + /// returned. + /// + /// If the map did have this key present, the new value is associated with + /// the key and all previous values are removed. **Note** that only a single + /// one of the previous values is returned. If there are multiple values + /// that have been previously associated with the key, then the first one is + /// returned. See `insert_mult` on `OccupiedEntry` for an API that returns + /// all values. + /// + /// The key is not updated, though; this matters for types that can be `==` + /// without being identical. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// assert!(map.insert(HOST, "world".parse().unwrap()).is_none()); + /// assert!(!map.is_empty()); + /// + /// let mut prev = map.insert(HOST, "earth".parse().unwrap()).unwrap(); + /// assert_eq!("world", prev); + /// ``` + pub fn insert(&mut self, key: K, val: T) -> Option + where K: IntoHeaderName, + { + key.insert(self, val) + } + + #[inline] + fn insert2(&mut self, key: K, value: T) -> Option + where K: Hash + Into, + HeaderName: PartialEq, + { + self.reserve_one(); + + insert_phase_one!( + self, key, probe, pos, hash, danger, + // Vacant + { + drop(danger); // Make lint happy + let index = self.entries.len(); + self.insert_entry(hash, key.into(), value); + self.indices[probe] = Pos::new(index, hash); + None + }, + // Occupied + Some(self.insert_occupied(pos, value)), + // Robinhood + { + self.insert_phase_two( + key.into(), + value, + hash, + probe, + danger); + None + }) + } + + /// Set an occupied bucket to the given value + #[inline] + fn insert_occupied(&mut self, index: usize, value: T) -> T { + if let Some(links) = self.entries[index].links { + self.remove_all_extra_values(links.next); + } + + let entry = &mut self.entries[index]; + mem::replace(&mut entry.value, value) + } + + fn insert_occupied_mult(&mut self, index: usize, value: T) -> ValueDrain { + let old; + let links; + + { + let entry = &mut self.entries[index]; + + old = mem::replace(&mut entry.value, value); + links = entry.links.take(); + } + + ValueDrain { + map: self as *mut _, + first: Some(old), + next: links.map(|l| l.next), + lt: PhantomData, + } + } + + /// Inserts a key-value pair into the map. + /// + /// If the map did not previously have this key present, then `false` is + /// returned. + /// + /// If the map did have this key present, the new value is pushed to the end + /// of the list of values currently associated with the key. The key is not + /// updated, though; this matters for types that can be `==` without being + /// identical. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// assert!(map.insert(HOST, "world".parse().unwrap()).is_none()); + /// assert!(!map.is_empty()); + /// + /// map.append(HOST, "earth".parse().unwrap()); + /// + /// let values = map.get_all("host"); + /// let mut i = values.iter(); + /// assert_eq!("world", *i.next().unwrap()); + /// assert_eq!("earth", *i.next().unwrap()); + /// ``` + pub fn append(&mut self, key: K, value: T) -> bool + where K: IntoHeaderName, + { + key.append(self, value) + } + + #[inline] + fn append2(&mut self, key: K, value: T) -> bool + where K: Hash + Into, + HeaderName: PartialEq, + { + self.reserve_one(); + + insert_phase_one!( + self, key, probe, pos, hash, danger, + // Vacant + { + drop(danger); + let index = self.entries.len(); + self.insert_entry(hash, key.into(), value); + self.indices[probe] = Pos::new(index, hash); + false + }, + // Occupied + { + append_value(pos, &mut self.entries[pos], &mut self.extra_values, value); + true + }, + // Robinhood + { + self.insert_phase_two( + key.into(), + value, + hash, + probe, + danger); + + false + }) + } + + #[inline] + fn find(&self, key: &K) -> Option<(usize, usize)> + where K: Hash + Into, + HeaderName: PartialEq, + { + if self.entries.is_empty() { + return None; + } + + let hash = hash_elem_using(&self.danger, key); + let mask = self.mask; + let mut probe = desired_pos(mask, hash); + let mut dist = 0; + + probe_loop!(probe < self.indices.len(), { + if let Some((i, entry_hash)) = self.indices[probe].resolve() { + if dist > probe_distance(mask, entry_hash, probe) { + // give up when probe distance is too long + return None; + } else if entry_hash == hash && self.entries[i].key == *key { + return Some((probe, i)); + } + } else { + return None; + } + + dist += 1; + }); + } + + /// phase 2 is post-insert where we forward-shift `Pos` in the indices. + #[inline] + fn insert_phase_two(&mut self, + key: HeaderName, + value: T, + hash: HashValue, + probe: usize, + danger: bool) -> usize + { + // Push the value and get the index + let index = self.entries.len(); + self.insert_entry(hash, key, value); + + let num_displaced = do_insert_phase_two( + &mut self.indices, + probe, + Pos::new(index, hash)); + + if danger || num_displaced >= DISPLACEMENT_THRESHOLD { + // Increase danger level + self.danger.to_yellow(); + } + + index + } + + /// Removes a key from the map, returning the value associated with the key. + /// + /// Returns `None` if the map does not contain the key. If there are + /// multiple values associated with the key, then the first one is returned. + /// See `remove_entry_mult` on `OccupiedEntry` for an API that yields all + /// values. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// let prev = map.remove(HOST).unwrap(); + /// assert_eq!("hello.world", prev); + /// + /// assert!(map.remove(HOST).is_none()); + /// ``` + pub fn remove(&mut self, key: K) -> Option + where K: AsHeaderName + { + match key.find(self) { + Some((probe, idx)) => { + if let Some(links) = self.entries[idx].links { + self.remove_all_extra_values(links.next); + } + + let entry = self.remove_found(probe, idx); + + Some(entry.value) + } + None => None, + } + } + + /// Remove an entry from the map. + #[inline] + fn remove_found(&mut self, probe: usize, found: usize) -> Bucket { + // index `probe` and entry `found` is to be removed + // use swap_remove, but then we need to update the index that points + // to the other entry that has to move + self.indices[probe] = Pos::none(); + let entry = self.entries.swap_remove(found); + + // correct index that points to the entry that had to swap places + if let Some(entry) = self.entries.get(found) { + // was not last element + // examine new element in `found` and find it in indices + let mut probe = desired_pos(self.mask, entry.hash); + + probe_loop!(probe < self.indices.len(), { + if let Some((i, _)) = self.indices[probe].resolve() { + if i >= self.entries.len() { + // found it + self.indices[probe] = Pos::new(found, entry.hash); + break; + } + } + }); + + // Update links + if let Some(links) = entry.links { + self.extra_values[links.next].prev = Link::Entry(found); + self.extra_values[links.tail].next = Link::Entry(found); + } + } + + // backward shift deletion in self.indices + // after probe, shift all non-ideally placed indices backward + if self.entries.len() > 0 { + let mut last_probe = probe; + let mut probe = probe + 1; + + probe_loop!(probe < self.indices.len(), { + if let Some((_, entry_hash)) = self.indices[probe].resolve() { + if probe_distance(self.mask, entry_hash, probe) > 0 { + self.indices[last_probe] = self.indices[probe]; + self.indices[probe] = Pos::none(); + } else { + break; + } + } else { + break; + } + + last_probe = probe; + }); + } + + entry + } + + /// Removes the `ExtraValue` at the given index. + #[inline] + fn remove_extra_value(&mut self, idx: usize) -> ExtraValue { + let prev; + let next; + + { + debug_assert!(self.extra_values.len() > idx); + let extra = &self.extra_values[idx]; + prev = extra.prev; + next = extra.next; + } + + // First unlink the extra value + match (prev, next) { + (Link::Entry(prev), Link::Entry(next)) => { + debug_assert_eq!(prev, next); + debug_assert!(self.entries.len() > prev); + + self.entries[prev].links = None; + } + (Link::Entry(prev), Link::Extra(next)) => { + debug_assert!(self.entries.len() > prev); + debug_assert!(self.entries[prev].links.is_some()); + + self.entries[prev].links.as_mut().unwrap() + .next = next; + + debug_assert!(self.extra_values.len() > next); + self.extra_values[next].prev = Link::Entry(prev); + } + (Link::Extra(prev), Link::Entry(next)) => { + debug_assert!(self.entries.len() > next); + debug_assert!(self.entries[next].links.is_some()); + + self.entries[next].links.as_mut().unwrap() + .tail = prev; + + debug_assert!(self.extra_values.len() > prev); + self.extra_values[prev].next = Link::Entry(next); + } + (Link::Extra(prev), Link::Extra(next)) => { + debug_assert!(self.extra_values.len() > next); + debug_assert!(self.extra_values.len() > prev); + + self.extra_values[prev].next = Link::Extra(next); + self.extra_values[next].prev = Link::Extra(prev); + } + } + + // Remove the extra value + let mut extra = self.extra_values.swap_remove(idx); + + // This is the index of the value that was moved (possibly `extra`) + let old_idx = self.extra_values.len(); + + // Update the links + if extra.prev == Link::Extra(old_idx) { + extra.prev = Link::Extra(idx); + } + + if extra.next == Link::Extra(old_idx) { + extra.next = Link::Extra(idx); + } + + // Check if another entry was displaced. If it was, then the links + // need to be fixed. + if idx != old_idx { + let next; + let prev; + + { + debug_assert!(self.extra_values.len() > idx); + let moved = &self.extra_values[idx]; + next = moved.next; + prev = moved.prev; + } + + // An entry was moved, we have to the links + match prev { + Link::Entry(entry_idx) => { + // It is critical that we do not attempt to read the + // header name or value as that memory may have been + // "released" already. + debug_assert!(self.entries.len() > entry_idx); + debug_assert!(self.entries[entry_idx].links.is_some()); + + let links = self.entries[entry_idx].links.as_mut().unwrap(); + links.next = idx; + } + Link::Extra(extra_idx) => { + debug_assert!(self.extra_values.len() > extra_idx); + self.extra_values[extra_idx].next = Link::Extra(idx); + } + } + + match next { + Link::Entry(entry_idx) => { + debug_assert!(self.entries.len() > entry_idx); + debug_assert!(self.entries[entry_idx].links.is_some()); + + let links = self.entries[entry_idx].links.as_mut().unwrap(); + links.tail = idx; + } + Link::Extra(extra_idx) => { + debug_assert!(self.extra_values.len() > extra_idx); + self.extra_values[extra_idx].prev = Link::Extra(idx); + } + } + } + + debug_assert!({ + for v in &self.extra_values { + assert!(v.next != Link::Extra(old_idx)); + assert!(v.prev != Link::Extra(old_idx)); + } + + true + }); + + extra + } + + fn remove_all_extra_values(&mut self, mut head: usize) { + loop { + let extra = self.remove_extra_value(head); + + if let Link::Extra(idx) = extra.next { + head = idx; + } else { + break; + } + } + } + + #[inline] + fn insert_entry(&mut self, hash: HashValue, key: HeaderName, value: T) { + assert!(self.entries.len() < MAX_SIZE, "header map at capacity"); + + self.entries.push(Bucket { + hash: hash, + key: key, + value: value, + links: None, + }); + } + + fn rebuild(&mut self) { + // Loop over all entries and re-insert them into the map + 'outer: + for (index, entry) in self.entries.iter_mut().enumerate() { + let hash = hash_elem_using(&self.danger, &entry.key); + let mut probe = desired_pos(self.mask, hash); + let mut dist = 0; + + // Update the entry's hash code + entry.hash = hash; + + probe_loop!(probe < self.indices.len(), { + if let Some((_, entry_hash)) = self.indices[probe].resolve() { + // if existing element probed less than us, swap + let their_dist = probe_distance(self.mask, entry_hash, probe); + + if their_dist < dist { + // Robinhood + break; + } + } else { + // Vacant slot + self.indices[probe] = Pos::new(index, hash); + continue 'outer; + } + + dist += 1; + }); + + do_insert_phase_two( + &mut self.indices, + probe, + Pos::new(index, hash)); + } + } + + fn reinsert_entry_in_order(&mut self, pos: Pos) { + if let Some((_, entry_hash)) = pos.resolve() { + // Find first empty bucket and insert there + let mut probe = desired_pos(self.mask, entry_hash); + + probe_loop!(probe < self.indices.len(), { + if self.indices[probe].resolve().is_none() { + // empty bucket, insert here + self.indices[probe] = pos; + return; + } + }); + } + } + + fn reserve_one(&mut self) { + let len = self.entries.len(); + + if self.danger.is_yellow() { + let load_factor = self.entries.len() as f32 / self.indices.len() as f32; + + if load_factor >= LOAD_FACTOR_THRESHOLD { + // Transition back to green danger level + self.danger.to_green(); + + // Double the capacity + let new_cap = self.indices.len() * 2; + + // Grow the capacity + self.grow(new_cap); + } else { + self.danger.to_red(); + + // Rebuild hash table + for index in self.indices.iter_mut() { + *index = Pos::none(); + } + + self.rebuild(); + } + } else if len == self.capacity() { + if len == 0 { + let new_raw_cap = 8; + self.mask = 8 - 1; + self.indices = vec![Pos::none(); new_raw_cap].into_boxed_slice(); + self.entries = Vec::with_capacity(usable_capacity(new_raw_cap)); + } else { + let raw_cap = self.indices.len(); + self.grow(raw_cap << 1); + } + } + } + + #[inline] + fn grow(&mut self, new_raw_cap: usize) { + // This path can never be reached when handling the first allocation in + // the map. + + // find first ideally placed element -- start of cluster + let mut first_ideal = 0; + + for (i, pos) in self.indices.iter().enumerate() { + if let Some((_, entry_hash)) = pos.resolve() { + if 0 == probe_distance(self.mask, entry_hash, i) { + first_ideal = i; + break; + } + } + } + + // visit the entries in an order where we can simply reinsert them + // into self.indices without any bucket stealing. + let old_indices = mem::replace(&mut self.indices, vec![Pos::none(); new_raw_cap].into_boxed_slice()); + self.mask = new_raw_cap.wrapping_sub(1) as Size; + + for &pos in &old_indices[first_ideal..] { + self.reinsert_entry_in_order(pos); + } + + for &pos in &old_indices[..first_ideal] { + self.reinsert_entry_in_order(pos); + } + + // Reserve additional entry slots + let more = self.capacity() - self.entries.len(); + self.entries.reserve_exact(more); + } +} + +impl<'a, T> IntoIterator for &'a HeaderMap { + type Item = (&'a HeaderName, &'a T); + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl<'a, T> IntoIterator for &'a mut HeaderMap { + type Item = (&'a HeaderName, &'a mut T); + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +impl IntoIterator for HeaderMap { + type Item = (Option, T); + type IntoIter = IntoIter; + + /// Creates a consuming iterator, that is, one that moves keys and values + /// out of the map in arbitrary order. The map cannot be used after calling + /// this. + /// + /// For each yielded item that has `None` provided for the `HeaderName`, + /// then the associated header name is the same as that of the previously + /// yielded item. The first yielded item will have `HeaderName` set. + /// + /// # Examples + /// + /// Basic usage. + /// + /// ``` + /// # use http::header; + /// # use http::header::*; + /// let mut map = HeaderMap::new(); + /// map.insert(header::CONTENT_LENGTH, "123".parse().unwrap()); + /// map.insert(header::CONTENT_TYPE, "json".parse().unwrap()); + /// + /// let mut iter = map.into_iter(); + /// assert_eq!(iter.next(), Some((Some(header::CONTENT_LENGTH), "123".parse().unwrap()))); + /// assert_eq!(iter.next(), Some((Some(header::CONTENT_TYPE), "json".parse().unwrap()))); + /// assert!(iter.next().is_none()); + /// ``` + /// + /// Multiple values per key. + /// + /// ``` + /// # use http::header; + /// # use http::header::*; + /// let mut map = HeaderMap::new(); + /// + /// map.append(header::CONTENT_LENGTH, "123".parse().unwrap()); + /// map.append(header::CONTENT_LENGTH, "456".parse().unwrap()); + /// + /// map.append(header::CONTENT_TYPE, "json".parse().unwrap()); + /// map.append(header::CONTENT_TYPE, "html".parse().unwrap()); + /// map.append(header::CONTENT_TYPE, "xml".parse().unwrap()); + /// + /// let mut iter = map.into_iter(); + /// + /// assert_eq!(iter.next(), Some((Some(header::CONTENT_LENGTH), "123".parse().unwrap()))); + /// assert_eq!(iter.next(), Some((None, "456".parse().unwrap()))); + /// + /// assert_eq!(iter.next(), Some((Some(header::CONTENT_TYPE), "json".parse().unwrap()))); + /// assert_eq!(iter.next(), Some((None, "html".parse().unwrap()))); + /// assert_eq!(iter.next(), Some((None, "xml".parse().unwrap()))); + /// assert!(iter.next().is_none()); + /// ``` + fn into_iter(self) -> IntoIter { + IntoIter { + next: None, + entries: self.entries.into_iter(), + extra_values: self.extra_values, + } + } +} + +impl FromIterator<(HeaderName, T)> for HeaderMap +{ + fn from_iter(iter: I) -> Self + where I: IntoIterator + { + let mut map = HeaderMap::default(); + map.extend(iter); + map + } +} + +impl Extend<(Option, T)> for HeaderMap { + /// Extend a `HeaderMap` with the contents of another `HeaderMap`. + /// + /// This function expects the yielded items to follow the same structure as + /// `IntoIter`. + /// + /// # Panics + /// + /// This panics if the first yielded item does not have a `HeaderName`. + /// + /// # Examples + /// + /// ``` + /// # use http::header::*; + /// let mut map = HeaderMap::new(); + /// + /// map.insert(ACCEPT, "text/plain".parse().unwrap()); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// let mut extra = HeaderMap::new(); + /// + /// extra.insert(HOST, "foo.bar".parse().unwrap()); + /// extra.insert(COOKIE, "hello".parse().unwrap()); + /// extra.append(COOKIE, "world".parse().unwrap()); + /// + /// map.extend(extra); + /// + /// assert_eq!(map["host"], "foo.bar"); + /// assert_eq!(map["accept"], "text/plain"); + /// assert_eq!(map["cookie"], "hello"); + /// + /// let v = map.get_all("host"); + /// assert_eq!(1, v.iter().count()); + /// + /// let v = map.get_all("cookie"); + /// assert_eq!(2, v.iter().count()); + /// ``` + fn extend, T)>>(&mut self, iter: I) { + let mut iter = iter.into_iter(); + + // The structure of this is a bit weird, but it is mostly to make the + // borrow checker happy. + let (mut key, mut val) = match iter.next() { + Some((Some(key), val)) => (key, val), + Some((None, _)) => panic!("expected a header name, but got None"), + None => return, + }; + + 'outer: + loop { + let mut entry = match self.entry2(key) { + Entry::Occupied(mut e) => { + // Replace all previous values while maintaining a handle to + // the entry. + e.insert(val); + e + } + Entry::Vacant(e) => { + e.insert_entry(val) + } + }; + + // As long as `HeaderName` is none, keep inserting the value into + // the current entry + 'inner: + loop { + match iter.next() { + Some((Some(k), v)) => { + key = k; + val = v; + continue 'outer; + } + Some((None, v)) => { + entry.append(v); + } + None => { + return; + } + } + } + } + } +} + +impl Extend<(HeaderName, T)> for HeaderMap +{ + fn extend>(&mut self, iter: I) { + // Keys may be already present or show multiple times in the iterator. + // Reserve the entire hint lower bound if the map is empty. + // Otherwise reserve half the hint (rounded up), so the map + // will only resize twice in the worst case. + let iter = iter.into_iter(); + + let reserve = if self.is_empty() { + iter.size_hint().0 + } else { + (iter.size_hint().0 + 1) / 2 + }; + + self.reserve(reserve); + + for (k, v) in iter { + self.append(k, v); + } + } +} + +impl PartialEq for HeaderMap { + fn eq(&self, other: &HeaderMap) -> bool { + if self.len() != other.len() { + return false; + } + + self.keys().all(|key| { + self.get_all(key) == other.get_all(key) + }) + } +} + +impl Eq for HeaderMap {} + +impl fmt::Debug for HeaderMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_map().entries(self.iter()).finish() + } +} + +impl Default for HeaderMap { + fn default() -> Self { + HeaderMap::with_capacity(0) + } +} + +impl<'a, K, T> ops::Index for HeaderMap + where K: AsHeaderName, +{ + type Output = T; + + /// # Panics + /// Using the index operator will cause a panic if the header you're querying isn't set. + #[inline] + fn index(&self, index: K) -> &T { + match self.get2(&index) { + Some(val) => val, + None => panic!("no entry found for key {:?}", index.as_str()), + } + } +} + +/// phase 2 is post-insert where we forward-shift `Pos` in the indices. +/// +/// returns the number of displaced elements +#[inline] +fn do_insert_phase_two(indices: &mut [Pos], + mut probe: usize, + mut old_pos: Pos) + -> usize +{ + let mut num_displaced = 0; + + probe_loop!(probe < indices.len(), { + let pos = &mut indices[probe]; + + if pos.is_none() { + *pos = old_pos; + break; + } else { + num_displaced += 1; + old_pos = mem::replace(pos, old_pos); + } + }); + + num_displaced +} + +#[inline] +fn append_value(entry_idx: usize, + entry: &mut Bucket, + extra: &mut Vec>, + value: T) +{ + match entry.links { + Some(links) => { + let idx = extra.len(); + extra.push(ExtraValue { + value: value, + prev: Link::Extra(links.tail), + next: Link::Entry(entry_idx), + }); + + extra[links.tail].next = Link::Extra(idx); + + entry.links = Some(Links { + tail: idx, + .. links + }); + } + None => { + let idx = extra.len(); + extra.push(ExtraValue { + value: value, + prev: Link::Entry(entry_idx), + next: Link::Entry(entry_idx), + }); + + entry.links = Some(Links { + next: idx, + tail: idx, + }); + } + } +} + +// ===== impl Iter ===== + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = (&'a HeaderName, &'a T); + + fn next(&mut self) -> Option { + self.inner.next_unsafe().map(|(key, ptr)| { + (key, unsafe { &*ptr }) + }) + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {} +unsafe impl<'a, T: Sync> Send for Iter<'a, T> {} + +// ===== impl IterMut ===== + +impl<'a, T> IterMut<'a, T> { + fn next_unsafe(&mut self) -> Option<(&'a HeaderName, *mut T)> { + use self::Cursor::*; + + if self.cursor.is_none() { + if (self.entry + 1) >= unsafe { &*self.map }.entries.len() { + return None; + } + + self.entry += 1; + self.cursor = Some(Cursor::Head); + } + + let entry = unsafe { &(*self.map).entries[self.entry] }; + + match self.cursor.unwrap() { + Head => { + self.cursor = entry.links.map(|l| Values(l.next)); + Some((&entry.key, &entry.value as *const _ as *mut _)) + } + Values(idx) => { + let extra = unsafe { &(*self.map).extra_values[idx] }; + + match extra.next { + Link::Entry(_) => self.cursor = None, + Link::Extra(i) => self.cursor = Some(Values(i)), + } + + Some((&entry.key, &extra.value as *const _ as *mut _)) + } + } + } +} + +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = (&'a HeaderName, &'a mut T); + + fn next(&mut self) -> Option { + self.next_unsafe().map(|(key, ptr)| { + (key, unsafe { &mut *ptr }) + }) + } + + fn size_hint(&self) -> (usize, Option) { + let map = unsafe { &*self.map }; + debug_assert!(map.entries.len() >= self.entry); + + let lower = map.entries.len() - self.entry; + // We could pessimistically guess at the upper bound, saying + // that its lower + map.extra_values.len(). That could be + // way over though, such as if we're near the end, and have + // already gone through several extra values... + (lower, None) + } +} + +unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} +unsafe impl<'a, T: Send> Send for IterMut<'a, T> {} + +// ===== impl Keys ===== + +impl<'a, T> Iterator for Keys<'a, T> { + type Item = &'a HeaderName; + + fn next(&mut self) -> Option { + self.inner.next().map(|b| &b.key) + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +impl<'a, T> ExactSizeIterator for Keys<'a, T> {} + +// ===== impl Values ==== + +impl<'a, T> Iterator for Values<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.inner.next().map(|(_, v)| v) + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +// ===== impl ValuesMut ==== + +impl<'a, T> Iterator for ValuesMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + self.inner.next().map(|(_, v)| v) + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +// ===== impl Drain ===== + +impl<'a, T> Iterator for Drain<'a, T> { + type Item = (HeaderName, ValueDrain<'a, T>); + + fn next(&mut self) -> Option { + let idx = self.idx; + + if idx == unsafe { (*self.map).entries.len() } { + return None; + } + + self.idx += 1; + + let key; + let value; + let next; + + unsafe { + let entry = &(*self.map).entries[idx]; + + // Read the header name + key = ptr::read(&entry.key as *const _); + value = ptr::read(&entry.value as *const _); + next = entry.links.map(|l| l.next); + }; + + let values = ValueDrain { + map: self.map, + first: Some(value), + next: next, + lt: PhantomData, + }; + + Some((key, values)) + } + + fn size_hint(&self) -> (usize, Option) { + let lower = unsafe { (*self.map).entries.len() } - self.idx; + (lower, Some(lower)) + } +} + +impl<'a, T> Drop for Drain<'a, T> { + fn drop(&mut self) { + unsafe { + let map = &mut *self.map; + debug_assert!(map.extra_values.is_empty()); + map.entries.set_len(0); + } + } +} + +unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {} +unsafe impl<'a, T: Send> Send for Drain<'a, T> {} + +// ===== impl Entry ===== + +impl<'a, T> Entry<'a, T> { + /// Ensures a value is in the entry by inserting the default if empty. + /// + /// Returns a mutable reference to the **first** value in the entry. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let mut map: HeaderMap = HeaderMap::default(); + /// + /// let headers = &[ + /// "content-length", + /// "x-hello", + /// "Content-Length", + /// "x-world", + /// ]; + /// + /// for &header in headers { + /// let counter = map.entry(header) + /// .expect("valid header names") + /// .or_insert(0); + /// *counter += 1; + /// } + /// + /// assert_eq!(map["content-length"], 2); + /// assert_eq!(map["x-hello"], 1); + /// ``` + pub fn or_insert(self, default: T) -> &'a mut T { + use self::Entry::*; + + match self { + Occupied(e) => e.into_mut(), + Vacant(e) => e.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default + /// function if empty. + /// + /// The default function is not called if the entry exists in the map. + /// Returns a mutable reference to the **first** value in the entry. + /// + /// # Examples + /// + /// Basic usage. + /// + /// ``` + /// # use http::HeaderMap; + /// let mut map = HeaderMap::new(); + /// + /// let res = map.entry("x-hello").unwrap() + /// .or_insert_with(|| "world".parse().unwrap()); + /// + /// assert_eq!(res, "world"); + /// ``` + /// + /// The default function is not called if the entry exists in the map. + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// + /// let res = map.entry("host") + /// .expect("host is a valid string") + /// .or_insert_with(|| unreachable!()); + /// + /// + /// assert_eq!(res, "world"); + /// ``` + pub fn or_insert_with T>(self, default: F) -> &'a mut T { + use self::Entry::*; + + match self { + Occupied(e) => e.into_mut(), + Vacant(e) => e.insert(default()), + } + } + + /// Returns a reference to the entry's key + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let mut map = HeaderMap::new(); + /// + /// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello"); + /// ``` + pub fn key(&self) -> &HeaderName { + use self::Entry::*; + + match *self { + Vacant(ref e) => e.key(), + Occupied(ref e) => e.key(), + } + } +} + +// ===== impl VacantEntry ===== + +impl<'a, T> VacantEntry<'a, T> { + /// Returns a reference to the entry's key + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// let mut map = HeaderMap::new(); + /// + /// assert_eq!(map.entry("x-hello").unwrap().key().as_str(), "x-hello"); + /// ``` + pub fn key(&self) -> &HeaderName { + &self.key + } + + /// Take ownership of the key + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry}; + /// let mut map = HeaderMap::new(); + /// + /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() { + /// assert_eq!(v.into_key().as_str(), "x-hello"); + /// } + /// ``` + pub fn into_key(self) -> HeaderName { + self.key + } + + /// Insert the value into the entry. + /// + /// The value will be associated with this entry's key. A mutable reference + /// to the inserted value will be returned. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry}; + /// let mut map = HeaderMap::new(); + /// + /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() { + /// v.insert("world".parse().unwrap()); + /// } + /// + /// assert_eq!(map["x-hello"], "world"); + /// ``` + pub fn insert(self, value: T) -> &'a mut T { + // Ensure that there is space in the map + let index = self.map.insert_phase_two( + self.key, + value.into(), + self.hash, + self.probe, + self.danger); + + &mut self.map.entries[index].value + } + + /// Insert the value into the entry. + /// + /// The value will be associated with this entry's key. The new + /// `OccupiedEntry` is returned, allowing for further manipulation. + /// + /// # Examples + /// + /// ``` + /// # use http::header::*; + /// let mut map = HeaderMap::new(); + /// + /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() { + /// let mut e = v.insert_entry("world".parse().unwrap()); + /// e.insert("world2".parse().unwrap()); + /// } + /// + /// assert_eq!(map["x-hello"], "world2"); + /// ``` + pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> { + // Ensure that there is space in the map + let index = self.map.insert_phase_two( + self.key, + value.into(), + self.hash, + self.probe, + self.danger); + + OccupiedEntry { + map: self.map, + index: index, + probe: self.probe, + } + } +} + + +// ===== impl GetAll ===== + +impl<'a, T: 'a> GetAll<'a, T> { + /// Returns an iterator visiting all values associated with the entry. + /// + /// Values are iterated in insertion order. + /// + /// # Examples + /// + /// ``` + /// # use http::HeaderMap; + /// # use http::header::HOST; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// map.append(HOST, "hello.earth".parse().unwrap()); + /// + /// let values = map.get_all("host"); + /// let mut iter = values.iter(); + /// assert_eq!(&"hello.world", iter.next().unwrap()); + /// assert_eq!(&"hello.earth", iter.next().unwrap()); + /// assert!(iter.next().is_none()); + /// ``` + pub fn iter(&self) -> ValueIter<'a, T> { + // This creates a new GetAll struct so that the lifetime + // isn't bound to &self. + GetAll { + map: self.map, + index: self.index, + }.into_iter() + } +} + +impl<'a, T: PartialEq> PartialEq for GetAll<'a, T> { + fn eq(&self, other: &Self) -> bool { + self.iter().eq(other.iter()) + } +} + +impl<'a, T> IntoIterator for GetAll<'a, T> { + type Item = &'a T; + type IntoIter = ValueIter<'a, T>; + + fn into_iter(self) -> ValueIter<'a, T> { + self.map.value_iter(self.index) + } +} + +impl<'a, 'b: 'a, T> IntoIterator for &'b GetAll<'a, T> { + type Item = &'a T; + type IntoIter = ValueIter<'a, T>; + + fn into_iter(self) -> ValueIter<'a, T> { + self.map.value_iter(self.index) + } +} + +// ===== impl ValueIter ===== + +impl<'a, T: 'a> Iterator for ValueIter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + use self::Cursor::*; + + + match self.front { + Some(Head) => { + let entry = &self.map.entries[self.index]; + + if self.back == Some(Head) { + self.front = None; + self.back = None; + } else { + // Update the iterator state + match entry.links { + Some(links) => { + self.front = Some(Values(links.next)); + } + None => unreachable!(), + } + } + + Some(&entry.value) + } + Some(Values(idx)) => { + let extra = &self.map.extra_values[idx]; + + if self.front == self.back { + self.front = None; + self.back = None; + } else { + match extra.next { + Link::Entry(_) => self.front = None, + Link::Extra(i) => self.front = Some(Values(i)), + } + } + + Some(&extra.value) + } + None => None, + } + } + + fn size_hint(&self) -> (usize, Option) { + match (self.front, self.back) { + // Exactly 1 value... + (Some(Cursor::Head), Some(Cursor::Head)) => (1, Some(1)), + // At least 1... + (Some(_), _) => (1, None), + // No more values... + (None, _) => (0, Some(0)), + } + } +} + +impl<'a, T: 'a> DoubleEndedIterator for ValueIter<'a, T> { + fn next_back(&mut self) -> Option { + use self::Cursor::*; + + + match self.back { + Some(Head) => { + self.front = None; + self.back = None; + Some(&self.map.entries[self.index].value) + } + Some(Values(idx)) => { + let extra = &self.map.extra_values[idx]; + + if self.front == self.back { + self.front = None; + self.back = None; + } else { + match extra.prev { + Link::Entry(_) => self.back = Some(Head), + Link::Extra(idx) => self.back = Some(Values(idx)), + } + } + + Some(&extra.value) + } + None => None, + } + } +} + +// ===== impl ValueIterMut ===== + +impl<'a, T: 'a> Iterator for ValueIterMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option { + use self::Cursor::*; + + let entry = unsafe { &mut (*self.map).entries[self.index] }; + + match self.front { + Some(Head) => { + if self.back == Some(Head) { + self.front = None; + self.back = None; + } else { + // Update the iterator state + match entry.links { + Some(links) => { + self.front = Some(Values(links.next)); + } + None => unreachable!(), + } + } + + Some(&mut entry.value) + } + Some(Values(idx)) => { + let extra = unsafe { &mut (*self.map).extra_values[idx] }; + + if self.front == self.back { + self.front = None; + self.back = None; + } else { + match extra.next { + Link::Entry(_) => self.front = None, + Link::Extra(i) => self.front = Some(Values(i)), + } + } + + Some(&mut extra.value) + } + None => None, + } + } +} + +impl<'a, T: 'a> DoubleEndedIterator for ValueIterMut<'a, T> { + fn next_back(&mut self) -> Option { + use self::Cursor::*; + + let entry = unsafe { &mut (*self.map).entries[self.index] }; + + match self.back { + Some(Head) => { + self.front = None; + self.back = None; + Some(&mut entry.value) + } + Some(Values(idx)) => { + let extra = unsafe { &mut (*self.map).extra_values[idx] }; + + if self.front == self.back { + self.front = None; + self.back = None; + } else { + match extra.prev { + Link::Entry(_) => self.back = Some(Head), + Link::Extra(idx) => self.back = Some(Values(idx)), + } + } + + Some(&mut extra.value) + } + None => None, + } + } +} + +unsafe impl<'a, T: Sync> Sync for ValueIterMut<'a, T> {} +unsafe impl<'a, T: Send> Send for ValueIterMut<'a, T> {} + +// ===== impl IntoIter ===== + +impl Iterator for IntoIter { + type Item = (Option, T); + + fn next(&mut self) -> Option { + if let Some(next) = self.next { + self.next = match self.extra_values[next].next { + Link::Entry(_) => None, + Link::Extra(v) => Some(v), + }; + + let value = unsafe { ptr::read(&self.extra_values[next].value) }; + + return Some((None, value)); + } + + if let Some(bucket) = self.entries.next() { + self.next = bucket.links.map(|l| l.next); + let name = Some(bucket.key); + let value = bucket.value; + + return Some((name, value)); + } + + None + } + + fn size_hint(&self) -> (usize, Option) { + let (lower, _) = self.entries.size_hint(); + // There could be more than just the entries upper, as there + // could be items in the `extra_values`. We could guess, saying + // `upper + extra_values.len()`, but that could overestimate by a lot. + (lower, None) + } +} + +impl Drop for IntoIter { + fn drop(&mut self) { + // Ensure the iterator is consumed + for _ in self.by_ref() { } + + // All the values have already been yielded out. + unsafe { self.extra_values.set_len(0); } + } +} + +// ===== impl OccupiedEntry ===== + +impl<'a, T> OccupiedEntry<'a, T> { + /// Returns a reference to the entry's key. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// + /// if let Entry::Occupied(e) = map.entry("host").unwrap() { + /// assert_eq!("host", e.key()); + /// } + /// ``` + pub fn key(&self) -> &HeaderName { + &self.map.entries[self.index].key + } + + /// Get a reference to the first value in the entry. + /// + /// Values are stored in insertion order. + /// + /// # Panics + /// + /// `get` panics if there are no values associated with the entry. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// assert_eq!(e.get(), &"hello.world"); + /// + /// e.append("hello.earth".parse().unwrap()); + /// + /// assert_eq!(e.get(), &"hello.world"); + /// } + /// ``` + pub fn get(&self) -> &T { + &self.map.entries[self.index].value + } + + /// Get a mutable reference to the first value in the entry. + /// + /// Values are stored in insertion order. + /// + /// # Panics + /// + /// `get_mut` panics if there are no values associated with the entry. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::default(); + /// map.insert(HOST, "hello.world".to_string()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// e.get_mut().push_str("-2"); + /// assert_eq!(e.get(), &"hello.world-2"); + /// } + /// ``` + pub fn get_mut(&mut self) -> &mut T { + &mut self.map.entries[self.index].value + } + + /// Converts the `OccupiedEntry` into a mutable reference to the **first** + /// value. + /// + /// The lifetime of the returned reference is bound to the original map. + /// + /// # Panics + /// + /// `into_mut` panics if there are no values associated with the entry. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::default(); + /// map.insert(HOST, "hello.world".to_string()); + /// map.append(HOST, "hello.earth".to_string()); + /// + /// if let Entry::Occupied(e) = map.entry("host").unwrap() { + /// e.into_mut().push_str("-2"); + /// } + /// + /// assert_eq!("hello.world-2", map["host"]); + /// ``` + pub fn into_mut(self) -> &'a mut T { + &mut self.map.entries[self.index].value + } + + /// Sets the value of the entry. + /// + /// All previous values associated with the entry are removed and the first + /// one is returned. See `insert_mult` for an API that returns all values. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "hello.world".parse().unwrap()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// let mut prev = e.insert("earth".parse().unwrap()); + /// assert_eq!("hello.world", prev); + /// } + /// + /// assert_eq!("earth", map["host"]); + /// ``` + pub fn insert(&mut self, value: T) -> T { + self.map.insert_occupied(self.index, value.into()) + } + + /// Sets the value of the entry. + /// + /// This function does the same as `insert` except it returns an iterator + /// that yields all values previously associated with the key. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// map.append(HOST, "world2".parse().unwrap()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// let mut prev = e.insert_mult("earth".parse().unwrap()); + /// assert_eq!("world", prev.next().unwrap()); + /// assert_eq!("world2", prev.next().unwrap()); + /// assert!(prev.next().is_none()); + /// } + /// + /// assert_eq!("earth", map["host"]); + /// ``` + pub fn insert_mult(&mut self, value: T) -> ValueDrain { + self.map.insert_occupied_mult(self.index, value.into()) + } + + /// Insert the value into the entry. + /// + /// The new value is appended to the end of the entry's value list. All + /// previous values associated with the entry are retained. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// e.append("earth".parse().unwrap()); + /// } + /// + /// let values = map.get_all("host"); + /// let mut i = values.iter(); + /// assert_eq!("world", *i.next().unwrap()); + /// assert_eq!("earth", *i.next().unwrap()); + /// ``` + pub fn append(&mut self, value: T) { + let idx = self.index; + let entry = &mut self.map.entries[idx]; + append_value(idx, entry, &mut self.map.extra_values, value.into()); + } + + /// Remove the entry from the map. + /// + /// All values associated with the entry are removed and the first one is + /// returned. See `remove_entry_mult` for an API that returns all values. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// + /// if let Entry::Occupied(e) = map.entry("host").unwrap() { + /// let mut prev = e.remove(); + /// assert_eq!("world", prev); + /// } + /// + /// assert!(!map.contains_key("host")); + /// ``` + pub fn remove(self) -> T { + self.remove_entry().1 + } + + /// Remove the entry from the map. + /// + /// The key and all values associated with the entry are removed and the + /// first one is returned. See `remove_entry_mult` for an API that returns + /// all values. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// + /// if let Entry::Occupied(e) = map.entry("host").unwrap() { + /// let (key, mut prev) = e.remove_entry(); + /// assert_eq!("host", key.as_str()); + /// assert_eq!("world", prev); + /// } + /// + /// assert!(!map.contains_key("host")); + /// ``` + pub fn remove_entry(self) -> (HeaderName, T) { + let entry = self.map.remove_found(self.probe, self.index); + + if let Some(links) = entry.links { + self.map.remove_all_extra_values(links.next); + } + + (entry.key, entry.value) + } + + /// Remove the entry from the map. + /// + /// The key and all values associated with the entry are removed and + /// returned. + pub fn remove_entry_mult(self) -> (HeaderName, ValueDrain<'a, T>) { + let entry = self.map.remove_found(self.probe, self.index); + let drain = ValueDrain { + map: self.map as *mut _, + first: Some(entry.value), + next: entry.links.map(|l| l.next), + lt: PhantomData, + }; + (entry.key, drain) + } + + /// Returns an iterator visiting all values associated with the entry. + /// + /// Values are iterated in insertion order. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::new(); + /// map.insert(HOST, "world".parse().unwrap()); + /// map.append(HOST, "earth".parse().unwrap()); + /// + /// if let Entry::Occupied(e) = map.entry("host").unwrap() { + /// let mut iter = e.iter(); + /// assert_eq!(&"world", iter.next().unwrap()); + /// assert_eq!(&"earth", iter.next().unwrap()); + /// assert!(iter.next().is_none()); + /// } + /// ``` + pub fn iter(&self) -> ValueIter { + self.map.value_iter(Some(self.index)) + } + + /// Returns an iterator mutably visiting all values associated with the + /// entry. + /// + /// Values are iterated in insertion order. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderMap, Entry, HOST}; + /// let mut map = HeaderMap::default(); + /// map.insert(HOST, "world".to_string()); + /// map.append(HOST, "earth".to_string()); + /// + /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() { + /// for e in e.iter_mut() { + /// e.push_str("-boop"); + /// } + /// } + /// + /// let mut values = map.get_all("host"); + /// let mut i = values.iter(); + /// assert_eq!(&"world-boop", i.next().unwrap()); + /// assert_eq!(&"earth-boop", i.next().unwrap()); + /// ``` + pub fn iter_mut(&mut self) -> ValueIterMut { + self.map.value_iter_mut(self.index) + } +} + +impl<'a, T> IntoIterator for OccupiedEntry<'a, T> { + type Item = &'a mut T; + type IntoIter = ValueIterMut<'a, T>; + + fn into_iter(self) -> ValueIterMut<'a, T> { + self.map.value_iter_mut(self.index) + } +} + +impl<'a, 'b: 'a, T> IntoIterator for &'b OccupiedEntry<'a, T> { + type Item = &'a T; + type IntoIter = ValueIter<'a, T>; + + fn into_iter(self) -> ValueIter<'a, T> { + self.iter() + } +} + +impl<'a, 'b: 'a, T> IntoIterator for &'b mut OccupiedEntry<'a, T> { + type Item = &'a mut T; + type IntoIter = ValueIterMut<'a, T>; + + fn into_iter(self) -> ValueIterMut<'a, T> { + self.iter_mut() + } +} + +// ===== impl ValueDrain ===== + +impl<'a, T> Iterator for ValueDrain<'a, T> { + type Item = T; + + fn next(&mut self) -> Option { + if self.first.is_some() { + self.first.take() + } else if let Some(next) = self.next { + // Remove the extra value + let extra = unsafe { &mut (*self.map) }.remove_extra_value(next); + + match extra.next { + Link::Extra(idx) => self.next = Some(idx), + Link::Entry(_) => self.next = None, + } + + Some(extra.value) + } else { + None + } + } + + fn size_hint(&self) -> (usize, Option) { + match (&self.first, self.next) { + // Exactly 1 + (&Some(_), None) => (1, Some(1)), + // At least 1 + (&_, Some(_)) => (1, None), + // No more + (&None, None) => (0, Some(0)), + } + } +} + +impl<'a, T> Drop for ValueDrain<'a, T> { + fn drop(&mut self) { + while let Some(_) = self.next() { + } + } +} + +unsafe impl<'a, T: Sync> Sync for ValueDrain<'a, T> {} +unsafe impl<'a, T: Send> Send for ValueDrain<'a, T> {} + +// ===== impl Pos ===== + +impl Pos { + #[inline] + fn new(index: usize, hash: HashValue) -> Self { + Pos { + index: index as Size, + hash: hash, + } + } + + #[inline] + fn none() -> Self { + Pos { + index: !0, + hash: HashValue(0), + } + } + + #[inline] + fn is_some(&self) -> bool { + !self.is_none() + } + + #[inline] + fn is_none(&self) -> bool { + self.index == !0 + } + + #[inline] + fn resolve(&self) -> Option<(usize, HashValue)> { + if self.is_some() { + Some((self.index, self.hash)) + } else { + None + } + } +} + +impl Danger { + fn is_red(&self) -> bool { + match *self { + Danger::Red(_) => true, + _ => false, + } + } + + fn to_red(&mut self) { + debug_assert!(self.is_yellow()); + *self = Danger::Red(RandomState::new()); + } + + fn is_yellow(&self) -> bool { + match *self { + Danger::Yellow => true, + _ => false, + } + } + + fn to_yellow(&mut self) { + match *self { + Danger::Green => { + *self = Danger::Yellow; + } + _ => {} + } + } + + fn to_green(&mut self) { + debug_assert!(self.is_yellow()); + *self = Danger::Green; + } +} + +// ===== impl Utils ===== + +#[inline] +fn usable_capacity(cap: usize) -> usize { + cap - cap / 4 +} + +#[inline] +fn to_raw_capacity(n: usize) -> usize { + n + n / 3 +} + +#[inline] +fn desired_pos(mask: Size, hash: HashValue) -> usize { + (hash.0 & mask) +} + +/// The number of steps that `current` is forward of the desired position for hash +#[inline] +fn probe_distance(mask: Size, hash: HashValue, current: usize) -> usize { + current.wrapping_sub(desired_pos(mask, hash)) & mask +} + +fn hash_elem_using(danger: &Danger, k: &K) -> HashValue + where K: Hash +{ + use fnv::FnvHasher; + + const MASK: u64 = (MAX_SIZE as u64) - 1; + + let hash = match *danger { + // Safe hash + Danger::Red(ref hasher) => { + let mut h = hasher.build_hasher(); + k.hash(&mut h); + h.finish() + } + // Fast hash + _ => { + let mut h = FnvHasher::default(); + k.hash(&mut h); + h.finish() + } + }; + + HashValue((hash & MASK) as usize) +} + +/* + * + * ===== impl IntoHeaderName / AsHeaderName ===== + * + */ + + +mod into_header_name { + use super::{HdrName, HeaderMap, HeaderName}; + + /// A marker trait used to identify values that can be used as insert keys + /// to a `HeaderMap`. + pub trait IntoHeaderName: Sealed {} + + // All methods are on this pub(super) trait, instead of `IntoHeaderName`, + // so that they aren't publicly exposed to the world. + // + // Being on the `IntoHeaderName` trait would mean users could call + // `"host".insert(&mut map, "localhost")`. + // + // Ultimately, this allows us to adjust the signatures of these methods + // without breaking any external crate. + pub trait Sealed { + #[doc(hidden)] + fn insert(self, map: &mut HeaderMap, val: T) -> Option; + + #[doc(hidden)] + fn append(self, map: &mut HeaderMap, val: T) -> bool; + } + + // ==== impls ==== + + impl Sealed for HeaderName { + #[doc(hidden)] + #[inline] + fn insert(self, map: &mut HeaderMap, val: T) -> Option { + map.insert2(self, val) + } + + #[doc(hidden)] + #[inline] + fn append(self, map: &mut HeaderMap, val: T) -> bool { + map.append2(self, val) + } + } + + impl IntoHeaderName for HeaderName {} + + impl<'a> Sealed for &'a HeaderName { + #[doc(hidden)] + #[inline] + fn insert(self, map: &mut HeaderMap, val: T) -> Option { + map.insert2(self, val) + } + #[doc(hidden)] + #[inline] + fn append(self, map: &mut HeaderMap, val: T) -> bool { + map.append2(self, val) + } + } + + impl<'a> IntoHeaderName for &'a HeaderName {} + + impl Sealed for &'static str { + #[doc(hidden)] + #[inline] + fn insert(self, map: &mut HeaderMap, val: T) -> Option { + HdrName::from_static(self, move |hdr| map.insert2(hdr, val)) + } + #[doc(hidden)] + #[inline] + fn append(self, map: &mut HeaderMap, val: T) -> bool { + HdrName::from_static(self, move |hdr| map.append2(hdr, val)) + } + } + + impl IntoHeaderName for &'static str {} +} + +mod as_header_name { + use super::{Entry, HdrName, HeaderMap, HeaderName, InvalidHeaderName}; + + /// A marker trait used to identify values that can be used as search keys + /// to a `HeaderMap`. + pub trait AsHeaderName: Sealed {} + + // All methods are on this pub(super) trait, instead of `AsHeaderName`, + // so that they aren't publicly exposed to the world. + // + // Being on the `AsHeaderName` trait would mean users could call + // `"host".find(&map)`. + // + // Ultimately, this allows us to adjust the signatures of these methods + // without breaking any external crate. + pub trait Sealed { + #[doc(hidden)] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName>; + + #[doc(hidden)] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)>; + + #[doc(hidden)] + fn as_str(&self) -> &str; + } + + // ==== impls ==== + + impl Sealed for HeaderName { + #[doc(hidden)] + #[inline] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName> { + Ok(map.entry2(self)) + } + + #[doc(hidden)] + #[inline] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)> { + map.find(self) + } + + #[doc(hidden)] + fn as_str(&self) -> &str { + ::as_str(self) + } + } + + impl AsHeaderName for HeaderName {} + + impl<'a> Sealed for &'a HeaderName { + #[doc(hidden)] + #[inline] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName> { + Ok(map.entry2(self)) + } + + #[doc(hidden)] + #[inline] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)> { + map.find(*self) + } + + #[doc(hidden)] + fn as_str(&self) -> &str { + ::as_str(*self) + } + } + + impl<'a> AsHeaderName for &'a HeaderName {} + + impl<'a> Sealed for &'a str { + #[doc(hidden)] + #[inline] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName> { + HdrName::from_bytes(self.as_bytes(), move |hdr| map.entry2(hdr)) + } + + #[doc(hidden)] + #[inline] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)> { + HdrName::from_bytes(self.as_bytes(), move |hdr| map.find(&hdr)).unwrap_or(None) + } + + #[doc(hidden)] + fn as_str(&self) -> &str { + self + } + } + + impl<'a> AsHeaderName for &'a str {} + + impl Sealed for String { + #[doc(hidden)] + #[inline] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName> { + self.as_str().entry(map) + } + + #[doc(hidden)] + #[inline] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)> { + Sealed::find(&self.as_str(), map) + } + + #[doc(hidden)] + fn as_str(&self) -> &str { + self + } + } + + impl AsHeaderName for String {} + + impl<'a> Sealed for &'a String { + #[doc(hidden)] + #[inline] + fn entry(self, map: &mut HeaderMap) -> Result, InvalidHeaderName> { + self.as_str().entry(map) + } + + #[doc(hidden)] + #[inline] + fn find(&self, map: &HeaderMap) -> Option<(usize, usize)> { + Sealed::find(*self, map) + } + + #[doc(hidden)] + fn as_str(&self) -> &str { + *self + } + } + + impl<'a> AsHeaderName for &'a String {} +} + + +#[test] +fn test_bounds() { + fn check_bounds() {} + + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); + check_bounds::>(); +} + +#[test] +fn skip_duplicates_during_key_iteration() { + let mut map = HeaderMap::new(); + map.append("a", HeaderValue::from_static("a")); + map.append("a", HeaderValue::from_static("b")); + assert_eq!(map.keys().count(), map.keys_len()); +} diff -Nru cargo-0.33.0/vendor/http/src/header/mod.rs cargo-0.35.0/vendor/http/src/header/mod.rs --- cargo-0.33.0/vendor/http/src/header/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/header/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,196 @@ +//! HTTP header types +//! +//! The module provides [`HeaderName`], [`HeaderMap`], and a number of types +//! used for interacting with `HeaderMap`. These types allow representing both +//! HTTP/1 and HTTP/2 headers. +//! +//! # `HeaderName` +//! +//! The `HeaderName` type represents both standard header names as well as +//! custom header names. The type handles the case insensitive nature of header +//! names and is used as the key portion of `HeaderMap`. Header names are +//! normalized to lower case. In other words, when creating a `HeaderName` with +//! a string, even if upper case characters are included, when getting a string +//! representation of the `HeaderName`, it will be all lower case. This allows +//! for faster `HeaderMap` comparison operations. +//! +//! The internal representation is optimized to efficiently handle the cases +//! most commonly encountered when working with HTTP. Standard header names are +//! special cased and are represented internally as an enum. Short custom +//! headers will be stored directly in the `HeaderName` struct and will not +//! incur any allocation overhead, however longer strings will require an +//! allocation for storage. +//! +//! ## Limitations +//! +//! `HeaderName` has a max length of 32,768 for header names. Attempting to +//! parse longer names will result in a panic. +//! +//! # `HeaderMap` +//! +//! `HeaderMap` is a map structure of header names highly optimized for use +//! cases common with HTTP. It is a [multimap] structure, where each header name +//! may have multiple associated header values. Given this, some of the APIs +//! diverge from [`HashMap`]. +//! +//! ## Overview +//! +//! Just like `HashMap` in Rust's stdlib, `HeaderMap` is based on [Robin Hood +//! hashing]. This algorithm tends to reduce the worst case search times in the +//! table and enables high load factors without seriously affecting performance. +//! Internally, keys and values are stored in vectors. As such, each insertion +//! will not incur allocation overhead. However, once the underlying vector +//! storage is full, a larger vector must be allocated and all values copied. +//! +//! ## Deterministic ordering +//! +//! Unlike Rust's `HashMap`, values in `HeaderMap` are deterministically +//! ordered. Roughly, values are ordered by insertion. This means that a +//! function that deterministically operates on a header map can rely on the +//! iteration order to remain consistent across processes and platforms. +//! +//! ## Adaptive hashing +//! +//! `HeaderMap` uses an adaptive hashing strategy in order to efficiently handle +//! most common cases. All standard headers have statically computed hash values +//! which removes the need to perform any hashing of these headers at runtime. +//! The default hash function emphasizes performance over robustness. However, +//! `HeaderMap` detects high collision rates and switches to a secure hash +//! function in those events. The threshold is set such that only denial of +//! service attacks should trigger it. +//! +//! ## Limitations +//! +//! `HeaderMap` can store a maximum of 32,768 headers (header name / value +//! pairs). Attempting to insert more will result in a panic. +//! +//! [`HeaderName`]: struct.HeaderName.html +//! [`HeaderMap`]: struct.HeaderMap.html +//! [multimap]: https://en.wikipedia.org/wiki/Multimap +//! [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html +//! [Robin Hood hashing]: https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing + +mod map; +mod name; +mod value; + +pub use self::map::{ + HeaderMap, + AsHeaderName, + IntoHeaderName, + Iter, + IterMut, + Keys, + Values, + ValuesMut, + Drain, + GetAll, + Entry, + VacantEntry, + OccupiedEntry, + ValueIter, + ValueIterMut, + ValueDrain, + IntoIter, +}; +pub use self::name::{ + HeaderName, + InvalidHeaderName, + InvalidHeaderNameBytes, +}; +pub use self::value::{ + HeaderValue, + InvalidHeaderValue, + InvalidHeaderValueBytes, + ToStrError, +}; + +// Use header name constants +pub use self::name::{ + ACCEPT, + ACCEPT_CHARSET, + ACCEPT_ENCODING, + ACCEPT_LANGUAGE, + ACCEPT_RANGES, + ACCESS_CONTROL_ALLOW_CREDENTIALS, + ACCESS_CONTROL_ALLOW_HEADERS, + ACCESS_CONTROL_ALLOW_METHODS, + ACCESS_CONTROL_ALLOW_ORIGIN, + ACCESS_CONTROL_EXPOSE_HEADERS, + ACCESS_CONTROL_MAX_AGE, + ACCESS_CONTROL_REQUEST_HEADERS, + ACCESS_CONTROL_REQUEST_METHOD, + AGE, + ALLOW, + ALT_SVC, + AUTHORIZATION, + CACHE_CONTROL, + CONNECTION, + CONTENT_DISPOSITION, + CONTENT_ENCODING, + CONTENT_LANGUAGE, + CONTENT_LENGTH, + CONTENT_LOCATION, + CONTENT_RANGE, + CONTENT_SECURITY_POLICY, + CONTENT_SECURITY_POLICY_REPORT_ONLY, + CONTENT_TYPE, + COOKIE, + DNT, + DATE, + ETAG, + EXPECT, + EXPIRES, + FORWARDED, + FROM, + HOST, + IF_MATCH, + IF_MODIFIED_SINCE, + IF_NONE_MATCH, + IF_RANGE, + IF_UNMODIFIED_SINCE, + LAST_MODIFIED, + LINK, + LOCATION, + MAX_FORWARDS, + ORIGIN, + PRAGMA, + PROXY_AUTHENTICATE, + PROXY_AUTHORIZATION, + PUBLIC_KEY_PINS, + PUBLIC_KEY_PINS_REPORT_ONLY, + RANGE, + REFERER, + REFERRER_POLICY, + REFRESH, + RETRY_AFTER, + SEC_WEBSOCKET_ACCEPT, + SEC_WEBSOCKET_EXTENSIONS, + SEC_WEBSOCKET_KEY, + SEC_WEBSOCKET_PROTOCOL, + SEC_WEBSOCKET_VERSION, + SERVER, + SET_COOKIE, + STRICT_TRANSPORT_SECURITY, + TE, + TRAILER, + TRANSFER_ENCODING, + UPGRADE, + UPGRADE_INSECURE_REQUESTS, + USER_AGENT, + VARY, + VIA, + WARNING, + WWW_AUTHENTICATE, + X_CONTENT_TYPE_OPTIONS, + X_DNS_PREFETCH_CONTROL, + X_FRAME_OPTIONS, + X_XSS_PROTECTION, +}; + +/// Maximum length of a header name +/// +/// Generally, 64kb for a header name is WAY too much than would ever be needed +/// in practice. Restricting it to this size enables using `u16` values to +/// represent offsets when dealing with header names. +const MAX_HEADER_NAME_LEN: usize = 1 << 16; diff -Nru cargo-0.33.0/vendor/http/src/header/name.rs cargo-0.35.0/vendor/http/src/header/name.rs --- cargo-0.33.0/vendor/http/src/header/name.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/header/name.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2206 @@ +use HttpTryFrom; +use byte_str::ByteStr; +use bytes::{Bytes, BytesMut}; + +use std::{fmt, mem}; +use std::borrow::Borrow; +use std::hash::{Hash, Hasher}; +use std::str::FromStr; +use std::error::Error; + +/// Represents an HTTP header field name +/// +/// Header field names identify the header. Header sets may include multiple +/// headers with the same name. The HTTP specification defines a number of +/// standard headers, but HTTP messages may include non-standard header names as +/// well as long as they adhere to the specification. +/// +/// `HeaderName` is used as the [`HeaderMap`] key. Constants are available for +/// all standard header names in the [`header`] module. +/// +/// # Representation +/// +/// `HeaderName` represents standard header names using an `enum`, as such they +/// will not require an allocation for storage. All custom header names are +/// lower cased upon conversion to a `HeaderName` value. This avoids the +/// overhead of dynamically doing lower case conversion during the hash code +/// computation and the comparison operation. +/// +/// [`HeaderMap`]: struct.HeaderMap.html +/// [`header`]: index.html +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct HeaderName { + inner: Repr, +} + +// Almost a full `HeaderName` +#[derive(Debug, Hash)] +pub struct HdrName<'a> { + inner: Repr>, +} + +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +enum Repr { + Standard(StandardHeader), + Custom(T), +} + +// Used to hijack the Hash impl +#[derive(Debug, Clone, Eq, PartialEq)] +struct Custom(ByteStr); + +#[derive(Debug, Clone)] +struct MaybeLower<'a> { + buf: &'a [u8], + lower: bool, +} + +/// A possible error when converting a `HeaderName` from another type. +#[derive(Debug)] +pub struct InvalidHeaderName { + _priv: (), +} + +/// A possible error when converting a `HeaderName` from another type. +#[derive(Debug)] +pub struct InvalidHeaderNameBytes(InvalidHeaderName) ; + +macro_rules! standard_headers { + ( + $( + $(#[$docs:meta])* + ($konst:ident, $upcase:ident, $name:expr); + )+ + ) => { + #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] + enum StandardHeader { + $( + $konst, + )+ + } + + $( + $(#[$docs])* + pub const $upcase: HeaderName = HeaderName { + inner: Repr::Standard(StandardHeader::$konst), + }; + )+ + + impl StandardHeader { + #[inline] + fn as_str(&self) -> &'static str { + match *self { + $( + StandardHeader::$konst => $name, + )+ + } + } + } + + #[cfg(test)] + const TEST_HEADERS: &'static [(StandardHeader, &'static str)] = &[ + $( + (StandardHeader::$konst, $name), + )+ + ]; + + #[test] + fn test_parse_standard_headers() { + for &(std, name) in TEST_HEADERS { + // Test lower case + assert_eq!(HeaderName::from_bytes(name.as_bytes()).unwrap(), HeaderName::from(std)); + + // Test upper case + let upper = name.to_uppercase().to_string(); + assert_eq!(HeaderName::from_bytes(upper.as_bytes()).unwrap(), HeaderName::from(std)); + } + } + + #[test] + fn test_standard_headers_into_bytes() { + for &(std, name) in TEST_HEADERS { + let std = HeaderName::from(std); + // Test lower case + let name_bytes = name.as_bytes(); + let bytes: Bytes = + HeaderName::from_bytes(name_bytes).unwrap().into(); + assert_eq!(bytes, name_bytes); + assert_eq!(HeaderName::from_bytes(name_bytes).unwrap(), std); + + // Test upper case + let upper = name.to_uppercase().to_string(); + let bytes: Bytes = + HeaderName::from_bytes(upper.as_bytes()).unwrap().into(); + assert_eq!(bytes, name.as_bytes()); + assert_eq!(HeaderName::from_bytes(upper.as_bytes()).unwrap(), + std); + + + } + + } + } +} + +// Generate constants for all standard HTTP headers. This includes a static hash +// code for the "fast hash" path. The hash code for static headers *do not* have +// to match the text representation of those headers. This is because header +// strings are always converted to the static values (when they match) before +// being hashed. This means that it is impossible to compare the static hash +// code of CONTENT_LENGTH with "content-length". +standard_headers! { + /// Advertises which content types the client is able to understand. + /// + /// The Accept request HTTP header advertises which content types, expressed + /// as MIME types, the client is able to understand. Using content + /// negotiation, the server then selects one of the proposals, uses it and + /// informs the client of its choice with the Content-Type response header. + /// Browsers set adequate values for this header depending of the context + /// where the request is done: when fetching a CSS stylesheet a different + /// value is set for the request than when fetching an image, video or a + /// script. + (Accept, ACCEPT, "accept"); + + /// Advertises which character set the client is able to understand. + /// + /// The Accept-Charset request HTTP header advertises which character set + /// the client is able to understand. Using content negotiation, the server + /// then selects one of the proposals, uses it and informs the client of its + /// choice within the Content-Type response header. Browsers usually don't + /// set this header as the default value for each content type is usually + /// correct and transmitting it would allow easier fingerprinting. + /// + /// If the server cannot serve any matching character set, it can + /// theoretically send back a 406 (Not Acceptable) error code. But, for a + /// better user experience, this is rarely done and the more common way is + /// to ignore the Accept-Charset header in this case. + (AcceptCharset, ACCEPT_CHARSET, "accept-charset"); + + /// Advertises which content encoding the client is able to understand. + /// + /// The Accept-Encoding request HTTP header advertises which content + /// encoding, usually a compression algorithm, the client is able to + /// understand. Using content negotiation, the server selects one of the + /// proposals, uses it and informs the client of its choice with the + /// Content-Encoding response header. + /// + /// Even if both the client and the server supports the same compression + /// algorithms, the server may choose not to compress the body of a + /// response, if the identity value is also acceptable. Two common cases + /// lead to this: + /// + /// * The data to be sent is already compressed and a second compression + /// won't lead to smaller data to be transmitted. This may the case with + /// some image formats; + /// + /// * The server is overloaded and cannot afford the computational overhead + /// induced by the compression requirement. Typically, Microsoft recommends + /// not to compress if a server use more than 80 % of its computational + /// power. + /// + /// As long as the identity value, meaning no encryption, is not explicitly + /// forbidden, by an identity;q=0 or a *;q=0 without another explicitly set + /// value for identity, the server must never send back a 406 Not Acceptable + /// error. + (AcceptEncoding, ACCEPT_ENCODING, "accept-encoding"); + + /// Advertises which languages the client is able to understand. + /// + /// The Accept-Language request HTTP header advertises which languages the + /// client is able to understand, and which locale variant is preferred. + /// Using content negotiation, the server then selects one of the proposals, + /// uses it and informs the client of its choice with the Content-Language + /// response header. Browsers set adequate values for this header according + /// their user interface language and even if a user can change it, this + /// happens rarely (and is frown upon as it leads to fingerprinting). + /// + /// This header is a hint to be used when the server has no way of + /// determining the language via another way, like a specific URL, that is + /// controlled by an explicit user decision. It is recommended that the + /// server never overrides an explicit decision. The content of the + /// Accept-Language is often out of the control of the user (like when + /// traveling and using an Internet Cafe in a different country); the user + /// may also want to visit a page in another language than the locale of + /// their user interface. + /// + /// If the server cannot serve any matching language, it can theoretically + /// send back a 406 (Not Acceptable) error code. But, for a better user + /// experience, this is rarely done and more common way is to ignore the + /// Accept-Language header in this case. + (AcceptLanguage, ACCEPT_LANGUAGE, "accept-language"); + + /// Marker used by the server to advertise partial request support. + /// + /// The Accept-Ranges response HTTP header is a marker used by the server to + /// advertise its support of partial requests. The value of this field + /// indicates the unit that can be used to define a range. + /// + /// In presence of an Accept-Ranges header, the browser may try to resume an + /// interrupted download, rather than to start it from the start again. + (AcceptRanges, ACCEPT_RANGES, "accept-ranges"); + + /// Preflight response indicating if the response to the request can be + /// exposed to the page. + /// + /// The Access-Control-Allow-Credentials response header indicates whether + /// or not the response to the request can be exposed to the page. It can be + /// exposed when the true value is returned; it can't in other cases. + /// + /// Credentials are cookies, authorization headers or TLS client + /// certificates. + /// + /// When used as part of a response to a preflight request, this indicates + /// whether or not the actual request can be made using credentials. Note + /// that simple GET requests are not preflighted, and so if a request is + /// made for a resource with credentials, if this header is not returned + /// with the resource, the response is ignored by the browser and not + /// returned to web content. + /// + /// The Access-Control-Allow-Credentials header works in conjunction with + /// the XMLHttpRequest.withCredentials property or with the credentials + /// option in the Request() constructor of the Fetch API. Credentials must + /// be set on both sides (the Access-Control-Allow-Credentials header and in + /// the XHR or Fetch request) in order for the CORS request with credentials + /// to succeed. + (AccessControlAllowCredentials, ACCESS_CONTROL_ALLOW_CREDENTIALS, "access-control-allow-credentials"); + + /// Preflight response indicating permitted HTTP headers. + /// + /// The Access-Control-Allow-Headers response header is used in response to + /// a preflight request to indicate which HTTP headers will be available via + /// Access-Control-Expose-Headers when making the actual request. + /// + /// The simple headers, Accept, Accept-Language, Content-Language, + /// Content-Type (but only with a MIME type of its parsed value (ignoring + /// parameters) of either application/x-www-form-urlencoded, + /// multipart/form-data, or text/plain), are always available and don't need + /// to be listed by this header. + /// + /// This header is required if the request has an + /// Access-Control-Request-Headers header. + (AccessControlAllowHeaders, ACCESS_CONTROL_ALLOW_HEADERS, "access-control-allow-headers"); + + /// Preflight header response indicating permitted access methods. + /// + /// The Access-Control-Allow-Methods response header specifies the method or + /// methods allowed when accessing the resource in response to a preflight + /// request. + (AccessControlAllowMethods, ACCESS_CONTROL_ALLOW_METHODS, "access-control-allow-methods"); + + /// Indicates whether the response can be shared with resources with the + /// given origin. + (AccessControlAllowOrigin, ACCESS_CONTROL_ALLOW_ORIGIN, "access-control-allow-origin"); + + /// Indicates which headers can be exposed as part of the response by + /// listing their names. + (AccessControlExposeHeaders, ACCESS_CONTROL_EXPOSE_HEADERS, "access-control-expose-headers"); + + /// Indicates how long the results of a preflight request can be cached. + (AccessControlMaxAge, ACCESS_CONTROL_MAX_AGE, "access-control-max-age"); + + /// Informs the server which HTTP headers will be used when an actual + /// request is made. + (AccessControlRequestHeaders, ACCESS_CONTROL_REQUEST_HEADERS, "access-control-request-headers"); + + /// Informs the server know which HTTP method will be used when the actual + /// request is made. + (AccessControlRequestMethod, ACCESS_CONTROL_REQUEST_METHOD, "access-control-request-method"); + + /// Indicates the time in seconds the object has been in a proxy cache. + /// + /// The Age header is usually close to zero. If it is Age: 0, it was + /// probably just fetched from the origin server; otherwise It is usually + /// calculated as a difference between the proxy's current date and the Date + /// general header included in the HTTP response. + (Age, AGE, "age"); + + /// Lists the set of methods support by a resource. + /// + /// This header must be sent if the server responds with a 405 Method Not + /// Allowed status code to indicate which request methods can be used. An + /// empty Allow header indicates that the resource allows no request + /// methods, which might occur temporarily for a given resource, for + /// example. + (Allow, ALLOW, "allow"); + + /// Advertises the availability of alternate services to clients. + (AltSvc, ALT_SVC, "alt-svc"); + + /// Contains the credentials to authenticate a user agent with a server. + /// + /// Usually this header is included after the server has responded with a + /// 401 Unauthorized status and the WWW-Authenticate header. + (Authorization, AUTHORIZATION, "authorization"); + + /// Specifies directives for caching mechanisms in both requests and + /// responses. + /// + /// Caching directives are unidirectional, meaning that a given directive in + /// a request is not implying that the same directive is to be given in the + /// response. + (CacheControl, CACHE_CONTROL, "cache-control"); + + /// Controls whether or not the network connection stays open after the + /// current transaction finishes. + /// + /// If the value sent is keep-alive, the connection is persistent and not + /// closed, allowing for subsequent requests to the same server to be done. + /// + /// Except for the standard hop-by-hop headers (Keep-Alive, + /// Transfer-Encoding, TE, Connection, Trailer, Upgrade, Proxy-Authorization + /// and Proxy-Authenticate), any hop-by-hop headers used by the message must + /// be listed in the Connection header, so that the first proxy knows he has + /// to consume them and not to forward them further. Standard hop-by-hop + /// headers can be listed too (it is often the case of Keep-Alive, but this + /// is not mandatory. + (Connection, CONNECTION, "connection"); + + /// Indicates if the content is expected to be displayed inline. + /// + /// In a regular HTTP response, the Content-Disposition response header is a + /// header indicating if the content is expected to be displayed inline in + /// the browser, that is, as a Web page or as part of a Web page, or as an + /// attachment, that is downloaded and saved locally. + /// + /// In a multipart/form-data body, the HTTP Content-Disposition general + /// header is a header that can be used on the subpart of a multipart body + /// to give information about the field it applies to. The subpart is + /// delimited by the boundary defined in the Content-Type header. Used on + /// the body itself, Content-Disposition has no effect. + /// + /// The Content-Disposition header is defined in the larger context of MIME + /// messages for e-mail, but only a subset of the possible parameters apply + /// to HTTP forms and POST requests. Only the value form-data, as well as + /// the optional directive name and filename, can be used in the HTTP + /// context. + (ContentDisposition, CONTENT_DISPOSITION, "content-disposition"); + + /// Used to compress the media-type. + /// + /// When present, its value indicates what additional content encoding has + /// been applied to the entity-body. It lets the client know, how to decode + /// in order to obtain the media-type referenced by the Content-Type header. + /// + /// It is recommended to compress data as much as possible and therefore to + /// use this field, but some types of resources, like jpeg images, are + /// already compressed. Sometimes using additional compression doesn't + /// reduce payload size and can even make the payload longer. + (ContentEncoding, CONTENT_ENCODING, "content-encoding"); + + /// Used to describe the languages intended for the audience. + /// + /// This header allows a user to differentiate according to the users' own + /// preferred language. For example, if "Content-Language: de-DE" is set, it + /// says that the document is intended for German language speakers + /// (however, it doesn't indicate the document is written in German. For + /// example, it might be written in English as part of a language course for + /// German speakers). + /// + /// If no Content-Language is specified, the default is that the content is + /// intended for all language audiences. Multiple language tags are also + /// possible, as well as applying the Content-Language header to various + /// media types and not only to textual documents. + (ContentLanguage, CONTENT_LANGUAGE, "content-language"); + + /// Indicates the size fo the entity-body. + /// + /// The header value must be a decimal indicating the number of octets sent + /// to the recipient. + (ContentLength, CONTENT_LENGTH, "content-length"); + + /// Indicates an alternate location for the returned data. + /// + /// The principal use case is to indicate the URL of the resource + /// transmitted as the result of content negotiation. + /// + /// Location and Content-Location are different: Location indicates the + /// target of a redirection (or the URL of a newly created document), while + /// Content-Location indicates the direct URL to use to access the resource, + /// without the need of further content negotiation. Location is a header + /// associated with the response, while Content-Location is associated with + /// the entity returned. + (ContentLocation, CONTENT_LOCATION, "content-location"); + + /// Indicates where in a full body message a partial message belongs. + (ContentRange, CONTENT_RANGE, "content-range"); + + /// Allows controlling resources the user agent is allowed to load for a + /// given page. + /// + /// With a few exceptions, policies mostly involve specifying server origins + /// and script endpoints. This helps guard against cross-site scripting + /// attacks (XSS). + (ContentSecurityPolicy, CONTENT_SECURITY_POLICY, "content-security-policy"); + + /// Allows experimenting with policies by monitoring their effects. + /// + /// The HTTP Content-Security-Policy-Report-Only response header allows web + /// developers to experiment with policies by monitoring (but not enforcing) + /// their effects. These violation reports consist of JSON documents sent + /// via an HTTP POST request to the specified URI. + (ContentSecurityPolicyReportOnly, CONTENT_SECURITY_POLICY_REPORT_ONLY, "content-security-policy-report-only"); + + /// Used to indicate the media type of the resource. + /// + /// In responses, a Content-Type header tells the client what the content + /// type of the returned content actually is. Browsers will do MIME sniffing + /// in some cases and will not necessarily follow the value of this header; + /// to prevent this behavior, the header X-Content-Type-Options can be set + /// to nosniff. + /// + /// In requests, (such as POST or PUT), the client tells the server what + /// type of data is actually sent. + (ContentType, CONTENT_TYPE, "content-type"); + + /// Contains stored HTTP cookies previously sent by the server with the + /// Set-Cookie header. + /// + /// The Cookie header might be omitted entirely, if the privacy setting of + /// the browser are set to block them, for example. + (Cookie, COOKIE, "cookie"); + + /// Indicates the client's tracking preference. + /// + /// This header lets users indicate whether they would prefer privacy rather + /// than personalized content. + (Dnt, DNT, "dnt"); + + /// Contains the date and time at which the message was originated. + (Date, DATE, "date"); + + /// Identifier for a specific version of a resource. + /// + /// This header allows caches to be more efficient, and saves bandwidth, as + /// a web server does not need to send a full response if the content has + /// not changed. On the other side, if the content has changed, etags are + /// useful to help prevent simultaneous updates of a resource from + /// overwriting each other ("mid-air collisions"). + /// + /// If the resource at a given URL changes, a new Etag value must be + /// generated. Etags are therefore similar to fingerprints and might also be + /// used for tracking purposes by some servers. A comparison of them allows + /// to quickly determine whether two representations of a resource are the + /// same, but they might also be set to persist indefinitely by a tracking + /// server. + (Etag, ETAG, "etag"); + + /// Indicates expectations that need to be fulfilled by the server in order + /// to properly handle the request. + /// + /// The only expectation defined in the specification is Expect: + /// 100-continue, to which the server shall respond with: + /// + /// * 100 if the information contained in the header is sufficient to cause + /// an immediate success, + /// + /// * 417 (Expectation Failed) if it cannot meet the expectation; or any + /// other 4xx status otherwise. + /// + /// For example, the server may reject a request if its Content-Length is + /// too large. + /// + /// No common browsers send the Expect header, but some other clients such + /// as cURL do so by default. + (Expect, EXPECT, "expect"); + + /// Contains the date/time after which the response is considered stale. + /// + /// Invalid dates, like the value 0, represent a date in the past and mean + /// that the resource is already expired. + /// + /// If there is a Cache-Control header with the "max-age" or "s-max-age" + /// directive in the response, the Expires header is ignored. + (Expires, EXPIRES, "expires"); + + /// Contains information from the client-facing side of proxy servers that + /// is altered or lost when a proxy is involved in the path of the request. + /// + /// The alternative and de-facto standard versions of this header are the + /// X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto headers. + /// + /// This header is used for debugging, statistics, and generating + /// location-dependent content and by design it exposes privacy sensitive + /// information, such as the IP address of the client. Therefore the user's + /// privacy must be kept in mind when deploying this header. + (Forwarded, FORWARDED, "forwarded"); + + /// Contains an Internet email address for a human user who controls the + /// requesting user agent. + /// + /// If you are running a robotic user agent (e.g. a crawler), the From + /// header should be sent, so you can be contacted if problems occur on + /// servers, such as if the robot is sending excessive, unwanted, or invalid + /// requests. + (From, FROM, "from"); + + /// Specifies the domain name of the server and (optionally) the TCP port + /// number on which the server is listening. + /// + /// If no port is given, the default port for the service requested (e.g., + /// "80" for an HTTP URL) is implied. + /// + /// A Host header field must be sent in all HTTP/1.1 request messages. A 400 + /// (Bad Request) status code will be sent to any HTTP/1.1 request message + /// that lacks a Host header field or contains more than one. + (Host, HOST, "host"); + + /// Makes a request conditional based on the E-Tag. + /// + /// For GET and HEAD methods, the server will send back the requested + /// resource only if it matches one of the listed ETags. For PUT and other + /// non-safe methods, it will only upload the resource in this case. + /// + /// The comparison with the stored ETag uses the strong comparison + /// algorithm, meaning two files are considered identical byte to byte only. + /// This is weakened when the W/ prefix is used in front of the ETag. + /// + /// There are two common use cases: + /// + /// * For GET and HEAD methods, used in combination with an Range header, it + /// can guarantee that the new ranges requested comes from the same resource + /// than the previous one. If it doesn't match, then a 416 (Range Not + /// Satisfiable) response is returned. + /// + /// * For other methods, and in particular for PUT, If-Match can be used to + /// prevent the lost update problem. It can check if the modification of a + /// resource that the user wants to upload will not override another change + /// that has been done since the original resource was fetched. If the + /// request cannot be fulfilled, the 412 (Precondition Failed) response is + /// returned. + (IfMatch, IF_MATCH, "if-match"); + + /// Makes a request conditional based on the modification date. + /// + /// The If-Modified-Since request HTTP header makes the request conditional: + /// the server will send back the requested resource, with a 200 status, + /// only if it has been last modified after the given date. If the request + /// has not been modified since, the response will be a 304 without any + /// body; the Last-Modified header will contain the date of last + /// modification. Unlike If-Unmodified-Since, If-Modified-Since can only be + /// used with a GET or HEAD. + /// + /// When used in combination with If-None-Match, it is ignored, unless the + /// server doesn't support If-None-Match. + /// + /// The most common use case is to update a cached entity that has no + /// associated ETag. + (IfModifiedSince, IF_MODIFIED_SINCE, "if-modified-since"); + + /// Makes a request conditional based on the E-Tag. + /// + /// The If-None-Match HTTP request header makes the request conditional. For + /// GET and HEAD methods, the server will send back the requested resource, + /// with a 200 status, only if it doesn't have an ETag matching the given + /// ones. For other methods, the request will be processed only if the + /// eventually existing resource's ETag doesn't match any of the values + /// listed. + /// + /// When the condition fails for GET and HEAD methods, then the server must + /// return HTTP status code 304 (Not Modified). For methods that apply + /// server-side changes, the status code 412 (Precondition Failed) is used. + /// Note that the server generating a 304 response MUST generate any of the + /// following header fields that would have been sent in a 200 (OK) response + /// to the same request: Cache-Control, Content-Location, Date, ETag, + /// Expires, and Vary. + /// + /// The comparison with the stored ETag uses the weak comparison algorithm, + /// meaning two files are considered identical not only if they are + /// identical byte to byte, but if the content is equivalent. For example, + /// two pages that would differ only by the date of generation in the footer + /// would be considered as identical. + /// + /// When used in combination with If-Modified-Since, it has precedence (if + /// the server supports it). + /// + /// There are two common use cases: + /// + /// * For `GET` and `HEAD` methods, to update a cached entity that has an associated ETag. + /// * For other methods, and in particular for `PUT`, `If-None-Match` used with + /// the `*` value can be used to save a file not known to exist, + /// guaranteeing that another upload didn't happen before, losing the data + /// of the previous put; this problems is the variation of the lost update + /// problem. + (IfNoneMatch, IF_NONE_MATCH, "if-none-match"); + + /// Makes a request conditional based on range. + /// + /// The If-Range HTTP request header makes a range request conditional: if + /// the condition is fulfilled, the range request will be issued and the + /// server sends back a 206 Partial Content answer with the appropriate + /// body. If the condition is not fulfilled, the full resource is sent back, + /// with a 200 OK status. + /// + /// This header can be used either with a Last-Modified validator, or with + /// an ETag, but not with both. + /// + /// The most common use case is to resume a download, to guarantee that the + /// stored resource has not been modified since the last fragment has been + /// received. + (IfRange, IF_RANGE, "if-range"); + + /// Makes the request conditional based on the last modification date. + /// + /// The If-Unmodified-Since request HTTP header makes the request + /// conditional: the server will send back the requested resource, or accept + /// it in the case of a POST or another non-safe method, only if it has not + /// been last modified after the given date. If the request has been + /// modified after the given date, the response will be a 412 (Precondition + /// Failed) error. + /// + /// There are two common use cases: + /// + /// * In conjunction non-safe methods, like POST, it can be used to + /// implement an optimistic concurrency control, like done by some wikis: + /// editions are rejected if the stored document has been modified since the + /// original has been retrieved. + /// + /// * In conjunction with a range request with a If-Range header, it can be + /// used to ensure that the new fragment requested comes from an unmodified + /// document. + (IfUnmodifiedSince, IF_UNMODIFIED_SINCE, "if-unmodified-since"); + + /// Content-Types that are acceptable for the response. + (LastModified, LAST_MODIFIED, "last-modified"); + + /// Allows the server to point an interested client to another resource + /// containing metadata about the requested resource. + (Link, LINK, "link"); + + /// Indicates the URL to redirect a page to. + /// + /// The Location response header indicates the URL to redirect a page to. It + /// only provides a meaning when served with a 3xx status response. + /// + /// The HTTP method used to make the new request to fetch the page pointed + /// to by Location depends of the original method and of the kind of + /// redirection: + /// + /// * If 303 (See Also) responses always lead to the use of a GET method, + /// 307 (Temporary Redirect) and 308 (Permanent Redirect) don't change the + /// method used in the original request; + /// + /// * 301 (Permanent Redirect) and 302 (Found) doesn't change the method + /// most of the time, though older user-agents may (so you basically don't + /// know). + /// + /// All responses with one of these status codes send a Location header. + /// + /// Beside redirect response, messages with 201 (Created) status also + /// include the Location header. It indicates the URL to the newly created + /// resource. + /// + /// Location and Content-Location are different: Location indicates the + /// target of a redirection (or the URL of a newly created resource), while + /// Content-Location indicates the direct URL to use to access the resource + /// when content negotiation happened, without the need of further content + /// negotiation. Location is a header associated with the response, while + /// Content-Location is associated with the entity returned. + (Location, LOCATION, "location"); + + /// Indicates the max number of intermediaries the request should be sent + /// through. + (MaxForwards, MAX_FORWARDS, "max-forwards"); + + /// Indicates where a fetch originates from. + /// + /// It doesn't include any path information, but only the server name. It is + /// sent with CORS requests, as well as with POST requests. It is similar to + /// the Referer header, but, unlike this header, it doesn't disclose the + /// whole path. + (Origin, ORIGIN, "origin"); + + /// HTTP/1.0 header usually used for backwards compatibility. + /// + /// The Pragma HTTP/1.0 general header is an implementation-specific header + /// that may have various effects along the request-response chain. It is + /// used for backwards compatibility with HTTP/1.0 caches where the + /// Cache-Control HTTP/1.1 header is not yet present. + (Pragma, PRAGMA, "pragma"); + + /// Defines the authentication method that should be used to gain access to + /// a proxy. + /// + /// Unlike `www-authenticate`, the `proxy-authenticate` header field applies + /// only to the next outbound client on the response chain. This is because + /// only the client that chose a given proxy is likely to have the + /// credentials necessary for authentication. However, when multiple proxies + /// are used within the same administrative domain, such as office and + /// regional caching proxies within a large corporate network, it is common + /// for credentials to be generated by the user agent and passed through the + /// hierarchy until consumed. Hence, in such a configuration, it will appear + /// as if Proxy-Authenticate is being forwarded because each proxy will send + /// the same challenge set. + /// + /// The `proxy-authenticate` header is sent along with a `407 Proxy + /// Authentication Required`. + (ProxyAuthenticate, PROXY_AUTHENTICATE, "proxy-authenticate"); + + /// Contains the credentials to authenticate a user agent to a proxy server. + /// + /// This header is usually included after the server has responded with a + /// 407 Proxy Authentication Required status and the Proxy-Authenticate + /// header. + (ProxyAuthorization, PROXY_AUTHORIZATION, "proxy-authorization"); + + /// Associates a specific cryptographic public key with a certain server. + /// + /// This decreases the risk of MITM attacks with forged certificates. If one + /// or several keys are pinned and none of them are used by the server, the + /// browser will not accept the response as legitimate, and will not display + /// it. + (PublicKeyPins, PUBLIC_KEY_PINS, "public-key-pins"); + + /// Sends reports of pinning violation to the report-uri specified in the + /// header. + /// + /// Unlike `Public-Key-Pins`, this header still allows browsers to connect + /// to the server if the pinning is violated. + (PublicKeyPinsReportOnly, PUBLIC_KEY_PINS_REPORT_ONLY, "public-key-pins-report-only"); + + /// Indicates the part of a document that the server should return. + /// + /// Several parts can be requested with one Range header at once, and the + /// server may send back these ranges in a multipart document. If the server + /// sends back ranges, it uses the 206 Partial Content for the response. If + /// the ranges are invalid, the server returns the 416 Range Not Satisfiable + /// error. The server can also ignore the Range header and return the whole + /// document with a 200 status code. + (Range, RANGE, "range"); + + /// Contains the address of the previous web page from which a link to the + /// currently requested page was followed. + /// + /// The Referer header allows servers to identify where people are visiting + /// them from and may use that data for analytics, logging, or optimized + /// caching, for example. + (Referer, REFERER, "referer"); + + /// Governs which referrer information should be included with requests + /// made. + (ReferrerPolicy, REFERRER_POLICY, "referrer-policy"); + + /// Informs the web browser that the current page or frame should be + /// refreshed. + (Refresh, REFRESH, "refresh"); + + /// The Retry-After response HTTP header indicates how long the user agent + /// should wait before making a follow-up request. There are two main cases + /// this header is used: + /// + /// * When sent with a 503 (Service Unavailable) response, it indicates how + /// long the service is expected to be unavailable. + /// + /// * When sent with a redirect response, such as 301 (Moved Permanently), + /// it indicates the minimum time that the user agent is asked to wait + /// before issuing the redirected request. + (RetryAfter, RETRY_AFTER, "retry-after"); + + /// The |Sec-WebSocket-Accept| header field is used in the WebSocket + /// opening handshake. It is sent from the server to the client to + /// confirm that the server is willing to initiate the WebSocket + /// connection. + (SecWebSocketAccept, SEC_WEBSOCKET_ACCEPT, "sec-websocket-accept"); + + /// The |Sec-WebSocket-Extensions| header field is used in the WebSocket + /// opening handshake. It is initially sent from the client to the + /// server, and then subsequently sent from the server to the client, to + /// agree on a set of protocol-level extensions to use for the duration + /// of the connection. + (SecWebSocketExtensions, SEC_WEBSOCKET_EXTENSIONS, "sec-websocket-extensions"); + + /// The |Sec-WebSocket-Key| header field is used in the WebSocket opening + /// handshake. It is sent from the client to the server to provide part + /// of the information used by the server to prove that it received a + /// valid WebSocket opening handshake. This helps ensure that the server + /// does not accept connections from non-WebSocket clients (e.g., HTTP + /// clients) that are being abused to send data to unsuspecting WebSocket + /// servers. + (SecWebSocketKey, SEC_WEBSOCKET_KEY, "sec-websocket-key"); + + /// The |Sec-WebSocket-Protocol| header field is used in the WebSocket + /// opening handshake. It is sent from the client to the server and back + /// from the server to the client to confirm the subprotocol of the + /// connection. This enables scripts to both select a subprotocol and be + /// sure that the server agreed to serve that subprotocol. + (SecWebSocketProtocol, SEC_WEBSOCKET_PROTOCOL, "sec-websocket-protocol"); + + /// The |Sec-WebSocket-Version| header field is used in the WebSocket + /// opening handshake. It is sent from the client to the server to + /// indicate the protocol version of the connection. This enables + /// servers to correctly interpret the opening handshake and subsequent + /// data being sent from the data, and close the connection if the server + /// cannot interpret that data in a safe manner. + (SecWebSocketVersion, SEC_WEBSOCKET_VERSION, "sec-websocket-version"); + + /// Contains information about the software used by the origin server to + /// handle the request. + /// + /// Overly long and detailed Server values should be avoided as they + /// potentially reveal internal implementation details that might make it + /// (slightly) easier for attackers to find and exploit known security + /// holes. + (Server, SERVER, "server"); + + /// Used to send cookies from the server to the user agent. + (SetCookie, SET_COOKIE, "set-cookie"); + + /// Tells the client to communicate with HTTPS instead of using HTTP. + (StrictTransportSecurity, STRICT_TRANSPORT_SECURITY, "strict-transport-security"); + + /// Informs the server of transfer encodings willing to be accepted as part + /// of the response. + /// + /// See also the Transfer-Encoding response header for more details on + /// transfer encodings. Note that chunked is always acceptable for HTTP/1.1 + /// recipients and you that don't have to specify "chunked" using the TE + /// header. However, it is useful for setting if the client is accepting + /// trailer fields in a chunked transfer coding using the "trailers" value. + (Te, TE, "te"); + + /// Allows the sender to include additional fields at the end of chunked + /// messages. + (Trailer, TRAILER, "trailer"); + + /// Specifies the form of encoding used to safely transfer the entity to the + /// client. + /// + /// `transfer-encoding` is a hop-by-hop header, that is applying to a + /// message between two nodes, not to a resource itself. Each segment of a + /// multi-node connection can use different `transfer-encoding` values. If + /// you want to compress data over the whole connection, use the end-to-end + /// header `content-encoding` header instead. + /// + /// When present on a response to a `HEAD` request that has no body, it + /// indicates the value that would have applied to the corresponding `GET` + /// message. + (TransferEncoding, TRANSFER_ENCODING, "transfer-encoding"); + + /// Contains a string that allows identifying the requesting client's + /// software. + (UserAgent, USER_AGENT, "user-agent"); + + /// Used as part of the exchange to upgrade the protocol. + (Upgrade, UPGRADE, "upgrade"); + + /// Sends a signal to the server expressing the client’s preference for an + /// encrypted and authenticated response. + (UpgradeInsecureRequests, UPGRADE_INSECURE_REQUESTS, "upgrade-insecure-requests"); + + /// Determines how to match future requests with cached responses. + /// + /// The `vary` HTTP response header determines how to match future request + /// headers to decide whether a cached response can be used rather than + /// requesting a fresh one from the origin server. It is used by the server + /// to indicate which headers it used when selecting a representation of a + /// resource in a content negotiation algorithm. + /// + /// The `vary` header should be set on a 304 Not Modified response exactly + /// like it would have been set on an equivalent 200 OK response. + (Vary, VARY, "vary"); + + /// Added by proxies to track routing. + /// + /// The `via` general header is added by proxies, both forward and reverse + /// proxies, and can appear in the request headers and the response headers. + /// It is used for tracking message forwards, avoiding request loops, and + /// identifying the protocol capabilities of senders along the + /// request/response chain. + (Via, VIA, "via"); + + /// General HTTP header contains information about possible problems with + /// the status of the message. + /// + /// More than one `warning` header may appear in a response. Warning header + /// fields can in general be applied to any message, however some warn-codes + /// are specific to caches and can only be applied to response messages. + (Warning, WARNING, "warning"); + + /// Defines the authentication method that should be used to gain access to + /// a resource. + (WwwAuthenticate, WWW_AUTHENTICATE, "www-authenticate"); + + /// Marker used by the server to indicate that the MIME types advertised in + /// the `content-type` headers should not be changed and be followed. + /// + /// This allows to opt-out of MIME type sniffing, or, in other words, it is + /// a way to say that the webmasters knew what they were doing. + /// + /// This header was introduced by Microsoft in IE 8 as a way for webmasters + /// to block content sniffing that was happening and could transform + /// non-executable MIME types into executable MIME types. Since then, other + /// browsers have introduced it, even if their MIME sniffing algorithms were + /// less aggressive. + /// + /// Site security testers usually expect this header to be set. + (XContentTypeOptions, X_CONTENT_TYPE_OPTIONS, "x-content-type-options"); + + /// Controls DNS prefetching. + /// + /// The `x-dns-prefetch-control` HTTP response header controls DNS + /// prefetching, a feature by which browsers proactively perform domain name + /// resolution on both links that the user may choose to follow as well as + /// URLs for items referenced by the document, including images, CSS, + /// JavaScript, and so forth. + /// + /// This prefetching is performed in the background, so that the DNS is + /// likely to have been resolved by the time the referenced items are + /// needed. This reduces latency when the user clicks a link. + (XDnsPrefetchControl, X_DNS_PREFETCH_CONTROL, "x-dns-prefetch-control"); + + /// Indicates whether or not a browser should be allowed to render a page in + /// a frame. + /// + /// Sites can use this to avoid clickjacking attacks, by ensuring that their + /// content is not embedded into other sites. + /// + /// The added security is only provided if the user accessing the document + /// is using a browser supporting `x-frame-options`. + (XFrameOptions, X_FRAME_OPTIONS, "x-frame-options"); + + /// Stop pages from loading when an XSS attack is detected. + /// + /// The HTTP X-XSS-Protection response header is a feature of Internet + /// Explorer, Chrome and Safari that stops pages from loading when they + /// detect reflected cross-site scripting (XSS) attacks. Although these + /// protections are largely unnecessary in modern browsers when sites + /// implement a strong Content-Security-Policy that disables the use of + /// inline JavaScript ('unsafe-inline'), they can still provide protections + /// for users of older web browsers that don't yet support CSP. + (XXssProtection, X_XSS_PROTECTION, "x-xss-protection"); +} + +/// Valid header name characters +/// +/// ```not_rust +/// field-name = token +/// separators = "(" | ")" | "<" | ">" | "@" +/// | "," | ";" | ":" | "\" | <"> +/// | "/" | "[" | "]" | "?" | "=" +/// | "{" | "}" | SP | HT +/// token = 1*tchar +/// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +/// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +/// / DIGIT / ALPHA +/// ; any VCHAR, except delimiters +/// ``` +const HEADER_CHARS: [u8; 256] = [ + // 0 1 2 3 4 5 6 7 8 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 0, 0, 0, b'!', b'"', b'#', b'$', b'%', b'&', b'\'', // 3x + 0, 0, b'*', b'+', 0, b'-', b'.', 0, b'0', b'1', // 4x + b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', 0, 0, // 5x + 0, 0, 0, 0, 0, b'a', b'b', b'c', b'd', b'e', // 6x + b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', // 7x + b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', // 8x + b'z', 0, 0, 0, b'^', b'_', b'`', b'a', b'b', b'c', // 9x + b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x + b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x + b'x', b'y', b'z', 0, b'|', 0, b'~', 0, 0, 0, // 12x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x + 0, 0, 0, 0, 0, 0 // 25x +]; + +const HEADER_CHARS_H2: [u8; 256] = [ + // 0 1 2 3 4 5 6 7 8 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 0, 0, 0, b'!', b'"', b'#', b'$', b'%', b'&', b'\'', // 3x + 0, 0, b'*', b'+', 0, b'-', b'.', 0, b'0', b'1', // 4x + b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', 0, 0, // 5x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, b'^', b'_', b'`', b'a', b'b', b'c', // 9x + b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x + b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x + b'x', b'y', b'z', 0, b'|', 0, b'~', 0, 0, 0, // 12x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x + 0, 0, 0, 0, 0, 0 // 25x +]; + +macro_rules! eq { + (($($cmp:expr,)*) $v:ident[$n:expr] ==) => { + $($cmp) && * + }; + (($($cmp:expr,)*) $v:ident[$n:expr] == $a:tt $($rest:tt)*) => { + eq!(($($cmp,)* $v[$n] == $a,) $v[$n+1] == $($rest)*) + }; + ($v:ident == $($rest:tt)+) => { + eq!(() $v[0] == $($rest)+) + }; + ($v:ident[$n:expr] == $($rest:tt)+) => { + eq!(() $v[$n] == $($rest)+) + }; +} + +fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256]) + -> Result, InvalidHeaderName> +{ + use self::StandardHeader::*; + + let len = data.len(); + + let validate = |buf: &'a [u8], len: usize| { + let buf = &buf[..len]; + if buf.iter().any(|&b| b == 0) { + Err(InvalidHeaderName::new()) + } else { + Ok(HdrName::custom(buf, true)) + } + }; + + + macro_rules! to_lower { + ($d:ident, $src:ident, 1) => { $d[0] = table[$src[0] as usize]; }; + ($d:ident, $src:ident, 2) => { to_lower!($d, $src, 1); $d[1] = table[$src[1] as usize]; }; + ($d:ident, $src:ident, 3) => { to_lower!($d, $src, 2); $d[2] = table[$src[2] as usize]; }; + ($d:ident, $src:ident, 4) => { to_lower!($d, $src, 3); $d[3] = table[$src[3] as usize]; }; + ($d:ident, $src:ident, 5) => { to_lower!($d, $src, 4); $d[4] = table[$src[4] as usize]; }; + ($d:ident, $src:ident, 6) => { to_lower!($d, $src, 5); $d[5] = table[$src[5] as usize]; }; + ($d:ident, $src:ident, 7) => { to_lower!($d, $src, 6); $d[6] = table[$src[6] as usize]; }; + ($d:ident, $src:ident, 8) => { to_lower!($d, $src, 7); $d[7] = table[$src[7] as usize]; }; + ($d:ident, $src:ident, 9) => { to_lower!($d, $src, 8); $d[8] = table[$src[8] as usize]; }; + ($d:ident, $src:ident, 10) => { to_lower!($d, $src, 9); $d[9] = table[$src[9] as usize]; }; + ($d:ident, $src:ident, 11) => { to_lower!($d, $src, 10); $d[10] = table[$src[10] as usize]; }; + ($d:ident, $src:ident, 12) => { to_lower!($d, $src, 11); $d[11] = table[$src[11] as usize]; }; + ($d:ident, $src:ident, 13) => { to_lower!($d, $src, 12); $d[12] = table[$src[12] as usize]; }; + ($d:ident, $src:ident, 14) => { to_lower!($d, $src, 13); $d[13] = table[$src[13] as usize]; }; + ($d:ident, $src:ident, 15) => { to_lower!($d, $src, 14); $d[14] = table[$src[14] as usize]; }; + ($d:ident, $src:ident, 16) => { to_lower!($d, $src, 15); $d[15] = table[$src[15] as usize]; }; + ($d:ident, $src:ident, 17) => { to_lower!($d, $src, 16); $d[16] = table[$src[16] as usize]; }; + ($d:ident, $src:ident, 18) => { to_lower!($d, $src, 17); $d[17] = table[$src[17] as usize]; }; + ($d:ident, $src:ident, 19) => { to_lower!($d, $src, 18); $d[18] = table[$src[18] as usize]; }; + ($d:ident, $src:ident, 20) => { to_lower!($d, $src, 19); $d[19] = table[$src[19] as usize]; }; + ($d:ident, $src:ident, 21) => { to_lower!($d, $src, 20); $d[20] = table[$src[20] as usize]; }; + ($d:ident, $src:ident, 22) => { to_lower!($d, $src, 21); $d[21] = table[$src[21] as usize]; }; + ($d:ident, $src:ident, 23) => { to_lower!($d, $src, 22); $d[22] = table[$src[22] as usize]; }; + ($d:ident, $src:ident, 24) => { to_lower!($d, $src, 23); $d[23] = table[$src[23] as usize]; }; + ($d:ident, $src:ident, 25) => { to_lower!($d, $src, 24); $d[24] = table[$src[24] as usize]; }; + ($d:ident, $src:ident, 26) => { to_lower!($d, $src, 25); $d[25] = table[$src[25] as usize]; }; + ($d:ident, $src:ident, 27) => { to_lower!($d, $src, 26); $d[26] = table[$src[26] as usize]; }; + ($d:ident, $src:ident, 28) => { to_lower!($d, $src, 27); $d[27] = table[$src[27] as usize]; }; + ($d:ident, $src:ident, 29) => { to_lower!($d, $src, 28); $d[28] = table[$src[28] as usize]; }; + ($d:ident, $src:ident, 30) => { to_lower!($d, $src, 29); $d[29] = table[$src[29] as usize]; }; + ($d:ident, $src:ident, 31) => { to_lower!($d, $src, 30); $d[30] = table[$src[30] as usize]; }; + ($d:ident, $src:ident, 32) => { to_lower!($d, $src, 31); $d[31] = table[$src[31] as usize]; }; + ($d:ident, $src:ident, 33) => { to_lower!($d, $src, 32); $d[32] = table[$src[32] as usize]; }; + ($d:ident, $src:ident, 34) => { to_lower!($d, $src, 33); $d[33] = table[$src[33] as usize]; }; + ($d:ident, $src:ident, 35) => { to_lower!($d, $src, 34); $d[34] = table[$src[34] as usize]; }; + } + + assert!(len < super::MAX_HEADER_NAME_LEN, + "header name too long -- max length is {}", + super::MAX_HEADER_NAME_LEN); + + match len { + 0 => { + Err(InvalidHeaderName::new()) + } + 2 => { + to_lower!(b, data, 2); + + if eq!(b == b't' b'e') { + Ok(Te.into()) + } else { + validate(b, len) + } + } + 3 => { + to_lower!(b, data, 3); + + if eq!(b == b'a' b'g' b'e') { + Ok(Age.into()) + } else if eq!(b == b'v' b'i' b'a') { + Ok(Via.into()) + } else if eq!(b == b'd' b'n' b't') { + Ok(Dnt.into()) + } else { + validate(b, len) + } + } + 4 => { + to_lower!(b, data, 4); + + if eq!(b == b'd' b'a' b't' b'e') { + Ok(Date.into()) + } else if eq!(b == b'e' b't' b'a' b'g') { + Ok(Etag.into()) + } else if eq!(b == b'f' b'r' b'o' b'm') { + Ok(From.into()) + } else if eq!(b == b'h' b'o' b's' b't') { + Ok(Host.into()) + } else if eq!(b == b'l' b'i' b'n' b'k') { + Ok(Link.into()) + } else if eq!(b == b'v' b'a' b'r' b'y') { + Ok(Vary.into()) + } else { + validate(b, len) + } + } + 5 => { + to_lower!(b, data, 5); + + if eq!(b == b'a' b'l' b'l' b'o' b'w') { + Ok(Allow.into()) + } else if eq!(b == b'r' b'a' b'n' b'g' b'e') { + Ok(Range.into()) + } else { + validate(b, len) + } + } + 6 => { + to_lower!(b, data, 6); + + if eq!(b == b'a' b'c' b'c' b'e' b'p' b't') { + return Ok(Accept.into()) + } else if eq!(b == b'c' b'o' b'o' b'k' b'i' b'e') { + return Ok(Cookie.into()) + } else if eq!(b == b'e' b'x' b'p' b'e' b'c' b't') { + return Ok(Expect.into()) + } else if eq!(b == b'o' b'r' b'i' b'g' b'i' b'n') { + return Ok(Origin.into()) + } else if eq!(b == b'p' b'r' b'a' b'g' b'm' b'a') { + return Ok(Pragma.into()) + } else if b[0] == b's' { + if eq!(b[1] == b'e' b'r' b'v' b'e' b'r') { + return Ok(Server.into()) + } + } + + validate(b, len) + } + 7 => { + to_lower!(b, data, 7); + + if eq!(b == b'a' b'l' b't' b'-' b's' b'v' b'c') { + Ok(AltSvc.into()) + } else if eq!(b == b'e' b'x' b'p' b'i' b'r' b'e' b's') { + Ok(Expires.into()) + } else if eq!(b == b'r' b'e' b'f' b'e' b'r' b'e' b'r') { + Ok(Referer.into()) + } else if eq!(b == b'r' b'e' b'f' b'r' b'e' b's' b'h') { + Ok(Refresh.into()) + } else if eq!(b == b't' b'r' b'a' b'i' b'l' b'e' b'r') { + Ok(Trailer.into()) + } else if eq!(b == b'u' b'p' b'g' b'r' b'a' b'd' b'e') { + Ok(Upgrade.into()) + } else if eq!(b == b'w' b'a' b'r' b'n' b'i' b'n' b'g') { + Ok(Warning.into()) + } else { + validate(b, len) + } + } + 8 => { + to_lower!(b, data, 8); + + if eq!(b == b'i' b'f' b'-') { + if eq!(b[3] == b'm' b'a' b't' b'c' b'h') { + return Ok(IfMatch.into()) + } else if eq!(b[3] == b'r' b'a' b'n' b'g' b'e') { + return Ok(IfRange.into()) + } + } else if eq!(b == b'l' b'o' b'c' b'a' b't' b'i' b'o' b'n') { + return Ok(Location.into()) + } + + validate(b, len) + } + 9 => { + to_lower!(b, data, 9); + + if eq!(b == b'f' b'o' b'r' b'w' b'a' b'r' b'd' b'e' b'd') { + Ok(Forwarded.into()) + } else { + validate(b, len) + } + } + 10 => { + to_lower!(b, data, 10); + + if eq!(b == b'c' b'o' b'n' b'n' b'e' b'c' b't' b'i' b'o' b'n') { + Ok(Connection.into()) + } else if eq!(b == b's' b'e' b't' b'-' b'c' b'o' b'o' b'k' b'i' b'e') { + Ok(SetCookie.into()) + } else if eq!(b == b'u' b's' b'e' b'r' b'-' b'a' b'g' b'e' b'n' b't') { + Ok(UserAgent.into()) + } else { + validate(b, len) + } + } + 11 => { + to_lower!(b, data, 11); + + if eq!(b == b'r' b'e' b't' b'r' b'y' b'-' b'a' b'f' b't' b'e' b'r') { + Ok(RetryAfter.into()) + } else { + validate(b, len) + } + } + 12 => { + to_lower!(b, data, 12); + + if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b't' b'y' b'p' b'e') { + Ok(ContentType.into()) + } else if eq!(b == b'm' b'a' b'x' b'-' b'f' b'o' b'r' b'w' b'a' b'r' b'd' b's') { + Ok(MaxForwards.into()) + } else { + validate(b, len) + } + } + 13 => { + to_lower!(b, data, 13); + + if b[0] == b'a' { + if eq!(b[1] == b'c' b'c' b'e' b'p' b't' b'-' b'r' b'a' b'n' b'g' b'e' b's') { + return Ok(AcceptRanges.into()) + } else if eq!(b[1] == b'u' b't' b'h' b'o' b'r' b'i' b'z' b'a' b't' b'i' b'o' b'n') { + return Ok(Authorization.into()) + } + } else if b[0] == b'c' { + if eq!(b[1] == b'a' b'c' b'h' b'e' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l') { + return Ok(CacheControl.into()) + } else if eq!(b[1] == b'o' b'n' b't' b'e' b'n' b't' b'-' b'r' b'a' b'n' b'g' b'e' ) { + return Ok(ContentRange.into()) + } + } else if eq!(b == b'i' b'f' b'-' b'n' b'o' b'n' b'e' b'-' b'm' b'a' b't' b'c' b'h') { + return Ok(IfNoneMatch.into()) + } else if eq!(b == b'l' b'a' b's' b't' b'-' b'm' b'o' b'd' b'i' b'f' b'i' b'e' b'd') { + return Ok(LastModified.into()) + } + + validate(b, len) + } + 14 => { + to_lower!(b, data, 14); + + if eq!(b == b'a' b'c' b'c' b'e' b'p' b't' b'-' b'c' b'h' b'a' b'r' b's' b'e' b't') { + Ok(AcceptCharset.into()) + } else if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b'l' b'e' b'n' b'g' b't' b'h') { + Ok(ContentLength.into()) + } else { + validate(b, len) + } + } + 15 => { + to_lower!(b, data, 15); + + if eq!(b == b'a' b'c' b'c' b'e' b'p' b't' b'-') { // accept- + if eq!(b[7] == b'e' b'n' b'c' b'o' b'd' b'i' b'n' b'g') { + return Ok(AcceptEncoding.into()) + } else if eq!(b[7] == b'l' b'a' b'n' b'g' b'u' b'a' b'g' b'e') { + return Ok(AcceptLanguage.into()) + } + } else if eq!(b == b'p' b'u' b'b' b'l' b'i' b'c' b'-' b'k' b'e' b'y' b'-' b'p' b'i' b'n' b's') { + return Ok(PublicKeyPins.into()) + } else if eq!(b == b'x' b'-' b'f' b'r' b'a' b'm' b'e' b'-' b'o' b'p' b't' b'i' b'o' b'n' b's') { + return Ok(XFrameOptions.into()) + } + else if eq!(b == b'r' b'e' b'f' b'e' b'r' b'r' b'e' b'r' b'-' b'p' b'o' b'l' b'i' b'c' b'y') { + return Ok(ReferrerPolicy.into()) + } + + validate(b, len) + } + 16 => { + to_lower!(b, data, 16); + + if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-') { + if eq!(b[8] == b'l' b'a' b'n' b'g' b'u' b'a' b'g' b'e') { + return Ok(ContentLanguage.into()) + } else if eq!(b[8] == b'l' b'o' b'c' b'a' b't' b'i' b'o' b'n') { + return Ok(ContentLocation.into()) + } else if eq!(b[8] == b'e' b'n' b'c' b'o' b'd' b'i' b'n' b'g') { + return Ok(ContentEncoding.into()) + } + } else if eq!(b == b'w' b'w' b'w' b'-' b'a' b'u' b't' b'h' b'e' b'n' b't' b'i' b'c' b'a' b't' b'e') { + return Ok(WwwAuthenticate.into()) + } else if eq!(b == b'x' b'-' b'x' b's' b's' b'-' b'p' b'r' b'o' b't' b'e' b'c' b't' b'i' b'o' b'n') { + return Ok(XXssProtection.into()) + } + + validate(b, len) + } + 17 => { + to_lower!(b, data, 17); + + if eq!(b == b't' b'r' b'a' b'n' b's' b'f' b'e' b'r' b'-' b'e' b'n' b'c' b'o' b'd' b'i' b'n' b'g') { + Ok(TransferEncoding.into()) + } else if eq!(b == b'i' b'f' b'-' b'm' b'o' b'd' b'i' b'f' b'i' b'e' b'd' b'-' b's' b'i' b'n' b'c' b'e') { + Ok(IfModifiedSince.into()) + } else if eq!(b == b's' b'e' b'c' b'-' b'w' b'e' b'b' b's' b'o' b'c' b'k' b'e' b't' b'-' b'k' b'e' b'y') { + Ok(SecWebSocketKey.into()) + } else { + validate(b, len) + } + } + 18 => { + to_lower!(b, data, 18); + + if eq!(b == b'p' b'r' b'o' b'x' b'y' b'-' b'a' b'u' b't' b'h' b'e' b'n' b't' b'i' b'c' b'a' b't' b'e') { + Ok(ProxyAuthenticate.into()) + } else { + validate(b, len) + } + } + 19 => { + to_lower!(b, data, 19); + + if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b'd' b'i' b's' b'p' b'o' b's' b'i' b't' b'i' b'o' b'n') { + Ok(ContentDisposition.into()) + } else if eq!(b == b'i' b'f' b'-' b'u' b'n' b'm' b'o' b'd' b'i' b'f' b'i' b'e' b'd' b'-' b's' b'i' b'n' b'c' b'e') { + Ok(IfUnmodifiedSince.into()) + } else if eq!(b == b'p' b'r' b'o' b'x' b'y' b'-' b'a' b'u' b't' b'h' b'o' b'r' b'i' b'z' b'a' b't' b'i' b'o' b'n') { + Ok(ProxyAuthorization.into()) + } else { + validate(b, len) + } + } + 20 => { + to_lower!(b, data, 20); + + if eq!(b == b's' b'e' b'c' b'-' b'w' b'e' b'b' b's' b'o' b'c' b'k' b'e' b't' b'-' b'a' b'c' b'c' b'e' b'p' b't') { + Ok(SecWebSocketAccept.into()) + } else { + validate(b, len) + } + } + 21 => { + to_lower!(b, data, 21); + + if eq!(b == b's' b'e' b'c' b'-' b'w' b'e' b'b' b's' b'o' b'c' b'k' b'e' b't' b'-' b'v' b'e' b'r' b's' b'i' b'o' b'n') { + Ok(SecWebSocketVersion.into()) + } else { + validate(b, len) + } + } + 22 => { + to_lower!(b, data, 22); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-' b'm' b'a' b'x' b'-' b'a' b'g' b'e') { + Ok(AccessControlMaxAge.into()) + } else if eq!(b == b'x' b'-' b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b't' b'y' b'p' b'e' b'-' b'o' b'p' b't' b'i' b'o' b'n' b's') { + Ok(XContentTypeOptions.into()) + } else if eq!(b == b'x' b'-' b'd' b'n' b's' b'-' b'p' b'r' b'e' b'f' b'e' b't' b'c' b'h' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l') { + Ok(XDnsPrefetchControl.into()) + } else if eq!(b == b's' b'e' b'c' b'-' b'w' b'e' b'b' b's' b'o' b'c' b'k' b'e' b't' b'-' b'p' b'r' b'o' b't' b'o' b'c' b'o' b'l') { + Ok(SecWebSocketProtocol.into()) + } else { + validate(b, len) + } + } + 23 => { + to_lower!(b, data, 23); + + if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b's' b'e' b'c' b'u' b'r' b'i' b't' b'y' b'-' b'p' b'o' b'l' b'i' b'c' b'y') { + Ok(ContentSecurityPolicy.into()) + } else { + validate(b, len) + } + } + 24 => { + to_lower!(b, data, 24); + + if eq!(b == b's' b'e' b'c' b'-' b'w' b'e' b'b' b's' b'o' b'c' b'k' b'e' b't' b'-' b'e' b'x' b't' b'e' b'n' b's' b'i' b'o' b'n' b's') { + Ok(SecWebSocketExtensions.into()) + } else { + validate(b, len) + } + } + 25 => { + to_lower!(b, data, 25); + + if eq!(b == b's' b't' b'r' b'i' b'c' b't' b'-' b't' b'r' b'a' b'n' b's' b'p' b'o' b'r' b't' b'-' b's' b'e' b'c' b'u' b'r' b'i' b't' b'y') { + Ok(StrictTransportSecurity.into()) + } else if eq!(b == b'u' b'p' b'g' b'r' b'a' b'd' b'e' b'-' b'i' b'n' b's' b'e' b'c' b'u' b'r' b'e' b'-' b'r' b'e' b'q' b'u' b'e' b's' b't' b's') { + Ok(UpgradeInsecureRequests.into()) + } else { + validate(b, len) + } + } + 27 => { + to_lower!(b, data, 27); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-' b'a' b'l' b'l' b'o' b'w' b'-' b'o' b'r' b'i' b'g' b'i' b'n') { + Ok(AccessControlAllowOrigin.into()) + } else if eq!(b == b'p' b'u' b'b' b'l' b'i' b'c' b'-' b'k' b'e' b'y' b'-' b'p' b'i' b'n' b's' b'-' b'r' b'e' b'p' b'o' b'r' b't' b'-' b'o' b'n' b'l' b'y') { + Ok(PublicKeyPinsReportOnly.into()) + } else { + validate(b, len) + } + } + 28 => { + to_lower!(b, data, 28); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-' b'a' b'l' b'l' b'o' b'w' b'-') { + if eq!(b[21] == b'h' b'e' b'a' b'd' b'e' b'r' b's') { + return Ok(AccessControlAllowHeaders.into()) + } else if eq!(b[21] == b'm' b'e' b't' b'h' b'o' b'd' b's') { + return Ok(AccessControlAllowMethods.into()) + } + } + + validate(b, len) + } + 29 => { + to_lower!(b, data, 29); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-') { + if eq!(b[15] == b'e' b'x' b'p' b'o' b's' b'e' b'-' b'h' b'e' b'a' b'd' b'e' b'r' b's') { + return Ok(AccessControlExposeHeaders.into()) + } else if eq!(b[15] == b'r' b'e' b'q' b'u' b'e' b's' b't' b'-' b'm' b'e' b't' b'h' b'o' b'd') { + return Ok(AccessControlRequestMethod.into()) + } + } + + validate(b, len) + } + 30 => { + to_lower!(b, data, 30); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-' b'r' b'e' b'q' b'u' b'e' b's' b't' b'-' b'h' b'e' b'a' b'd' b'e' b'r' b's') { + Ok(AccessControlRequestHeaders.into()) + } else { + validate(b, len) + } + } + 32 => { + to_lower!(b, data, 32); + + if eq!(b == b'a' b'c' b'c' b'e' b's' b's' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l' b'-' b'a' b'l' b'l' b'o' b'w' b'-' b'c' b'r' b'e' b'd' b'e' b'n' b't' b'i' b'a' b'l' b's') { + Ok(AccessControlAllowCredentials.into()) + } else { + validate(b, len) + } + } + 35 => { + to_lower!(b, data, 35); + + if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b's' b'e' b'c' b'u' b'r' b'i' b't' b'y' b'-' b'p' b'o' b'l' b'i' b'c' b'y' b'-' b'r' b'e' b'p' b'o' b'r' b't' b'-' b'o' b'n' b'l' b'y') { + Ok(ContentSecurityPolicyReportOnly.into()) + } else { + validate(b, len) + } + } + _ => { + if len < 64 { + for i in 0..len { + b[i] = table[data[i] as usize]; + } + + validate(b, len) + } else { + Ok(HdrName::custom(data, false)) + } + } + } +} + +impl<'a> From for HdrName<'a> { + fn from(hdr: StandardHeader) -> HdrName<'a> { + HdrName { inner: Repr::Standard(hdr) } + } +} + +impl HeaderName { + /// Converts a slice of bytes to an HTTP header name. + /// + /// This function normalizes the input. + pub fn from_bytes(src: &[u8]) -> Result { + let mut buf = unsafe { mem::uninitialized() }; + match parse_hdr(src, &mut buf, &HEADER_CHARS)?.inner { + Repr::Standard(std) => Ok(std.into()), + Repr::Custom(MaybeLower { buf, lower: true }) => { + let buf = Bytes::from(buf); + let val = unsafe { ByteStr::from_utf8_unchecked(buf) }; + Ok(Custom(val).into()) + } + Repr::Custom(MaybeLower { buf, lower: false }) => { + use bytes::{BufMut}; + let mut dst = BytesMut::with_capacity(buf.len()); + + for b in buf.iter() { + let b = HEADER_CHARS[*b as usize]; + + if b == 0 { + return Err(InvalidHeaderName::new()); + } + + dst.put(b); + } + + let val = unsafe { ByteStr::from_utf8_unchecked(dst.freeze()) }; + + Ok(Custom(val).into()) + } + } + } + + /// Converts a slice of bytes to an HTTP header name. + /// + /// This function expects the input to only contain lowercase characters. + /// This is useful when decoding HTTP/2.0 headers. The HTTP/2.0 + /// specification requires that all headers be represented in lower case. + /// + /// # Examples + /// + /// ``` + /// # use http::header::*; + /// + /// // Parsing a lower case header + /// let hdr = HeaderName::from_lowercase(b"content-length").unwrap(); + /// assert_eq!(CONTENT_LENGTH, hdr); + /// + /// // Parsing a header that contains uppercase characters + /// assert!(HeaderName::from_lowercase(b"Content-Length").is_err()); + /// ``` + pub fn from_lowercase(src: &[u8]) -> Result { + let mut buf = unsafe { mem::uninitialized() }; + match parse_hdr(src, &mut buf, &HEADER_CHARS_H2)?.inner { + Repr::Standard(std) => Ok(std.into()), + Repr::Custom(MaybeLower { buf, lower: true }) => { + let buf = Bytes::from(buf); + let val = unsafe { ByteStr::from_utf8_unchecked(buf) }; + Ok(Custom(val).into()) + } + Repr::Custom(MaybeLower { buf, lower: false }) => { + for &b in buf.iter() { + if b != HEADER_CHARS[b as usize] { + return Err(InvalidHeaderName::new()); + } + } + + let buf = Bytes::from(buf); + let val = unsafe { ByteStr::from_utf8_unchecked(buf) }; + Ok(Custom(val).into()) + } + } + } + + /// Converts a static string to a HTTP header name. + /// + /// This function panics when the static string is a invalid header. + /// + /// This function requires the static string to only contain lowercase + /// characters, numerals and symbols, as per the HTTP/2.0 specification + /// and header names internal representation within this library. + /// + /// + /// # Examples + /// + /// ``` + /// # use http::header::*; + /// // Parsing a standard header + /// let hdr = HeaderName::from_static("content-length"); + /// assert_eq!(CONTENT_LENGTH, hdr); + /// + /// // Parsing a custom header + /// let CUSTOM_HEADER: &'static str = "custom-header"; + /// + /// let a = HeaderName::from_lowercase(b"custom-header").unwrap(); + /// let b = HeaderName::from_static(CUSTOM_HEADER); + /// assert_eq!(a, b); + /// ``` + /// + /// ```should_panic + /// # use http::header::*; + /// # + /// // Parsing a header that contains invalid symbols(s): + /// HeaderName::from_static("content{}{}length"); // This line panics! + /// + /// // Parsing a header that contains invalid uppercase characters. + /// let a = HeaderName::from_static("foobar"); + /// let b = HeaderName::from_static("FOOBAR"); // This line panics! + /// ``` + pub fn from_static(src: &'static str) -> HeaderName { + let bytes = src.as_bytes(); + let mut buf = unsafe { mem::uninitialized() }; + match parse_hdr(bytes, &mut buf, &HEADER_CHARS_H2) { + Ok(hdr_name) => match hdr_name.inner { + Repr::Standard(std) => std.into(), + Repr::Custom(MaybeLower { buf: _, lower: true }) => { + let val = ByteStr::from_static(src); + Custom(val).into() + }, + Repr::Custom(MaybeLower { buf: _, lower: false }) => { + // With lower false, the string is left unchecked by + // parse_hdr and must be validated manually. + for &b in bytes.iter() { + if HEADER_CHARS_H2[b as usize] == 0 { + panic!("invalid header name") + } + } + + let val = ByteStr::from_static(src); + Custom(val).into() + } + }, + + Err(_) => panic!("invalid header name") + } + } + + /// Returns a `str` representation of the header. + /// + /// The returned string will always be lower case. + #[inline] + pub fn as_str(&self) -> &str { + match self.inner { + Repr::Standard(v) => v.as_str(), + Repr::Custom(ref v) => &*v.0, + } + } +} + +impl FromStr for HeaderName { + type Err = InvalidHeaderName; + + fn from_str(s: &str) -> Result { + HeaderName::from_bytes(s.as_bytes()) + .map_err(|_| InvalidHeaderName { + _priv: (), + }) + } +} + +impl AsRef for HeaderName { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl AsRef<[u8]> for HeaderName { + fn as_ref(&self) -> &[u8] { + self.as_str().as_bytes() + } +} + +impl Borrow for HeaderName { + fn borrow(&self) -> &str { + self.as_str() + } +} + +impl fmt::Debug for HeaderName { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_str(), fmt) + } +} + +impl fmt::Display for HeaderName { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self.as_str(), fmt) + } +} + +impl InvalidHeaderName { + fn new() -> InvalidHeaderName { + InvalidHeaderName { _priv: () } + } +} + +impl<'a> From<&'a HeaderName> for HeaderName { + fn from(src: &'a HeaderName) -> HeaderName { + src.clone() + } +} + +#[doc(hidden)] +impl From> for Bytes +where T: Into { + fn from(repr: Repr) -> Bytes { + match repr { + Repr::Standard(header) => + Bytes::from_static(header.as_str().as_bytes()), + Repr::Custom(header) => header.into() + } + } +} + +impl From for Bytes { + #[inline] + fn from(Custom(inner): Custom) -> Bytes { + Bytes::from(inner) + } +} + +impl From for Bytes { + #[inline] + fn from(name: HeaderName) -> Bytes { + name.inner.into() + } +} + +impl<'a> HttpTryFrom<&'a HeaderName> for HeaderName { + type Error = ::error::Never; + + #[inline] + fn try_from(t: &'a HeaderName) -> Result { + Ok(t.clone()) + } +} + +impl<'a> HttpTryFrom<&'a str> for HeaderName { + type Error = InvalidHeaderName; + #[inline] + fn try_from(s: &'a str) -> Result { + Self::from_bytes(s.as_bytes()) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for HeaderName { + type Error = InvalidHeaderName; + #[inline] + fn try_from(s: &'a [u8]) -> Result { + Self::from_bytes(s) + } +} + +impl HttpTryFrom for HeaderName { + type Error = InvalidHeaderNameBytes; + #[inline] + fn try_from(bytes: Bytes) -> Result { + Self::from_bytes(bytes.as_ref()).map_err(InvalidHeaderNameBytes) + } +} + +#[doc(hidden)] +impl From for HeaderName { + fn from(src: StandardHeader) -> HeaderName { + HeaderName { + inner: Repr::Standard(src), + } + } +} + +#[doc(hidden)] +impl From for HeaderName { + fn from(src: Custom) -> HeaderName { + HeaderName { inner: Repr::Custom(src) } + } +} + +impl<'a> PartialEq<&'a HeaderName> for HeaderName { + #[inline] + fn eq(&self, other: &&'a HeaderName) -> bool { + *self == **other + } +} + + +impl<'a> PartialEq for &'a HeaderName { + #[inline] + fn eq(&self, other: &HeaderName) -> bool { + *other == *self + } +} + +impl PartialEq for HeaderName { + /// Performs a case-insensitive comparison of the string against the header + /// name + /// + /// # Examples + /// + /// ``` + /// use http::header::CONTENT_LENGTH; + /// + /// assert_eq!(CONTENT_LENGTH, "content-length"); + /// assert_eq!(CONTENT_LENGTH, "Content-Length"); + /// assert_ne!(CONTENT_LENGTH, "content length"); + /// ``` + #[inline] + fn eq(&self, other: &str) -> bool { + eq_ignore_ascii_case(self.as_ref(), other.as_bytes()) + } +} + + +impl PartialEq for str { + /// Performs a case-insensitive comparison of the string against the header + /// name + /// + /// # Examples + /// + /// ``` + /// use http::header::CONTENT_LENGTH; + /// + /// assert_eq!(CONTENT_LENGTH, "content-length"); + /// assert_eq!(CONTENT_LENGTH, "Content-Length"); + /// assert_ne!(CONTENT_LENGTH, "content length"); + /// ``` + #[inline] + fn eq(&self, other: &HeaderName) -> bool { + *other == *self + } +} + +impl<'a> PartialEq<&'a str> for HeaderName { + /// Performs a case-insensitive comparison of the string against the header + /// name + #[inline] + fn eq(&self, other: &&'a str) -> bool { + *self == **other + } +} + + +impl<'a> PartialEq for &'a str { + /// Performs a case-insensitive comparison of the string against the header + /// name + #[inline] + fn eq(&self, other: &HeaderName) -> bool { + *other == *self + } +} + +impl fmt::Display for InvalidHeaderName { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.description().fmt(f) + } +} + +impl Error for InvalidHeaderName { + fn description(&self) -> &str { + "invalid HTTP header name" + } +} + +impl fmt::Display for InvalidHeaderNameBytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Error for InvalidHeaderNameBytes { + fn description(&self) -> &str { + self.0.description() + } +} + +// ===== HdrName ===== + +impl<'a> HdrName<'a> { + fn custom(buf: &'a [u8], lower: bool) -> HdrName<'a> { + HdrName { + inner: Repr::Custom(MaybeLower { + buf: buf, + lower: lower, + }), + } + } + + pub fn from_bytes(hdr: &[u8], f: F) -> Result + where F: FnOnce(HdrName) -> U, + { + let mut buf = unsafe { mem::uninitialized() }; + let hdr = parse_hdr(hdr, &mut buf, &HEADER_CHARS)?; + Ok(f(hdr)) + } + + pub fn from_static(hdr: &'static str, f: F) -> U + where F: FnOnce(HdrName) -> U, + { + let mut buf = unsafe { mem::uninitialized() }; + let hdr = parse_hdr(hdr.as_bytes(), &mut buf, &HEADER_CHARS) + .expect("static str is invalid name"); + f(hdr) + } +} + +#[doc(hidden)] +impl<'a> From> for HeaderName { + fn from(src: HdrName<'a>) -> HeaderName { + match src.inner { + Repr::Standard(s) => { + HeaderName { + inner: Repr::Standard(s), + } + } + Repr::Custom(maybe_lower) => { + if maybe_lower.lower { + let buf = Bytes::from(&maybe_lower.buf[..]); + let byte_str = unsafe { ByteStr::from_utf8_unchecked(buf) }; + + HeaderName { + inner: Repr::Custom(Custom(byte_str)), + } + } else { + use bytes::{BufMut}; + let mut dst = BytesMut::with_capacity(maybe_lower.buf.len()); + + for b in maybe_lower.buf.iter() { + dst.put(HEADER_CHARS[*b as usize]); + } + + let buf = unsafe { ByteStr::from_utf8_unchecked(dst.freeze()) }; + + HeaderName { + inner: Repr::Custom(Custom(buf)), + } + } + } + } + } +} + +#[doc(hidden)] +impl<'a> PartialEq> for HeaderName { + #[inline] + fn eq(&self, other: &HdrName<'a>) -> bool { + match self.inner { + Repr::Standard(a) => { + match other.inner { + Repr::Standard(b) => a == b, + _ => false, + } + } + Repr::Custom(Custom(ref a)) => { + match other.inner { + Repr::Custom(ref b) => { + if b.lower { + a.as_bytes() == b.buf + } else { + eq_ignore_ascii_case(a.as_bytes(), b.buf) + } + } + _ => false, + } + } + } + } +} + +// ===== Custom ===== + +impl Hash for Custom { + #[inline] + fn hash(&self, hasher: &mut H) { + hasher.write(self.0.as_bytes()) + } +} + +// ===== MaybeLower ===== + +impl<'a> Hash for MaybeLower<'a> { + #[inline] + fn hash(&self, hasher: &mut H) { + if self.lower { + hasher.write(self.buf); + } else { + for &b in self.buf { + hasher.write(&[HEADER_CHARS[b as usize]]); + } + } + } +} + +// Assumes that the left hand side is already lower case +#[inline] +fn eq_ignore_ascii_case(lower: &[u8], s: &[u8]) -> bool { + if lower.len() != s.len() { + return false; + } + + lower.iter().zip(s).all(|(a, b)| { + *a == HEADER_CHARS[*b as usize] + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use self::StandardHeader::Vary; + + #[test] + fn test_bounds() { + fn check_bounds() {} + check_bounds::(); + } + + #[test] + fn test_parse_invalid_headers() { + for i in 0..128 { + let hdr = vec![1u8; i]; + assert!(HeaderName::from_bytes(&hdr).is_err(), "{} invalid header chars did not fail", i); + } + } + + #[test] + fn test_from_hdr_name() { + use self::StandardHeader::Vary; + + let name = HeaderName::from(HdrName { + inner: Repr::Standard(Vary), + }); + + assert_eq!(name.inner, Repr::Standard(Vary)); + + let name = HeaderName::from(HdrName { + inner: Repr::Custom(MaybeLower { + buf: b"hello-world", + lower: true, + }), + }); + + assert_eq!(name.inner, Repr::Custom(Custom(ByteStr::from_static("hello-world")))); + + let name = HeaderName::from(HdrName { + inner: Repr::Custom(MaybeLower { + buf: b"Hello-World", + lower: false, + }), + }); + + assert_eq!(name.inner, Repr::Custom(Custom(ByteStr::from_static("hello-world")))); + } + + #[test] + fn test_eq_hdr_name() { + use self::StandardHeader::Vary; + + let a = HeaderName { inner: Repr::Standard(Vary) }; + let b = HdrName { inner: Repr::Standard(Vary) }; + + assert_eq!(a, b); + + let a = HeaderName { inner: Repr::Custom(Custom(ByteStr::from_static("vaary"))) }; + assert_ne!(a, b); + + let b = HdrName { inner: Repr::Custom(MaybeLower { + buf: b"vaary", + lower: true, + })}; + + assert_eq!(a, b); + + let b = HdrName { inner: Repr::Custom(MaybeLower { + buf: b"vaary", + lower: false, + })}; + + assert_eq!(a, b); + + let b = HdrName { inner: Repr::Custom(MaybeLower { + buf: b"VAARY", + lower: false, + })}; + + assert_eq!(a, b); + + let a = HeaderName { inner: Repr::Standard(Vary) }; + assert_ne!(a, b); + } + + #[test] + fn test_from_static_std() { + let a = HeaderName { inner: Repr::Standard(Vary) }; + + let b = HeaderName::from_static("vary"); + assert_eq!(a, b); + + let b = HeaderName::from_static("vaary"); + assert_ne!(a, b); + } + + #[test] + #[should_panic] + fn test_from_static_std_uppercase() { + HeaderName::from_static("Vary"); + } + + #[test] + #[should_panic] + fn test_from_static_std_symbol() { + HeaderName::from_static("vary{}"); + } + + // MaybeLower { lower: true } + #[test] + fn test_from_static_custom_short() { + let a = HeaderName { inner: Repr::Custom(Custom(ByteStr::from_static("customheader"))) }; + let b = HeaderName::from_static("customheader"); + assert_eq!(a, b); + } + + #[test] + #[should_panic] + fn test_from_static_custom_short_uppercase() { + HeaderName::from_static("custom header"); + } + + #[test] + #[should_panic] + fn test_from_static_custom_short_symbol() { + HeaderName::from_static("CustomHeader"); + } + + // MaybeLower { lower: false } + #[test] + fn test_from_static_custom_long() { + let a = HeaderName { inner: Repr::Custom(Custom(ByteStr::from_static( + "longer-than-63--thisheaderislongerthansixtythreecharactersandthushandleddifferent" + ))) }; + let b = HeaderName::from_static( + "longer-than-63--thisheaderislongerthansixtythreecharactersandthushandleddifferent" + ); + assert_eq!(a, b); + } + + #[test] + #[should_panic] + fn test_from_static_custom_long_uppercase() { + HeaderName::from_static( + "Longer-Than-63--ThisHeaderIsLongerThanSixtyThreeCharactersAndThusHandledDifferent" + ); + } + + #[test] + #[should_panic] + fn test_from_static_custom_long_symbol() { + HeaderName::from_static( + "longer-than-63--thisheader{}{}{}{}islongerthansixtythreecharactersandthushandleddifferent" + ); + } + + #[test] + fn test_from_static_custom_single_char() { + let a = HeaderName { inner: Repr::Custom(Custom(ByteStr::from_static("a"))) }; + let b = HeaderName::from_static("a"); + assert_eq!(a, b); + } + + #[test] + #[should_panic] + fn test_from_static_empty() { + HeaderName::from_static(""); + } + + #[test] + fn test_all_tokens() { + HeaderName::from_static("!#$%&'*+-.^_`|~0123456789abcdefghijklmnopqrstuvwxyz"); + } +} diff -Nru cargo-0.33.0/vendor/http/src/header/value.rs cargo-0.35.0/vendor/http/src/header/value.rs --- cargo-0.33.0/vendor/http/src/header/value.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/header/value.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,797 @@ +use bytes::{Bytes, BytesMut}; + +use std::{cmp, fmt, mem, str}; +use std::error::Error; +use std::str::FromStr; + +use ::convert::HttpTryFrom; +use ::error::Never; +use header::name::HeaderName; + +/// Represents an HTTP header field value. +/// +/// In practice, HTTP header field values are usually valid ASCII. However, the +/// HTTP spec allows for a header value to contain opaque bytes as well. In this +/// case, the header field value is not able to be represented as a string. +/// +/// To handle this, the `HeaderValue` is useable as a type and can be compared +/// with strings and implements `Debug`. A `to_str` fn is provided that returns +/// an `Err` if the header value contains non visible ascii characters. +#[derive(Clone, Hash)] +pub struct HeaderValue { + inner: Bytes, + is_sensitive: bool, +} + +/// A possible error when converting a `HeaderValue` from a string or byte +/// slice. +#[derive(Debug)] +pub struct InvalidHeaderValue { + _priv: (), +} + +/// A possible error when converting a `HeaderValue` from a string or byte +/// slice. +#[derive(Debug)] +pub struct InvalidHeaderValueBytes(InvalidHeaderValue); + +/// A possible error when converting a `HeaderValue` to a string representation. +/// +/// Header field values may contain opaque bytes, in which case it is not +/// possible to represent the value as a string. +#[derive(Debug)] +pub struct ToStrError { + _priv: (), +} + +impl HeaderValue { + /// Convert a static string to a `HeaderValue`. + /// + /// This function will not perform any copying, however the string is + /// checked to ensure that no invalid characters are present. Only visible + /// ASCII characters (32-127) are permitted. + /// + /// # Panics + /// + /// This function panics if the argument contains invalid header value + /// characters. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_static("hello"); + /// assert_eq!(val, "hello"); + /// ``` + #[inline] + pub fn from_static(src: &'static str) -> HeaderValue { + let bytes = src.as_bytes(); + for &b in bytes { + if !is_visible_ascii(b) { + panic!("invalid header value"); + } + } + + HeaderValue { + inner: Bytes::from_static(bytes), + is_sensitive: false, + } + } + + /// Attempt to convert a string to a `HeaderValue`. + /// + /// If the argument contains invalid header value characters, an error is + /// returned. Only visible ASCII characters (32-127) are permitted. Use + /// `from_bytes` to create a `HeaderValue` that includes opaque octets + /// (128-255). + /// + /// This function is intended to be replaced in the future by a `TryFrom` + /// implementation once the trait is stabilized in std. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_str("hello").unwrap(); + /// assert_eq!(val, "hello"); + /// ``` + /// + /// An invalid value + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_str("\n"); + /// assert!(val.is_err()); + /// ``` + #[inline] + pub fn from_str(src: &str) -> Result { + HeaderValue::try_from(src) + } + + /// Converts a HeaderName into a HeaderValue + /// + /// Since every valid HeaderName is a valid HeaderValue this is done infallibly. + /// + /// # Examples + /// + /// ``` + /// # use http::header::{HeaderValue, HeaderName}; + /// # use http::header::ACCEPT; + /// let val = HeaderValue::from_name(ACCEPT); + /// assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap()); + /// ``` + #[inline] + pub fn from_name(name: HeaderName) -> HeaderValue { + name.into() + } + + /// Attempt to convert a byte slice to a `HeaderValue`. + /// + /// If the argument contains invalid header value bytes, an error is + /// returned. Only byte values between 32 and 255 (inclusive) are permitted, + /// excluding byte 127 (DEL). + /// + /// This function is intended to be replaced in the future by a `TryFrom` + /// implementation once the trait is stabilized in std. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_bytes(b"hello\xfa").unwrap(); + /// assert_eq!(val, &b"hello\xfa"[..]); + /// ``` + /// + /// An invalid value + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_bytes(b"\n"); + /// assert!(val.is_err()); + /// ``` + #[inline] + pub fn from_bytes(src: &[u8]) -> Result { + HeaderValue::try_from(src) + } + + /// Attempt to convert a `Bytes` buffer to a `HeaderValue`. + /// + /// If the argument contains invalid header value bytes, an error is + /// returned. Only byte values between 32 and 255 (inclusive) are permitted, + /// excluding byte 127 (DEL). + /// + /// This function is intended to be replaced in the future by a `TryFrom` + /// implementation once the trait is stabilized in std. + #[inline] + pub fn from_shared(src: Bytes) -> Result { + HeaderValue::try_from(src).map_err(InvalidHeaderValueBytes) + } + + /// Convert a `Bytes` directly into a `HeaderValue` without validating. + /// + /// This function does NOT validate that illegal bytes are not contained + /// within the buffer. + #[inline] + pub unsafe fn from_shared_unchecked(src: Bytes) -> HeaderValue { + if cfg!(debug_assertions) { + match HeaderValue::from_shared(src) { + Ok(val) => val, + Err(_err) => { + //TODO: if the Bytes were part of the InvalidHeaderValueBytes, + //this message could include the invalid bytes. + panic!("HeaderValue::from_shared_unchecked() with invalid bytes"); + }, + } + } else { + HeaderValue { + inner: src, + is_sensitive: false, + } + } + } + + fn try_from + Into>(src: T) -> Result { + for &b in src.as_ref() { + if !is_valid(b) { + return Err(InvalidHeaderValue { + _priv: (), + }); + } + } + Ok(HeaderValue { + inner: src.into(), + is_sensitive: false, + }) + } + + /// Yields a `&str` slice if the `HeaderValue` only contains visible ASCII + /// chars. + /// + /// This function will perform a scan of the header value, checking all the + /// characters. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_static("hello"); + /// assert_eq!(val.to_str().unwrap(), "hello"); + /// ``` + pub fn to_str(&self) -> Result<&str, ToStrError> { + let bytes = self.as_ref(); + + for &b in bytes { + if !is_visible_ascii(b) { + return Err(ToStrError { _priv: () }); + } + } + + unsafe { Ok(str::from_utf8_unchecked(bytes)) } + } + + /// Returns the length of `self`. + /// + /// This length is in bytes. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_static("hello"); + /// assert_eq!(val.len(), 5); + /// ``` + #[inline] + pub fn len(&self) -> usize { + self.as_ref().len() + } + + /// Returns true if the `HeaderValue` has a length of zero bytes. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_static(""); + /// assert!(val.is_empty()); + /// + /// let val = HeaderValue::from_static("hello"); + /// assert!(!val.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Converts a `HeaderValue` to a byte slice. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let val = HeaderValue::from_static("hello"); + /// assert_eq!(val.as_bytes(), b"hello"); + /// ``` + #[inline] + pub fn as_bytes(&self) -> &[u8] { + self.as_ref() + } + + /// Mark that the header value represents sensitive information. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let mut val = HeaderValue::from_static("my secret"); + /// + /// val.set_sensitive(true); + /// assert!(val.is_sensitive()); + /// + /// val.set_sensitive(false); + /// assert!(!val.is_sensitive()); + /// ``` + #[inline] + pub fn set_sensitive(&mut self, val: bool) { + self.is_sensitive = val; + } + + /// Returns `true` if the value represents sensitive data. + /// + /// Sensitive data could represent passwords or other data that should not + /// be stored on disk or in memory. This setting can be used by components + /// like caches to avoid storing the value. HPACK encoders must set the + /// header field to never index when `is_sensitive` returns true. + /// + /// Note that sensitivity is not factored into equality or ordering. + /// + /// # Examples + /// + /// ``` + /// # use http::header::HeaderValue; + /// let mut val = HeaderValue::from_static("my secret"); + /// + /// val.set_sensitive(true); + /// assert!(val.is_sensitive()); + /// + /// val.set_sensitive(false); + /// assert!(!val.is_sensitive()); + /// ``` + #[inline] + pub fn is_sensitive(&self) -> bool { + self.is_sensitive + } +} + +impl AsRef<[u8]> for HeaderValue { + #[inline] + fn as_ref(&self) -> &[u8] { + self.inner.as_ref() + } +} + +impl fmt::Debug for HeaderValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.is_sensitive { + f.write_str("Sensitive") + } else { + f.write_str("\"")?; + let mut from = 0; + let bytes = self.as_bytes(); + for (i, &b) in bytes.iter().enumerate() { + if !is_visible_ascii(b) || b == b'"' { + if from != i { + f.write_str(unsafe { + str::from_utf8_unchecked(&bytes[from..i]) + })?; + } + if b == b'"' { + f.write_str("\\\"")?; + } else { + write!(f, "\\x{:x}", b)?; + } + from = i + 1; + } + } + + f.write_str(unsafe { + str::from_utf8_unchecked(&bytes[from..]) + })?; + f.write_str("\"") + } + } +} + +impl From for HeaderValue { + #[inline] + fn from(h: HeaderName) -> HeaderValue { + HeaderValue { + inner: h.into(), + is_sensitive: false, + } + } +} + +macro_rules! from_integers { + ($($name:ident: $t:ident => $max_len:expr),*) => {$( + impl From<$t> for HeaderValue { + fn from(num: $t) -> HeaderValue { + let mut buf = if mem::size_of::() - 1 < $max_len { + // On 32bit platforms, BytesMut max inline size + // is 15 bytes, but the $max_len could be bigger. + // + // The likelihood of the number *actually* being + // that big is very small, so only allocate + // if the number needs that space. + // + // The largest decimal number in 15 digits: + // It wold be 10.pow(15) - 1, but this is a constant + // version. + if num as u64 > 999_999_999_999_999_999 { + BytesMut::with_capacity($max_len) + } else { + // fits inline... + BytesMut::new() + } + } else { + // full value fits inline, so don't allocate! + BytesMut::new() + }; + let _ = ::itoa::fmt(&mut buf, num); + HeaderValue { + inner: buf.freeze(), + is_sensitive: false, + } + } + } + + impl HttpTryFrom<$t> for HeaderValue { + type Error = Never; + + #[inline] + fn try_from(num: $t) -> Result { + Ok(num.into()) + } + } + + #[test] + fn $name() { + let n: $t = 55; + let val = HeaderValue::from(n); + assert_eq!(val, &n.to_string()); + + let n = ::std::$t::MAX; + let val = HeaderValue::from(n); + assert_eq!(val, &n.to_string()); + } + )*}; +} + +from_integers! { + // integer type => maximum decimal length + + // u8 purposely left off... HeaderValue::from(b'3') could be confusing + from_u16: u16 => 5, + from_i16: i16 => 6, + from_u32: u32 => 10, + from_i32: i32 => 11, + from_u64: u64 => 20, + from_i64: i64 => 20 +} + +#[cfg(target_pointer_width = "16")] +from_integers! { + from_usize: usize => 5, + from_isize: isize => 6 +} + +#[cfg(target_pointer_width = "32")] +from_integers! { + from_usize: usize => 10, + from_isize: isize => 11 +} + +#[cfg(target_pointer_width = "64")] +from_integers! { + from_usize: usize => 20, + from_isize: isize => 20 +} + +#[cfg(test)] +mod from_header_name_tests { + use super::*; + use header::map::HeaderMap; + use header::name; + + #[test] + fn it_can_insert_header_name_as_header_value() { + let mut map = HeaderMap::new(); + map.insert(name::UPGRADE, name::SEC_WEBSOCKET_PROTOCOL.into()); + map.insert(name::ACCEPT, name::HeaderName::from_bytes(b"hello-world").unwrap().into()); + + assert_eq!( + map.get(name::UPGRADE).unwrap(), + HeaderValue::from_bytes(b"sec-websocket-protocol").unwrap() + ); + + assert_eq!( + map.get(name::ACCEPT).unwrap(), + HeaderValue::from_bytes(b"hello-world").unwrap() + ); + } +} + +impl FromStr for HeaderValue { + type Err = InvalidHeaderValue; + + #[inline] + fn from_str(s: &str) -> Result { + HeaderValue::from_str(s) + } +} + +impl From for Bytes { + #[inline] + fn from(value: HeaderValue) -> Bytes { + value.inner + } +} + +impl<'a> From<&'a HeaderValue> for HeaderValue { + #[inline] + fn from(t: &'a HeaderValue) -> Self { + t.clone() + } +} + +impl<'a> HttpTryFrom<&'a HeaderValue> for HeaderValue { + type Error = ::error::Never; + + #[inline] + fn try_from(t: &'a HeaderValue) -> Result { + Ok(t.clone()) + } +} + +impl<'a> HttpTryFrom<&'a str> for HeaderValue { + type Error = InvalidHeaderValue; + + #[inline] + fn try_from(t: &'a str) -> Result { + t.parse() + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for HeaderValue { + type Error = InvalidHeaderValue; + + #[inline] + fn try_from(t: &'a [u8]) -> Result { + HeaderValue::from_bytes(t) + } +} + +impl HttpTryFrom for HeaderValue { + type Error = InvalidHeaderValueBytes; + + #[inline] + fn try_from(t: String) -> Result { + HeaderValue::from_shared(t.into()) + } +} + +impl HttpTryFrom for HeaderValue { + type Error = InvalidHeaderValueBytes; + + #[inline] + fn try_from(bytes: Bytes) -> Result { + HeaderValue::from_shared(bytes) + } +} + +impl HttpTryFrom for HeaderValue { + type Error = InvalidHeaderValue; + + #[inline] + fn try_from(name: HeaderName) -> Result { + // Infallable as header names have the same validations + Ok(name.into()) + } +} + +#[cfg(test)] +mod try_from_header_name_tests { + use super::*; + use header::name; + + #[test] + fn it_converts_using_try_from() { + assert_eq!( + HeaderValue::try_from(name::UPGRADE).unwrap(), + HeaderValue::from_bytes(b"upgrade").unwrap() + ); + } +} + +fn is_visible_ascii(b: u8) -> bool { + b >= 32 && b < 127 || b == b'\t' +} + +#[inline] +fn is_valid(b: u8) -> bool { + b >= 32 && b != 127 || b == b'\t' +} + +impl fmt::Display for InvalidHeaderValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.description().fmt(f) + } +} + +impl Error for InvalidHeaderValue { + fn description(&self) -> &str { + "failed to parse header value" + } +} + +impl fmt::Display for InvalidHeaderValueBytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Error for InvalidHeaderValueBytes { + fn description(&self) -> &str { + self.0.description() + } +} + +impl fmt::Display for ToStrError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.description().fmt(f) + } +} + +impl Error for ToStrError { + fn description(&self) -> &str { + "failed to convert header to a str" + } +} + +// ===== PartialEq / PartialOrd ===== + +impl PartialEq for HeaderValue { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + self.inner == other.inner + } +} + +impl Eq for HeaderValue {} + +impl PartialOrd for HeaderValue { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + self.inner.partial_cmp(&other.inner) + } +} + +impl Ord for HeaderValue { + #[inline] + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.inner.cmp(&other.inner) + } +} + +impl PartialEq for HeaderValue { + #[inline] + fn eq(&self, other: &str) -> bool { + self.inner == other.as_bytes() + } +} + +impl PartialEq<[u8]> for HeaderValue { + #[inline] + fn eq(&self, other: &[u8]) -> bool { + self.inner == other + } +} + +impl PartialOrd for HeaderValue { + #[inline] + fn partial_cmp(&self, other: &str) -> Option { + (*self.inner).partial_cmp(other.as_bytes()) + } +} + +impl PartialOrd<[u8]> for HeaderValue { + #[inline] + fn partial_cmp(&self, other: &[u8]) -> Option { + (*self.inner).partial_cmp(other) + } +} + +impl PartialEq for str { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + *other == *self + } +} + +impl PartialEq for [u8] { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + *other == *self + } +} + +impl PartialOrd for str { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + self.as_bytes().partial_cmp(other.as_bytes()) + } +} + +impl PartialOrd for [u8] { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + self.partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for HeaderValue { + #[inline] + fn eq(&self, other: &String) -> bool { + *self == &other[..] + } +} + +impl PartialOrd for HeaderValue { + #[inline] + fn partial_cmp(&self, other: &String) -> Option { + self.inner.partial_cmp(other.as_bytes()) + } +} + +impl PartialEq for String { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + *other == *self + } +} + +impl PartialOrd for String { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + self.as_bytes().partial_cmp(other.as_bytes()) + } +} + +impl<'a> PartialEq for &'a HeaderValue { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + **self == *other + } +} + +impl<'a> PartialOrd for &'a HeaderValue { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + (**self).partial_cmp(other) + } +} + +impl<'a, T: ?Sized> PartialEq<&'a T> for HeaderValue + where HeaderValue: PartialEq +{ + #[inline] + fn eq(&self, other: &&'a T) -> bool { + *self == **other + } +} + +impl<'a, T: ?Sized> PartialOrd<&'a T> for HeaderValue + where HeaderValue: PartialOrd +{ + #[inline] + fn partial_cmp(&self, other: &&'a T) -> Option { + self.partial_cmp(*other) + } +} + +impl<'a> PartialEq for &'a str { + #[inline] + fn eq(&self, other: &HeaderValue) -> bool { + *other == *self + } +} + +impl<'a> PartialOrd for &'a str { + #[inline] + fn partial_cmp(&self, other: &HeaderValue) -> Option { + self.as_bytes().partial_cmp(other.as_bytes()) + } +} + +#[test] +fn test_try_from() { + HeaderValue::try_from(vec![127]).unwrap_err(); +} + +#[test] +fn test_debug() { + let cases = &[ + ("hello", "\"hello\""), + ("hello \"world\"", "\"hello \\\"world\\\"\""), + ("\u{7FFF}hello", "\"\\xe7\\xbf\\xbfhello\""), + ]; + + for &(value, expected) in cases { + let val = HeaderValue::from_bytes(value.as_bytes()).unwrap(); + let actual = format!("{:?}", val); + assert_eq!(expected, actual); + } + + let mut sensitive = HeaderValue::from_static("password"); + sensitive.set_sensitive(true); + assert_eq!("Sensitive", format!("{:?}", sensitive)); +} diff -Nru cargo-0.33.0/vendor/http/src/lib.rs cargo-0.35.0/vendor/http/src/lib.rs --- cargo-0.33.0/vendor/http/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,206 @@ +#![doc(html_root_url = "https://docs.rs/http/0.1.17")] + +//! A general purpose library of common HTTP types +//! +//! This crate is a general purpose library for common types found when working +//! with the HTTP protocol. You'll find `Request` and `Response` types for +//! working as either a client or a server as well as all of their components. +//! Notably you'll find `Uri` for what a `Request` is requesting, a `Method` +//! for how it's being requested, a `StatusCode` for what sort of response came +//! back, a `Version` for how this was communicated, and +//! `HeaderName`/`HeaderValue` definitions to get grouped in a `HeaderMap` to +//! work with request/response headers. +//! +//! You will notably *not* find an implementation of sending requests or +//! spinning up a server in this crate. It's intended that this crate is the +//! "standard library" for HTTP clients and servers without dictating any +//! particular implementation. Note that this crate is still early on in its +//! lifecycle so the support libraries that integrate with the `http` crate are +//! a work in progress! Stay tuned and we'll be sure to highlight crates here +//! in the future. +//! +//! ## Requests and Responses +//! +//! Perhaps the main two types in this crate are the `Request` and `Response` +//! types. A `Request` could either be constructed to get sent off as a client +//! or it can also be received to generate a `Response` for a server. Similarly +//! as a client a `Response` is what you get after sending a `Request`, whereas +//! on a server you'll be manufacturing a `Response` to send back to the client. +//! +//! Each type has a number of accessors for the component fields. For as a +//! server you might want to inspect a requests URI to dispatch it: +//! +//! ``` +//! use http::{Request, Response}; +//! +//! fn response(req: Request<()>) -> http::Result> { +//! match req.uri().path() { +//! "/" => index(req), +//! "/foo" => foo(req), +//! "/bar" => bar(req), +//! _ => not_found(req), +//! } +//! } +//! # fn index(_req: Request<()>) -> http::Result> { panic!() } +//! # fn foo(_req: Request<()>) -> http::Result> { panic!() } +//! # fn bar(_req: Request<()>) -> http::Result> { panic!() } +//! # fn not_found(_req: Request<()>) -> http::Result> { panic!() } +//! ``` +//! +//! On a `Request` you'll also find accessors like `method` to return a +//! `Method` and `headers` to inspect the various headers. A `Response` +//! has similar methods for headers, the status code, etc. +//! +//! In addition to getters, request/response types also have mutable accessors +//! to edit the request/response: +//! +//! ``` +//! use http::{Response, StatusCode}; +//! use http::header::{CONTENT_TYPE, HeaderValue}; +//! +//! fn add_server_headers(response: &mut Response) { +//! response.headers_mut() +//! .insert(CONTENT_TYPE, HeaderValue::from_static("text/html")); +//! *response.status_mut() = StatusCode::OK; +//! } +//! ``` +//! +//! And finally, one of the most important aspects of requests/responses, the +//! body! The `Request` and `Response` types in this crate are *generic* in +//! what their body is. This allows downstream libraries to use different +//! representations such as `Request>`, `Response`, +//! `Request, Error = _>>`, or even +//! `Response` where the custom type was deserialized from JSON. +//! +//! The body representation is intentionally flexible to give downstream +//! libraries maximal flexibility in implementing the body as appropriate. +//! +//! ## HTTP Headers +//! +//! Another major piece of functionality in this library is HTTP header +//! interpretation and generation. The `HeaderName` type serves as a way to +//! define header *names*, or what's to the left of the colon. A `HeaderValue` +//! conversely is the header *value*, or what's to the right of a colon. +//! +//! For example, if you have an HTTP request that looks like: +//! +//! ```http +//! GET /foo HTTP/1.1 +//! Accept: text/html +//! ``` +//! +//! Then `"Accept"` is a `HeaderName` while `"text/html"` is a `HeaderValue`. +//! Each of these is a dedicated type to allow for a number of interesting +//! optimizations and to also encode the static guarantees of each type. For +//! example a `HeaderName` is always a valid `&str`, but a `HeaderValue` may +//! not be valid UTF-8. +//! +//! The most common header names are already defined for you as constant values +//! in the `header` module of this crate. For example: +//! +//! ``` +//! use http::header::{self, HeaderName}; +//! +//! let name: HeaderName = header::ACCEPT; +//! assert_eq!(name.as_str(), "accept"); +//! ``` +//! +//! You can, however, also parse header names from strings: +//! +//! ``` +//! use http::header::{self, HeaderName}; +//! +//! let name = "Accept".parse::().unwrap(); +//! assert_eq!(name, header::ACCEPT); +//! ``` +//! +//! Header values can be created from string literals through the `from_static` +//! function: +//! +//! ``` +//! use http::header::HeaderValue; +//! +//! let value = HeaderValue::from_static("text/html"); +//! assert_eq!(value.as_bytes(), b"text/html"); +//! ``` +//! +//! And header values can also be parsed like names: +//! +//! ``` +//! use http::header::HeaderValue; +//! +//! let value = "text/html"; +//! let value = value.parse::().unwrap(); +//! ``` +//! +//! Most HTTP requests and responses tend to come with more than one header, so +//! it's not too useful to just work with names and values only! This crate also +//! provides a `HeaderMap` type which is a specialized hash map for keys as +//! `HeaderName` and generic values. This type, like header names, is optimized +//! for common usage but should continue to scale with your needs over time. +//! +//! # URIs +//! +//! Each HTTP `Request` has an associated URI with it. This may just be a path +//! like `/index.html` but it could also be an absolute URL such as +//! `https://www.rust-lang.org/index.html`. A `URI` has a number of accessors to +//! interpret it: +//! +//! ``` +//! use http::Uri; +//! +//! let uri = "https://www.rust-lang.org/index.html".parse::().unwrap(); +//! +//! assert_eq!(uri.scheme(), Some("https")); +//! assert_eq!(uri.host(), Some("www.rust-lang.org")); +//! assert_eq!(uri.path(), "/index.html"); +//! assert_eq!(uri.query(), None); +//! ``` + +#![deny(warnings, missing_docs, missing_debug_implementations)] + +extern crate bytes; +extern crate fnv; +extern crate itoa; + +pub mod header; +pub mod method; +pub mod request; +pub mod response; +pub mod status; +pub mod version; +pub mod uri; + +mod byte_str; +mod convert; +mod error; +mod extensions; + +pub use convert::HttpTryFrom; +pub use error::{Error, Result}; +pub use extensions::Extensions; +#[doc(no_inline)] +pub use header::HeaderMap; +pub use method::Method; +pub use request::Request; +pub use response::Response; +pub use status::StatusCode; +pub use uri::Uri; +pub use version::Version; + +fn _assert_types() { + fn assert_send() {} + fn assert_sync() {} + + assert_send::>(); + assert_send::>(); + + assert_sync::>(); + assert_sync::>(); +} + +mod sealed { + /// Private trait to this crate to prevent traits from being implemented in + /// downstream crates. + pub trait Sealed {} +} diff -Nru cargo-0.33.0/vendor/http/src/method.rs cargo-0.35.0/vendor/http/src/method.rs --- cargo-0.33.0/vendor/http/src/method.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/method.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,422 @@ +//! The HTTP request method +//! +//! This module contains HTTP-method related structs and errors and such. The +//! main type of this module, `Method`, is also reexported at the root of the +//! crate as `http::Method` and is intended for import through that location +//! primarily. +//! +//! # Examples +//! +//! ``` +//! use http::Method; +//! +//! assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap()); +//! assert!(Method::GET.is_idempotent()); +//! assert_eq!(Method::POST.as_str(), "POST"); +//! ``` + +use HttpTryFrom; +use self::Inner::*; + +use std::{fmt, str}; +use std::convert::AsRef; +use std::error::Error; +use std::str::FromStr; + +/// The Request Method (VERB) +/// +/// This type also contains constants for a number of common HTTP methods such +/// as GET, POST, etc. +/// +/// Currently includes 8 variants representing the 8 methods defined in +/// [RFC 7230](https://tools.ietf.org/html/rfc7231#section-4.1), plus PATCH, +/// and an Extension variant for all extensions. +/// +/// # Examples +/// +/// ``` +/// use http::Method; +/// +/// assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap()); +/// assert!(Method::GET.is_idempotent()); +/// assert_eq!(Method::POST.as_str(), "POST"); +/// ``` +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct Method(Inner); + +/// A possible error value when converting `Method` from bytes. +#[derive(Debug)] +pub struct InvalidMethod { + _priv: (), +} + +#[derive(Clone, PartialEq, Eq, Hash)] +enum Inner { + Options, + Get, + Post, + Put, + Delete, + Head, + Trace, + Connect, + Patch, + // If the extension is short enough, store it inline + ExtensionInline([u8; MAX_INLINE], u8), + // Otherwise, allocate it + ExtensionAllocated(Box<[u8]>), +} + +const MAX_INLINE: usize = 15; + +// From the HTTP spec section 5.1.1, the HTTP method is case-sensitive and can +// contain the following characters: +// +// ``` +// method = token +// token = 1*tchar +// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / +// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA +// ``` +// +// https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#Method +// +const METHOD_CHARS: [u8; 256] = [ + // 0 1 2 3 4 5 6 7 8 9 + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 1x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 2x + b'\0', b'\0', b'\0', b'!', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 3x + b'\0', b'\0', b'*', b'+', b'\0', b'-', b'.', b'\0', b'0', b'1', // 4x + b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'\0', b'\0', // 5x + b'\0', b'\0', b'\0', b'\0', b'\0', b'A', b'B', b'C', b'D', b'E', // 6x + b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x + b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x + b'Z', b'\0', b'\0', b'\0', b'^', b'_', b'`', b'a', b'b', b'c', // 9x + b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x + b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x + b'x', b'y', b'z', b'\0', b'|', b'\0', b'~', b'\0', b'\0', b'\0', // 12x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 13x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 14x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 15x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 16x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 17x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 18x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 19x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 20x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 21x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 22x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 23x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', b'\0', // 24x + b'\0', b'\0', b'\0', b'\0', b'\0', b'\0' // 25x +]; + + +impl Method { + /// GET + pub const GET: Method = Method(Get); + + /// POST + pub const POST: Method = Method(Post); + + /// PUT + pub const PUT: Method = Method(Put); + + /// DELETE + pub const DELETE: Method = Method(Delete); + + /// HEAD + pub const HEAD: Method = Method(Head); + + /// OPTIONS + pub const OPTIONS: Method = Method(Options); + + /// CONNECT + pub const CONNECT: Method = Method(Connect); + + /// PATCH + pub const PATCH: Method = Method(Patch); + + /// TRACE + pub const TRACE: Method = Method(Trace); + + /// Converts a slice of bytes to an HTTP method. + pub fn from_bytes(src: &[u8]) -> Result { + match src.len() { + 0 => { + Err(InvalidMethod::new()) + } + 3 => { + match src { + b"GET" => Ok(Method(Get)), + b"PUT" => Ok(Method(Put)), + _ => Method::extension_inline(src), + } + } + 4 => { + match src { + b"POST" => Ok(Method(Post)), + b"HEAD" => Ok(Method(Head)), + _ => Method::extension_inline(src), + } + } + 5 => { + match src { + b"PATCH" => Ok(Method(Patch)), + b"TRACE" => Ok(Method(Trace)), + _ => Method::extension_inline(src), + } + } + 6 => { + match src { + b"DELETE" => Ok(Method(Delete)), + _ => Method::extension_inline(src), + } + } + 7 => { + match src { + b"OPTIONS" => Ok(Method(Options)), + b"CONNECT" => Ok(Method(Connect)), + _ => Method::extension_inline(src), + } + } + _ => { + if src.len() < MAX_INLINE { + Method::extension_inline(src) + } else { + let mut data: Vec = vec![0; src.len()]; + + write_checked(src, &mut data)?; + + Ok(Method(ExtensionAllocated(data.into_boxed_slice()))) + } + } + } + } + + fn extension_inline(src: &[u8]) -> Result { + let mut data: [u8; MAX_INLINE] = Default::default(); + + write_checked(src, &mut data)?; + + Ok(Method(ExtensionInline(data, src.len() as u8))) + } + + /// Whether a method is considered "safe", meaning the request is + /// essentially read-only. + /// + /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.1) + /// for more words. + pub fn is_safe(&self) -> bool { + match self.0 { + Get | Head | Options | Trace => true, + _ => false + } + } + + /// Whether a method is considered "idempotent", meaning the request has + /// the same result if executed multiple times. + /// + /// See [the spec](https://tools.ietf.org/html/rfc7231#section-4.2.2) for + /// more words. + pub fn is_idempotent(&self) -> bool { + if self.is_safe() { + true + } else { + match self.0 { + Put | Delete => true, + _ => false + } + } + } + + /// Return a &str representation of the HTTP method + #[inline] + pub fn as_str(&self) -> &str { + match self.0 { + Options => "OPTIONS", + Get => "GET", + Post => "POST", + Put => "PUT", + Delete => "DELETE", + Head => "HEAD", + Trace => "TRACE", + Connect => "CONNECT", + Patch => "PATCH", + ExtensionInline(ref data, len) => { + unsafe { + str::from_utf8_unchecked(&data[..len as usize]) + } + } + ExtensionAllocated(ref data) => { + unsafe { + str::from_utf8_unchecked(data) + } + } + } + } +} + +fn write_checked(src: &[u8], dst: &mut [u8]) -> Result<(), InvalidMethod> { + for (i, &b) in src.iter().enumerate() { + let b = METHOD_CHARS[b as usize]; + + if b == 0 { + return Err(InvalidMethod::new()); + } + + dst[i] = b; + } + + Ok(()) +} + +impl AsRef for Method { + #[inline] + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl<'a> PartialEq<&'a Method> for Method { + #[inline] + fn eq(&self, other: & &'a Method) -> bool { + self == *other + } +} + +impl<'a> PartialEq for &'a Method { + #[inline] + fn eq(&self, other: &Method) -> bool { + *self == other + } +} + +impl PartialEq for Method { + #[inline] + fn eq(&self, other: &str) -> bool { + self.as_ref() == other + } +} + +impl PartialEq for str { + #[inline] + fn eq(&self, other: &Method) -> bool { + self == other.as_ref() + } +} + +impl<'a> PartialEq<&'a str> for Method { + #[inline] + fn eq(&self, other: &&'a str) -> bool { + self.as_ref() == *other + } +} + +impl<'a> PartialEq for &'a str { + #[inline] + fn eq(&self, other: &Method) -> bool { + *self == other.as_ref() + } +} + +impl fmt::Debug for Method { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_ref()) + } +} + +impl fmt::Display for Method { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str(self.as_ref()) + } +} + +impl Default for Method { + #[inline] + fn default() -> Method { + Method::GET + } +} + +impl<'a> From<&'a Method> for Method { + #[inline] + fn from(t: &'a Method) -> Self { + t.clone() + } +} + +impl<'a> HttpTryFrom<&'a Method> for Method { + type Error = ::error::Never; + + #[inline] + fn try_from(t: &'a Method) -> Result { + Ok(t.clone()) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for Method { + type Error = InvalidMethod; + + #[inline] + fn try_from(t: &'a [u8]) -> Result { + Method::from_bytes(t) + } +} + +impl<'a> HttpTryFrom<&'a str> for Method { + type Error = InvalidMethod; + + #[inline] + fn try_from(t: &'a str) -> Result { + HttpTryFrom::try_from(t.as_bytes()) + } +} + +impl FromStr for Method { + type Err = InvalidMethod; + + #[inline] + fn from_str(t: &str) -> Result { + HttpTryFrom::try_from(t) + } +} + +impl InvalidMethod { + fn new() -> InvalidMethod { + InvalidMethod { + _priv: (), + } + } +} + +impl fmt::Display for InvalidMethod { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.description()) + } +} + +impl Error for InvalidMethod { + fn description(&self) -> &str { + "invalid HTTP method" + } +} + +#[test] +fn test_method_eq() { + assert_eq!(Method::GET, Method::GET); + assert_eq!(Method::GET, "GET"); + assert_eq!(&Method::GET, "GET"); + + assert_eq!("GET", Method::GET); + assert_eq!("GET", &Method::GET); + + assert_eq!(&Method::GET, Method::GET); + assert_eq!(Method::GET, &Method::GET); +} + +#[test] +fn test_invalid_method() { + assert!(Method::from_str("").is_err()); + assert!(Method::from_bytes(b"").is_err()); +} diff -Nru cargo-0.33.0/vendor/http/src/request.rs cargo-0.35.0/vendor/http/src/request.rs --- cargo-0.33.0/vendor/http/src/request.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/request.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1069 @@ +//! HTTP request types. +//! +//! This module contains structs related to HTTP requests, notably the +//! `Request` type itself as well as a builder to create requests. Typically +//! you'll import the `http::Request` type rather than reaching into this +//! module itself. +//! +//! # Examples +//! +//! Creating a `Request` to send +//! +//! ```no_run +//! use http::{Request, Response}; +//! +//! let mut request = Request::builder(); +//! request.uri("https://www.rust-lang.org/") +//! .header("User-Agent", "my-awesome-agent/1.0"); +//! +//! if needs_awesome_header() { +//! request.header("Awesome", "yes"); +//! } +//! +//! let response = send(request.body(()).unwrap()); +//! +//! # fn needs_awesome_header() -> bool { +//! # true +//! # } +//! # +//! fn send(req: Request<()>) -> Response<()> { +//! // ... +//! # panic!() +//! } +//! ``` +//! +//! Inspecting a request to see what was sent. +//! +//! ``` +//! use http::{Request, Response, StatusCode}; +//! +//! fn respond_to(req: Request<()>) -> http::Result> { +//! if req.uri() != "/awesome-url" { +//! return Response::builder() +//! .status(StatusCode::NOT_FOUND) +//! .body(()) +//! } +//! +//! let has_awesome_header = req.headers().contains_key("Awesome"); +//! let body = req.body(); +//! +//! // ... +//! # panic!() +//! } +//! ``` + +use std::any::Any; +use std::fmt; + +use {Uri, Error, Result, HttpTryFrom, Extensions}; +use header::{HeaderMap, HeaderName, HeaderValue}; +use method::Method; +use version::Version; + +/// Represents an HTTP request. +/// +/// An HTTP request consists of a head and a potentially optional body. The body +/// component is generic, enabling arbitrary types to represent the HTTP body. +/// For example, the body could be `Vec`, a `Stream` of byte chunks, or a +/// value that has been deserialized. +/// +/// # Examples +/// +/// Creating a `Request` to send +/// +/// ```no_run +/// use http::{Request, Response}; +/// +/// let mut request = Request::builder(); +/// request.uri("https://www.rust-lang.org/") +/// .header("User-Agent", "my-awesome-agent/1.0"); +/// +/// if needs_awesome_header() { +/// request.header("Awesome", "yes"); +/// } +/// +/// let response = send(request.body(()).unwrap()); +/// +/// # fn needs_awesome_header() -> bool { +/// # true +/// # } +/// # +/// fn send(req: Request<()>) -> Response<()> { +/// // ... +/// # panic!() +/// } +/// ``` +/// +/// Inspecting a request to see what was sent. +/// +/// ``` +/// use http::{Request, Response, StatusCode}; +/// +/// fn respond_to(req: Request<()>) -> http::Result> { +/// if req.uri() != "/awesome-url" { +/// return Response::builder() +/// .status(StatusCode::NOT_FOUND) +/// .body(()) +/// } +/// +/// let has_awesome_header = req.headers().contains_key("Awesome"); +/// let body = req.body(); +/// +/// // ... +/// # panic!() +/// } +/// ``` +/// +/// Deserialize a request of bytes via json: +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Request; +/// use serde::de; +/// +/// fn deserialize(req: Request>) -> serde_json::Result> +/// where for<'de> T: de::Deserialize<'de>, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::from_slice(&body)?; +/// Ok(Request::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +/// +/// Or alternatively, serialize the body of a request to json +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Request; +/// use serde::ser; +/// +/// fn serialize(req: Request) -> serde_json::Result>> +/// where T: ser::Serialize, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::to_vec(&body)?; +/// Ok(Request::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +pub struct Request { + head: Parts, + body: T, +} + +/// Component parts of an HTTP `Request` +/// +/// The HTTP request head consists of a method, uri, version, and a set of +/// header fields. +pub struct Parts { + /// The request's method + pub method: Method, + + /// The request's URI + pub uri: Uri, + + /// The request's version + pub version: Version, + + /// The request's headers + pub headers: HeaderMap, + + /// The request's extensions + pub extensions: Extensions, + + _priv: (), +} + +/// An HTTP request builder +/// +/// This type can be used to construct an instance or `Request` +/// through a builder-like pattern. +#[derive(Debug)] +pub struct Builder { + head: Option, + err: Option, +} + +impl Request<()> { + /// Creates a new builder-style object to manufacture a `Request` + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::builder() + /// .method("GET") + /// .uri("https://www.rust-lang.org/") + /// .header("X-Custom-Foo", "Bar") + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn builder() -> Builder { + Builder::new() + } + + + /// Creates a new `Builder` initialized with a GET method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::get("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn get(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::GET).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a PUT method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::put("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn put(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::PUT).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a POST method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::post("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn post(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::POST).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a DELETE method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::delete("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn delete(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::DELETE).uri(uri); + b + } + + /// Creates a new `Builder` initialized with an OPTIONS method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::options("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// # assert_eq!(*request.method(), Method::OPTIONS); + /// ``` + pub fn options(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::OPTIONS).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a HEAD method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::head("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn head(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::HEAD).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a CONNECT method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::connect("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn connect(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::CONNECT).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a PATCH method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::patch("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn patch(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::PATCH).uri(uri); + b + } + + /// Creates a new `Builder` initialized with a TRACE method and the given URI. + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Request`. + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::trace("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn trace(uri: T) -> Builder + where Uri: HttpTryFrom { + let mut b = Builder::new(); + b.method(Method::TRACE).uri(uri); + b + } +} + +impl Request { + /// Creates a new blank `Request` with the body + /// + /// The component parts of this request will be set to their default, e.g. + /// the GET method, no headers, etc. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new("hello world"); + /// + /// assert_eq!(*request.method(), Method::GET); + /// assert_eq!(*request.body(), "hello world"); + /// ``` + #[inline] + pub fn new(body: T) -> Request { + Request { + head: Parts::new(), + body: body, + } + } + + /// Creates a new `Request` with the given components parts and body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new("hello world"); + /// let (mut parts, body) = request.into_parts(); + /// parts.method = Method::POST; + /// + /// let request = Request::from_parts(parts, body); + /// ``` + #[inline] + pub fn from_parts(parts: Parts, body: T) -> Request { + Request { + head: parts, + body: body, + } + } + + /// Returns a reference to the associated HTTP method. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(*request.method(), Method::GET); + /// ``` + #[inline] + pub fn method(&self) -> &Method { + &self.head.method + } + + /// Returns a mutable reference to the associated HTTP method. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.method_mut() = Method::PUT; + /// assert_eq!(*request.method(), Method::PUT); + /// ``` + #[inline] + pub fn method_mut(&mut self) -> &mut Method { + &mut self.head.method + } + + /// Returns a reference to the associated URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(*request.uri(), *"/"); + /// ``` + #[inline] + pub fn uri(&self) -> &Uri { + &self.head.uri + } + + /// Returns a mutable reference to the associated URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.uri_mut() = "/hello".parse().unwrap(); + /// assert_eq!(*request.uri(), *"/hello"); + /// ``` + #[inline] + pub fn uri_mut(&mut self) -> &mut Uri { + &mut self.head.uri + } + + /// Returns the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert_eq!(request.version(), Version::HTTP_11); + /// ``` + #[inline] + pub fn version(&self) -> Version { + self.head.version + } + + /// Returns a mutable reference to the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request<()> = Request::default(); + /// *request.version_mut() = Version::HTTP_2; + /// assert_eq!(request.version(), Version::HTTP_2); + /// ``` + #[inline] + pub fn version_mut(&mut self) -> &mut Version { + &mut self.head.version + } + + /// Returns a reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert!(request.headers().is_empty()); + /// ``` + #[inline] + pub fn headers(&self) -> &HeaderMap { + &self.head.headers + } + + /// Returns a mutable reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut request: Request<()> = Request::default(); + /// request.headers_mut().insert(HOST, HeaderValue::from_static("world")); + /// assert!(!request.headers().is_empty()); + /// ``` + #[inline] + pub fn headers_mut(&mut self) -> &mut HeaderMap { + &mut self.head.headers + } + + /// Returns a reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request<()> = Request::default(); + /// assert!(request.extensions().get::().is_none()); + /// ``` + #[inline] + pub fn extensions(&self) -> &Extensions { + &self.head.extensions + } + + /// Returns a mutable reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut request: Request<()> = Request::default(); + /// request.extensions_mut().insert("hello"); + /// assert_eq!(request.extensions().get(), Some(&"hello")); + /// ``` + #[inline] + pub fn extensions_mut(&mut self) -> &mut Extensions { + &mut self.head.extensions + } + + /// Returns a reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request: Request = Request::default(); + /// assert!(request.body().is_empty()); + /// ``` + #[inline] + pub fn body(&self) -> &T { + &self.body + } + + /// Returns a mutable reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut request: Request = Request::default(); + /// request.body_mut().push_str("hello world"); + /// assert!(!request.body().is_empty()); + /// ``` + #[inline] + pub fn body_mut(&mut self) -> &mut T { + &mut self.body + } + + + /// Consumes the request, returning just the body. + /// + /// # Examples + /// + /// ``` + /// # use http::Request; + /// let request = Request::new(10); + /// let body = request.into_body(); + /// assert_eq!(body, 10); + /// ``` + #[inline] + pub fn into_body(self) -> T { + self.body + } + + /// Consumes the request returning the head and body parts. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::new(()); + /// let (parts, body) = request.into_parts(); + /// assert_eq!(parts.method, Method::GET); + /// ``` + #[inline] + pub fn into_parts(self) -> (Parts, T) { + (self.head, self.body) + } + + /// Consumes the request returning a new request with body mapped to the + /// return type of the passed in function. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let request = Request::builder().body("some string").unwrap(); + /// let mapped_request: Request<&[u8]> = request.map(|b| { + /// assert_eq!(b, "some string"); + /// b.as_bytes() + /// }); + /// assert_eq!(mapped_request.body(), &"some string".as_bytes()); + /// ``` + #[inline] + pub fn map(self, f: F) -> Request + where F: FnOnce(T) -> U + { + Request { body: f(self.body), head: self.head } + } +} + +impl Default for Request { + fn default() -> Request { + Request::new(T::default()) + } +} + +impl fmt::Debug for Request { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Request") + .field("method", self.method()) + .field("uri", self.uri()) + .field("version", &self.version()) + .field("headers", self.headers()) + // omits Extensions because not useful + .field("body", self.body()) + .finish() + } +} + +impl Parts { + /// Creates a new default instance of `Parts` + fn new() -> Parts { + Parts{ + method: Method::default(), + uri: Uri::default(), + version: Version::default(), + headers: HeaderMap::default(), + extensions: Extensions::default(), + _priv: (), + } + } +} + +impl fmt::Debug for Parts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Parts") + .field("method", &self.method) + .field("uri", &self.uri) + .field("version", &self.version) + .field("headers", &self.headers) + // omits Extensions because not useful + // omits _priv because not useful + .finish() + } +} + +impl Builder { + /// Creates a new default instance of `Builder` to construct a `Request`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = request::Builder::new() + /// .method("POST") + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn new() -> Builder { + Builder::default() + } + + /// Set the HTTP method for this request. + /// + /// This function will configure the HTTP method of the `Request` that will + /// be returned from `Builder::build`. + /// + /// By default this is `GET`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .method("POST") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn method(&mut self, method: T) -> &mut Builder + where Method: HttpTryFrom, + { + if let Some(head) = head(&mut self.head, &self.err) { + match HttpTryFrom::try_from(method) { + Ok(s) => head.method = s, + Err(e) => self.err = Some(e.into()), + } + } + self + } + + /// Get the HTTP Method for this request. + /// + /// By default this is `GET`. + /// if builder has error, returns None. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let mut req = Request::builder(); + /// assert_eq!(req.method_ref(),Some(&Method::GET)); + /// req.method("POST"); + /// assert_eq!(req.method_ref(),Some(&Method::POST)); + /// req.method("DELETE"); + /// assert_eq!(req.method_ref(),Some(&Method::DELETE)); + /// ``` + pub fn method_ref(&self) -> Option<&Method> + { + if self.err.is_some() { + return None + } + match self.head { + Some(ref head) => Some(&head.method), + None => None + } + } + + /// Set the URI for this request. + /// + /// This function will configure the URI of the `Request` that will + /// be returned from `Builder::build`. + /// + /// By default this is `/`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .uri("https://www.rust-lang.org/") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn uri(&mut self, uri: T) -> &mut Builder + where Uri: HttpTryFrom, + { + if let Some(head) = head(&mut self.head, &self.err) { + match HttpTryFrom::try_from(uri) { + Ok(s) => head.uri = s, + Err(e) => self.err = Some(e.into()), + } + } + self + } + + /// Get the URI for this request + /// + /// By default this is `/` + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let mut req = Request::builder(); + /// assert_eq!(req.uri_ref().unwrap().to_string(), "/" ); + /// req.uri("https://www.rust-lang.org/"); + /// assert_eq!(req.uri_ref().unwrap().to_string(), "https://www.rust-lang.org/" ); + /// ``` + pub fn uri_ref(&self) -> Option<&Uri> + { + if self.err.is_some() { + return None; + } + match self.head + { + Some(ref head) => Some(&head.uri), + None => None + } + } + + /// Set the HTTP version for this request. + /// + /// This function will configure the HTTP version of the `Request` that + /// will be returned from `Builder::build`. + /// + /// By default this is HTTP/1.1 + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .version(Version::HTTP_2) + /// .body(()) + /// .unwrap(); + /// ``` + pub fn version(&mut self, version: Version) -> &mut Builder { + if let Some(head) = head(&mut self.head, &self.err) { + head.version = version; + } + self + } + + /// Appends a header to this request builder. + /// + /// This function will append the provided key/value as a header to the + /// internal `HeaderMap` being constructed. Essentially this is equivalent + /// to calling `HeaderMap::append`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// + /// let req = Request::builder() + /// .header("Accept", "text/html") + /// .header("X-Custom-Foo", "bar") + /// .body(()) + /// .unwrap(); + /// ``` + pub fn header(&mut self, key: K, value: V) -> &mut Builder + where HeaderName: HttpTryFrom, + HeaderValue: HttpTryFrom + { + if let Some(head) = head(&mut self.head, &self.err) { + match >::try_from(key) { + Ok(key) => { + match >::try_from(value) { + Ok(value) => { head.headers.append(key, value); } + Err(e) => self.err = Some(e.into()), + } + }, + Err(e) => self.err = Some(e.into()), + }; + } + self + } + + /// Get header on this request builder. + /// when builder has error returns None + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// # use http::request::Builder; + /// let mut req = Request::builder(); + /// req.header("Accept", "text/html") + /// .header("X-Custom-Foo", "bar"); + /// let headers = req.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_ref(&self) -> Option<&HeaderMap> { + if self.err.is_some() { + return None; + } + match self.head + { + Some(ref head) => Some(&head.headers), + None => None + } + } + + /// Get header on this request builder. + /// when builder has error returns None + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// # use http::request::Builder; + /// let mut req = Request::builder(); + /// { + /// let headers = req.headers_mut().unwrap(); + /// headers.insert("Accept", HeaderValue::from_static("text/html")); + /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar")); + /// } + /// let headers = req.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_mut(&mut self) -> Option<&mut HeaderMap> { + if self.err.is_some() { + return None; + } + match self.head + { + Some(ref mut head) => Some(&mut head.headers), + None => None + } + } + + /// Adds an extension to this builder + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let req = Request::builder() + /// .extension("My Extension") + /// .body(()) + /// .unwrap(); + /// + /// assert_eq!(req.extensions().get::<&'static str>(), + /// Some(&"My Extension")); + /// ``` + pub fn extension(&mut self, extension: T) -> &mut Builder + where T: Any + Send + Sync + 'static, + { + if let Some(head) = head(&mut self.head, &self.err) { + head.extensions.insert(extension); + } + self + } + + fn take_parts(&mut self) -> Result { + let ret = self.head.take().expect("cannot reuse request builder"); + if let Some(e) = self.err.take() { + return Err(e) + } + Ok(ret) + } + + /// "Consumes" this builder, using the provided `body` to return a + /// constructed `Request`. + /// + /// # Errors + /// + /// This function may return an error if any previously configured argument + /// failed to parse or get converted to the internal representation. For + /// example if an invalid `head` was specified via `header("Foo", + /// "Bar\r\n")` the error will be returned when this function is called + /// rather than when `header` was called. + /// + /// # Panics + /// + /// This method will panic if the builder is reused. The `body` function can + /// only be called once. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let request = Request::builder() + /// .body(()) + /// .unwrap(); + /// ``` + pub fn body(&mut self, body: T) -> Result> { + Ok(Request { + head: self.take_parts()?, + body: body, + }) + } +} + +fn head<'a>(head: &'a mut Option, err: &Option) + -> Option<&'a mut Parts> +{ + if err.is_some() { + return None + } + head.as_mut() +} + +impl Default for Builder { + #[inline] + fn default() -> Builder { + Builder { + head: Some(Parts::new()), + err: None, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_can_map_a_body_from_one_type_to_another() { + let request= Request::builder().body("some string").unwrap(); + let mapped_request = request.map(|s| { + assert_eq!(s, "some string"); + 123u32 + }); + assert_eq!(mapped_request.body(), &123u32); + } +} diff -Nru cargo-0.33.0/vendor/http/src/response.rs cargo-0.35.0/vendor/http/src/response.rs --- cargo-0.33.0/vendor/http/src/response.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/response.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,787 @@ +//! HTTP response types. +//! +//! This module contains structs related to HTTP responses, notably the +//! `Response` type itself as well as a builder to create responses. Typically +//! you'll import the `http::Response` type rather than reaching into this +//! module itself. +//! +//! # Examples +//! +//! Creating a `Response` to return +//! +//! ``` +//! use http::{Request, Response, StatusCode}; +//! +//! fn respond_to(req: Request<()>) -> http::Result> { +//! let mut response = Response::builder(); +//! response.header("Foo", "Bar") +//! .status(StatusCode::OK); +//! +//! if req.headers().contains_key("Another-Header") { +//! response.header("Another-Header", "Ack"); +//! } +//! +//! response.body(()) +//! } +//! ``` +//! +//! A simple 404 handler +//! +//! ``` +//! use http::{Request, Response, StatusCode}; +//! +//! fn not_found(_req: Request<()>) -> http::Result> { +//! Response::builder() +//! .status(StatusCode::NOT_FOUND) +//! .body(()) +//! } +//! ``` +//! +//! Or otherwise inspecting the result of a request: +//! +//! ```no_run +//! use http::{Request, Response}; +//! +//! fn get(url: &str) -> http::Result> { +//! // ... +//! # panic!() +//! } +//! +//! let response = get("https://www.rust-lang.org/").unwrap(); +//! +//! if !response.status().is_success() { +//! panic!("failed to get a successful response status!"); +//! } +//! +//! if let Some(date) = response.headers().get("Date") { +//! // we've got a `Date` header! +//! } +//! +//! let body = response.body(); +//! // ... +//! ``` + +use std::any::Any; +use std::fmt; + +use {Error, Result, HttpTryFrom, Extensions}; +use header::{HeaderMap, HeaderName, HeaderValue}; +use status::StatusCode; +use version::Version; + +/// Represents an HTTP response +/// +/// An HTTP response consists of a head and a potentially optional body. The body +/// component is generic, enabling arbitrary types to represent the HTTP body. +/// For example, the body could be `Vec`, a `Stream` of byte chunks, or a +/// value that has been deserialized. +/// +/// Typically you'll work with responses on the client side as the result of +/// sending a `Request` and on the server you'll be generating a `Request` to +/// send back to the client. +/// +/// # Examples +/// +/// Creating a `Response` to return +/// +/// ``` +/// use http::{Request, Response, StatusCode}; +/// +/// fn respond_to(req: Request<()>) -> http::Result> { +/// let mut response = Response::builder(); +/// response.header("Foo", "Bar") +/// .status(StatusCode::OK); +/// +/// if req.headers().contains_key("Another-Header") { +/// response.header("Another-Header", "Ack"); +/// } +/// +/// response.body(()) +/// } +/// ``` +/// +/// A simple 404 handler +/// +/// ``` +/// use http::{Request, Response, StatusCode}; +/// +/// fn not_found(_req: Request<()>) -> http::Result> { +/// Response::builder() +/// .status(StatusCode::NOT_FOUND) +/// .body(()) +/// } +/// ``` +/// +/// Or otherwise inspecting the result of a request: +/// +/// ```no_run +/// use http::{Request, Response}; +/// +/// fn get(url: &str) -> http::Result> { +/// // ... +/// # panic!() +/// } +/// +/// let response = get("https://www.rust-lang.org/").unwrap(); +/// +/// if !response.status().is_success() { +/// panic!("failed to get a successful response status!"); +/// } +/// +/// if let Some(date) = response.headers().get("Date") { +/// // we've got a `Date` header! +/// } +/// +/// let body = response.body(); +/// // ... +/// ``` +/// +/// Deserialize a response of bytes via json: +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Response; +/// use serde::de; +/// +/// fn deserialize(req: Response>) -> serde_json::Result> +/// where for<'de> T: de::Deserialize<'de>, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::from_slice(&body)?; +/// Ok(Response::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +/// +/// Or alternatively, serialize the body of a response to json +/// +/// ``` +/// # extern crate serde; +/// # extern crate serde_json; +/// # extern crate http; +/// use http::Response; +/// use serde::ser; +/// +/// fn serialize(req: Response) -> serde_json::Result>> +/// where T: ser::Serialize, +/// { +/// let (parts, body) = req.into_parts(); +/// let body = serde_json::to_vec(&body)?; +/// Ok(Response::from_parts(parts, body)) +/// } +/// # +/// # fn main() {} +/// ``` +pub struct Response { + head: Parts, + body: T, +} + +/// Component parts of an HTTP `Response` +/// +/// The HTTP response head consists of a status, version, and a set of +/// header fields. +pub struct Parts { + /// The response's status + pub status: StatusCode, + + /// The response's version + pub version: Version, + + /// The response's headers + pub headers: HeaderMap, + + /// The response's extensions + pub extensions: Extensions, + + _priv: (), +} + +/// An HTTP response builder +/// +/// This type can be used to construct an instance of `Response` through a +/// builder-like pattern. +#[derive(Debug)] +pub struct Builder { + head: Option, + err: Option, +} + +impl Response<()> { + /// Creates a new builder-style object to manufacture a `Response` + /// + /// This method returns an instance of `Builder` which can be used to + /// create a `Response`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response = Response::builder() + /// .status(200) + /// .header("X-Custom-Foo", "Bar") + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn builder() -> Builder { + Builder::new() + } +} + +impl Response { + /// Creates a new blank `Response` with the body + /// + /// The component ports of this response will be set to their default, e.g. + /// the ok status, no headers, etc. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response = Response::new("hello world"); + /// + /// assert_eq!(response.status(), StatusCode::OK); + /// assert_eq!(*response.body(), "hello world"); + /// ``` + #[inline] + pub fn new(body: T) -> Response { + Response { + head: Parts::new(), + body: body, + } + } + + /// Creates a new `Response` with the given head and body + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response = Response::new("hello world"); + /// let (mut parts, body) = response.into_parts(); + /// + /// parts.status = StatusCode::BAD_REQUEST; + /// let response = Response::from_parts(parts, body); + /// + /// assert_eq!(response.status(), StatusCode::BAD_REQUEST); + /// assert_eq!(*response.body(), "hello world"); + /// ``` + #[inline] + pub fn from_parts(parts: Parts, body: T) -> Response { + Response { + head: parts, + body: body, + } + } + + /// Returns the `StatusCode`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response<()> = Response::default(); + /// assert_eq!(response.status(), StatusCode::OK); + /// ``` + #[inline] + pub fn status(&self) -> StatusCode { + self.head.status + } + + /// Returns a mutable reference to the associated `StatusCode`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut response: Response<()> = Response::default(); + /// *response.status_mut() = StatusCode::CREATED; + /// assert_eq!(response.status(), StatusCode::CREATED); + /// ``` + #[inline] + pub fn status_mut(&mut self) -> &mut StatusCode { + &mut self.head.status + } + + /// Returns a reference to the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response<()> = Response::default(); + /// assert_eq!(response.version(), Version::HTTP_11); + /// ``` + #[inline] + pub fn version(&self) -> Version { + self.head.version + } + + /// Returns a mutable reference to the associated version. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut response: Response<()> = Response::default(); + /// *response.version_mut() = Version::HTTP_2; + /// assert_eq!(response.version(), Version::HTTP_2); + /// ``` + #[inline] + pub fn version_mut(&mut self) -> &mut Version { + &mut self.head.version + } + + /// Returns a reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response<()> = Response::default(); + /// assert!(response.headers().is_empty()); + /// ``` + #[inline] + pub fn headers(&self) -> &HeaderMap { + &self.head.headers + } + + /// Returns a mutable reference to the associated header field map. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut response: Response<()> = Response::default(); + /// response.headers_mut().insert(HOST, HeaderValue::from_static("world")); + /// assert!(!response.headers().is_empty()); + /// ``` + #[inline] + pub fn headers_mut(&mut self) -> &mut HeaderMap { + &mut self.head.headers + } + + /// Returns a reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response<()> = Response::default(); + /// assert!(response.extensions().get::().is_none()); + /// ``` + #[inline] + pub fn extensions(&self) -> &Extensions { + &self.head.extensions + } + + /// Returns a mutable reference to the associated extensions. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::*; + /// let mut response: Response<()> = Response::default(); + /// response.extensions_mut().insert("hello"); + /// assert_eq!(response.extensions().get(), Some(&"hello")); + /// ``` + #[inline] + pub fn extensions_mut(&mut self) -> &mut Extensions { + &mut self.head.extensions + } + + /// Returns a reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response = Response::default(); + /// assert!(response.body().is_empty()); + /// ``` + #[inline] + pub fn body(&self) -> &T { + &self.body + } + + /// Returns a mutable reference to the associated HTTP body. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let mut response: Response = Response::default(); + /// response.body_mut().push_str("hello world"); + /// assert!(!response.body().is_empty()); + /// ``` + #[inline] + pub fn body_mut(&mut self) -> &mut T { + &mut self.body + } + + /// Consumes the response, returning just the body. + /// + /// # Examples + /// + /// ``` + /// # use http::Response; + /// let response = Response::new(10); + /// let body = response.into_body(); + /// assert_eq!(body, 10); + /// ``` + #[inline] + pub fn into_body(self) -> T { + self.body + } + + /// Consumes the response returning the head and body parts. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response: Response<()> = Response::default(); + /// let (parts, body) = response.into_parts(); + /// assert_eq!(parts.status, StatusCode::OK); + /// ``` + #[inline] + pub fn into_parts(self) -> (Parts, T) { + (self.head, self.body) + } + + /// Consumes the response returning a new response with body mapped to the + /// return type of the passed in function. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// let response = Response::builder().body("some string").unwrap(); + /// let mapped_response: Response<&[u8]> = response.map(|b| { + /// assert_eq!(b, "some string"); + /// b.as_bytes() + /// }); + /// assert_eq!(mapped_response.body(), &"some string".as_bytes()); + /// ``` + #[inline] + pub fn map(self, f: F) -> Response + where F: FnOnce(T) -> U + { + Response { body: f(self.body), head: self.head } + } +} + +impl Default for Response { + #[inline] + fn default() -> Response { + Response::new(T::default()) + } +} + +impl fmt::Debug for Response { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Response") + .field("status", &self.status()) + .field("version", &self.version()) + .field("headers", self.headers()) + // omits Extensions because not useful + .field("body", self.body()) + .finish() + } +} + +impl Parts { + /// Creates a new default instance of `Parts` + fn new() -> Parts { + Parts{ + status: StatusCode::default(), + version: Version::default(), + headers: HeaderMap::default(), + extensions: Extensions::default(), + _priv: (), + } + } +} + +impl fmt::Debug for Parts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Parts") + .field("status", &self.status) + .field("version", &self.version) + .field("headers", &self.headers) + // omits Extensions because not useful + // omits _priv because not useful + .finish() + } +} + +impl Builder { + /// Creates a new default instance of `Builder` to construct either a + /// `Head` or a `Response`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let response = response::Builder::new() + /// .status(200) + /// .body(()) + /// .unwrap(); + /// ``` + #[inline] + pub fn new() -> Builder { + Builder::default() + } + + /// Set the HTTP status for this response. + /// + /// This function will configure the HTTP status code of the `Response` that + /// will be returned from `Builder::build`. + /// + /// By default this is `200`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let response = Response::builder() + /// .status(200) + /// .body(()) + /// .unwrap(); + /// ``` + pub fn status(&mut self, status: T) -> &mut Builder + where StatusCode: HttpTryFrom, + { + if let Some(head) = head(&mut self.head, &self.err) { + match HttpTryFrom::try_from(status) { + Ok(s) => head.status = s, + Err(e) => self.err = Some(e.into()), + } + } + self + } + + /// Set the HTTP version for this response. + /// + /// This function will configure the HTTP version of the `Response` that + /// will be returned from `Builder::build`. + /// + /// By default this is HTTP/1.1 + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let response = Response::builder() + /// .version(Version::HTTP_2) + /// .body(()) + /// .unwrap(); + /// ``` + pub fn version(&mut self, version: Version) -> &mut Builder { + if let Some(head) = head(&mut self.head, &self.err) { + head.version = version; + } + self + } + + /// Appends a header to this response builder. + /// + /// This function will append the provided key/value as a header to the + /// internal `HeaderMap` being constructed. Essentially this is equivalent + /// to calling `HeaderMap::append`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// + /// let response = Response::builder() + /// .header("Content-Type", "text/html") + /// .header("X-Custom-Foo", "bar") + /// .header("content-length", 0) + /// .body(()) + /// .unwrap(); + /// ``` + pub fn header(&mut self, key: K, value: V) -> &mut Builder + where HeaderName: HttpTryFrom, + HeaderValue: HttpTryFrom + { + if let Some(head) = head(&mut self.head, &self.err) { + match >::try_from(key) { + Ok(key) => { + match >::try_from(value) { + Ok(value) => { head.headers.append(key, value); } + Err(e) => self.err = Some(e.into()), + } + }, + Err(e) => self.err = Some(e.into()), + }; + } + self + } + + /// Get header on this response builder. + /// when builder has error returns None + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// # use http::response::Builder; + /// let mut res = Response::builder(); + /// res.header("Accept", "text/html") + /// .header("X-Custom-Foo", "bar"); + /// let headers = res.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_ref(&self) -> Option<&HeaderMap> { + if self.err.is_some() { + return None; + } + match self.head + { + Some(ref head) => Some(&head.headers), + None => None + } + } + + /// Get header on this response builder. + /// when builder has error returns None + /// + /// # Example + /// + /// ``` + /// # use http::*; + /// # use http::header::HeaderValue; + /// # use http::response::Builder; + /// let mut res = Response::builder(); + /// { + /// let headers = res.headers_mut().unwrap(); + /// headers.insert("Accept", HeaderValue::from_static("text/html")); + /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar")); + /// } + /// let headers = res.headers_ref().unwrap(); + /// assert_eq!( headers["Accept"], "text/html" ); + /// assert_eq!( headers["X-Custom-Foo"], "bar" ); + /// ``` + pub fn headers_mut(&mut self) -> Option<&mut HeaderMap> { + if self.err.is_some() { + return None; + } + match self.head + { + Some(ref mut head) => Some(&mut head.headers), + None => None + } + } + + /// Adds an extension to this builder + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let response = Response::builder() + /// .extension("My Extension") + /// .body(()) + /// .unwrap(); + /// + /// assert_eq!(response.extensions().get::<&'static str>(), + /// Some(&"My Extension")); + /// ``` + pub fn extension(&mut self, extension: T) -> &mut Builder + where T: Any + Send + Sync + 'static, + { + if let Some(head) = head(&mut self.head, &self.err) { + head.extensions.insert(extension); + } + self + } + + fn take_parts(&mut self) -> Result { + let ret = self.head.take().expect("cannot reuse response builder"); + if let Some(e) = self.err.take() { + return Err(e) + } + Ok(ret) + } + + /// "Consumes" this builder, using the provided `body` to return a + /// constructed `Response`. + /// + /// # Errors + /// + /// This function may return an error if any previously configured argument + /// failed to parse or get converted to the internal representation. For + /// example if an invalid `head` was specified via `header("Foo", + /// "Bar\r\n")` the error will be returned when this function is called + /// rather than when `header` was called. + /// + /// # Panics + /// + /// This method will panic if the builder is reused. The `body` function can + /// only be called once. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let response = Response::builder() + /// .body(()) + /// .unwrap(); + /// ``` + pub fn body(&mut self, body: T) -> Result> { + Ok(Response { + head: self.take_parts()?, + body: body, + }) + } +} + +fn head<'a>(head: &'a mut Option, err: &Option) + -> Option<&'a mut Parts> +{ + if err.is_some() { + return None + } + head.as_mut() +} + +impl Default for Builder { + #[inline] + fn default() -> Builder { + Builder { + head: Some(Parts::new()), + err: None, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_can_map_a_body_from_one_type_to_another() { + let response = Response::builder().body("some string").unwrap(); + let mapped_response = response.map(|s| { + assert_eq!(s, "some string"); + 123u32 + }); + assert_eq!(mapped_response.body(), &123u32); + } +} diff -Nru cargo-0.33.0/vendor/http/src/status.rs cargo-0.35.0/vendor/http/src/status.rs --- cargo-0.33.0/vendor/http/src/status.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/status.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,563 @@ +//! HTTP status codes +//! +//! This module contains HTTP-status code related structs an errors. The main +//! type in this module is `StatusCode` which is not intended to be used through +//! this module but rather the `http::StatusCode` type. +//! +//! # Examples +//! +//! ``` +//! use http::StatusCode; +//! +//! assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); +//! assert_eq!(StatusCode::NOT_FOUND, 404); +//! assert!(StatusCode::OK.is_success()); +//! ``` + +use std::fmt; +use std::error::Error; +use std::str::FromStr; + +use HttpTryFrom; + +/// An HTTP status code (`status-code` in RFC 7230 et al.). +/// +/// This type contains constants for all common status codes. +/// It allows status codes in the range [100, 599]. +/// +/// IANA maintain the [Hypertext Transfer Protocol (HTTP) Status Code +/// Registry](http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml) which is +/// the source for this enum (with one exception, 418 I'm a teapot, which is +/// inexplicably not in the register). +/// +/// # Examples +/// +/// ``` +/// use http::StatusCode; +/// +/// assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); +/// assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404); +/// assert!(StatusCode::OK.is_success()); +/// ``` +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct StatusCode(u16); + +/// A possible error value when converting a `StatusCode` from a `u16` or `&str` +/// +/// This error indicates that the supplied input was not a valid number, was less +/// than 100, or was greater than 599. +#[derive(Debug)] +pub struct InvalidStatusCode { + _priv: (), +} + +impl StatusCode { + /// Converts a u16 to a status code. + /// + /// The function validates the correctness of the supplied u16. It must be + /// greater or equal to 100 but less than 600. + /// + /// # Example + /// + /// ``` + /// use http::StatusCode; + /// + /// let ok = StatusCode::from_u16(200).unwrap(); + /// assert_eq!(ok, StatusCode::OK); + /// + /// let err = StatusCode::from_u16(99); + /// assert!(err.is_err()); + /// ``` + #[inline] + pub fn from_u16(src: u16) -> Result { + if src < 100 || src >= 600 { + return Err(InvalidStatusCode::new()); + } + + Ok(StatusCode(src)) + } + + /// Converts a &[u8] to a status code + pub fn from_bytes(src: &[u8]) -> Result { + if src.len() != 3 { + return Err(InvalidStatusCode::new()); + } + + let a = src[0].wrapping_sub(b'0') as u16; + let b = src[1].wrapping_sub(b'0') as u16; + let c = src[2].wrapping_sub(b'0') as u16; + + if a == 0 || a > 5 || b > 9 || c > 9 { + return Err(InvalidStatusCode::new()); + } + + let status = (a * 100) + (b * 10) + c; + Ok(StatusCode(status)) + } + + /// Returns the `u16` corresponding to this `StatusCode`. + /// + /// # Note + /// + /// This is the same as the `From` implementation, but + /// included as an inherent method because that implementation doesn't + /// appear in rustdocs, as well as a way to force the type instead of + /// relying on inference. + /// + /// # Example + /// + /// ``` + /// let status = http::StatusCode::OK; + /// assert_eq!(status.as_u16(), 200); + /// ``` + #[inline] + pub fn as_u16(&self) -> u16 { + (*self).into() + } + + /// Returns a &str representation of the `StatusCode` + /// + /// The return value only includes a numerical representation of the + /// status code. The canonical reason is not included. + /// + /// # Example + /// + /// ``` + /// let status = http::StatusCode::OK; + /// assert_eq!(status.as_str(), "200"); + /// ``` + #[inline] + pub fn as_str(&self) -> &str { + CODES_AS_STR[(self.0 - 100) as usize] + } + + /// Get the standardised `reason-phrase` for this status code. + /// + /// This is mostly here for servers writing responses, but could potentially have application + /// at other times. + /// + /// The reason phrase is defined as being exclusively for human readers. You should avoid + /// deriving any meaning from it at all costs. + /// + /// Bear in mind also that in HTTP/2.0 the reason phrase is abolished from transmission, and so + /// this canonical reason phrase really is the only reason phrase you’ll find. + /// + /// # Example + /// + /// ``` + /// let status = http::StatusCode::OK; + /// assert_eq!(status.canonical_reason(), Some("OK")); + /// ``` + pub fn canonical_reason(&self) -> Option<&'static str> { + canonical_reason(self.0) + } + + + /// Check if status is within 100-199. + #[inline] + pub fn is_informational(&self) -> bool { + 200 > self.0 && self.0 >= 100 + } + + /// Check if status is within 200-299. + #[inline] + pub fn is_success(&self) -> bool { + 300 > self.0 && self.0 >= 200 + } + + /// Check if status is within 300-399. + #[inline] + pub fn is_redirection(&self) -> bool { + 400 > self.0 && self.0 >= 300 + } + + /// Check if status is within 400-499. + #[inline] + pub fn is_client_error(&self) -> bool { + 500 > self.0 && self.0 >= 400 + } + + /// Check if status is within 500-599. + #[inline] + pub fn is_server_error(&self) -> bool { + 600 > self.0 && self.0 >= 500 + } +} + +impl fmt::Debug for StatusCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.0, f) + } +} + +/// Formats the status code, *including* the canonical reason. +/// +/// # Example +/// +/// ``` +/// # use http::StatusCode; +/// assert_eq!(format!("{}", StatusCode::OK), "200 OK"); +/// ``` +impl fmt::Display for StatusCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} {}", u16::from(*self), + self.canonical_reason().unwrap_or("")) + } +} + +impl Default for StatusCode { + #[inline] + fn default() -> StatusCode { + StatusCode::OK + } +} + +impl PartialEq for StatusCode { + #[inline] + fn eq(&self, other: &u16) -> bool { + self.as_u16() == *other + } +} + +impl PartialEq for u16 { + #[inline] + fn eq(&self, other: &StatusCode) -> bool { + *self == other.as_u16() + } +} + +impl From for u16 { + #[inline] + fn from(status: StatusCode) -> u16 { + status.0 + } +} + +impl FromStr for StatusCode { + type Err = InvalidStatusCode; + + fn from_str(s: &str) -> Result { + StatusCode::from_bytes(s.as_ref()) + } +} + +impl<'a> From<&'a StatusCode> for StatusCode { + #[inline] + fn from(t: &'a StatusCode) -> Self { + t.clone() + } +} + +impl<'a> HttpTryFrom<&'a StatusCode> for StatusCode { + type Error = ::error::Never; + + #[inline] + fn try_from(t: &'a StatusCode) -> Result { + Ok(t.clone()) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for StatusCode { + type Error = InvalidStatusCode; + + #[inline] + fn try_from(t: &'a [u8]) -> Result { + StatusCode::from_bytes(t) + } +} + +impl<'a> HttpTryFrom<&'a str> for StatusCode { + type Error = InvalidStatusCode; + + #[inline] + fn try_from(t: &'a str) -> Result { + t.parse() + } +} + +impl HttpTryFrom for StatusCode { + type Error = InvalidStatusCode; + + #[inline] + fn try_from(t: u16) -> Result { + StatusCode::from_u16(t) + } +} + +impl InvalidStatusCode { + fn new() -> InvalidStatusCode { + InvalidStatusCode { + _priv: (), + } + } +} + +macro_rules! status_codes { + ( + $( + $(#[$docs:meta])* + ($num:expr, $konst:ident, $phrase:expr); + )+ + ) => { + impl StatusCode { + $( + $(#[$docs])* + pub const $konst: StatusCode = StatusCode($num); + )+ + + } + + fn canonical_reason(num: u16) -> Option<&'static str> { + match num { + $( + $num => Some($phrase), + )+ + _ => None + } + } + } +} + +status_codes! { + /// 100 Continue + /// [[RFC7231, Section 6.2.1](https://tools.ietf.org/html/rfc7231#section-6.2.1)] + (100, CONTINUE, "Continue"); + /// 101 Switching Protocols + /// [[RFC7231, Section 6.2.2](https://tools.ietf.org/html/rfc7231#section-6.2.2)] + (101, SWITCHING_PROTOCOLS, "Switching Protocols"); + /// 102 Processing + /// [[RFC2518](https://tools.ietf.org/html/rfc2518)] + (102, PROCESSING, "Processing"); + + /// 200 OK + /// [[RFC7231, Section 6.3.1](https://tools.ietf.org/html/rfc7231#section-6.3.1)] + (200, OK, "OK"); + /// 201 Created + /// [[RFC7231, Section 6.3.2](https://tools.ietf.org/html/rfc7231#section-6.3.2)] + (201, CREATED, "Created"); + /// 202 Accepted + /// [[RFC7231, Section 6.3.3](https://tools.ietf.org/html/rfc7231#section-6.3.3)] + (202, ACCEPTED, "Accepted"); + /// 203 Non-Authoritative Information + /// [[RFC7231, Section 6.3.4](https://tools.ietf.org/html/rfc7231#section-6.3.4)] + (203, NON_AUTHORITATIVE_INFORMATION, "Non Authoritative Information"); + /// 204 No Content + /// [[RFC7231, Section 6.3.5](https://tools.ietf.org/html/rfc7231#section-6.3.5)] + (204, NO_CONTENT, "No Content"); + /// 205 Reset Content + /// [[RFC7231, Section 6.3.6](https://tools.ietf.org/html/rfc7231#section-6.3.6)] + (205, RESET_CONTENT, "Reset Content"); + /// 206 Partial Content + /// [[RFC7233, Section 4.1](https://tools.ietf.org/html/rfc7233#section-4.1)] + (206, PARTIAL_CONTENT, "Partial Content"); + /// 207 Multi-Status + /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] + (207, MULTI_STATUS, "Multi-Status"); + /// 208 Already Reported + /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] + (208, ALREADY_REPORTED, "Already Reported"); + + /// 226 IM Used + /// [[RFC3229](https://tools.ietf.org/html/rfc3229)] + (226, IM_USED, "IM Used"); + + /// 300 Multiple Choices + /// [[RFC7231, Section 6.4.1](https://tools.ietf.org/html/rfc7231#section-6.4.1)] + (300, MULTIPLE_CHOICES, "Multiple Choices"); + /// 301 Moved Permanently + /// [[RFC7231, Section 6.4.2](https://tools.ietf.org/html/rfc7231#section-6.4.2)] + (301, MOVED_PERMANENTLY, "Moved Permanently"); + /// 302 Found + /// [[RFC7231, Section 6.4.3](https://tools.ietf.org/html/rfc7231#section-6.4.3)] + (302, FOUND, "Found"); + /// 303 See Other + /// [[RFC7231, Section 6.4.4](https://tools.ietf.org/html/rfc7231#section-6.4.4)] + (303, SEE_OTHER, "See Other"); + /// 304 Not Modified + /// [[RFC7232, Section 4.1](https://tools.ietf.org/html/rfc7232#section-4.1)] + (304, NOT_MODIFIED, "Not Modified"); + /// 305 Use Proxy + /// [[RFC7231, Section 6.4.5](https://tools.ietf.org/html/rfc7231#section-6.4.5)] + (305, USE_PROXY, "Use Proxy"); + /// 307 Temporary Redirect + /// [[RFC7231, Section 6.4.7](https://tools.ietf.org/html/rfc7231#section-6.4.7)] + (307, TEMPORARY_REDIRECT, "Temporary Redirect"); + /// 308 Permanent Redirect + /// [[RFC7238](https://tools.ietf.org/html/rfc7238)] + (308, PERMANENT_REDIRECT, "Permanent Redirect"); + + /// 400 Bad Request + /// [[RFC7231, Section 6.5.1](https://tools.ietf.org/html/rfc7231#section-6.5.1)] + (400, BAD_REQUEST, "Bad Request"); + /// 401 Unauthorized + /// [[RFC7235, Section 3.1](https://tools.ietf.org/html/rfc7235#section-3.1)] + (401, UNAUTHORIZED, "Unauthorized"); + /// 402 Payment Required + /// [[RFC7231, Section 6.5.2](https://tools.ietf.org/html/rfc7231#section-6.5.2)] + (402, PAYMENT_REQUIRED, "Payment Required"); + /// 403 Forbidden + /// [[RFC7231, Section 6.5.3](https://tools.ietf.org/html/rfc7231#section-6.5.3)] + (403, FORBIDDEN, "Forbidden"); + /// 404 Not Found + /// [[RFC7231, Section 6.5.4](https://tools.ietf.org/html/rfc7231#section-6.5.4)] + (404, NOT_FOUND, "Not Found"); + /// 405 Method Not Allowed + /// [[RFC7231, Section 6.5.5](https://tools.ietf.org/html/rfc7231#section-6.5.5)] + (405, METHOD_NOT_ALLOWED, "Method Not Allowed"); + /// 406 Not Acceptable + /// [[RFC7231, Section 6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6)] + (406, NOT_ACCEPTABLE, "Not Acceptable"); + /// 407 Proxy Authentication Required + /// [[RFC7235, Section 3.2](https://tools.ietf.org/html/rfc7235#section-3.2)] + (407, PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required"); + /// 408 Request Timeout + /// [[RFC7231, Section 6.5.7](https://tools.ietf.org/html/rfc7231#section-6.5.7)] + (408, REQUEST_TIMEOUT, "Request Timeout"); + /// 409 Conflict + /// [[RFC7231, Section 6.5.8](https://tools.ietf.org/html/rfc7231#section-6.5.8)] + (409, CONFLICT, "Conflict"); + /// 410 Gone + /// [[RFC7231, Section 6.5.9](https://tools.ietf.org/html/rfc7231#section-6.5.9)] + (410, GONE, "Gone"); + /// 411 Length Required + /// [[RFC7231, Section 6.5.10](https://tools.ietf.org/html/rfc7231#section-6.5.10)] + (411, LENGTH_REQUIRED, "Length Required"); + /// 412 Precondition Failed + /// [[RFC7232, Section 4.2](https://tools.ietf.org/html/rfc7232#section-4.2)] + (412, PRECONDITION_FAILED, "Precondition Failed"); + /// 413 Payload Too Large + /// [[RFC7231, Section 6.5.11](https://tools.ietf.org/html/rfc7231#section-6.5.11)] + (413, PAYLOAD_TOO_LARGE, "Payload Too Large"); + /// 414 URI Too Long + /// [[RFC7231, Section 6.5.12](https://tools.ietf.org/html/rfc7231#section-6.5.12)] + (414, URI_TOO_LONG, "URI Too Long"); + /// 415 Unsupported Media Type + /// [[RFC7231, Section 6.5.13](https://tools.ietf.org/html/rfc7231#section-6.5.13)] + (415, UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"); + /// 416 Range Not Satisfiable + /// [[RFC7233, Section 4.4](https://tools.ietf.org/html/rfc7233#section-4.4)] + (416, RANGE_NOT_SATISFIABLE, "Range Not Satisfiable"); + /// 417 Expectation Failed + /// [[RFC7231, Section 6.5.14](https://tools.ietf.org/html/rfc7231#section-6.5.14)] + (417, EXPECTATION_FAILED, "Expectation Failed"); + /// 418 I'm a teapot + /// [curiously not registered by IANA but [RFC2324](https://tools.ietf.org/html/rfc2324)] + (418, IM_A_TEAPOT, "I'm a teapot"); + + /// 421 Misdirected Request + /// [RFC7540, Section 9.1.2](http://tools.ietf.org/html/rfc7540#section-9.1.2) + (421, MISDIRECTED_REQUEST, "Misdirected Request"); + /// 422 Unprocessable Entity + /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] + (422, UNPROCESSABLE_ENTITY, "Unprocessable Entity"); + /// 423 Locked + /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] + (423, LOCKED, "Locked"); + /// 424 Failed Dependency + /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] + (424, FAILED_DEPENDENCY, "Failed Dependency"); + + /// 426 Upgrade Required + /// [[RFC7231, Section 6.5.15](https://tools.ietf.org/html/rfc7231#section-6.5.15)] + (426, UPGRADE_REQUIRED, "Upgrade Required"); + + /// 428 Precondition Required + /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] + (428, PRECONDITION_REQUIRED, "Precondition Required"); + /// 429 Too Many Requests + /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] + (429, TOO_MANY_REQUESTS, "Too Many Requests"); + + /// 431 Request Header Fields Too Large + /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] + (431, REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large"); + + /// 451 Unavailable For Legal Reasons + /// [[RFC7725](http://tools.ietf.org/html/rfc7725)] + (451, UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons"); + + /// 500 Internal Server Error + /// [[RFC7231, Section 6.6.1](https://tools.ietf.org/html/rfc7231#section-6.6.1)] + (500, INTERNAL_SERVER_ERROR, "Internal Server Error"); + /// 501 Not Implemented + /// [[RFC7231, Section 6.6.2](https://tools.ietf.org/html/rfc7231#section-6.6.2)] + (501, NOT_IMPLEMENTED, "Not Implemented"); + /// 502 Bad Gateway + /// [[RFC7231, Section 6.6.3](https://tools.ietf.org/html/rfc7231#section-6.6.3)] + (502, BAD_GATEWAY, "Bad Gateway"); + /// 503 Service Unavailable + /// [[RFC7231, Section 6.6.4](https://tools.ietf.org/html/rfc7231#section-6.6.4)] + (503, SERVICE_UNAVAILABLE, "Service Unavailable"); + /// 504 Gateway Timeout + /// [[RFC7231, Section 6.6.5](https://tools.ietf.org/html/rfc7231#section-6.6.5)] + (504, GATEWAY_TIMEOUT, "Gateway Timeout"); + /// 505 HTTP Version Not Supported + /// [[RFC7231, Section 6.6.6](https://tools.ietf.org/html/rfc7231#section-6.6.6)] + (505, HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported"); + /// 506 Variant Also Negotiates + /// [[RFC2295](https://tools.ietf.org/html/rfc2295)] + (506, VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates"); + /// 507 Insufficient Storage + /// [[RFC4918](https://tools.ietf.org/html/rfc4918)] + (507, INSUFFICIENT_STORAGE, "Insufficient Storage"); + /// 508 Loop Detected + /// [[RFC5842](https://tools.ietf.org/html/rfc5842)] + (508, LOOP_DETECTED, "Loop Detected"); + + /// 510 Not Extended + /// [[RFC2774](https://tools.ietf.org/html/rfc2774)] + (510, NOT_EXTENDED, "Not Extended"); + /// 511 Network Authentication Required + /// [[RFC6585](https://tools.ietf.org/html/rfc6585)] + (511, NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required"); +} + +impl fmt::Display for InvalidStatusCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.description()) + } +} + +impl Error for InvalidStatusCode { + fn description(&self) -> &str { + "invalid status code" + } +} + +macro_rules! status_code_strs { + ($($num:expr,)+) => { + const CODES_AS_STR: [&'static str; 500] = [ $( stringify!($num), )+ ]; + } +} + +status_code_strs!( + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, + + 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, + 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, + 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, + ); diff -Nru cargo-0.33.0/vendor/http/src/uri/authority.rs cargo-0.35.0/vendor/http/src/uri/authority.rs --- cargo-0.33.0/vendor/http/src/uri/authority.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/authority.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,615 @@ +// Deprecated in 1.26, needed until our minimum version is >=1.23. +#[allow(unused, deprecated)] +use std::ascii::AsciiExt; +use std::{cmp, fmt, str}; +use std::hash::{Hash, Hasher}; +use std::str::FromStr; + +use bytes::Bytes; + +use byte_str::ByteStr; +use convert::HttpTryFrom; +use super::{ErrorKind, InvalidUri, InvalidUriBytes, URI_CHARS, Port}; + +/// Represents the authority component of a URI. +#[derive(Clone)] +pub struct Authority { + pub(super) data: ByteStr, +} + +impl Authority { + pub(super) fn empty() -> Self { + Authority { data: ByteStr::new() } + } + + /// Attempt to convert an `Authority` from `Bytes`. + /// + /// This function will be replaced by a `TryFrom` implementation once the + /// trait lands in stable. + /// + /// # Examples + /// + /// ``` + /// # extern crate http; + /// # use http::uri::*; + /// extern crate bytes; + /// + /// use bytes::Bytes; + /// + /// # pub fn main() { + /// let bytes = Bytes::from("example.com"); + /// let authority = Authority::from_shared(bytes).unwrap(); + /// + /// assert_eq!(authority.host(), "example.com"); + /// # } + /// ``` + pub fn from_shared(s: Bytes) -> Result { + let authority_end = Authority::parse_non_empty(&s[..]).map_err(InvalidUriBytes)?; + + if authority_end != s.len() { + return Err(ErrorKind::InvalidUriChar.into()); + } + + Ok(Authority { + data: unsafe { ByteStr::from_utf8_unchecked(s) }, + }) + } + + /// Attempt to convert an `Authority` from a static string. + /// + /// This function will not perform any copying, and the string will be + /// checked if it is empty or contains an invalid character. + /// + /// # Panics + /// + /// This function panics if the argument contains invalid characters or + /// is empty. + /// + /// # Examples + /// + /// ``` + /// # use http::uri::Authority; + /// let authority = Authority::from_static("example.com"); + /// assert_eq!(authority.host(), "example.com"); + /// ``` + pub fn from_static(src: &'static str) -> Self { + let s = src.as_bytes(); + let b = Bytes::from_static(s); + let authority_end = Authority::parse_non_empty(&b[..]).expect("static str is not valid authority"); + + if authority_end != b.len() { + panic!("static str is not valid authority"); + } + + Authority { + data: unsafe { ByteStr::from_utf8_unchecked(b) }, + } + } + + // Note: this may return an *empty* Authority. You might want `parse_non_empty`. + pub(super) fn parse(s: &[u8]) -> Result { + let mut colon_cnt = 0; + let mut start_bracket = false; + let mut end_bracket = false; + let mut has_percent = false; + let mut end = s.len(); + let mut at_sign_pos = None; + + for (i, &b) in s.iter().enumerate() { + match URI_CHARS[b as usize] { + b'/' | b'?' | b'#' => { + end = i; + break; + } + b':' => { + colon_cnt += 1; + }, + b'[' => { + start_bracket = true; + } + b']' => { + end_bracket = true; + + // Those were part of an IPv6 hostname, so forget them... + colon_cnt = 0; + } + b'@' => { + at_sign_pos = Some(i); + + // Those weren't a port colon, but part of the + // userinfo, so it needs to be forgotten. + colon_cnt = 0; + has_percent = false; + } + 0 if b == b'%' => { + // Per https://tools.ietf.org/html/rfc3986#section-3.2.1 and + // https://url.spec.whatwg.org/#authority-state + // the userinfo can have a percent-encoded username and password, + // so record that a `%` was found. If this turns out to be + // part of the userinfo, this flag will be cleared. + // If the flag hasn't been cleared at the end, that means this + // was part of the hostname, and will fail with an error. + has_percent = true; + } + 0 => { + return Err(ErrorKind::InvalidUriChar.into()); + } + _ => {} + } + } + + if start_bracket ^ end_bracket { + return Err(ErrorKind::InvalidAuthority.into()); + } + + if colon_cnt > 1 { + // Things like 'localhost:8080:3030' are rejected. + return Err(ErrorKind::InvalidAuthority.into()); + } + + if end > 0 && at_sign_pos == Some(end - 1) { + // If there's nothing after an `@`, this is bonkers. + return Err(ErrorKind::InvalidAuthority.into()); + } + + if has_percent { + // Something after the userinfo has a `%`, so reject it. + return Err(ErrorKind::InvalidAuthority.into()); + } + + Ok(end) + } + + // Parse bytes as an Authority, not allowing an empty string. + // + // This should be used by functions that allow a user to parse + // an `Authority` by itself. + fn parse_non_empty(s: &[u8]) -> Result { + if s.is_empty() { + return Err(ErrorKind::Empty.into()); + } + Authority::parse(s) + } + + /// Get the host of this `Authority`. + /// + /// The host subcomponent of authority is identified by an IP literal + /// encapsulated within square brackets, an IPv4 address in dotted- decimal + /// form, or a registered name. The host subcomponent is **case-insensitive**. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |---------| + /// | + /// host + /// ``` + /// + /// # Examples + /// + /// ``` + /// # use http::uri::*; + /// let authority: Authority = "example.org:80".parse().unwrap(); + /// + /// assert_eq!(authority.host(), "example.org"); + /// ``` + #[inline] + pub fn host(&self) -> &str { + host(self.as_str()) + } + + #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")] + #[doc(hidden)] + pub fn port(&self) -> Option { + self.port_u16() + } + + /// Get the port part of this `Authority`. + /// + /// The port subcomponent of authority is designated by an optional port + /// number following the host and delimited from it by a single colon (":") + /// character. It can be turned into a decimal port number with the `as_u16` + /// method or as a `str` with the `as_str` method. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-| + /// | + /// port + /// ``` + /// + /// # Examples + /// + /// Authority with port + /// + /// ``` + /// # use http::uri::Authority; + /// let authority: Authority = "example.org:80".parse().unwrap(); + /// + /// let port = authority.port_part().unwrap(); + /// assert_eq!(port.as_u16(), 80); + /// assert_eq!(port.as_str(), "80"); + /// ``` + /// + /// Authority without port + /// + /// ``` + /// # use http::uri::Authority; + /// let authority: Authority = "example.org".parse().unwrap(); + /// + /// assert!(authority.port_part().is_none()); + /// ``` + pub fn port_part(&self) -> Option> { + let bytes = self.as_str(); + bytes + .rfind(":") + .and_then(|i| Port::from_str(&bytes[i + 1..]).ok()) + } + + /// Get the port of this `Authority` as a `u16`. + /// + /// # Example + /// + /// ``` + /// # use http::uri::Authority; + /// let authority: Authority = "example.org:80".parse().unwrap(); + /// + /// assert_eq!(authority.port_u16(), Some(80)); + /// ``` + pub fn port_u16(&self) -> Option { + self.port_part().and_then(|p| Some(p.as_u16())) + } + + /// Return a str representation of the authority + #[inline] + pub fn as_str(&self) -> &str { + &self.data[..] + } + + /// Converts this `Authority` back to a sequence of bytes + #[inline] + pub fn into_bytes(self) -> Bytes { + self.into() + } +} + +impl AsRef for Authority { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl PartialEq for Authority { + fn eq(&self, other: &Authority) -> bool { + self.data.eq_ignore_ascii_case(&other.data) + } +} + +impl Eq for Authority {} + +/// Case-insensitive equality +/// +/// # Examples +/// +/// ``` +/// # use http::uri::Authority; +/// let authority: Authority = "HELLO.com".parse().unwrap(); +/// assert_eq!(authority, "hello.coM"); +/// assert_eq!("hello.com", authority); +/// ``` +impl PartialEq for Authority { + fn eq(&self, other: &str) -> bool { + self.data.eq_ignore_ascii_case(other) + } +} + +impl PartialEq for str { + fn eq(&self, other: &Authority) -> bool { + self.eq_ignore_ascii_case(other.as_str()) + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &Authority) -> bool { + self.eq_ignore_ascii_case(other.as_str()) + } +} + +impl<'a> PartialEq<&'a str> for Authority { + fn eq(&self, other: &&'a str) -> bool { + self.data.eq_ignore_ascii_case(other) + } +} + +impl PartialEq for Authority { + fn eq(&self, other: &String) -> bool { + self.data.eq_ignore_ascii_case(other.as_str()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &Authority) -> bool { + self.as_str().eq_ignore_ascii_case(other.as_str()) + } +} + +/// Case-insensitive ordering +/// +/// # Examples +/// +/// ``` +/// # use http::uri::Authority; +/// let authority: Authority = "DEF.com".parse().unwrap(); +/// assert!(authority < "ghi.com"); +/// assert!(authority > "abc.com"); +/// ``` +impl PartialOrd for Authority { + fn partial_cmp(&self, other: &Authority) -> Option { + let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl PartialOrd for Authority { + fn partial_cmp(&self, other: &str) -> Option { + let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl PartialOrd for str { + fn partial_cmp(&self, other: &Authority) -> Option { + let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl<'a> PartialOrd for &'a str { + fn partial_cmp(&self, other: &Authority) -> Option { + let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl<'a> PartialOrd<&'a str> for Authority { + fn partial_cmp(&self, other: &&'a str) -> Option { + let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl PartialOrd for Authority { + fn partial_cmp(&self, other: &String) -> Option { + let left = self.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +impl PartialOrd for String { + fn partial_cmp(&self, other: &Authority) -> Option { + let left = self.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + let right = other.data.as_bytes().iter().map(|b| b.to_ascii_lowercase()); + left.partial_cmp(right) + } +} + +/// Case-insensitive hashing +/// +/// # Examples +/// +/// ``` +/// # use http::uri::Authority; +/// # use std::hash::{Hash, Hasher}; +/// # use std::collections::hash_map::DefaultHasher; +/// +/// let a: Authority = "HELLO.com".parse().unwrap(); +/// let b: Authority = "hello.coM".parse().unwrap(); +/// +/// let mut s = DefaultHasher::new(); +/// a.hash(&mut s); +/// let a = s.finish(); +/// +/// let mut s = DefaultHasher::new(); +/// b.hash(&mut s); +/// let b = s.finish(); +/// +/// assert_eq!(a, b); +/// ``` +impl Hash for Authority { + fn hash(&self, state: &mut H) where H: Hasher { + self.data.len().hash(state); + for &b in self.data.as_bytes() { + state.write_u8(b.to_ascii_lowercase()); + } + } +} + +impl HttpTryFrom for Authority { + type Error = InvalidUriBytes; + #[inline] + fn try_from(bytes: Bytes) -> Result { + Authority::from_shared(bytes) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for Authority { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a [u8]) -> Result { + // parse first, and only turn into Bytes if valid + let end = Authority::parse_non_empty(s)?; + + if end != s.len() { + return Err(ErrorKind::InvalidAuthority.into()); + } + + Ok(Authority { + data: unsafe { ByteStr::from_utf8_unchecked(s.into()) }, + }) + } +} + +impl<'a> HttpTryFrom<&'a str> for Authority { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a str) -> Result { + HttpTryFrom::try_from(s.as_bytes()) + } +} + +impl FromStr for Authority { + type Err = InvalidUri; + + fn from_str(s: &str) -> Result { + HttpTryFrom::try_from(s) + } +} + +impl From for Bytes { + #[inline] + fn from(src: Authority) -> Bytes { + src.data.into() + } +} + +impl fmt::Debug for Authority { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl fmt::Display for Authority { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +fn host(auth: &str) -> &str { + let host_port = auth.rsplitn(2, '@') + .next() + .expect("split always has at least 1 item"); + + if host_port.as_bytes()[0] == b'[' { + let i = host_port.find(']') + .expect("parsing should validate brackets"); + // ..= ranges aren't available in 1.20, our minimum Rust version... + &host_port[0 .. i + 1] + } else { + host_port.split(':') + .next() + .expect("split always has at least 1 item") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_empty_string_is_error() { + let err = Authority::parse_non_empty(b"").unwrap_err(); + assert_eq!(err.0, ErrorKind::Empty); + } + + #[test] + fn equal_to_self_of_same_authority() { + let authority1: Authority = "example.com".parse().unwrap(); + let authority2: Authority = "EXAMPLE.COM".parse().unwrap(); + assert_eq!(authority1, authority2); + assert_eq!(authority2, authority1); + } + + #[test] + fn not_equal_to_self_of_different_authority() { + let authority1: Authority = "example.com".parse().unwrap(); + let authority2: Authority = "test.com".parse().unwrap(); + assert_ne!(authority1, authority2); + assert_ne!(authority2, authority1); + } + + #[test] + fn equates_with_a_str() { + let authority: Authority = "example.com".parse().unwrap(); + assert_eq!(&authority, "EXAMPLE.com"); + assert_eq!("EXAMPLE.com", &authority); + assert_eq!(authority, "EXAMPLE.com"); + assert_eq!("EXAMPLE.com", authority); + } + + #[test] + fn not_equal_with_a_str_of_a_different_authority() { + let authority: Authority = "example.com".parse().unwrap(); + assert_ne!(&authority, "test.com"); + assert_ne!("test.com", &authority); + assert_ne!(authority, "test.com"); + assert_ne!("test.com", authority); + } + + #[test] + fn equates_with_a_string() { + let authority: Authority = "example.com".parse().unwrap(); + assert_eq!(authority, "EXAMPLE.com".to_string()); + assert_eq!("EXAMPLE.com".to_string(), authority); + } + + #[test] + fn equates_with_a_string_of_a_different_authority() { + let authority: Authority = "example.com".parse().unwrap(); + assert_ne!(authority, "test.com".to_string()); + assert_ne!("test.com".to_string(), authority); + } + + #[test] + fn compares_to_self() { + let authority1: Authority = "abc.com".parse().unwrap(); + let authority2: Authority = "def.com".parse().unwrap(); + assert!(authority1 < authority2); + assert!(authority2 > authority1); + } + + #[test] + fn compares_with_a_str() { + let authority: Authority = "def.com".parse().unwrap(); + // with ref + assert!(&authority < "ghi.com"); + assert!("ghi.com" > &authority); + assert!(&authority > "abc.com"); + assert!("abc.com" < &authority); + + // no ref + assert!(authority < "ghi.com"); + assert!("ghi.com" > authority); + assert!(authority > "abc.com"); + assert!("abc.com" < authority); + } + + #[test] + fn compares_with_a_string() { + let authority: Authority = "def.com".parse().unwrap(); + assert!(authority < "ghi.com".to_string()); + assert!("ghi.com".to_string() > authority); + assert!(authority > "abc.com".to_string()); + assert!("abc.com".to_string() < authority); + } + + #[test] + fn allows_percent_in_userinfo() { + let authority_str = "a%2f:b%2f@example.com"; + let authority: Authority = authority_str.parse().unwrap(); + assert_eq!(authority, authority_str); + } + + #[test] + fn rejects_percent_in_hostname() { + let err = Authority::parse_non_empty(b"example%2f.com").unwrap_err(); + assert_eq!(err.0, ErrorKind::InvalidAuthority); + + let err = Authority::parse_non_empty(b"a%2f:b%2f@example%2f.com").unwrap_err(); + assert_eq!(err.0, ErrorKind::InvalidAuthority); + } +} diff -Nru cargo-0.33.0/vendor/http/src/uri/builder.rs cargo-0.35.0/vendor/http/src/uri/builder.rs --- cargo-0.33.0/vendor/http/src/uri/builder.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/builder.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,156 @@ +use {Uri, Result}; +use convert::{HttpTryFrom, HttpTryInto}; +use super::{Authority, Scheme, Parts, PathAndQuery}; + +/// A builder for `Uri`s. +/// +/// This type can be used to construct an instance of `Uri` +/// through a builder pattern. +#[derive(Debug)] +pub struct Builder { + parts: Option>, +} + +impl Builder { + /// Creates a new default instance of `Builder` to construct a `Uri`. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let uri = uri::Builder::new() + /// .scheme("https") + /// .authority("hyper.rs") + /// .path_and_query("/") + /// .build() + /// .unwrap(); + /// ``` + #[inline] + pub fn new() -> Builder { + Builder::default() + } + + /// Set the `Scheme` for this URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let mut builder = uri::Builder::new(); + /// builder.scheme("https"); + /// ``` + pub fn scheme(&mut self, scheme: T) -> &mut Self + where + Scheme: HttpTryFrom, + { + self.map(|parts| { + parts.scheme = Some(scheme.http_try_into()?); + Ok(()) + }) + } + + /// Set the `Authority` for this URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let uri = uri::Builder::new() + /// .authority("tokio.rs") + /// .build() + /// .unwrap(); + /// ``` + pub fn authority(&mut self, auth: T) -> &mut Self + where + Authority: HttpTryFrom, + { + self.map(|parts| { + parts.authority = Some(auth.http_try_into()?); + Ok(()) + }) + } + + /// Set the `PathAndQuery` for this URI. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let uri = uri::Builder::new() + /// .path_and_query("/hello?foo=bar") + /// .build() + /// .unwrap(); + /// ``` + pub fn path_and_query(&mut self, p_and_q: T) -> &mut Self + where + PathAndQuery: HttpTryFrom, + { + self.map(|parts| { + parts.path_and_query = Some(p_and_q.http_try_into()?); + Ok(()) + }) + } + + /// Consumes this builder, and tries to construct a valid `Uri` from + /// the configured pieces. + /// + /// # Errors + /// + /// This function may return an error if any previously configured argument + /// failed to parse or get converted to the internal representation. For + /// example if an invalid `scheme` was specified via `scheme("!@#%/^")` + /// the error will be returned when this function is called rather than + /// when `scheme` was called. + /// + /// Additionally, the various forms of URI require certain combinations of + /// parts to be set to be valid. If the parts don't fit into any of the + /// valid forms of URI, a new error is returned. + /// + /// # Examples + /// + /// ``` + /// # use http::*; + /// + /// let uri = Uri::builder() + /// .build() + /// .unwrap(); + /// ``` + pub fn build(&mut self) -> Result { + self + .parts + .take() + .expect("cannot reuse Uri builder") + .and_then(|parts| parts.http_try_into()) + } + + fn map(&mut self, f: F) -> &mut Self + where + F: FnOnce(&mut Parts) -> Result<()>, + { + let res = if let Some(Ok(ref mut parts)) = self.parts { + f(parts) + } else { + return self; + }; + + if let Err(err) = res { + self.parts = Some(Err(err)); + } + + self + } +} + +impl Default for Builder { + #[inline] + fn default() -> Builder { + Builder { + parts: Some(Ok(Parts::default())), + } + } +} + diff -Nru cargo-0.33.0/vendor/http/src/uri/mod.rs cargo-0.35.0/vendor/http/src/uri/mod.rs --- cargo-0.33.0/vendor/http/src/uri/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1138 @@ +//! URI component of request and response lines +//! +//! This module primarily contains the `Uri` type which is a component of all +//! HTTP requests and also reexports this type at the root of the crate. A URI +//! is not always a "full URL" in the sense of something you'd type into a web +//! browser, but HTTP requests may only have paths on servers but may have full +//! schemes and hostnames on clients. +//! +//! # Examples +//! +//! ``` +//! use http::Uri; +//! +//! let uri = "/foo/bar?baz".parse::().unwrap(); +//! assert_eq!(uri.path(), "/foo/bar"); +//! assert_eq!(uri.query(), Some("baz")); +//! assert_eq!(uri.host(), None); +//! +//! let uri = "https://www.rust-lang.org/install.html".parse::().unwrap(); +//! assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https")); +//! assert_eq!(uri.host(), Some("www.rust-lang.org")); +//! assert_eq!(uri.path(), "/install.html"); +//! ``` + +use HttpTryFrom; +use byte_str::ByteStr; + +use bytes::Bytes; + +use std::{fmt, u8, u16}; +// Deprecated in 1.26, needed until our minimum version is >=1.23. +#[allow(unused, deprecated)] +use std::ascii::AsciiExt; +use std::hash::{Hash, Hasher}; +use std::str::{self, FromStr}; +use std::error::Error; + +use self::scheme::Scheme2; + +pub use self::authority::Authority; +pub use self::builder::Builder; +pub use self::path::PathAndQuery; +pub use self::scheme::Scheme; +pub use self::port::Port; + +mod authority; +mod builder; +mod path; +mod port; +mod scheme; +#[cfg(test)] +mod tests; + +/// The URI component of a request. +/// +/// For HTTP 1, this is included as part of the request line. From Section 5.3, +/// Request Target: +/// +/// > Once an inbound connection is obtained, the client sends an HTTP +/// > request message (Section 3) with a request-target derived from the +/// > target URI. There are four distinct formats for the request-target, +/// > depending on both the method being requested and whether the request +/// > is to a proxy. +/// > +/// > ```notrust +/// > request-target = origin-form +/// > / absolute-form +/// > / authority-form +/// > / asterisk-form +/// > ``` +/// +/// The URI is structured as follows: +/// +/// ```notrust +/// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 +/// |-| |-------------------------------||--------| |-------------------| |-----| +/// | | | | | +/// scheme authority path query fragment +/// ``` +/// +/// For HTTP 2.0, the URI is encoded using pseudoheaders. +/// +/// # Examples +/// +/// ``` +/// use http::Uri; +/// +/// let uri = "/foo/bar?baz".parse::().unwrap(); +/// assert_eq!(uri.path(), "/foo/bar"); +/// assert_eq!(uri.query(), Some("baz")); +/// assert_eq!(uri.host(), None); +/// +/// let uri = "https://www.rust-lang.org/install.html".parse::().unwrap(); +/// assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https")); +/// assert_eq!(uri.host(), Some("www.rust-lang.org")); +/// assert_eq!(uri.path(), "/install.html"); +/// ``` +#[derive(Clone)] +pub struct Uri { + scheme: Scheme, + authority: Authority, + path_and_query: PathAndQuery, +} + +/// The various parts of a URI. +/// +/// This struct is used to provide to and retrieve from a URI. +#[derive(Debug, Default)] +pub struct Parts { + /// The scheme component of a URI + pub scheme: Option, + + /// The authority component of a URI + pub authority: Option, + + /// The origin-form component of a URI + pub path_and_query: Option, + + /// Allow extending in the future + _priv: (), +} + +/// An error resulting from a failed attempt to construct a URI. +#[derive(Debug)] +pub struct InvalidUri(ErrorKind); + +/// An error resulting from a failed attempt to construct a URI. +#[derive(Debug)] +pub struct InvalidUriBytes(InvalidUri); + +/// An error resulting from a failed attempt to construct a URI. +#[derive(Debug)] +pub struct InvalidUriParts(InvalidUri); + +#[derive(Debug, Eq, PartialEq)] +enum ErrorKind { + InvalidUriChar, + InvalidScheme, + InvalidAuthority, + InvalidPort, + InvalidFormat, + SchemeMissing, + AuthorityMissing, + PathAndQueryMissing, + TooLong, + Empty, + SchemeTooLong, +} + +// u16::MAX is reserved for None +const MAX_LEN: usize = (u16::MAX - 1) as usize; + +const URI_CHARS: [u8; 256] = [ + // 0 1 2 3 4 5 6 7 8 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 0, 0, 0, b'!', 0, b'#', b'$', 0, b'&', b'\'', // 3x + b'(', b')', b'*', b'+', b',', b'-', b'.', b'/', b'0', b'1', // 4x + b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', // 5x + 0, b'=', 0, b'?', b'@', b'A', b'B', b'C', b'D', b'E', // 6x + b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x + b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x + b'Z', b'[', 0, b']', 0, b'_', 0, b'a', b'b', b'c', // 9x + b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x + b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x + b'x', b'y', b'z', 0, 0, 0, b'~', 0, 0, 0, // 12x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x + 0, 0, 0, 0, 0, 0 // 25x +]; + +impl Uri { + /// Creates a new builder-style object to manufacture a `Uri`. + /// + /// This method returns an instance of `Builder` which can be usd to + /// create a `Uri`. + /// + /// # Examples + /// + /// ``` + /// use http::Uri; + /// + /// let uri = Uri::builder() + /// .scheme("https") + /// .authority("hyper.rs") + /// .path_and_query("/") + /// .build() + /// .unwrap(); + /// ``` + pub fn builder() -> Builder { + Builder::new() + } + + /// Attempt to convert a `Uri` from `Parts` + pub fn from_parts(src: Parts) -> Result { + if src.scheme.is_some() { + if src.authority.is_none() { + return Err(ErrorKind::AuthorityMissing.into()); + } + + if src.path_and_query.is_none() { + return Err(ErrorKind::PathAndQueryMissing.into()); + } + } else { + if src.authority.is_some() && src.path_and_query.is_some() { + return Err(ErrorKind::SchemeMissing.into()); + } + } + + let scheme = match src.scheme { + Some(scheme) => scheme, + None => Scheme { inner: Scheme2::None }, + }; + + let authority = match src.authority { + Some(authority) => authority, + None => Authority::empty(), + }; + + let path_and_query = match src.path_and_query { + Some(path_and_query) => path_and_query, + None => PathAndQuery::empty(), + }; + + Ok(Uri { + scheme: scheme, + authority: authority, + path_and_query: path_and_query, + }) + } + + /// Attempt to convert a `Uri` from `Bytes` + /// + /// This function will be replaced by a `TryFrom` implementation once the + /// trait lands in stable. + /// + /// # Examples + /// + /// ``` + /// # extern crate http; + /// # use http::uri::*; + /// extern crate bytes; + /// + /// use bytes::Bytes; + /// + /// # pub fn main() { + /// let bytes = Bytes::from("http://example.com/foo"); + /// let uri = Uri::from_shared(bytes).unwrap(); + /// + /// assert_eq!(uri.host().unwrap(), "example.com"); + /// assert_eq!(uri.path(), "/foo"); + /// # } + /// ``` + pub fn from_shared(s: Bytes) -> Result { + use self::ErrorKind::*; + + if s.len() > MAX_LEN { + return Err(TooLong.into()); + } + + match s.len() { + 0 => { + return Err(Empty.into()); + } + 1 => { + match s[0] { + b'/' => { + return Ok(Uri { + scheme: Scheme::empty(), + authority: Authority::empty(), + path_and_query: PathAndQuery::slash(), + }); + } + b'*' => { + return Ok(Uri { + scheme: Scheme::empty(), + authority: Authority::empty(), + path_and_query: PathAndQuery::star(), + }); + } + _ => { + let authority = Authority::from_shared(s)?; + + return Ok(Uri { + scheme: Scheme::empty(), + authority: authority, + path_and_query: PathAndQuery::empty(), + }); + } + } + } + _ => {} + } + + if s[0] == b'/' { + return Ok(Uri { + scheme: Scheme::empty(), + authority: Authority::empty(), + path_and_query: PathAndQuery::from_shared(s)?, + }); + } + + parse_full(s) + } + + /// Convert a `Uri` from a static string. + /// + /// This function will not perform any copying, however the string is + /// checked to ensure that it is valid. + /// + /// # Panics + /// + /// This function panics if the argument is an invalid URI. + /// + /// # Examples + /// + /// ``` + /// # use http::uri::Uri; + /// let uri = Uri::from_static("http://example.com/foo"); + /// + /// assert_eq!(uri.host().unwrap(), "example.com"); + /// assert_eq!(uri.path(), "/foo"); + /// ``` + pub fn from_static(src: &'static str) -> Self { + let s = Bytes::from_static(src.as_bytes()); + match Uri::from_shared(s) { + Ok(uri) => uri, + Err(e) => panic!("static str is not valid URI: {}", e), + } + } + + /// Convert a `Uri` into `Parts`. + /// + /// # Note + /// + /// This is just an inherent method providing the same functionality as + /// `let parts: Parts = uri.into()` + /// + /// # Examples + /// + /// ``` + /// # use http::uri::*; + /// let uri: Uri = "/foo".parse().unwrap(); + /// + /// let parts = uri.into_parts(); + /// + /// assert_eq!(parts.path_and_query.unwrap(), "/foo"); + /// + /// assert!(parts.scheme.is_none()); + /// assert!(parts.authority.is_none()); + /// ``` + #[inline] + pub fn into_parts(self) -> Parts { + self.into() + } + + /// Returns the path & query components of the Uri + #[inline] + pub fn path_and_query(&self) -> Option<&PathAndQuery> { + if !self.scheme.inner.is_none() || self.authority.data.is_empty() { + Some(&self.path_and_query) + } else { + None + } + } + + /// Get the path of this `Uri`. + /// + /// Both relative and absolute URIs contain a path component, though it + /// might be the empty string. The path component is **case sensitive**. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |--------| + /// | + /// path + /// ``` + /// + /// If the URI is `*` then the path component is equal to `*`. + /// + /// # Examples + /// + /// A relative URI + /// + /// ``` + /// # use http::Uri; + /// + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.path(), "/hello/world"); + /// ``` + /// + /// An absolute URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.path(), "/hello/world"); + /// ``` + #[inline] + pub fn path(&self) -> &str { + if self.has_path() { + self.path_and_query.path() + } else { + "" + } + } + + /// Get the scheme of this `Uri`. + /// + /// The URI scheme refers to a specification for assigning identifiers + /// within that scheme. Only absolute URIs contain a scheme component, but + /// not all absolute URIs will contain a scheme component. Although scheme + /// names are case-insensitive, the canonical form is lowercase. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-| + /// | + /// scheme + /// ``` + /// + /// # Examples + /// + /// Absolute URI + /// + /// ``` + /// use http::uri::{Scheme, Uri}; + /// + /// let uri: Uri = "http://example.org/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.scheme_part(), Some(&Scheme::HTTP)); + /// ``` + /// + /// + /// Relative URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert!(uri.scheme_part().is_none()); + /// ``` + #[inline] + pub fn scheme_part(&self) -> Option<&Scheme> { + if self.scheme.inner.is_none() { + None + } else { + Some(&self.scheme) + } + } + + #[deprecated(since = "0.1.2", note = "use scheme_part or scheme_str instead")] + #[doc(hidden)] + #[inline] + pub fn scheme(&self) -> Option<&str> { + self.scheme_str() + } + + /// Get the scheme of this `Uri` as a `&str`. + /// + /// # Example + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.scheme_str(), Some("http")); + /// ``` + #[inline] + pub fn scheme_str(&self) -> Option<&str> { + if self.scheme.inner.is_none() { + None + } else { + Some(self.scheme.as_str()) + } + } + + /// Get the authority of this `Uri`. + /// + /// The authority is a hierarchical element for naming authority such that + /// the remainder of the URI is delegated to that authority. For HTTP, the + /// authority consists of the host and port. The host portion of the + /// authority is **case-insensitive**. + /// + /// The authority also includes a `username:password` component, however + /// the use of this is deprecated and should be avoided. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-------------------------------| + /// | + /// authority + /// ``` + /// + /// This function will be renamed to `authority` in the next semver release. + /// + /// # Examples + /// + /// Absolute URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.authority_part().map(|a| a.as_str()), Some("example.org:80")); + /// ``` + /// + /// + /// Relative URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert!(uri.authority_part().is_none()); + /// ``` + #[inline] + pub fn authority_part(&self) -> Option<&Authority> { + if self.authority.data.is_empty() { + None + } else { + Some(&self.authority) + } + } + + #[deprecated(since = "0.1.1", note = "use authority_part instead")] + #[doc(hidden)] + #[inline] + pub fn authority(&self) -> Option<&str> { + if self.authority.data.is_empty() { + None + } else { + Some(self.authority.as_str()) + } + } + + /// Get the host of this `Uri`. + /// + /// The host subcomponent of authority is identified by an IP literal + /// encapsulated within square brackets, an IPv4 address in dotted- decimal + /// form, or a registered name. The host subcomponent is **case-insensitive**. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |---------| + /// | + /// host + /// ``` + /// + /// # Examples + /// + /// Absolute URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.host(), Some("example.org")); + /// ``` + /// + /// + /// Relative URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert!(uri.host().is_none()); + /// ``` + #[inline] + pub fn host(&self) -> Option<&str> { + self.authority_part().map(|a| a.host()) + } + + #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")] + #[doc(hidden)] + pub fn port(&self) -> Option { + self.port_u16() + } + + /// Get the port part of this `Uri`. + /// + /// The port subcomponent of authority is designated by an optional port + /// number following the host and delimited from it by a single colon (":") + /// character. It can be turned into a decimal port number with the `as_u16` + /// method or as a `str` with the `as_str` method. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-| + /// | + /// port + /// ``` + /// + /// # Examples + /// + /// Absolute URI with port + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap(); + /// + /// let port = uri.port_part().unwrap(); + /// assert_eq!(port.as_u16(), 80); + /// ``` + /// + /// Absolute URI without port + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org/hello/world".parse().unwrap(); + /// + /// assert!(uri.port_part().is_none()); + /// ``` + /// + /// Relative URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert!(uri.port_part().is_none()); + /// ``` + pub fn port_part(&self) -> Option> { + self.authority_part() + .and_then(|a| a.port_part()) + } + + /// Get the port of this `Uri` as a `u16`. + /// + /// + /// # Example + /// + /// ``` + /// # use http::{Uri, uri::Port}; + /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap(); + /// + /// assert_eq!(uri.port_u16(), Some(80)); + /// ``` + pub fn port_u16(&self) -> Option { + self.port_part().and_then(|p| Some(p.as_u16())) + } + + /// Get the query string of this `Uri`, starting after the `?`. + /// + /// The query component contains non-hierarchical data that, along with data + /// in the path component, serves to identify a resource within the scope of + /// the URI's scheme and naming authority (if any). The query component is + /// indicated by the first question mark ("?") character and terminated by a + /// number sign ("#") character or by the end of the URI. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-------------------| + /// | + /// query + /// ``` + /// + /// # Examples + /// + /// Absolute URI + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap(); + /// + /// assert_eq!(uri.query(), Some("key=value")); + /// ``` + /// + /// Relative URI with a query string component + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap(); + /// + /// assert_eq!(uri.query(), Some("key=value&foo=bar")); + /// ``` + /// + /// Relative URI without a query string component + /// + /// ``` + /// # use http::Uri; + /// let uri: Uri = "/hello/world".parse().unwrap(); + /// + /// assert!(uri.query().is_none()); + /// ``` + #[inline] + pub fn query(&self) -> Option<&str> { + self.path_and_query.query() + } + + fn has_path(&self) -> bool { + !self.path_and_query.data.is_empty() || !self.scheme.inner.is_none() + } +} + +impl<'a> HttpTryFrom<&'a str> for Uri { + type Error = InvalidUri; + + #[inline] + fn try_from(t: &'a str) -> Result { + t.parse() + } +} + +impl<'a> HttpTryFrom<&'a String> for Uri { + type Error = InvalidUri; + + #[inline] + fn try_from(t: &'a String) -> Result { + t.parse() + } +} + +impl HttpTryFrom for Uri { + type Error = InvalidUriBytes; + + #[inline] + fn try_from(t: String) -> Result { + Uri::from_shared(Bytes::from(t)) + } +} + +impl HttpTryFrom for Uri { + type Error = InvalidUriBytes; + + #[inline] + fn try_from(t: Bytes) -> Result { + Uri::from_shared(t) + } +} + +impl HttpTryFrom for Uri { + type Error = InvalidUriParts; + + #[inline] + fn try_from(src: Parts) -> Result { + Uri::from_parts(src) + } +} + +impl<'a> HttpTryFrom<&'a Uri> for Uri { + type Error = ::Error; + + #[inline] + fn try_from(src: &'a Uri) -> Result { + Ok(src.clone()) + } +} + +/// Convert a `Uri` from parts +/// +/// # Examples +/// +/// Relative URI +/// +/// ``` +/// # use http::uri::*; +/// let mut parts = Parts::default(); +/// parts.path_and_query = Some("/foo".parse().unwrap()); +/// +/// let uri = Uri::from_parts(parts).unwrap(); +/// +/// assert_eq!(uri.path(), "/foo"); +/// +/// assert!(uri.scheme_part().is_none()); +/// assert!(uri.authority().is_none()); +/// ``` +/// +/// Absolute URI +/// +/// ``` +/// # use http::uri::*; +/// let mut parts = Parts::default(); +/// parts.scheme = Some("http".parse().unwrap()); +/// parts.authority = Some("foo.com".parse().unwrap()); +/// parts.path_and_query = Some("/foo".parse().unwrap()); +/// +/// let uri = Uri::from_parts(parts).unwrap(); +/// +/// assert_eq!(uri.scheme_part().unwrap().as_str(), "http"); +/// assert_eq!(uri.authority().unwrap(), "foo.com"); +/// assert_eq!(uri.path(), "/foo"); +/// ``` +impl From for Parts { + fn from(src: Uri) -> Self { + let path_and_query = if src.has_path() { + Some(src.path_and_query) + } else { + None + }; + + let scheme = match src.scheme.inner { + Scheme2::None => None, + _ => Some(src.scheme), + }; + + let authority = if src.authority.data.is_empty() { + None + } else { + Some(src.authority) + }; + + Parts { + scheme: scheme, + authority: authority, + path_and_query: path_and_query, + _priv: (), + } + } +} + +fn parse_full(mut s: Bytes) -> Result { + // Parse the scheme + let scheme = match Scheme2::parse(&s[..]).map_err(InvalidUriBytes)? { + Scheme2::None => Scheme2::None, + Scheme2::Standard(p) => { + // TODO: use truncate + let _ = s.split_to(p.len() + 3); + Scheme2::Standard(p) + } + Scheme2::Other(n) => { + // Grab the protocol + let mut scheme = s.split_to(n + 3); + + // Strip ://, TODO: truncate + let _ = scheme.split_off(n); + + // Allocate the ByteStr + let val = unsafe { ByteStr::from_utf8_unchecked(scheme) }; + + Scheme2::Other(Box::new(val)) + } + }; + + // Find the end of the authority. The scheme will already have been + // extracted. + let authority_end = Authority::parse(&s[..]).map_err(InvalidUriBytes)?; + + if scheme.is_none() { + if authority_end != s.len() { + return Err(ErrorKind::InvalidFormat.into()); + } + + let authority = Authority { + data: unsafe { ByteStr::from_utf8_unchecked(s) }, + }; + + return Ok(Uri { + scheme: scheme.into(), + authority: authority, + path_and_query: PathAndQuery::empty(), + }); + } + + // Authority is required when absolute + if authority_end == 0 { + return Err(ErrorKind::InvalidFormat.into()); + } + + let authority = s.split_to(authority_end); + let authority = Authority { + data: unsafe { ByteStr::from_utf8_unchecked(authority) }, + }; + + Ok(Uri { + scheme: scheme.into(), + authority: authority, + path_and_query: PathAndQuery::from_shared(s)?, + }) +} + +impl FromStr for Uri { + type Err = InvalidUri; + + #[inline] + fn from_str(s: &str) -> Result { + Uri::from_shared(s.into()).map_err(|e| e.0) + } +} + +impl PartialEq for Uri { + fn eq(&self, other: &Uri) -> bool { + if self.scheme_part() != other.scheme_part() { + return false; + } + + if self.authority_part() != other.authority_part() { + return false; + } + + if self.path() != other.path() { + return false; + } + + if self.query() != other.query() { + return false; + } + + true + } +} + +impl PartialEq for Uri { + fn eq(&self, other: &str) -> bool { + let mut other = other.as_bytes(); + let mut absolute = false; + + if let Some(scheme) = self.scheme_part() { + let scheme = scheme.as_str().as_bytes(); + absolute = true; + + if other.len() < scheme.len() + 3 { + return false; + } + + if !scheme.eq_ignore_ascii_case(&other[..scheme.len()]) { + return false; + } + + other = &other[scheme.len()..]; + + if &other[..3] != b"://" { + return false; + } + + other = &other[3..]; + } + + if let Some(auth) = self.authority_part() { + let len = auth.data.len(); + absolute = true; + + if other.len() < len { + return false; + } + + if !auth.data.as_bytes().eq_ignore_ascii_case(&other[..len]) { + return false; + } + + other = &other[len..]; + } + + let path = self.path(); + + if other.len() < path.len() || path.as_bytes() != &other[..path.len()] { + if absolute && path == "/" { + // PathAndQuery can be ommitted, fall through + } else { + return false; + } + } else { + other = &other[path.len()..]; + } + + if let Some(query) = self.query() { + if other.len() == 0 { + return query.len() == 0; + } + + if other[0] != b'?' { + return false; + } + + other = &other[1..]; + + if other.len() < query.len() { + return false; + } + + if query.as_bytes() != &other[..query.len()] { + return false; + } + + other = &other[query.len()..]; + } + + other.is_empty() || other[0] == b'#' + } +} + +impl PartialEq for str { + fn eq(&self, uri: &Uri) -> bool { + uri == self + } +} + +impl<'a> PartialEq<&'a str> for Uri { + fn eq(&self, other: & &'a str) -> bool { + self == *other + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, uri: &Uri) -> bool { + uri == *self + } +} + +impl Eq for Uri {} + +/// Returns a `Uri` representing `/` +impl Default for Uri { + #[inline] + fn default() -> Uri { + Uri { + scheme: Scheme::empty(), + authority: Authority::empty(), + path_and_query: PathAndQuery::slash(), + } + } +} + +impl fmt::Display for Uri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(scheme) = self.scheme_part() { + write!(f, "{}://", scheme)?; + } + + if let Some(authority) = self.authority_part() { + write!(f, "{}", authority)?; + } + + write!(f, "{}", self.path())?; + + if let Some(query) = self.query() { + write!(f, "?{}", query)?; + } + + Ok(()) + } +} + +impl fmt::Debug for Uri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl From for InvalidUri { + fn from(src: ErrorKind) -> InvalidUri { + InvalidUri(src) + } +} + +impl From for InvalidUriBytes { + fn from(src: ErrorKind) -> InvalidUriBytes { + InvalidUriBytes(src.into()) + } +} + +impl From for InvalidUriParts { + fn from(src: ErrorKind) -> InvalidUriParts { + InvalidUriParts(src.into()) + } +} + +impl fmt::Display for InvalidUri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.description().fmt(f) + } +} + +impl Error for InvalidUri { + fn description(&self) -> &str { + match self.0 { + ErrorKind::InvalidUriChar => "invalid uri character", + ErrorKind::InvalidScheme => "invalid scheme", + ErrorKind::InvalidAuthority => "invalid authority", + ErrorKind::InvalidPort => "invalid port", + ErrorKind::InvalidFormat => "invalid format", + ErrorKind::SchemeMissing => "scheme missing", + ErrorKind::AuthorityMissing => "authority missing", + ErrorKind::PathAndQueryMissing => "path missing", + ErrorKind::TooLong => "uri too long", + ErrorKind::Empty => "empty string", + ErrorKind::SchemeTooLong => "scheme too long", + } + } +} + +impl fmt::Display for InvalidUriBytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl fmt::Display for InvalidUriParts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Error for InvalidUriBytes { + fn description(&self) -> &str { + self.0.description() + } +} + +impl Error for InvalidUriParts { + fn description(&self) -> &str { + self.0.description() + } +} + +impl Hash for Uri { + fn hash(&self, state: &mut H) where H: Hasher { + if !self.scheme.inner.is_none() { + self.scheme.hash(state); + state.write_u8(0xff); + } + + if let Some(auth) = self.authority_part() { + auth.hash(state); + } + + Hash::hash_slice(self.path().as_bytes(), state); + + if let Some(query) = self.query() { + b'?'.hash(state); + Hash::hash_slice(query.as_bytes(), state); + } + } +} diff -Nru cargo-0.33.0/vendor/http/src/uri/path.rs cargo-0.35.0/vendor/http/src/uri/path.rs --- cargo-0.33.0/vendor/http/src/uri/path.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/path.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,544 @@ +use std::{cmp, fmt, str}; +use std::str::FromStr; + +use bytes::Bytes; + +use byte_str::ByteStr; +use convert::HttpTryFrom; +use super::{ErrorKind, InvalidUri, InvalidUriBytes}; + +/// Represents the path component of a URI +#[derive(Clone)] +pub struct PathAndQuery { + pub(super) data: ByteStr, + pub(super) query: u16, +} + +const NONE: u16 = ::std::u16::MAX; + +impl PathAndQuery { + /// Attempt to convert a `PathAndQuery` from `Bytes`. + /// + /// This function will be replaced by a `TryFrom` implementation once the + /// trait lands in stable. + /// + /// # Examples + /// + /// ``` + /// # extern crate http; + /// # use http::uri::*; + /// extern crate bytes; + /// + /// use bytes::Bytes; + /// + /// # pub fn main() { + /// let bytes = Bytes::from("/hello?world"); + /// let path_and_query = PathAndQuery::from_shared(bytes).unwrap(); + /// + /// assert_eq!(path_and_query.path(), "/hello"); + /// assert_eq!(path_and_query.query(), Some("world")); + /// # } + /// ``` + pub fn from_shared(mut src: Bytes) -> Result { + let mut query = NONE; + let mut fragment = None; + + // block for iterator borrow + { + let mut iter = src.as_ref().iter().enumerate(); + + // path ... + for (i, &b) in &mut iter { + // See https://url.spec.whatwg.org/#path-state + match b { + b'?' => { + debug_assert_eq!(query, NONE); + query = i as u16; + break; + } + b'#' => { + fragment = Some(i); + break; + }, + + // This is the range of bytes that don't need to be + // percent-encoded in the path. If it should have been + // percent-encoded, then error. + 0x21 | + 0x24...0x3B | + 0x3D | + 0x40...0x5F | + 0x61...0x7A | + 0x7C | + 0x7E => {}, + + _ => return Err(ErrorKind::InvalidUriChar.into()), + } + } + + // query ... + if query != NONE { + for (i, &b) in iter { + match b { + // While queries *should* be percent-encoded, most + // bytes are actually allowed... + // See https://url.spec.whatwg.org/#query-state + // + // Allowed: 0x21 / 0x24 - 0x3B / 0x3D / 0x3F - 0x7E + 0x21 | + 0x24...0x3B | + 0x3D | + 0x3F...0x7E => {}, + + b'#' => { + fragment = Some(i); + break; + }, + + _ => return Err(ErrorKind::InvalidUriChar.into()), + } + } + } + } + + if let Some(i) = fragment { + src.truncate(i); + } + + Ok(PathAndQuery { + data: unsafe { ByteStr::from_utf8_unchecked(src) }, + query: query, + }) + } + + /// Convert a `PathAndQuery` from a static string. + /// + /// This function will not perform any copying, however the string is + /// checked to ensure that it is valid. + /// + /// # Panics + /// + /// This function panics if the argument is an invalid path and query. + /// + /// # Examples + /// + /// ``` + /// # use http::uri::*; + /// let v = PathAndQuery::from_static("/hello?world"); + /// + /// assert_eq!(v.path(), "/hello"); + /// assert_eq!(v.query(), Some("world")); + /// ``` + #[inline] + pub fn from_static(src: &'static str) -> Self { + let src = Bytes::from_static(src.as_bytes()); + + PathAndQuery::from_shared(src) + .unwrap() + } + + pub(super) fn empty() -> Self { + PathAndQuery { + data: ByteStr::new(), + query: NONE, + } + } + + pub(super) fn slash() -> Self { + PathAndQuery { + data: ByteStr::from_static("/"), + query: NONE, + } + } + + pub(super) fn star() -> Self { + PathAndQuery { + data: ByteStr::from_static("*"), + query: NONE, + } + } + + /// Returns the path component + /// + /// The path component is **case sensitive**. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |--------| + /// | + /// path + /// ``` + /// + /// If the URI is `*` then the path component is equal to `*`. + /// + /// # Examples + /// + /// ``` + /// # use http::uri::*; + /// + /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap(); + /// + /// assert_eq!(path_and_query.path(), "/hello/world"); + /// ``` + #[inline] + pub fn path(&self) -> &str { + let ret = if self.query == NONE { + &self.data[..] + } else { + &self.data[..self.query as usize] + }; + + if ret.is_empty() { + return "/"; + } + + ret + } + + /// Returns the query string component + /// + /// The query component contains non-hierarchical data that, along with data + /// in the path component, serves to identify a resource within the scope of + /// the URI's scheme and naming authority (if any). The query component is + /// indicated by the first question mark ("?") character and terminated by a + /// number sign ("#") character or by the end of the URI. + /// + /// ```notrust + /// abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 + /// |-------------------| + /// | + /// query + /// ``` + /// + /// # Examples + /// + /// With a query string component + /// + /// ``` + /// # use http::uri::*; + /// let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap(); + /// + /// assert_eq!(path_and_query.query(), Some("key=value&foo=bar")); + /// ``` + /// + /// Without a query string component + /// + /// ``` + /// # use http::uri::*; + /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap(); + /// + /// assert!(path_and_query.query().is_none()); + /// ``` + #[inline] + pub fn query(&self) -> Option<&str> { + if self.query == NONE { + None + } else { + let i = self.query + 1; + Some(&self.data[i as usize..]) + } + } + + /// Returns the path and query as a string component. + /// + /// # Examples + /// + /// With a query string component + /// + /// ``` + /// # use http::uri::*; + /// let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap(); + /// + /// assert_eq!(path_and_query.as_str(), "/hello/world?key=value&foo=bar"); + /// ``` + /// + /// Without a query string component + /// + /// ``` + /// # use http::uri::*; + /// let path_and_query: PathAndQuery = "/hello/world".parse().unwrap(); + /// + /// assert_eq!(path_and_query.as_str(), "/hello/world"); + /// ``` + #[inline] + pub fn as_str(&self) -> &str { + let ret = &self.data[..]; + if ret.is_empty() { + return "/"; + } + ret + } + + /// Converts this `PathAndQuery` back to a sequence of bytes + #[inline] + pub fn into_bytes(self) -> Bytes { + self.into() + } +} + +impl HttpTryFrom for PathAndQuery { + type Error = InvalidUriBytes; + #[inline] + fn try_from(bytes: Bytes) -> Result { + PathAndQuery::from_shared(bytes) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for PathAndQuery { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a [u8]) -> Result { + PathAndQuery::from_shared(s.into()).map_err(|e| e.0) + } +} + +impl<'a> HttpTryFrom<&'a str> for PathAndQuery { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a str) -> Result { + HttpTryFrom::try_from(s.as_bytes()) + } +} + +impl FromStr for PathAndQuery { + type Err = InvalidUri; + #[inline] + fn from_str(s: &str) -> Result { + HttpTryFrom::try_from(s) + } +} + +impl From for Bytes { + fn from(src: PathAndQuery) -> Bytes { + src.data.into() + } +} + +impl fmt::Debug for PathAndQuery { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Display for PathAndQuery { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + if !self.data.is_empty() { + match self.data.as_bytes()[0] { + b'/' | b'*' => write!(fmt, "{}", &self.data[..]), + _ => write!(fmt, "/{}", &self.data[..]), + } + } else { + write!(fmt, "/") + } + } +} + +// ===== PartialEq / PartialOrd ===== + +impl PartialEq for PathAndQuery { + #[inline] + fn eq(&self, other: &PathAndQuery) -> bool { + self.data == other.data + } +} + +impl Eq for PathAndQuery {} + +impl PartialEq for PathAndQuery { + #[inline] + fn eq(&self, other: &str) -> bool { + self.as_str() == other + } +} + +impl<'a> PartialEq for &'a str { + #[inline] + fn eq(&self, other: &PathAndQuery) -> bool { + self == &other.as_str() + } +} + +impl<'a> PartialEq<&'a str> for PathAndQuery { + #[inline] + fn eq(&self, other: &&'a str) -> bool { + self.as_str() == *other + } +} + +impl PartialEq for str { + #[inline] + fn eq(&self, other: &PathAndQuery) -> bool { + self == other.as_str() + } +} + +impl PartialEq for PathAndQuery { + #[inline] + fn eq(&self, other: &String) -> bool { + self.as_str() == other.as_str() + } +} + +impl PartialEq for String { + #[inline] + fn eq(&self, other: &PathAndQuery) -> bool { + self.as_str() == other.as_str() + } +} + +impl PartialOrd for PathAndQuery { + #[inline] + fn partial_cmp(&self, other: &PathAndQuery) -> Option { + self.as_str().partial_cmp(other.as_str()) + } +} + +impl PartialOrd for PathAndQuery { + #[inline] + fn partial_cmp(&self, other: &str) -> Option { + self.as_str().partial_cmp(other) + } +} + +impl PartialOrd for str { + #[inline] + fn partial_cmp(&self, other: &PathAndQuery) -> Option { + self.partial_cmp(other.as_str()) + } +} + +impl<'a> PartialOrd<&'a str> for PathAndQuery { + #[inline] + fn partial_cmp(&self, other: &&'a str) -> Option { + self.as_str().partial_cmp(*other) + } +} + +impl<'a> PartialOrd for &'a str { + #[inline] + fn partial_cmp(&self, other: &PathAndQuery) -> Option { + self.partial_cmp(&other.as_str()) + } +} + +impl PartialOrd for PathAndQuery { + #[inline] + fn partial_cmp(&self, other: &String) -> Option { + self.as_str().partial_cmp(other.as_str()) + } +} + +impl PartialOrd for String { + #[inline] + fn partial_cmp(&self, other: &PathAndQuery) -> Option { + self.as_str().partial_cmp(other.as_str()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn equal_to_self_of_same_path() { + let p1: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + let p2: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + assert_eq!(p1, p2); + assert_eq!(p2, p1); + } + + #[test] + fn not_equal_to_self_of_different_path() { + let p1: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + let p2: PathAndQuery = "/world&foo=bar".parse().unwrap(); + assert_ne!(p1, p2); + assert_ne!(p2, p1); + } + + #[test] + fn equates_with_a_str() { + let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + assert_eq!(&path_and_query, "/hello/world&foo=bar"); + assert_eq!("/hello/world&foo=bar", &path_and_query); + assert_eq!(path_and_query, "/hello/world&foo=bar"); + assert_eq!("/hello/world&foo=bar", path_and_query); + } + + #[test] + fn not_equal_with_a_str_of_a_different_path() { + let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + // as a reference + assert_ne!(&path_and_query, "/hello&foo=bar"); + assert_ne!("/hello&foo=bar", &path_and_query); + // without reference + assert_ne!(path_and_query, "/hello&foo=bar"); + assert_ne!("/hello&foo=bar", path_and_query); + } + + #[test] + fn equates_with_a_string() { + let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + assert_eq!(path_and_query, "/hello/world&foo=bar".to_string()); + assert_eq!("/hello/world&foo=bar".to_string(), path_and_query); + } + + #[test] + fn not_equal_with_a_string_of_a_different_path() { + let path_and_query: PathAndQuery = "/hello/world&foo=bar".parse().unwrap(); + assert_ne!(path_and_query, "/hello&foo=bar".to_string()); + assert_ne!("/hello&foo=bar".to_string(), path_and_query); + } + + #[test] + fn compares_to_self() { + let p1: PathAndQuery = "/a/world&foo=bar".parse().unwrap(); + let p2: PathAndQuery = "/b/world&foo=bar".parse().unwrap(); + assert!(p1 < p2); + assert!(p2 > p1); + } + + #[test] + fn compares_with_a_str() { + let path_and_query: PathAndQuery = "/b/world&foo=bar".parse().unwrap(); + // by ref + assert!(&path_and_query < "/c/world&foo=bar"); + assert!("/c/world&foo=bar" > &path_and_query); + assert!(&path_and_query > "/a/world&foo=bar"); + assert!("/a/world&foo=bar" < &path_and_query); + + // by val + assert!(path_and_query < "/c/world&foo=bar"); + assert!("/c/world&foo=bar" > path_and_query); + assert!(path_and_query > "/a/world&foo=bar"); + assert!("/a/world&foo=bar" < path_and_query); + } + + #[test] + fn compares_with_a_string() { + let path_and_query: PathAndQuery = "/b/world&foo=bar".parse().unwrap(); + assert!(path_and_query < "/c/world&foo=bar".to_string()); + assert!("/c/world&foo=bar".to_string() > path_and_query); + assert!(path_and_query > "/a/world&foo=bar".to_string()); + assert!("/a/world&foo=bar".to_string() < path_and_query); + } + + #[test] + fn ignores_valid_percent_encodings() { + assert_eq!("/a%20b", pq("/a%20b?r=1").path()); + assert_eq!("qr=%31", pq("/a/b?qr=%31").query().unwrap()); + } + + #[test] + fn ignores_invalid_percent_encodings() { + assert_eq!("/a%%b", pq("/a%%b?r=1").path()); + assert_eq!("/aaa%", pq("/aaa%").path()); + assert_eq!("/aaa%", pq("/aaa%?r=1").path()); + assert_eq!("/aa%2", pq("/aa%2").path()); + assert_eq!("/aa%2", pq("/aa%2?r=1").path()); + assert_eq!("qr=%3", pq("/a/b?qr=%3").query().unwrap()); + } + + fn pq(s: &str) -> PathAndQuery { + s.parse().expect(&format!("parsing {}", s)) + } +} diff -Nru cargo-0.33.0/vendor/http/src/uri/port.rs cargo-0.35.0/vendor/http/src/uri/port.rs --- cargo-0.33.0/vendor/http/src/uri/port.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/port.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,158 @@ +use std::fmt; + +use super::{ErrorKind, InvalidUri}; + +/// The port component of a URI. +pub struct Port { + port: u16, + repr: T, +} + +impl Port { + /// Returns the port number as a `u16`. + /// + /// # Examples + /// + /// Port as `u16`. + /// + /// ``` + /// # use http::uri::Authority; + /// let authority: Authority = "example.org:80".parse().unwrap(); + /// + /// let port = authority.port_part().unwrap(); + /// assert_eq!(port.as_u16(), 80); + /// ``` + pub fn as_u16(&self) -> u16 { + self.port + } +} + +impl Port +where + T: AsRef, +{ + /// Converts a `str` to a port number. + /// + /// The supplied `str` must be a valid u16. + pub(crate) fn from_str(bytes: T) -> Result { + bytes + .as_ref() + .parse::() + .map(|port| Port { + port, + repr: bytes, + }) + .map_err(|_| { + ErrorKind::InvalidPort.into() + }) + } + + /// Returns the port number as a `str`. + /// + /// # Examples + /// + /// Port as `str`. + /// + /// ``` + /// # use http::uri::Authority; + /// let authority: Authority = "example.org:80".parse().unwrap(); + /// + /// let port = authority.port_part().unwrap(); + /// assert_eq!(port.as_str(), "80"); + /// ``` + pub fn as_str(&self) -> &str { + self.repr.as_ref() + } +} + +impl fmt::Debug for Port +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Port") + .field(&self.port) + .finish() + } +} + +impl fmt::Display for Port { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Use `u16::fmt` so that it respects any formatting flags that + // may have been set (like padding, align, etc). + fmt::Display::fmt(&self.port, f) + } +} + +impl From> for u16 { + fn from(port: Port) -> Self { + port.as_u16() + } +} + +impl AsRef for Port +where + T: AsRef, +{ + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl PartialEq> for Port { + fn eq(&self, other: &Port) -> bool { + self.port == other.port + } +} + +impl PartialEq for Port { + fn eq(&self, other: &u16) -> bool { + self.port == *other + } +} + +impl PartialEq> for u16 { + fn eq(&self, other: &Port) -> bool { + other.port == *self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn partialeq_port() { + let port_a = Port::from_str("8080").unwrap(); + let port_b = Port::from_str("8080").unwrap(); + assert_eq!(port_a, port_b); + } + + #[test] + fn partialeq_port_different_reprs() { + let port_a = Port { + repr: "8081", + port: 8081, + }; + let port_b = Port { + repr: String::from("8081"), + port: 8081, + }; + assert_eq!(port_a, port_b); + assert_eq!(port_b, port_a); + } + + #[test] + fn partialeq_u16() { + let port = Port::from_str("8080").unwrap(); + // test equals in both directions + assert_eq!(port, 8080); + assert_eq!(8080, port); + } + + #[test] + fn u16_from_port() { + let port = Port::from_str("8080").unwrap(); + assert_eq!(8080, u16::from(port)); + } +} diff -Nru cargo-0.33.0/vendor/http/src/uri/scheme.rs cargo-0.35.0/vendor/http/src/uri/scheme.rs --- cargo-0.33.0/vendor/http/src/uri/scheme.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/scheme.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,389 @@ +// Deprecated in 1.26, needed until our minimum version is >=1.23. +#[allow(unused, deprecated)] +use std::ascii::AsciiExt; +use std::fmt; +use std::hash::{Hash, Hasher}; +use std::str::FromStr; + +use bytes::Bytes; + +use byte_str::ByteStr; +use convert::HttpTryFrom; +use super::{ErrorKind, InvalidUri, InvalidUriBytes}; + +/// Represents the scheme component of a URI +#[derive(Clone)] +pub struct Scheme { + pub(super) inner: Scheme2, +} + +#[derive(Clone, Debug)] +pub(super) enum Scheme2> { + None, + Standard(Protocol), + Other(T), +} + +#[derive(Copy, Clone, Debug)] +pub(super) enum Protocol { + Http, + Https, +} + +impl Scheme { + /// HTTP protocol scheme + pub const HTTP: Scheme = Scheme { + inner: Scheme2::Standard(Protocol::Http), + }; + + /// HTTP protocol over TLS. + pub const HTTPS: Scheme = Scheme { + inner: Scheme2::Standard(Protocol::Https), + }; + + /// Attempt to convert a `Scheme` from `Bytes` + /// + /// This function will be replaced by a `TryFrom` implementation once the + /// trait lands in stable. + /// + /// # Examples + /// + /// ``` + /// # extern crate http; + /// # use http::uri::*; + /// extern crate bytes; + /// + /// use bytes::Bytes; + /// + /// # pub fn main() { + /// let bytes = Bytes::from("http"); + /// let scheme = Scheme::from_shared(bytes).unwrap(); + /// + /// assert_eq!(scheme.as_str(), "http"); + /// # } + /// ``` + pub fn from_shared(s: Bytes) -> Result { + use self::Scheme2::*; + + match Scheme2::parse_exact(&s[..]).map_err(InvalidUriBytes)? { + None => Err(ErrorKind::InvalidScheme.into()), + Standard(p) => Ok(Standard(p).into()), + Other(_) => { + let b = unsafe { ByteStr::from_utf8_unchecked(s) }; + Ok(Other(Box::new(b)).into()) + } + } + } + + pub(super) fn empty() -> Self { + Scheme { + inner: Scheme2::None, + } + } + + /// Return a str representation of the scheme + /// + /// # Examples + /// + /// ``` + /// # use http::uri::*; + /// let scheme: Scheme = "http".parse().unwrap(); + /// assert_eq!(scheme.as_str(), "http"); + /// ``` + #[inline] + pub fn as_str(&self) -> &str { + use self::Scheme2::*; + use self::Protocol::*; + + match self.inner { + Standard(Http) => "http", + Standard(Https) => "https", + Other(ref v) => &v[..], + None => unreachable!(), + } + } + + /// Converts this `Scheme` back to a sequence of bytes + #[inline] + pub fn into_bytes(self) -> Bytes { + self.into() + } +} + +impl HttpTryFrom for Scheme { + type Error = InvalidUriBytes; + #[inline] + fn try_from(bytes: Bytes) -> Result { + Scheme::from_shared(bytes) + } +} + +impl<'a> HttpTryFrom<&'a [u8]> for Scheme { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a [u8]) -> Result { + use self::Scheme2::*; + + match Scheme2::parse_exact(s)? { + None => Err(ErrorKind::InvalidScheme.into()), + Standard(p) => Ok(Standard(p).into()), + Other(_) => { + // Unsafe: parse_exact already checks for a strict subset of UTF-8 + Ok(Other(Box::new(unsafe { + ByteStr::from_utf8_unchecked(s.into()) + })).into()) + } + } + } +} + +impl<'a> HttpTryFrom<&'a str> for Scheme { + type Error = InvalidUri; + #[inline] + fn try_from(s: &'a str) -> Result { + HttpTryFrom::try_from(s.as_bytes()) + } +} + +impl FromStr for Scheme { + type Err = InvalidUri; + + fn from_str(s: &str) -> Result { + HttpTryFrom::try_from(s) + } +} + +impl From for Bytes { + #[inline] + fn from(src: Scheme) -> Self { + use self::Scheme2::*; + use self::Protocol::*; + + match src.inner { + None => Bytes::new(), + Standard(Http) => Bytes::from_static(b"http"), + Standard(Https) => Bytes::from_static(b"https"), + Other(v) => (*v).into(), + } + } +} + +impl fmt::Debug for Scheme { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.as_str(), f) + } +} + +impl fmt::Display for Scheme { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl AsRef for Scheme { + #[inline] + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl PartialEq for Scheme { + fn eq(&self, other: &Scheme) -> bool { + use self::Protocol::*; + use self::Scheme2::*; + + match (&self.inner, &other.inner) { + (&Standard(Http), &Standard(Http)) => true, + (&Standard(Https), &Standard(Https)) => true, + (&Other(ref a), &Other(ref b)) => a.eq_ignore_ascii_case(b), + (&None, _) | (_, &None) => unreachable!(), + _ => false, + } + } +} + +impl Eq for Scheme {} + +/// Case-insensitive equality +/// +/// # Examples +/// +/// ``` +/// # use http::uri::Scheme; +/// let scheme: Scheme = "HTTP".parse().unwrap(); +/// assert_eq!(scheme, *"http"); +/// ``` +impl PartialEq for Scheme { + fn eq(&self, other: &str) -> bool { + self.as_str().eq_ignore_ascii_case(other) + } +} + +/// Case-insensitive equality +impl PartialEq for str { + fn eq(&self, other: &Scheme) -> bool { + other == self + } +} + +/// Case-insensitive hashing +impl Hash for Scheme { + fn hash(&self, state: &mut H) where H: Hasher { + match self.inner { + Scheme2::None => (), + Scheme2::Standard(Protocol::Http) => state.write_u8(1), + Scheme2::Standard(Protocol::Https) => state.write_u8(2), + Scheme2::Other(ref other) => { + other.len().hash(state); + for &b in other.as_bytes() { + state.write_u8(b.to_ascii_lowercase()); + } + } + } + } +} + +impl Scheme2 { + pub(super) fn is_none(&self) -> bool { + match *self { + Scheme2::None => true, + _ => false, + } + } +} + +// Require the scheme to not be too long in order to enable further +// optimizations later. +const MAX_SCHEME_LEN: usize = 64; + +// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) +// +const SCHEME_CHARS: [u8; 256] = [ + // 0 1 2 3 4 5 6 7 8 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3x + 0, 0, 0, b'+', 0, b'-', b'.', 0, b'0', b'1', // 4x + b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', 0, // 5x + 0, 0, 0, 0, 0, b'A', b'B', b'C', b'D', b'E', // 6x + b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', // 7x + b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', // 8x + b'Z', 0, 0, 0, 0, 0, 0, b'a', b'b', b'c', // 9x + b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', // 10x + b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', // 11x + b'x', b'y', b'z', 0, 0, 0, b'~', 0, 0, 0, // 12x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 18x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 19x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 21x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 22x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 23x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 24x + 0, 0, 0, 0, 0, 0 // 25x +]; + +impl Scheme2 { + fn parse_exact(s: &[u8]) -> Result, InvalidUri> { + match s { + b"http" => Ok(Protocol::Http.into()), + b"https" => Ok(Protocol::Https.into()), + _ => { + if s.len() > MAX_SCHEME_LEN { + return Err(ErrorKind::SchemeTooLong.into()); + } + + for &b in s { + match SCHEME_CHARS[b as usize] { + b':' => { + // Don't want :// here + return Err(ErrorKind::InvalidScheme.into()); + } + 0 => { + return Err(ErrorKind::InvalidScheme.into()); + } + _ => {} + } + } + + Ok(Scheme2::Other(())) + } + } + } + + pub(super) fn parse(s: &[u8]) -> Result, InvalidUri> { + if s.len() >= 7 { + // Check for HTTP + if s[..7].eq_ignore_ascii_case(b"http://") { + // Prefix will be striped + return Ok(Protocol::Http.into()); + } + } + + if s.len() >= 8 { + // Check for HTTPs + if s[..8].eq_ignore_ascii_case(b"https://") { + return Ok(Protocol::Https.into()); + } + } + + if s.len() > 3 { + for i in 0..s.len() { + let b = s[i]; + + if i == MAX_SCHEME_LEN { + return Err(ErrorKind::SchemeTooLong.into()); + } + + match SCHEME_CHARS[b as usize] { + b':' => { + // Not enough data remaining + if s.len() < i + 3 { + break; + } + + // Not a scheme + if &s[i+1..i+3] != b"//" { + break; + } + + // Return scheme + return Ok(Scheme2::Other(i)); + } + // Invald scheme character, abort + 0 => break, + _ => {} + } + } + } + + Ok(Scheme2::None) + } +} + +impl Protocol { + pub(super) fn len(&self) -> usize { + match *self { + Protocol::Http => 4, + Protocol::Https => 5, + } + } +} + +impl From for Scheme2 { + fn from(src: Protocol) -> Self { + Scheme2::Standard(src) + } +} + +#[doc(hidden)] +impl From for Scheme { + fn from(src: Scheme2) -> Self { + Scheme { inner: src } + } +} diff -Nru cargo-0.33.0/vendor/http/src/uri/tests.rs cargo-0.35.0/vendor/http/src/uri/tests.rs --- cargo-0.33.0/vendor/http/src/uri/tests.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/uri/tests.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,484 @@ +use std::str::FromStr; + +use super::{ErrorKind, InvalidUri, Uri, URI_CHARS, Port}; + +#[test] +fn test_char_table() { + for (i, &v) in URI_CHARS.iter().enumerate() { + if v != 0 { + assert_eq!(i, v as usize); + } + } +} + +macro_rules! part { + ($s:expr) => ( + Some(&$s.parse().unwrap()) + ) +} + +macro_rules! test_parse { + ( + $test_name:ident, + $str:expr, + $alt:expr, + $($method:ident = $value:expr,)* + ) => ( + #[test] + fn $test_name() { + let orig_str = $str; + let uri = match Uri::from_str(orig_str) { + Ok(uri) => uri, + Err(err) => { + panic!("parse error {:?} from {:?}", err, orig_str); + }, + }; + $( + assert_eq!(uri.$method(), $value, "{}: uri = {:?}", stringify!($method), uri); + )+ + assert_eq!(uri, orig_str, "partial eq to original str"); + assert_eq!(uri, uri.clone(), "clones are equal"); + + let new_str = uri.to_string(); + let new_uri = Uri::from_str(&new_str).expect("to_string output parses again as a Uri"); + assert_eq!(new_uri, orig_str, "round trip still equals original str"); + + const ALT: &'static [&'static str] = &$alt; + + for &alt in ALT.iter() { + let other: Uri = alt.parse().unwrap(); + assert_eq!(uri, *alt); + assert_eq!(uri, other); + } + } + ); +} + +test_parse! { + test_uri_parse_path_and_query, + "/some/path/here?and=then&hello#and-bye", + [], + + scheme_part = None, + authority_part = None, + path = "/some/path/here", + query = Some("and=then&hello"), + host = None, +} + +test_parse! { + test_uri_parse_absolute_form, + "http://127.0.0.1:61761/chunks", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1:61761"), + path = "/chunks", + query = None, + host = Some("127.0.0.1"), + port_part = Port::from_str("61761").ok(), +} + +test_parse! { + test_uri_parse_absolute_form_without_path, + "https://127.0.0.1:61761", + ["https://127.0.0.1:61761/"], + + scheme_part = part!("https"), + authority_part = part!("127.0.0.1:61761"), + path = "/", + query = None, + host = Some("127.0.0.1"), + port_part = Port::from_str("61761").ok(), +} + +test_parse! { + test_uri_parse_asterisk_form, + "*", + [], + + scheme_part = None, + authority_part = None, + path = "*", + query = None, + host = None, +} + +test_parse! { + test_uri_parse_authority_no_port, + "localhost", + ["LOCALHOST", "LocaLHOSt"], + + scheme_part = None, + authority_part = part!("localhost"), + path = "", + query = None, + port_part = None, + host = Some("localhost"), +} + +test_parse! { + test_uri_authority_only_one_character_issue_197, + "S", + [], + + scheme_part = None, + authority_part = part!("S"), + path = "", + query = None, + port_part = None, + host = Some("S"), +} + +test_parse! { + test_uri_parse_authority_form, + "localhost:3000", + ["localhosT:3000"], + + scheme_part = None, + authority_part = part!("localhost:3000"), + path = "", + query = None, + host = Some("localhost"), + port_part = Port::from_str("3000").ok(), +} + + +test_parse! { + test_uri_parse_absolute_with_default_port_http, + "http://127.0.0.1:80", + ["http://127.0.0.1:80/"], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1:80"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = Port::from_str("80").ok(), +} + +test_parse! { + test_uri_parse_absolute_with_default_port_https, + "https://127.0.0.1:443", + ["https://127.0.0.1:443/"], + + scheme_part = part!("https"), + authority_part = part!("127.0.0.1:443"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = Port::from_str("443").ok(), +} + +test_parse! { + test_uri_parse_fragment_questionmark, + "http://127.0.0.1/#?", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_uri_parse_path_with_terminating_questionmark, + "http://127.0.0.1/path?", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1"), + path = "/path", + query = Some(""), + port_part = None, +} + +test_parse! { + test_uri_parse_absolute_form_with_empty_path_and_nonempty_query, + "http://127.0.0.1?foo=bar", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1"), + path = "/", + query = Some("foo=bar"), + port_part = None, +} + +test_parse! { + test_uri_parse_absolute_form_with_empty_path_and_fragment_with_slash, + "http://127.0.0.1#foo/bar", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_uri_parse_absolute_form_with_empty_path_and_fragment_with_questionmark, + "http://127.0.0.1#foo?bar", + [], + + scheme_part = part!("http"), + authority_part = part!("127.0.0.1"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_userinfo1, + "http://a:b@127.0.0.1:1234/", + [], + + scheme_part = part!("http"), + authority_part = part!("a:b@127.0.0.1:1234"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = Port::from_str("1234").ok(), +} + +test_parse! { + test_userinfo2, + "http://a:b@127.0.0.1/", + [], + + scheme_part = part!("http"), + authority_part = part!("a:b@127.0.0.1"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_userinfo3, + "http://a@127.0.0.1/", + [], + + scheme_part = part!("http"), + authority_part = part!("a@127.0.0.1"), + host = Some("127.0.0.1"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_userinfo_with_port, + "user@localhost:3000", + [], + + scheme_part = None, + authority_part = part!("user@localhost:3000"), + path = "", + query = None, + host = Some("localhost"), + port_part = Port::from_str("3000").ok(), +} + +test_parse! { + test_userinfo_pass_with_port, + "user:pass@localhost:3000", + [], + + scheme_part = None, + authority_part = part!("user:pass@localhost:3000"), + path = "", + query = None, + host = Some("localhost"), + port_part = Port::from_str("3000").ok(), +} + +test_parse! { + test_ipv6, + "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/", + [], + + scheme_part = part!("http"), + authority_part = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"), + host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_ipv6_shorthand, + "http://[::1]/", + [], + + scheme_part = part!("http"), + authority_part = part!("[::1]"), + host = Some("[::1]"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_ipv6_shorthand2, + "http://[::]/", + [], + + scheme_part = part!("http"), + authority_part = part!("[::]"), + host = Some("[::]"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_ipv6_shorthand3, + "http://[2001:db8::2:1]/", + [], + + scheme_part = part!("http"), + authority_part = part!("[2001:db8::2:1]"), + host = Some("[2001:db8::2:1]"), + path = "/", + query = None, + port_part = None, +} + +test_parse! { + test_ipv6_with_port, + "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008/", + [], + + scheme_part = part!("http"), + authority_part = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008"), + host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"), + path = "/", + query = None, + port_part = Port::from_str("8008").ok(), +} + +test_parse! { + test_percentage_encoded_path, + "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478", + [], + + scheme_part = None, + authority_part = None, + host = None, + path = "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478", + query = None, + port_part = None, +} + +test_parse! { + test_path_permissive, + "/foo=bar|baz\\^~%", + [], + + path = "/foo=bar|baz\\^~%", +} + +test_parse! { + test_query_permissive, + "/?foo={bar|baz}\\^`", + [], + + query = Some("foo={bar|baz}\\^`"), +} + +#[test] +fn test_uri_parse_error() { + fn err(s: &str) { + Uri::from_str(s).unwrap_err(); + } + + err("http://"); + err("htt:p//host"); + err("hyper.rs/"); + err("hyper.rs?key=val"); + err("?key=val"); + err("localhost/"); + err("localhost?key=val"); + err("\0"); + err("http://[::1"); + err("http://::1]"); + err("localhost:8080:3030"); + err("@"); + err("http://username:password@/wut"); + + // illegal queries + err("/?foo\rbar"); + err("/?foo\nbar"); + err("/?<"); + err("/?>"); +} + +#[test] +fn test_max_uri_len() { + let mut uri = vec![]; + uri.extend(b"http://localhost/"); + uri.extend(vec![b'a'; 70 * 1024]); + + let uri = String::from_utf8(uri).unwrap(); + let res: Result = uri.parse(); + + assert_eq!(res.unwrap_err().0, ErrorKind::TooLong); +} + +#[test] +fn test_long_scheme() { + let mut uri = vec![]; + uri.extend(vec![b'a'; 256]); + uri.extend(b"://localhost/"); + + let uri = String::from_utf8(uri).unwrap(); + let res: Result = uri.parse(); + + assert_eq!(res.unwrap_err().0, ErrorKind::SchemeTooLong); +} + +#[test] +fn test_uri_to_path_and_query() { + let cases = vec![ + ("/", "/"), + ("/foo?bar", "/foo?bar"), + ("/foo?bar#nope", "/foo?bar"), + ("http://hyper.rs", "/"), + ("http://hyper.rs/", "/"), + ("http://hyper.rs/path", "/path"), + ("http://hyper.rs?query", "/?query"), + ("*", "*"), + ]; + + for case in cases { + let uri = Uri::from_str(case.0).unwrap(); + let s = uri.path_and_query().unwrap().to_string(); + + assert_eq!(s, case.1); + } +} + +#[test] +fn test_authority_uri_parts_round_trip() { + let s = "hyper.rs"; + let uri = Uri::from_str(s).expect("first parse"); + assert_eq!(uri, s); + assert_eq!(uri.to_string(), s); + + let parts = uri.into_parts(); + let uri2 = Uri::from_parts(parts).expect("from_parts"); + assert_eq!(uri2, s); + assert_eq!(uri2.to_string(), s); +} + +#[test] +fn test_partial_eq_path_with_terminating_questionmark() { + let a = "/path"; + let uri = Uri::from_str("/path?").expect("first parse"); + + assert_eq!(uri, a); +} diff -Nru cargo-0.33.0/vendor/http/src/version.rs cargo-0.35.0/vendor/http/src/version.rs --- cargo-0.33.0/vendor/http/src/version.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/src/version.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,68 @@ +//! HTTP version +//! +//! This module contains a definition of the `Version` type. The `Version` +//! type is intended to be accessed through the root of the crate +//! (`http::Version`) rather than this module. +//! +//! The `Version` type contains constants that represent the various versions +//! of the HTTP protocol. +//! +//! # Examples +//! +//! ``` +//! use http::Version; +//! +//! let http11 = Version::HTTP_11; +//! let http2 = Version::HTTP_2; +//! assert!(http11 != http2); +//! +//! println!("{:?}", http2); +//! ``` + +use std::fmt; + +/// Represents a version of the HTTP spec. +#[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)] +pub struct Version(Http); + +impl Version { + /// `HTTP/0.9` + pub const HTTP_09: Version = Version(Http::Http09); + + /// `HTTP/1.0` + pub const HTTP_10: Version = Version(Http::Http10); + + /// `HTTP/1.1` + pub const HTTP_11: Version = Version(Http::Http11); + + /// `HTTP/2.0` + pub const HTTP_2: Version = Version(Http::H2); +} + +#[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)] +enum Http { + Http09, + Http10, + Http11, + H2, +} + +impl Default for Version { + #[inline] + fn default() -> Version { + Version::HTTP_11 + } +} + +impl fmt::Debug for Version { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::Http::*; + + f.write_str(match self.0 { + Http09 => "HTTP/0.9", + Http10 => "HTTP/1.0", + Http11 => "HTTP/1.1", + H2 => "HTTP/2.0", + }) + } +} diff -Nru cargo-0.33.0/vendor/http/tests/header_map_fuzz.rs cargo-0.35.0/vendor/http/tests/header_map_fuzz.rs --- cargo-0.33.0/vendor/http/tests/header_map_fuzz.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/tests/header_map_fuzz.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,365 @@ +extern crate http; +extern crate rand; +extern crate quickcheck; + +use http::*; +use http::header::*; + +use quickcheck::{Arbitrary, Gen, QuickCheck, TestResult}; +use rand::{StdRng, SeedableRng, Rng}; + +use std::collections::HashMap; + +#[test] +fn header_map_fuzz() { + fn prop(fuzz: Fuzz) -> TestResult { + fuzz.run(); + TestResult::from_bool(true) + } + + QuickCheck::new() + .quickcheck(prop as fn(Fuzz) -> TestResult) +} + +#[derive(Debug, Clone)] +struct Fuzz { + // The magic seed that makes the test case reproducible + seed: [usize; 4], + + // Actions to perform + steps: Vec, + + // Number of steps to drop + reduce: usize, +} + +#[derive(Debug)] +struct Weight { + insert: usize, + remove: usize, + append: usize, +} + +#[derive(Debug, Clone)] +struct Step { + action: Action, + expect: AltMap, +} + +#[derive(Debug, Clone)] +enum Action { + Insert { + name: HeaderName, // Name to insert + val: HeaderValue, // Value to insert + old: Option, // Old value + }, + Append { + name: HeaderName, + val: HeaderValue, + ret: bool, + }, + Remove { + name: HeaderName, // Name to remove + val: Option, // Value to get + }, +} + +// An alternate implementation of HeaderMap backed by HashMap +#[derive(Debug, Clone, Default)] +struct AltMap { + map: HashMap>, +} + +impl Fuzz { + fn new(seed: [usize; 4]) -> Fuzz { + // Seed the RNG + let mut rng = StdRng::from_seed(&seed); + + let mut steps = vec![]; + let mut expect = AltMap::default(); + let num = rng.gen_range(5, 500); + + let weight = Weight { + insert: rng.gen_range(1, 10), + remove: rng.gen_range(1, 10), + append: rng.gen_range(1, 10), + }; + + while steps.len() < num { + steps.push(expect.gen_step(&weight, &mut rng)); + } + + Fuzz { + seed: seed, + steps: steps, + reduce: 0, + } + } + + fn run(self) { + // Create a new header map + let mut map = HeaderMap::new(); + + // Number of steps to perform + let take = self.steps.len() - self.reduce; + + for step in self.steps.into_iter().take(take) { + step.action.apply(&mut map); + + step.expect.assert_identical(&map); + } + } +} + +impl Arbitrary for Fuzz { + fn arbitrary(g: &mut G) -> Self { + Fuzz::new(quickcheck::Rng::gen(g)) + } +} + +impl AltMap { + fn gen_step(&mut self, weight: &Weight, rng: &mut StdRng) -> Step { + let action = self.gen_action(weight, rng); + + Step { + action: action, + expect: self.clone(), + } + } + + /// This will also apply the action against `self` + fn gen_action(&mut self, weight: &Weight, rng: &mut StdRng) -> Action { + let sum = weight.insert + + weight.remove + + weight.append; + + let mut num = rng.gen_range(0, sum); + + if num < weight.insert { + return self.gen_insert(rng); + } + + num -= weight.insert; + + if num < weight.remove { + return self.gen_remove(rng); + } + + num -= weight.remove; + + if num < weight.append { + return self.gen_append(rng); + } + + unreachable!(); + } + + fn gen_insert(&mut self, rng: &mut StdRng) -> Action { + let name = self.gen_name(4, rng); + let val = gen_header_value(rng); + let old = self.insert(name.clone(), val.clone()); + + Action::Insert { + name: name, + val: val, + old: old, + } + } + + fn gen_remove(&mut self, rng: &mut StdRng) -> Action { + let name = self.gen_name(-4, rng); + let val = self.remove(&name); + + Action::Remove { + name: name, + val: val, + } + } + + fn gen_append(&mut self, rng: &mut StdRng) -> Action { + let name = self.gen_name(-5, rng); + let val = gen_header_value(rng); + + let vals = self.map.entry(name.clone()) + .or_insert(vec![]); + + let ret = !vals.is_empty(); + vals.push(val.clone()); + + Action::Append { + name: name, + val: val, + ret: ret, + } + } + + /// Negative numbers weigh finding an existing header higher + fn gen_name(&self, weight: i32, rng: &mut StdRng) -> HeaderName { + let mut existing = rng.gen_weighted_bool(weight.abs() as u32); + + if weight < 0 { + existing = !existing; + } + + if existing { + // Existing header + if let Some(name) = self.find_random_name(rng) { + name + } else { + gen_header_name(rng) + } + } else { + gen_header_name(rng) + } + } + + fn find_random_name(&self, rng: &mut StdRng) -> Option { + if self.map.is_empty() { + None + } else { + let n = rng.gen_range(0, self.map.len()); + self.map.keys().nth(n).map(Clone::clone) + } + } + + fn insert(&mut self, name: HeaderName, val: HeaderValue) -> Option { + let old = self.map.insert(name, vec![val]); + old.and_then(|v| v.into_iter().next()) + } + + fn remove(&mut self, name: &HeaderName) -> Option { + self.map.remove(name).and_then(|v| v.into_iter().next()) + } + + fn assert_identical(&self, other: &HeaderMap) { + assert_eq!(self.map.len(), other.keys_len()); + + for (key, val) in &self.map { + // Test get + assert_eq!(other.get(key), val.get(0)); + + // Test get_all + let vals = other.get_all(key); + let actual: Vec<_> = vals.iter().collect(); + assert_eq!(&actual[..], &val[..]); + } + } +} + +impl Action { + fn apply(self, map: &mut HeaderMap) { + match self { + Action::Insert { name, val, old } => { + let actual = map.insert(name, val); + assert_eq!(actual, old); + } + Action::Remove { name, val } => { + // Just to help track the state, load all associated values. + map.get_all(&name).iter().collect::>(); + + let actual = map.remove(&name); + assert_eq!(actual, val); + } + Action::Append { name, val, ret } => { + assert_eq!(ret, map.append(name, val)); + } + } + } +} + +fn gen_header_name(g: &mut StdRng) -> HeaderName { + if g.gen_weighted_bool(2) { + g.choose(&[ + header::ACCEPT, + header::ACCEPT_CHARSET, + header::ACCEPT_ENCODING, + header::ACCEPT_LANGUAGE, + header::ACCEPT_RANGES, + header::ACCESS_CONTROL_ALLOW_CREDENTIALS, + header::ACCESS_CONTROL_ALLOW_HEADERS, + header::ACCESS_CONTROL_ALLOW_METHODS, + header::ACCESS_CONTROL_ALLOW_ORIGIN, + header::ACCESS_CONTROL_EXPOSE_HEADERS, + header::ACCESS_CONTROL_MAX_AGE, + header::ACCESS_CONTROL_REQUEST_HEADERS, + header::ACCESS_CONTROL_REQUEST_METHOD, + header::AGE, + header::ALLOW, + header::ALT_SVC, + header::AUTHORIZATION, + header::CACHE_CONTROL, + header::CONNECTION, + header::CONTENT_DISPOSITION, + header::CONTENT_ENCODING, + header::CONTENT_LANGUAGE, + header::CONTENT_LENGTH, + header::CONTENT_LOCATION, + header::CONTENT_RANGE, + header::CONTENT_SECURITY_POLICY, + header::CONTENT_SECURITY_POLICY_REPORT_ONLY, + header::CONTENT_TYPE, + header::COOKIE, + header::DNT, + header::DATE, + header::ETAG, + header::EXPECT, + header::EXPIRES, + header::FORWARDED, + header::FROM, + header::HOST, + header::IF_MATCH, + header::IF_MODIFIED_SINCE, + header::IF_NONE_MATCH, + header::IF_RANGE, + header::IF_UNMODIFIED_SINCE, + header::LAST_MODIFIED, + header::LINK, + header::LOCATION, + header::MAX_FORWARDS, + header::ORIGIN, + header::PRAGMA, + header::PROXY_AUTHENTICATE, + header::PROXY_AUTHORIZATION, + header::PUBLIC_KEY_PINS, + header::PUBLIC_KEY_PINS_REPORT_ONLY, + header::RANGE, + header::REFERER, + header::REFERRER_POLICY, + header::RETRY_AFTER, + header::SERVER, + header::SET_COOKIE, + header::STRICT_TRANSPORT_SECURITY, + header::TE, + header::TRAILER, + header::TRANSFER_ENCODING, + header::USER_AGENT, + header::UPGRADE, + header::UPGRADE_INSECURE_REQUESTS, + header::VARY, + header::VIA, + header::WARNING, + header::WWW_AUTHENTICATE, + header::X_CONTENT_TYPE_OPTIONS, + header::X_DNS_PREFETCH_CONTROL, + header::X_FRAME_OPTIONS, + header::X_XSS_PROTECTION, + ]).unwrap().clone() + } else { + let value = gen_string(g, 1, 25); + HeaderName::from_bytes(value.as_bytes()).unwrap() + } +} + +fn gen_header_value(g: &mut StdRng) -> HeaderValue { + let value = gen_string(g, 0, 70); + HeaderValue::from_bytes(value.as_bytes()).unwrap() +} + +fn gen_string(g: &mut StdRng, min: usize, max: usize) -> String { + let bytes: Vec<_> = (min..max).map(|_| { + // Chars to pick from + g.choose(b"ABCDEFGHIJKLMNOPQRSTUVabcdefghilpqrstuvwxyz----").unwrap().clone() + }).collect(); + + String::from_utf8(bytes).unwrap() +} diff -Nru cargo-0.33.0/vendor/http/tests/header_map.rs cargo-0.35.0/vendor/http/tests/header_map.rs --- cargo-0.33.0/vendor/http/tests/header_map.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/tests/header_map.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,329 @@ +extern crate http; + +use http::*; +use http::header::*; + +#[test] +fn smoke() { + let mut headers = HeaderMap::new(); + + assert!(headers.get("hello").is_none()); + + let name: HeaderName = "hello".parse().unwrap(); + + match headers.entry(&name).unwrap() { + Entry::Vacant(e) => { + e.insert("world".parse().unwrap()); + } + _ => panic!(), + } + + assert!(headers.get("hello").is_some()); + + match headers.entry(&name).unwrap() { + Entry::Occupied(mut e) => { + assert_eq!(e.get(), &"world"); + + // Push another value + e.append("zomg".parse().unwrap()); + + let mut i = e.iter(); + + assert_eq!(*i.next().unwrap(), "world"); + assert_eq!(*i.next().unwrap(), "zomg"); + assert!(i.next().is_none()); + } + _ => panic!(), + } +} + +#[test] +fn drain() { + let mut headers = HeaderMap::new(); + + // Insert a single value + let name: HeaderName = "hello".parse().unwrap(); + headers.insert(name, "world".parse().unwrap()); + + { + let mut iter = headers.drain(); + let (name, values) = iter.next().unwrap(); + assert_eq!(name.as_str(), "hello"); + + let values: Vec<_> = values.collect(); + assert_eq!(values.len(), 1); + assert_eq!(values[0], "world"); + + assert!(iter.next().is_none()); + } + + assert!(headers.is_empty()); + + // Insert two sequential values + headers.insert("hello".parse::().unwrap(), "world".parse().unwrap()); + headers.insert("zomg".parse::().unwrap(), "bar".parse().unwrap()); + headers.append("hello".parse::().unwrap(), "world2".parse().unwrap()); + + // Drain... + { + let mut iter = headers.drain(); + let (name, values) = iter.next().unwrap(); + assert_eq!(name.as_str(), "hello"); + + let values: Vec<_> = values.collect(); + assert_eq!(values.len(), 2); + assert_eq!(values[0], "world"); + assert_eq!(values[1], "world2"); + + let (name, values) = iter.next().unwrap(); + assert_eq!(name.as_str(), "zomg"); + + let values: Vec<_> = values.collect(); + assert_eq!(values.len(), 1); + assert_eq!(values[0], "bar"); + + assert!(iter.next().is_none()); + } +} + +#[test] +fn drain_entry() { + let mut headers = HeaderMap::new(); + + headers.insert("hello".parse::().unwrap(), "world".parse().unwrap()); + headers.insert("zomg".parse::().unwrap(), "foo".parse().unwrap()); + headers.append("hello".parse::().unwrap(), "world2".parse().unwrap()); + headers.insert("more".parse::().unwrap(), "words".parse().unwrap()); + headers.append("more".parse::().unwrap(), "insertions".parse().unwrap()); + + // Using insert + { + let mut e = match headers.entry("hello").unwrap() { + Entry::Occupied(e) => e, + _ => panic!(), + }; + + let vals: Vec<_> = e.insert_mult("wat".parse().unwrap()).collect(); + assert_eq!(2, vals.len()); + assert_eq!(vals[0], "world"); + assert_eq!(vals[1], "world2"); + } +} + +#[test] +fn eq() { + let mut a = HeaderMap::new(); + let mut b = HeaderMap::new(); + + assert_eq!(a, b); + + a.insert("hello".parse::().unwrap(), "world".parse().unwrap()); + assert_ne!(a, b); + + b.insert("hello".parse::().unwrap(), "world".parse().unwrap()); + assert_eq!(a, b); + + a.insert("foo".parse::().unwrap(), "bar".parse().unwrap()); + a.append("foo".parse::().unwrap(), "baz".parse().unwrap()); + assert_ne!(a, b); + + b.insert("foo".parse::().unwrap(), "bar".parse().unwrap()); + assert_ne!(a, b); + + b.append("foo".parse::().unwrap(), "baz".parse().unwrap()); + assert_eq!(a, b); + + a.append("a".parse::().unwrap(), "a".parse().unwrap()); + a.append("a".parse::().unwrap(), "b".parse().unwrap()); + b.append("a".parse::().unwrap(), "b".parse().unwrap()); + b.append("a".parse::().unwrap(), "a".parse().unwrap()); + + assert_ne!(a, b); +} + +#[test] +fn into_header_name() { + let mut m = HeaderMap::new(); + m.insert(HOST, "localhost".parse().unwrap()); + m.insert(&ACCEPT, "*/*".parse().unwrap()); + m.insert("connection", "keep-alive".parse().unwrap()); + + m.append(LOCATION, "/".parse().unwrap()); + m.append(&VIA, "bob".parse().unwrap()); + m.append("transfer-encoding", "chunked".parse().unwrap()); + + assert_eq!(m.len(), 6); +} + +#[test] +fn as_header_name() { + let mut m = HeaderMap::new(); + let v: HeaderValue = "localhost".parse().unwrap(); + m.insert(HOST, v.clone()); + + let expected = Some(&v); + + assert_eq!(m.get("host"), expected); + assert_eq!(m.get(&HOST), expected); + + let s = String::from("host"); + assert_eq!(m.get(&s), expected); + assert_eq!(m.get(s.as_str()), expected); +} + +#[test] +fn insert_all_std_headers() { + let mut m = HeaderMap::new(); + + for (i, hdr) in STD.iter().enumerate() { + m.insert(hdr.clone(), hdr.as_str().parse().unwrap()); + + for j in 0..(i+1) { + assert_eq!(m[&STD[j]], STD[j].as_str()); + } + + if i != 0 { + for j in (i+1)..STD.len() { + assert!(m.get(&STD[j]).is_none(), "contained {}; j={}", STD[j].as_str(), j); + } + } + } +} + +#[test] +fn insert_79_custom_std_headers() { + let mut h = HeaderMap::new(); + let hdrs = custom_std(79); + + for (i, hdr) in hdrs.iter().enumerate() { + h.insert(hdr.clone(), hdr.as_str().parse().unwrap()); + + for j in 0..(i+1) { + assert_eq!(h[&hdrs[j]], hdrs[j].as_str()); + } + + for j in (i+1)..hdrs.len() { + assert!(h.get(&hdrs[j]).is_none()); + } + } +} + +#[test] +fn append_multiple_values() { + let mut map = HeaderMap::new(); + + map.append(header::CONTENT_TYPE, "json".parse().unwrap()); + map.append(header::CONTENT_TYPE, "html".parse().unwrap()); + map.append(header::CONTENT_TYPE, "xml".parse().unwrap()); + + let vals = map.get_all(&header::CONTENT_TYPE) + .iter() + .collect::>(); + + assert_eq!(&vals, &[&"json", &"html", &"xml"]); +} + +fn custom_std(n: usize) -> Vec { + (0..n).map(|i| { + let s = format!("{}-{}", STD[i % STD.len()].as_str(), i); + s.parse().unwrap() + }).collect() +} + +const STD: &'static [HeaderName] = &[ + ACCEPT, + ACCEPT_CHARSET, + ACCEPT_ENCODING, + ACCEPT_LANGUAGE, + ACCEPT_RANGES, + ACCESS_CONTROL_ALLOW_CREDENTIALS, + ACCESS_CONTROL_ALLOW_HEADERS, + ACCESS_CONTROL_ALLOW_METHODS, + ACCESS_CONTROL_ALLOW_ORIGIN, + ACCESS_CONTROL_EXPOSE_HEADERS, + ACCESS_CONTROL_MAX_AGE, + ACCESS_CONTROL_REQUEST_HEADERS, + ACCESS_CONTROL_REQUEST_METHOD, + AGE, + ALLOW, + ALT_SVC, + AUTHORIZATION, + CACHE_CONTROL, + CONNECTION, + CONTENT_DISPOSITION, + CONTENT_ENCODING, + CONTENT_LANGUAGE, + CONTENT_LENGTH, + CONTENT_LOCATION, + CONTENT_RANGE, + CONTENT_SECURITY_POLICY, + CONTENT_SECURITY_POLICY_REPORT_ONLY, + CONTENT_TYPE, + COOKIE, + DNT, + DATE, + ETAG, + EXPECT, + EXPIRES, + FORWARDED, + FROM, + HOST, + IF_MATCH, + IF_MODIFIED_SINCE, + IF_NONE_MATCH, + IF_RANGE, + IF_UNMODIFIED_SINCE, + LAST_MODIFIED, + LINK, + LOCATION, + MAX_FORWARDS, + ORIGIN, + PRAGMA, + PROXY_AUTHENTICATE, + PROXY_AUTHORIZATION, + PUBLIC_KEY_PINS, + PUBLIC_KEY_PINS_REPORT_ONLY, + RANGE, + REFERER, + REFERRER_POLICY, + RETRY_AFTER, + SERVER, + SET_COOKIE, + STRICT_TRANSPORT_SECURITY, + TE, + TRAILER, + TRANSFER_ENCODING, + USER_AGENT, + UPGRADE, + UPGRADE_INSECURE_REQUESTS, + VARY, + VIA, + WARNING, + WWW_AUTHENTICATE, + X_CONTENT_TYPE_OPTIONS, + X_DNS_PREFETCH_CONTROL, + X_FRAME_OPTIONS, + X_XSS_PROTECTION, +]; + +#[test] +fn get_invalid() { + let mut headers = HeaderMap::new(); + headers.insert("foo", "bar".parse().unwrap()); + assert!(headers.get("Evil\r\nKey").is_none()); +} + +#[test] +#[should_panic] +fn insert_invalid() { + let mut headers = HeaderMap::new(); + headers.insert("evil\r\nfoo", "bar".parse().unwrap()); +} + +#[test] +fn value_htab() { + // RFC 7230 Section 3.2: + // > field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + HeaderValue::from_static("hello\tworld"); + HeaderValue::from_str("hello\tworld").unwrap(); +} diff -Nru cargo-0.33.0/vendor/http/tests/status_code.rs cargo-0.35.0/vendor/http/tests/status_code.rs --- cargo-0.33.0/vendor/http/tests/status_code.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/http/tests/status_code.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,67 @@ +extern crate http; + +use http::*; + +#[test] +fn from_bytes() { + for ok in &["100", "101", "199", "200", "250", "299", "321", "399", "499", "599"] { + assert!(StatusCode::from_bytes(ok.as_bytes()).is_ok()); + } + + for not_ok in &["0", "00", "10", "40", "99", "000", "010", "099", "600", "610", "999"] { + assert!(StatusCode::from_bytes(not_ok.as_bytes()).is_err()); + } +} + +#[test] +fn equates_with_u16() { + let status = StatusCode::from_u16(200u16).unwrap(); + assert_eq!(200u16, status); + assert_eq!(status, 200u16); +} + +macro_rules! test_round_trip { + ($($num:expr,)+) => { + #[test] + fn roundtrip() { + $( + let status = StatusCode::from_bytes(stringify!($num).as_bytes()).unwrap(); + let expect = $num; + + assert_eq!(u16::from(status), expect); + )+ + } + } +} + +test_round_trip!( + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, + + 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, + 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, + 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, + ); diff -Nru cargo-0.33.0/vendor/ignore/.cargo-checksum.json cargo-0.35.0/vendor/ignore/.cargo-checksum.json --- cargo-0.33.0/vendor/ignore/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"ad03ca67dc12474ecd91fdb94d758cbd20cb4e7a78ebe831df26a9b7511e1162"} \ No newline at end of file +{"files":{},"package":"8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/ignore/Cargo.toml cargo-0.35.0/vendor/ignore/Cargo.toml --- cargo-0.33.0/vendor/ignore/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "ignore" -version = "0.4.6" +version = "0.4.7" authors = ["Andrew Gallant "] description = "A fast library for efficiently matching ignore files such as `.gitignore`\nagainst file paths.\n" homepage = "https://github.com/BurntSushi/ripgrep/tree/master/ignore" @@ -26,35 +26,35 @@ name = "ignore" bench = false [dependencies.crossbeam-channel] -version = "0.3.3" +version = "0.3.6" [dependencies.globset] -version = "0.4.2" +version = "0.4.3" [dependencies.lazy_static] -version = "1.1.0" +version = "1.1" [dependencies.log] version = "0.4.5" [dependencies.memchr] -version = "2.0.2" +version = "2.1" [dependencies.regex] -version = "1.0.5" +version = "1.1" [dependencies.same-file] -version = "1.0.3" +version = "1.0.4" [dependencies.thread_local] version = "0.3.6" [dependencies.walkdir] -version = "2.2.5" +version = "2.2.7" [dev-dependencies.tempfile] version = "3.0.5" [features] simd-accel = ["globset/simd-accel"] [target."cfg(windows)".dependencies.winapi-util] -version = "0.1.1" +version = "0.1.2" diff -Nru cargo-0.33.0/vendor/ignore/src/dir.rs cargo-0.35.0/vendor/ignore/src/dir.rs --- cargo-0.33.0/vendor/ignore/src/dir.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/dir.rs 2019-05-15 11:26:24.000000000 +0000 @@ -22,6 +22,7 @@ use pathutil::{is_hidden, strip_prefix}; use overrides::{self, Override}; use types::{self, Types}; +use walk::DirEntry; use {Error, Match, PartialErrorBuilder}; /// IgnoreMatch represents information about where a match came from when using @@ -73,6 +74,8 @@ git_ignore: bool, /// Whether to read .git/info/exclude files. git_exclude: bool, + /// Whether to ignore files case insensitively + ignore_case_insensitive: bool, } /// Ignore is a matcher useful for recursively walking one or more directories. @@ -225,7 +228,11 @@ Gitignore::empty() } else { let (m, err) = - create_gitignore(&dir, &self.0.custom_ignore_filenames); + create_gitignore( + &dir, + &self.0.custom_ignore_filenames, + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -233,7 +240,12 @@ if !self.0.opts.ignore { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".ignore"]); + let (m, err) = + create_gitignore( + &dir, + &[".ignore"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -241,7 +253,12 @@ if !self.0.opts.git_ignore { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".gitignore"]); + let (m, err) = + create_gitignore( + &dir, + &[".gitignore"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -249,7 +266,12 @@ if !self.0.opts.git_exclude { Gitignore::empty() } else { - let (m, err) = create_gitignore(&dir, &[".git/info/exclude"]); + let (m, err) = + create_gitignore( + &dir, + &[".git/info/exclude"], + self.0.opts.ignore_case_insensitive, + ); errs.maybe_push(err); m }; @@ -285,11 +307,23 @@ || has_explicit_ignores } + /// Like `matched`, but works with a directory entry instead. + pub fn matched_dir_entry<'a>( + &'a self, + dent: &DirEntry, + ) -> Match> { + let m = self.matched(dent.path(), dent.is_dir()); + if m.is_none() && self.0.opts.hidden && is_hidden(dent) { + return Match::Ignore(IgnoreMatch::hidden()); + } + m + } + /// Returns a match indicating whether the given file path should be /// ignored or not. /// /// The match contains information about its origin. - pub fn matched<'a, P: AsRef>( + fn matched<'a, P: AsRef>( &'a self, path: P, is_dir: bool, @@ -330,9 +364,6 @@ whitelisted = mat; } } - if whitelisted.is_none() && self.0.opts.hidden && is_hidden(path) { - return Match::Ignore(IgnoreMatch::hidden()); - } whitelisted } @@ -483,6 +514,7 @@ git_global: true, git_ignore: true, git_exclude: true, + ignore_case_insensitive: false, }, } } @@ -496,7 +528,11 @@ if !self.opts.git_global { Gitignore::empty() } else { - let (gi, err) = Gitignore::global(); + let mut builder = GitignoreBuilder::new(""); + builder + .case_insensitive(self.opts.ignore_case_insensitive) + .unwrap(); + let (gi, err) = builder.build_global(); if let Some(err) = err { debug!("{}", err); } @@ -627,6 +663,17 @@ self.opts.git_exclude = yes; self } + + /// Process ignore files case insensitively + /// + /// This is disabled by default. + pub fn ignore_case_insensitive( + &mut self, + yes: bool, + ) -> &mut IgnoreBuilder { + self.opts.ignore_case_insensitive = yes; + self + } } /// Creates a new gitignore matcher for the directory given. @@ -638,9 +685,11 @@ pub fn create_gitignore>( dir: &Path, names: &[T], + case_insensitive: bool, ) -> (Gitignore, Option) { let mut builder = GitignoreBuilder::new(dir); let mut errs = PartialErrorBuilder::default(); + builder.case_insensitive(case_insensitive).unwrap(); for name in names { let gipath = dir.join(name.as_ref()); errs.maybe_push_ignore_io(builder.add(gipath)); @@ -830,7 +879,7 @@ #[test] fn errored() { let td = tmpdir("ignore-test-"); - wfile(td.path().join(".gitignore"), "f**oo"); + wfile(td.path().join(".gitignore"), "{foo"); let (_, err) = IgnoreBuilder::new().build().add_child(td.path()); assert!(err.is_some()); @@ -839,8 +888,8 @@ #[test] fn errored_both() { let td = tmpdir("ignore-test-"); - wfile(td.path().join(".gitignore"), "f**oo"); - wfile(td.path().join(".ignore"), "fo**o"); + wfile(td.path().join(".gitignore"), "{foo"); + wfile(td.path().join(".ignore"), "{bar"); let (_, err) = IgnoreBuilder::new().build().add_child(td.path()); assert_eq!(2, partial(err.expect("an error")).len()); @@ -850,7 +899,7 @@ fn errored_partial() { let td = tmpdir("ignore-test-"); mkdirp(td.path().join(".git")); - wfile(td.path().join(".gitignore"), "f**oo\nbar"); + wfile(td.path().join(".gitignore"), "{foo\nbar"); let (ig, err) = IgnoreBuilder::new().build().add_child(td.path()); assert!(err.is_some()); @@ -860,7 +909,7 @@ #[test] fn errored_partial_and_ignore() { let td = tmpdir("ignore-test-"); - wfile(td.path().join(".gitignore"), "f**oo\nbar"); + wfile(td.path().join(".gitignore"), "{foo\nbar"); wfile(td.path().join(".ignore"), "!bar"); let (ig, err) = IgnoreBuilder::new().build().add_child(td.path()); diff -Nru cargo-0.33.0/vendor/ignore/src/gitignore.rs cargo-0.35.0/vendor/ignore/src/gitignore.rs --- cargo-0.33.0/vendor/ignore/src/gitignore.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/gitignore.rs 2019-05-15 11:26:24.000000000 +0000 @@ -69,8 +69,7 @@ /// Returns true if and only if this glob has a `**/` prefix. fn has_doublestar_prefix(&self) -> bool { - self.actual.starts_with("**/") - || (self.actual == "**" && self.is_only_dir) + self.actual.starts_with("**/") || self.actual == "**" } } @@ -127,16 +126,7 @@ /// `$XDG_CONFIG_HOME/git/ignore` is read. If `$XDG_CONFIG_HOME` is not /// set or is empty, then `$HOME/.config/git/ignore` is used instead. pub fn global() -> (Gitignore, Option) { - match gitconfig_excludes_path() { - None => (Gitignore::empty(), None), - Some(path) => { - if !path.is_file() { - (Gitignore::empty(), None) - } else { - Gitignore::new(path) - } - } - } + GitignoreBuilder::new("").build_global() } /// Creates a new empty gitignore matcher that never matches anything. @@ -359,6 +349,36 @@ }) } + /// Build a global gitignore matcher using the configuration in this + /// builder. + /// + /// This consumes ownership of the builder unlike `build` because it + /// must mutate the builder to add the global gitignore globs. + /// + /// Note that this ignores the path given to this builder's constructor + /// and instead derives the path automatically from git's global + /// configuration. + pub fn build_global(mut self) -> (Gitignore, Option) { + match gitconfig_excludes_path() { + None => (Gitignore::empty(), None), + Some(path) => { + if !path.is_file() { + (Gitignore::empty(), None) + } else { + let mut errs = PartialErrorBuilder::default(); + errs.maybe_push_ignore_io(self.add(path)); + match self.build() { + Ok(gi) => (gi, errs.into_error_option()), + Err(err) => { + errs.push(err); + (Gitignore::empty(), errs.into_error_option()) + } + } + } + } + } + } + /// Add each glob from the file path given. /// /// The file given should be formatted as a `gitignore` file. @@ -437,7 +457,6 @@ is_whitelist: false, is_only_dir: false, }; - let mut literal_separator = false; let mut is_absolute = false; if line.starts_with("\\!") || line.starts_with("\\#") { line = &line[1..]; @@ -452,7 +471,6 @@ // then the glob can only match the beginning of a path // (relative to the location of gitignore). We achieve this by // simply banning wildcards from matching /. - literal_separator = true; line = &line[1..]; is_absolute = true; } @@ -465,16 +483,11 @@ line = &line[..i]; } } - // If there is a literal slash, then we note that so that globbing - // doesn't let wildcards match slashes. glob.actual = line.to_string(); - if is_absolute || line.chars().any(|c| c == '/') { - literal_separator = true; - } - // If there was a slash, then this is a glob that must match the entire - // path name. Otherwise, we should let it match anywhere, so use a **/ - // prefix. - if !literal_separator { + // If there is a literal slash, then this is a glob that must match the + // entire path name. Otherwise, we should let it match anywhere, so use + // a **/ prefix. + if !is_absolute && !line.chars().any(|c| c == '/') { // ... but only if we don't already have a **/ prefix. if !glob.has_doublestar_prefix() { glob.actual = format!("**/{}", glob.actual); @@ -488,7 +501,7 @@ } let parsed = GlobBuilder::new(&glob.actual) - .literal_separator(literal_separator) + .literal_separator(true) .case_insensitive(self.case_insensitive) .backslash_escape(true) .build() @@ -505,12 +518,16 @@ /// Toggle whether the globs should be matched case insensitively or not. /// - /// When this option is changed, only globs added after the change will be affected. + /// When this option is changed, only globs added after the change will be + /// affected. /// /// This is disabled by default. pub fn case_insensitive( - &mut self, yes: bool + &mut self, + yes: bool, ) -> Result<&mut GitignoreBuilder, Error> { + // TODO: This should not return a `Result`. Fix this in the next semver + // release. self.case_insensitive = yes; Ok(self) } @@ -691,6 +708,9 @@ ignored!(ig39, ROOT, "\\?", "?"); ignored!(ig40, ROOT, "\\*", "*"); ignored!(ig41, ROOT, "\\a", "a"); + ignored!(ig42, ROOT, "s*.rs", "sfoo.rs"); + ignored!(ig43, ROOT, "**", "foo.rs"); + ignored!(ig44, ROOT, "**/**/*", "a/foo.rs"); not_ignored!(ignot1, ROOT, "amonths", "months"); not_ignored!(ignot2, ROOT, "monthsa", "months"); @@ -712,6 +732,7 @@ not_ignored!(ignot16, ROOT, "*\n!**/", "foo", true); not_ignored!(ignot17, ROOT, "src/*.rs", "src/grep/src/main.rs"); not_ignored!(ignot18, ROOT, "path1/*", "path2/path1/foo"); + not_ignored!(ignot19, ROOT, "s*.rs", "src/foo.rs"); fn bytes(s: &str) -> Vec { s.to_string().into_bytes() diff -Nru cargo-0.33.0/vendor/ignore/src/overrides.rs cargo-0.35.0/vendor/ignore/src/overrides.rs --- cargo-0.33.0/vendor/ignore/src/overrides.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/overrides.rs 2019-05-15 11:26:24.000000000 +0000 @@ -139,13 +139,16 @@ } /// Toggle whether the globs should be matched case insensitively or not. - /// + /// /// When this option is changed, only globs added after the change will be affected. /// /// This is disabled by default. pub fn case_insensitive( - &mut self, yes: bool + &mut self, + yes: bool, ) -> Result<&mut OverrideBuilder, Error> { + // TODO: This should not return a `Result`. Fix this in the next semver + // release. self.builder.case_insensitive(yes)?; Ok(self) } diff -Nru cargo-0.33.0/vendor/ignore/src/pathutil.rs cargo-0.35.0/vendor/ignore/src/pathutil.rs --- cargo-0.33.0/vendor/ignore/src/pathutil.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/pathutil.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,22 +1,56 @@ use std::ffi::OsStr; use std::path::Path; -/// Returns true if and only if this file path is considered to be hidden. +use walk::DirEntry; + +/// Returns true if and only if this entry is considered to be hidden. +/// +/// This only returns true if the base name of the path starts with a `.`. +/// +/// On Unix, this implements a more optimized check. #[cfg(unix)] -pub fn is_hidden>(path: P) -> bool { +pub fn is_hidden(dent: &DirEntry) -> bool { use std::os::unix::ffi::OsStrExt; - if let Some(name) = file_name(path.as_ref()) { + if let Some(name) = file_name(dent.path()) { name.as_bytes().get(0) == Some(&b'.') } else { false } } -/// Returns true if and only if this file path is considered to be hidden. -#[cfg(not(unix))] -pub fn is_hidden>(path: P) -> bool { - if let Some(name) = file_name(path.as_ref()) { +/// Returns true if and only if this entry is considered to be hidden. +/// +/// On Windows, this returns true if one of the following is true: +/// +/// * The base name of the path starts with a `.`. +/// * The file attributes have the `HIDDEN` property set. +#[cfg(windows)] +pub fn is_hidden(dent: &DirEntry) -> bool { + use std::os::windows::fs::MetadataExt; + use winapi_util::file; + + // This looks like we're doing an extra stat call, but on Windows, the + // directory traverser reuses the metadata retrieved from each directory + // entry and stores it on the DirEntry itself. So this is "free." + if let Ok(md) = dent.metadata() { + if file::is_hidden(md.file_attributes() as u64) { + return true; + } + } + if let Some(name) = file_name(dent.path()) { + name.to_str().map(|s| s.starts_with(".")).unwrap_or(false) + } else { + false + } +} + +/// Returns true if and only if this entry is considered to be hidden. +/// +/// This only returns true if the base name of the path starts with a `.`. +#[cfg(not(any(unix, windows)))] +pub fn is_hidden(dent: &DirEntry) -> bool { + if let Some(name) = file_name(dent.path()) { name.to_str().map(|s| s.starts_with(".")).unwrap_or(false) } else { false diff -Nru cargo-0.33.0/vendor/ignore/src/types.rs cargo-0.35.0/vendor/ignore/src/types.rs --- cargo-0.33.0/vendor/ignore/src/types.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/types.rs 2019-05-15 11:26:24.000000000 +0000 @@ -108,9 +108,10 @@ ("awk", &["*.awk"]), ("bazel", &["*.bzl", "WORKSPACE", "BUILD", "BUILD.bazel"]), ("bitbake", &["*.bb", "*.bbappend", "*.bbclass", "*.conf", "*.inc"]), + ("brotli", &["*.br"]), ("buildstream", &["*.bst"]), - ("bzip2", &["*.bz2"]), - ("c", &["*.c", "*.h", "*.H", "*.cats"]), + ("bzip2", &["*.bz2", "*.tbz2"]), + ("c", &["*.[chH]", "*.[chH].in", "*.cats"]), ("cabal", &["*.cabal"]), ("cbor", &["*.cbor"]), ("ceylon", &["*.ceylon"]), @@ -120,8 +121,8 @@ ("creole", &["*.creole"]), ("config", &["*.cfg", "*.conf", "*.config", "*.ini"]), ("cpp", &[ - "*.C", "*.cc", "*.cpp", "*.cxx", - "*.h", "*.H", "*.hh", "*.hpp", "*.hxx", "*.inl", + "*.[ChH]", "*.cc", "*.[ch]pp", "*.[ch]xx", "*.hh", "*.inl", + "*.[ChH].in", "*.cc.in", "*.[ch]pp.in", "*.[ch]xx.in", "*.hh.in", ]), ("crystal", &["Projectfile", "*.cr"]), ("cs", &["*.cs"]), @@ -147,7 +148,7 @@ ("fsharp", &["*.fs", "*.fsx", "*.fsi"]), ("gn", &["*.gn", "*.gni"]), ("go", &["*.go"]), - ("gzip", &["*.gz"]), + ("gzip", &["*.gz", "*.tgz"]), ("groovy", &["*.groovy", "*.gradle"]), ("h", &["*.h", "*.hpp"]), ("hbs", &["*.hbs"]), @@ -155,7 +156,7 @@ ("hs", &["*.hs", "*.lhs"]), ("html", &["*.htm", "*.html", "*.ejs"]), ("idris", &["*.idr", "*.lidr"]), - ("java", &["*.java", "*.jsp"]), + ("java", &["*.java", "*.jsp", "*.jspx", "*.properties"]), ("jinja", &["*.j2", "*.jinja", "*.jinja2"]), ("js", &[ "*.js", "*.jsx", "*.vue", @@ -195,14 +196,16 @@ "OFL-*[0-9]*", ]), ("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]), + ("lock", &["*.lock", "package-lock.json"]), ("log", &["*.log"]), ("lua", &["*.lua"]), ("lzma", &["*.lzma"]), ("lz4", &["*.lz4"]), ("m4", &["*.ac", "*.m4"]), ("make", &[ - "gnumakefile", "Gnumakefile", "GNUmakefile", - "makefile", "Makefile", + "[Gg][Nn][Uu]makefile", "[Mm]akefile", + "[Gg][Nn][Uu]makefile.am", "[Mm]akefile.am", + "[Gg][Nn][Uu]makefile.in", "[Mm]akefile.in", "*.mk", "*.mak" ]), ("mako", &["*.mako", "*.mao"]), @@ -233,6 +236,7 @@ ("purs", &["*.purs"]), ("py", &["*.py"]), ("qmake", &["*.pro", "*.pri", "*.prf"]), + ("qml", &["*.qml"]), ("readme", &["README*", "*README"]), ("r", &["*.R", "*.r", "*.Rmd", "*.Rnw"]), ("rdoc", &["*.rdoc"]), @@ -281,7 +285,7 @@ ]), ("taskpaper", &["*.taskpaper"]), ("tcl", &["*.tcl"]), - ("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib"]), + ("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib", "*.dtx", "*.ins"]), ("textile", &["*.textile"]), ("thrift", &["*.thrift"]), ("tf", &["*.tf"]), @@ -297,10 +301,14 @@ ("vimscript", &["*.vim"]), ("wiki", &["*.mediawiki", "*.wiki"]), ("webidl", &["*.idl", "*.webidl", "*.widl"]), - ("xml", &["*.xml", "*.xml.dist"]), - ("xz", &["*.xz"]), + ("xml", &[ + "*.xml", "*.xml.dist", "*.dtd", "*.xsl", "*.xslt", "*.xsd", "*.xjb", + "*.rng", "*.sch", + ]), + ("xz", &["*.xz", "*.txz"]), ("yacc", &["*.y"]), ("yaml", &["*.yaml", "*.yml"]), + ("zig", &["*.zig"]), ("zsh", &[ ".zshenv", "zshenv", ".zlogin", "zlogin", @@ -309,6 +317,7 @@ ".zshrc", "zshrc", "*.zsh", ]), + ("zstd", &["*.zst", "*.zstd"]), ]; /// Glob represents a single glob in a set of file type definitions. @@ -347,6 +356,18 @@ fn unmatched() -> Glob<'a> { Glob(GlobInner::UnmatchedIgnore) } + + /// Return the file type defintion that matched, if one exists. A file type + /// definition always exists when a specific definition matches a file + /// path. + pub fn file_type_def(&self) -> Option<&FileTypeDef> { + match self { + Glob(GlobInner::UnmatchedIgnore) => None, + Glob(GlobInner::Matched { def, .. }) => { + Some(def) + }, + } + } } /// A single file type definition. diff -Nru cargo-0.33.0/vendor/ignore/src/walk.rs cargo-0.35.0/vendor/ignore/src/walk.rs --- cargo-0.33.0/vendor/ignore/src/walk.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ignore/src/walk.rs 2019-05-15 11:26:24.000000000 +0000 @@ -99,7 +99,7 @@ } /// Returns true if and only if this entry points to a directory. - fn is_dir(&self) -> bool { + pub(crate) fn is_dir(&self) -> bool { self.dent.is_dir() } @@ -764,6 +764,14 @@ self } + /// Process ignore files case insensitively + /// + /// This is disabled by default. + pub fn ignore_case_insensitive(&mut self, yes: bool) -> &mut WalkBuilder { + self.ig_builder.ignore_case_insensitive(yes); + self + } + /// Set a function for sorting directory entries by their path. /// /// If a compare function is set, the resulting iterator will return all @@ -875,16 +883,17 @@ return Ok(true); } } - let is_dir = ent.file_type().map_or(false, |ft| ft.is_dir()); - let max_size = self.max_filesize; - let should_skip_path = skip_path(&self.ig, ent.path(), is_dir); - let should_skip_filesize = if !is_dir && max_size.is_some() { - skip_filesize(max_size.unwrap(), ent.path(), &ent.metadata().ok()) - } else { - false - }; - - Ok(should_skip_path || should_skip_filesize) + if should_skip_entry(&self.ig, ent) { + return Ok(true); + } + if self.max_filesize.is_some() && !ent.is_dir() { + return Ok(skip_filesize( + self.max_filesize.unwrap(), + ent.path(), + &ent.metadata().ok(), + )); + } + Ok(false) } } @@ -1412,13 +1421,11 @@ return WalkState::Continue; } } - let is_dir = dent.is_dir(); - let max_size = self.max_filesize; - let should_skip_path = skip_path(ig, dent.path(), is_dir); + let should_skip_path = should_skip_entry(ig, &dent); let should_skip_filesize = - if !is_dir && max_size.is_some() { + if self.max_filesize.is_some() && !dent.is_dir() { skip_filesize( - max_size.unwrap(), + self.max_filesize.unwrap(), dent.path(), &dent.metadata().ok(), ) @@ -1601,17 +1608,16 @@ } } -fn skip_path( +fn should_skip_entry( ig: &Ignore, - path: &Path, - is_dir: bool, + dent: &DirEntry, ) -> bool { - let m = ig.matched(path, is_dir); + let m = ig.matched_dir_entry(dent); if m.is_ignore() { - debug!("ignoring {}: {:?}", path.display(), m); + debug!("ignoring {}: {:?}", dent.path().display(), m); true } else if m.is_whitelist() { - debug!("whitelisting {}: {:?}", path.display(), m); + debug!("whitelisting {}: {:?}", dent.path().display(), m); false } else { false diff -Nru cargo-0.33.0/vendor/im-rc/.cargo-checksum.json cargo-0.35.0/vendor/im-rc/.cargo-checksum.json --- cargo-0.33.0/vendor/im-rc/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"9460397452f537fd51808056ff209f4c4c4c9d20d42ae952f517708726284972"} \ No newline at end of file +{"files":{},"package":"e882e6e7cd335baacae574b56aa3ce74844ec82fc6777def7c0ac368837dc3d5"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/im-rc/Cargo.toml cargo-0.35.0/vendor/im-rc/Cargo.toml --- cargo-0.33.0/vendor/im-rc/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -11,8 +11,9 @@ # will likely look very different (and much more reasonable) [package] +edition = "2018" name = "im-rc" -version = "12.3.0" +version = "12.3.4" authors = ["Bodil Stokke "] build = "./build.rs" description = "Immutable collection datatypes (the fast but not thread safe version)" @@ -27,7 +28,7 @@ [lib] path = "./src/lib.rs" [dependencies.proptest] -version = "0.8" +version = "0.9" optional = true [dependencies.quickcheck] @@ -42,16 +43,22 @@ version = "1.0" optional = true +[dependencies.sized-chunks] +version = "0.1.2" + [dependencies.typenum] version = "1.10" [dev-dependencies.metrohash] version = "1.0.6" [dev-dependencies.pretty_assertions] -version = "0.5" +version = "0.6" [dev-dependencies.proptest] -version = "0.8" +version = "0.9" + +[dev-dependencies.proptest-derive] +version = "0.1.0" [dev-dependencies.rand] version = "0.6" @@ -64,6 +71,9 @@ [dev-dependencies.serde_json] version = "1.0" + +[dev-dependencies.syntect] +version = "3.1.0" [build-dependencies.rustc_version] version = "0.2" [badges.travis-ci] diff -Nru cargo-0.33.0/vendor/im-rc/CHANGELOG.md cargo-0.35.0/vendor/im-rc/CHANGELOG.md --- cargo-0.33.0/vendor/im-rc/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -6,6 +6,54 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [12.3.4] - 2019-04-08 + +### Changed + +- `Clone` constraints have been further relaxed on maps and sets, so that you + can now lookup and iterate over them without requiring a `Clone` constraint + (though you do still need `Clone` to actually insert data into them to lookup + or iterate over). (#81) + +### Fixed + +- Enforces the latest bugfix release of sized-chunks. (#78) +- Another edge case bugfix to `Vector`'s size table handling. (#79) + +## [12.3.3] - 2019-03-11 + +### Fixed + +- A number of issues were fixed where `Vector`'s size table would get out of + sync with the node structure if exercised too much and cause erroneous + behaviour. (#72, #74) +- Comprehensive generative tests were added to test all data structures through + more unexpected code paths. + +## [12.3.2] - 2019-03-05 + +### Changed + +- `Clone` constraints on all data structures, as well as relevant constraints on + maps and sets, have been relaxed where possible, so that you can now construct + empty instances and call most query methods without requiring values implement + `Clone` etc. (#63) + +### Fixed + +- Constructing an empty `Vector` will not allocate any heap memory, instead + deferring allocation until you perform an operation that would increase its + length. (#65) +- Some bugs arising when using `Vector::append` repeatedly were fixed. (#67, + #70) + +## [12.3.1] - 2019-02-19 + +### Changed + +- Unsafe chunks have been separated out into the `sized-chunks` crate, which is + now a dependency of `im`. + ## [12.3.0] - 2019-01-15 ### Added diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/hash/map.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/hash/map.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/hash/map.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/hash/map.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,16 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 3591451162 2655640551 804983804 3307909230 # shrinks to ref m = {-13697: 30985, 1338: 29274, -14139: -4092, 673: -19662, -19198: 333, 9155: -4794, -24816: -12851, 14658: -17795, 23662: -25253, -4783: -12972, -31711: -1639, -26495: 16710, -7087: -26434, 18175: -4121, 5045: 8040, -23549: 17012, 6304: -7492, -23305: -28186, 606: 8452, -15872: 2415, 17913: 2306, -20500: 28581} +xs 1457767450 3825624317 1539332905 3279740856 # shrinks to ref m = {7136: -9742, -7547: 13954, -15860: 17017, -31620: -15850, 25480: -13526, 9943: -13939, 1142: 22444, 20378: -26706, -10165: -14641} +xs 2468731224 2159341902 336190467 4018852179 # shrinks to ref m = {22114: -20101, -30886: -4356, 29938: 40, 6256: -29990, 8450: -21821, 30253: 901, -10781: -24620, 22431: 593} +xs 1344206258 166909451 3875523340 3155104601 # shrinks to ref m = {25488: 22186, -4852: 28282, -5097: 4497, 29501: 8087, -29096: -18313, 22286: -17383, 30624: 25063, -2270: -1319, 31014: -28777, 23935: 1507} +xs 2403854785 21349881 2962261870 427550728 # shrinks to ref pairs = [(-17914, 0), (16838, 0)] +xs 1508395022 1122347352 4113209817 3965614759 # shrinks to ref m = {0: 0, 1: 0} +xs 1627474128 2843908894 3937915137 1370561421 # shrinks to ref input = {0: 0}, index_rand = 0 +xs 1863744963 3828268266 3976454353 1279901501 # shrinks to ref m = {1033: ",¦⾘f\u{b}C\u{bae94}}$n\"\u{fc28d}\u{feff}\u{b}-", 2568: "\u{8db77}ꖽ\r\u{7af7f}�7\u{a7bf3}\u{393b9}\u{0}G\u{8}\'%5E\u{cd0dc}?\u{ba311}%\u{ee814}Ѩ\\\u{80aa1}", 3527: "\u{41005}\u{41ff0}$`,L&%\u{1b}~\u{36ada}", 3577: "\u{feff}5\u{109dd9}:\u{8}\u{3}𬃹\u{3c2b6}\\\"5𡂏\'\u{feff}%\u{b8c12}?", 4544: "0*8🕴�\u{33669}\r\"\u{92011}𮡱<\u{0}<\u{1}$\u{1},\u{f1234}{G\u{1b}J\u{ceaa4}\\", 4560: "🕴\r\tѨ@\u{edbda}\u{1b}t�\u{b}\u{2}�ò\u{80090}.\'\u{34690}g%Ѩ\u{0}=\u{1}", 7113: "*", 7944: "¨\u{b6d08}$🕴&{H\rUi\u{feff}\u{0}.¥ô{_*\u{d73fc}:Ѩf`2.*\u{c9c6c}", 8738: "%𬊢*:Ä\u{90}\u{b}\u{48d7b}\"\u{4}"} +xs 1567907912 1646837549 2298759549 1787615177 # shrinks to ref pairs = [(-28601, 0), (2569, 0), (-3384, 0), (5639, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (-30583, 0), (0, 0), (-154, 0), (-27, 0), (105, 0), (-29, 0), (9, 0), (9, 0), (-508, 0), (-478, 0), (-4095, 0), (-2017, 0), (-130, 0), (27145, 0), (2345, 0), (3241, 0), (458, 0), (-6211, 0), (361, 0), (-4772, 0), (-7717, 0), (4265, 0), (-1144, 0)] +xs 2574157460 1821361166 2171243272 102290569 # shrinks to ref pairs = [(0, 0), (7, 0), (7, 0), (2055, 0), (0, 0), (-9530, 0), (0, 0), (6, 0), (6, 0), (0, 0), (6, 0), (0, 0), (0, 0), (0, 0), (0, 0), (-11133, 0), (-161, 0), (-2, 0), (-2051, 0), (-3111, 0), (-2092, 0), (0, 0), (24131, 0), (-5278, 0), (6, 0), (70, 0), (0, 0), (6, 0), (6, 0), (-31, 0), (-3492, 0), (-2373, 0), (8902, 0), (-2438, 0), (3014, 0), (7206, 0), (6854, 0), (15161, 0), (-699, 0)] diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/hash/set.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/hash/set.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/hash/set.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/hash/set.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 4213962225 2884706512 1606470227 2259275645 # shrinks to ref s = {"\\\u{4}\u{b}\u{c7afb}Q$x/\u{1a4f0}\u{1}\u{399ac}$.\u{0}=J>\"\u{2}=\t\t*q乣\'?6\u{ca350}\u{a20b5}", "\u{b50f2}$", "\u{de54f}/¥\u{1b}{*\"¥*:\\\u{e77d2}*s`?\u{3}/\u{9daa7}\t\u{1b}\":\'\u{7cf05}G🕴j", "\u{a2848}\u{bf244}.$=d\u{51d0f}¥\u{98d35}\u{3457c}<`𖡒{\"k�\t.$u\u{0}.", "!`", "\u{4}\u{9c2d9}r\u{d33a9}¥쇛\u{cd875}\u{7f}\\\u{37b37}`\u{b}\ruR\r\t\u{8aaa0}\\&`\u{b}\u{feff}\u{b868c}\u{a976e}\u{0}\\X\u{514dd}&k", "\u{feff}🕴M", "\u{b162a}S\u{6}\"\r\u{4b435}🕴 \\\u{b16df}\'\u{3468e}\\", "÷/\\\u{4dfaf}\u{7f}*\u{47f16}\"�aZ\r(Tj\u{1b}记\t;¥*<\u{1b}E\u{8d037}"} diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/ord/map cargo-0.35.0/vendor/im-rc/proptest-regressions/ord/map --- cargo-0.33.0/vendor/im-rc/proptest-regressions/ord/map 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/ord/map 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,20 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 1087347487 1450735596 3800950698 1648897824 # shrinks to ref m = {29894: -24214, -22768: -29852, -25204: 19090, -22710: 4694, -27608: 14656, -27740: 29393, 7285: -78, -3041: 77, 20980: 467, 13472: 3518, 2845: -9597, 6987: -29072, -30486: 827, -1022: 15821, 22068: -24552, 6293: -21073, -7161: 10155, 3791: -27929, 6361: 15318, 3190: 30164, 31756: 4331, 11824: 30151, -14319: -451, -17781: -5693, -5991: 372, -27192: -2983, 23456: 21711, -19546: 28578, -9753: 30988, 21193: 22302, 432: 24303, -15110: 26679, -11612: -6722, 12373: -31848, -20837: -16031, 25861: -12660, -23775: 32410, -6760: 25269, 21702: -26852, -17649: 27279, -12789: -28758, -26032: 6316, -16837: -16182, 31817: -24478, -3564: -20084, -5315: 23517, 11955: -29343, 9175: -4003, 20615: -19515, -3453: 24768, -28231: 3065, 10336: -24811, -8978: 17861, 23428: 19571, -450: 14904, -5293: -12205, -15735: -13395, 12747: -25893, 29368: 14652, 16863: -31998, 29612: 2394, 3212: 4512, -2804: 16628, -9070: 2599, -8946: -6150, 22872: -15322, -12672: 22236, 8415: -22569, 18541: -20698, 12395: -11080, -3888: -6244, -4893: 21952, -3595: 16707, 11722: -9301, 23547: 8317, -10052: -5551, -8428: -1168, -6805: 1438, 6185: 27026, 9265: 14429, -7016: -19640, 4739: 28713, 27505: -9101, -21379: 11843, 10141: 26568, -27662: -7672, -5384: -15814, -31927: 23347, 28068: -13380, -3075: 11627, -28778: 26949, 821: 22814, 11572: 16591, -10426: 5726, -14986: 6492, -4472: -12187, -22049: -18715, 3822: -26724, -13821: 24964, 14780: 23541, -26068: -17472, 6419: -16387, -21443: -32036, -27285: -11138, -12544: -22185, -25942: -22158, 8799: 22607, 22203: 23175, -29997: 9170, 18341: -19711, -25162: -29851, 29377: -4845, -4337: -3624, -30764: 13318, 2000: 6862, 13510: 4642, 25068: -1590, 16270: -1390, -23439: 16616, -13611: 30094, 10084: -30492, -6677: 12289, 28032: -21767, 10105: 8774, 627: 24722, 27190: 3954, -26665: -7354, 27566: -8037, 15625: -9453, -30151: -25954, -28349: 30379, -6142: 691, -9262: 24633, 27808: -5306, 11490: -10950, 22022: -705, 7283: -7208, 29941: 6208, -4204: -2121, -9279: 17669, -4498: -4582, -4833: 29055, -22069: 27589, 32004: -31982, 4036: 11622, -5971: 6511, 7362: -31402, 2132: 16965, -17605: 3529, 16899: -16958, 20305: -26766, 18755: 21882, 13064: -29474, 1391: -25296, 9071: -8029, -20305: 30895, 167: 21243, 23450: -32278, -22095: 13405, 12963: 18120, 24666: 28046, 14320: 8050, 30437: -12581, 17277: 15852, -19808: -27963, -23409: 24638, 29401: 15328, -21257: -3018, 28299: 29000, 18823: -8987, 15409: 9114, -2476: -12749, 5807: -25088, -17559: 19530, -3994: 32042, -23994: 11576, 17613: -11312, 24203: 30135, 14421: 29461, -8181: 17641, 6171: -20014, 31027: 1105, 20177: 11742, 28023: 10685, -5413: 22256, -29512: -27827, 26068: -31380, 10750: 9166, -19988: 26137, 6165: -12868, -9662: 15887, 12809: -12054, 25972: 23426, -3522: 11010, -13516: 10518, -20198: 8172, -20051: -21390, 17149: 27954, -25908: -3999, 22600: -21800, -15240: -21275, -12894: -31550, 11168: 6165, 1471: -30312, 25562: 31867, -3575: -5407, 16896: -21901, -31594: -2825, 24966: -2987, 31931: 19139, -671: 16835, -13289: 32113, -7420: -21883, -26225: -29508, 14029: -23627, 13600: 7738, 19823: 22879, -7278: -31931, -18518: -15028, -24285: 15271, 30158: -6041, -7778: -10728, 18967: -9084, 12216: 15282, 7667: -29473, -29079: 5065, 28475: 262, 9873: 455, 14700: 2632, -6257: 15024, 2641: -23165, 25766: -21115, 30853: -8411, 24163: -4764, -30666: 17364, -14056: 31344, -16470: -21166, 7863: -28957, 28281: -15377, 4107: -8950, -9388: -32765, 24227: -9133, -10558: 13655, 23295: 9762, -3019: -27437, 11095: 29763, 10609: 12051, -19079: 16494, -638: -5842, 4362: 27932, 2639: -25626, -3030: -14761, 21408: -18773, -21262: -4491, -5008: 1094, -11589: -2784, 15655: 29651, -19013: -9552, 7540: -28066, 18000: 17054, 29752: 18144, 28226: 27155, -12924: 7241, 22083: 13808, -18448: -3080, 29456: 16400, 53: -12710, -1221: 30244, -16504: 24240, 5545: -27714, -20630: -18870, -21090: 28104, 4959: 12418, -15608: 1794, -23432: -22218} +xs 2470012874 1108569466 2705233914 2105395150 # shrinks to ref m = {-26536: -10140, -31941: 2328, -23547: -9253, -28157: -17639, -2098: -25615, 9417: -4376, 5027: 16722, 17121: -24663, 8128: -25969, 25933: 18490, -25489: 10837, -13402: 29678, 31055: 14092, -3811: 19345, 3565: -15536, 8160: 25591, 21133: -5677, 31382: -12602, -4552: -6140, 23595: 6118, -5496: 2443, 25445: -32364, 1737: -5168, -9077: -15214, 7942: -27346, 503: 29459, 30229: 31798, -21623: -984, -20767: 1391, -20732: -5138, 179: -2480, -30700: 32256, 23991: -29242, 5811: -2677, 8242: -19246, 14001: 121, 23994: 15968, 16850: 22675, 27403: 20078, 28998: 29713, -18285: -28709, 15265: -345, -2024: -7961, -26394: -16075, -15563: -14632, 3611: -4743, -16600: 8421, 9494: 30533, -26355: -7995, -31604: 15030, -28372: -30678, -1460: 4493, 12812: 6867, 3327: 5994, -27683: -25261, -6712: 14346, 20460: 1089, 10960: 1352, 24869: -29446, -8174: 30195, 24471: -27707, 26252: 15759, -17935: 12699, -19327: 31902, 10672: -17255, -3178: -31772, 14367: 13488, 9093: 13209, -20473: -9178, -31120: 3147, -5795: -3982, -24184: 19687, -8033: 16211, -12944: 8417, -9993: 4190, 2100: 30585, -1397: -27306, 68: -17544, 12442: -4284, 7519: -12190, 22795: -29312, -21157: -16782, -32441: -15527, 3210: -4247, 32108: 9123, 24488: 25516, 11162: -10170, -19251: -2295, -28559: -4773, 31985: 172, -227: 30045, -2104: 26418, -3076: 15669, 14672: 12100, 7576: -13667, -5021: -32276, 21621: 29212, 13537: -19166, -2389: 8930, -4556: -31064, -10630: 3433, 29934: 12298, 6640: -32416, 29552: -6676, 2449: 9495, -20587: -24712, -12359: 29691, -26177: -31729, 4421: -9542, -9965: 7463, 28677: 26334, -27845: -6260, 13285: 11380, 32752: -20965, 15706: -17233, 29886: 13339, 17438: -28315, 26609: 30547, 15151: -15429, -2919: -19952, 16934: -32480, 26615: 24385, 233: -32369, -10268: -10139, 29343: -30102, -15885: 30182, 15822: 25778, -26549: -2360, 2001: -4014, -12019: -1196, 731: 29634, -29995: -22547, -15831: -27743, 1976: -14216, 24671: 21678, -10275: -5156, 28289: 17246, 12893: -32150, -16308: 7767, 5729: 11546, 18882: -31578, -4231: 18279, -25379: -31185, -1139: -16861, -18054: -8385, -31606: -23236, 21235: 7426, -6400: -7360, -8606: -2630, -22484: -11090, 15370: -5085, 5679: -17878, -28308: -24539, 9009: -24480, -16109: -19862, -20544: -20765, -6411: -28066, 11890: 21190, 4579: -7721, -22198: -22517, 338: -4143, 12184: -11969, -15946: -24141, -23654: 2485, 9886: -26974, 11733: 28587, -8243: -20115, 13309: 31556, -14397: -19926, 29872: 19550, -4716: -14669, 16769: 14751, 8353: 18931, -22070: -5371, 24224: -26199, 24823: -30739, 9421: -13020, 19874: -2767, -10193: 2881, 6660: 1643, -31321: -16602, -12356: -8592, 7484: 15900, 4220: 7816, 2781: -7331, 17673: 7955, 21734: -2072, -4406: -26944, -2747: 17863, 4584: -2492, 31654: 15772, -10883: 4363, -3737: 3686, -18179: 30440, 18460: 23217, -3702: 15120, 14407: -18596, 7749: -11497, -27197: 12065, 15409: 18406, 1457: 4533, 24941: 24486, 12520: -29147, 9179: 31948, -14078: -21063, -22741: -21277, 29691: 24484, 13093: 30490, 11422: -28999, 19850: 28538, 58: -1946, 26401: -32289, 16997: -26844, -23467: -28453, 24138: -6868, -14289: 2223, -3164: -12604, -24071: -11711, 6645: -19591, 17685: 9616, -29576: 31095, 15812: -19219, -30119: 20657, -9465: -20600, 5077: 19208, -10326: 3699, 27078: -4075, -7152: 28943, 14558: -22676, -10615: 31120, 29487: 29114, -6096: -1001, 5941: -21634, -30352: 30888, 582: -23140, 16391: 7248, 25557: -14944, 21501: 18193, 11316: 11352, 18183: 17500, -18516: 2584, -2107: -32422, -8402: 12344, -17372: 11869, -15723: 2627, -1765: 19581, 2975: 1, -5867: 23341, 25489: -2444, 9809: 21415, 29497: -18101, -25328: 28247, 9621: -3108, 28275: 8915, 6846: 3451, 28008: 18058, 6195: 10677, 12779: 1341, 13248: 30900, -18786: 27113, -26425: 9293, 16195: 8935, -2461: -16811, -31431: 4635, -9480: 779, -22487: 19715, -15600: -8938, 29782: -1315, 8079: -27635, 3322: 10561, -23910: -4240, -10716: 3872, 12155: -11450, -23322: -27745, 3206: 9309, -23080: 1961, 6761: -31058, 28940: -20745, -29586: -5915, -9310: -8874, 23578: -31849, -24336: 2811, -31640: 13432, 17145: 4078, -10857: 25423, -28879: 7602, 8971: -12084, -19239: 2917, -32289: 12788, 10482: -26779, 7196: 18090, 17174: -28319, -16874: -29949, -10772: 15992, -1774: 239, 5296: -15898, -8433: 14050, -12827: 28010, 29685: -21923, -4742: 18358, -9399: 13522, -3136: 23448, 9803: -30280, 4633: 9138, 22129: -3054, -24759: -3027, 13549: -10895, 770: 13115, -22180: -30951, 26425: 26303, 15351: -14655, -2361: 9031, 21063: -15719, 26334: -23261, 1253: 4242, 21284: -31915, -16220: 4816, 957: -25495, -454: 18872, 8183: 8829, -21137: -20303, -6282: 12896, -23187: 23, -32053: 21416, -924: -16666, -30888: 11634, 31358: 22911, -6028: -984, -28864: 9371, 28554: 18962, 13368: -9926, 25395: 11310, -22859: -15920, 24079: 24924, -20238: -29669, -2746: -24651, -21422: 21027, 30773: 9672, -8756: -14597, -11425: 30250, -8475: 3559, 14902: 23939, 32064: 4283, 15572: 18467, -8531: -31074, 26651: -5381, 27619: -17005, -29712: 2868, 16457: 20436, -11057: -2269, 3024: -15357, 15023: -26768, 14212: -26881, -19185: -18690, -4924: 7128, 23174: -20610, -9472: -16907, 17569: -23072, 20118: -14428, 9805: 26597, 6994: -8522, 2040: -32366, 25162: -31175, -1386: 16672, -22403: 26995, 7584: 27458, -17532: -141, 18644: 3005, 24808: 28562, 9341: -5445, -25768: 32689, 16892: 17059, -30689: -12568, 28747: -19363, -2091: 1259, -11643: -20020} +xs 1943497849 4012822781 687301666 4052323690 # shrinks to ref input = {-14552: -9546, -24687: 4553, -5948: -11033, -30216: 31225, -1329: 18654, 25756: 28243, 26320: 32308, 14380: 20303, 30195: -29219, 12769: -13515, 4261: -10098, -15032: 27827, 22373: -30648, -18543: -27064, 20765: -17004, -7193: 29946, 17191: -11212, -9550: 6145, 30413: -3896, 25650: 15492, 6991: -3005, -27117: -18341, -31108: -14720, 2037: -9230, 21209: -17697, -17478: -15083, -7092: -21790, -18620: -19170, 7611: -13546, -10267: -19624, -32677: 26187, 23727: 29533, -3698: -10243, 5300: -3822, 346: -5404, -22233: 16053, 18668: 22996, 2804: 14570, -7140: -914, 29328: 531, 22194: 580, -29271: 32284, -30855: -25589, -24039: 22663, -17584: -7090, 30655: -22419, 6962: 3019, -11388: -29702, 7470: 10191, 12733: -8953, 31781: 29536, -4713: 28624, 29225: 2850, 10639: -17353, 28644: -28651, 27509: 26751, -21653: -3068, -23302: 16505, 23875: -4223, -12294: 8408, 22871: -26300, -11807: -10674, 11617: -20802, -12917: -3942, 12525: 8275, -28360: 25924, -11694: -17660, -8376: -23674, 28022: -11052, 1701: 16466, -10152: 27738, 25396: 3306, 27309: -15176, -24958: 25332, 13257: -9440, 28652: -31476, 28824: -25210, 19544: -26806, -16312: -554, -29314: -25624, -6344: -27482, 12638: 11012, 29993: -5753, -7052: -5445, 6885: -32534, -2710: 15172, 25838: -29888, -4162: 25600, 8274: 3660, 14914: -11250, 18077: 21149, 30865: 29780, 7652: -29810, -27575: -22324, 27190: 13088, -28712: -24931, 32575: 14212, 16100: 2414, 22459: -12558, 12914: 12488, -5756: 26535, -11609: 21588, -23178: 22887, -6623: 10056, 11425: 5119, -24807: 1930, 20747: -2695, 22174: 28280, 26661: -7627, -22429: 26131, 30256: -13483, -23654: -6600, 23857: 20134, -6396: 26307, 27673: -19775, 21325: -20165, 18149: -5624, -16291: 20822, 30797: -19910, -16498: -12698, -28455: -13778, -19937: 16733, 22899: 23440, 20491: -29335, 6724: -14015, 20327: 29236, -13404: 17062, 21857: 21139, -11068: -11817, -24465: -19689, 13258: -20349, -8846: 24655, -14100: -5192, 18797: -4050, 15238: -20885, 21853: -14590, -21265: -5581, 7767: 16287, -29108: -18338, 15365: -10543, -28008: 20715, -27679: 9383, 28946: -32523, -6815: -11660, 25311: -30043, -24259: -32354, -26480: -29813, -4922: -31962, -23235: -14838, -28240: -16289, -20429: -10753, -31466: 4099, 17742: 9919, 22328: -29633, 11484: 5947, -30743: -3454, 27329: -28404, -1440: 16220, -21058: -15381, -7339: 775, 23003: 3428, -29181: -11177, -7918: 18487, 26135: -17235, 31493: -32374, 8674: -29831, 23135: 3319, 22008: 26647, 14087: 926, 9495: 32645, -28424: 4358, -28839: -25000, 12270: 1203, -3843: 24513, 28974: 3537, -11154: 20241, -308: 15509, -1063: 1938, 22352: 16339, 22065: -4794, 25625: 30704, -29994: 25473, -32588: 8066, -19799: -28784, -16369: -7522, 12819: -26116, -10: -12210, 23530: -8239, -8702: 15218, -29559: -6059, 17386: 8272, 9791: 11158, 31268: -23502, 839: -12740, -20953: 30929, -6498: -6179, 18058: 26452, 17715: 21182, -444: 26708, -12166: -10624, -17286: -11707, -5285: 28283, 26686: 28422, -27560: 24488, -9092: -21679, -341: 5249, -1777: -19160, -8798: -18074, 5664: -26770, 8831: 21172, -15630: 10171, 10815: -23739, 10322: -14746, 3683: -28968, -968: -11470, 4300: -21106, 17329: -3943, 919: 15039, 11736: 24420, 18566: 8425, -6499: 17007, 1038: -20933, -1760: 2435, 32364: 17255, -23412: -10508, -20606: -2288, -12261: -24932, 23266: -16759, 29366: -24835, -4536: -26835, 11130: 15321, 9689: -25898, 10497: -8, 8379: -17866, 32503: 1391, -7464: -7476, -10905: 21006, 28934: 27973, -2489: 22253, 18422: -3749, -16897: -26476, 26037: 24177, 25372: -5235, -17793: 5394, -31916: 8290, 2514: 17926, -12681: 10612, -31402: 4216, -21993: 5489, -333: -29732, -7208: 12324, -2259: 7182, -14269: 19700, 7113: -6447, 312: 21681, 16777: -5191, 19799: -22785, -16984: 20498, 13781: -19721, -15005: -27421, -5197: 16418, -26014: 14386, -21116: -29472, 22218: -3249, -12769: 13282, -962: 27871, 323: -26453, -9145: 28365, 20899: 5521, 2983: -28582, 27272: 17304, 14965: 6793, 1119: -8804, 11980: 24389, -27467: 31369, -6059: 22193, 11148: -13064, 28685: 13279, 9266: 23559, 491: 31840, -24358: 20417, -1039: 32656, -8354: 27428, -6823: 13026, 7306: -28986, -29124: -12391, 11358: 19868, 21852: 31747, -354: 17738, -6380: -31076, 6993: -3593, 7749: -26991, -5736: 26845, -23757: -25868, -23018: 21291, -29482: -13037, -28028: -17152, -11500: -2400, 14240: 27368, 8517: -7890, 3318: 26016, 8702: -21694, -15698: -18674, -29992: -16745, 17497: 3921, 17256: 23908, 12994: 16354, -12133: -5976, -9636: -19253, 13662: 26694, -5291: -27961, -19711: -2634, 24676: 200, -21683: -20419, -10755: -20201, 5389: -24265, -18644: 25881, 24013: 26905, -15710: -40, -1078: 24024, 29202: 25073, 7358: 5121, -23181: -31628, 10282: -26184, -20910: -2762, 31789: -11576, -15966: 18578, -14285: 3170, 1448: -13499, -10080: 23097, 9012: -30126, -15463: -12150, 20289: 31453, -23544: -15457, 14694: -5005, 25006: -25213, 20402: -18375, 29679: 20672, -4570: -7111, 22495: -6454, 28869: 31665, 14191: 13852, 16134: 32353, 4529: 8494, 19093: 6864, -794: 18776, 17957: -11241, 25597: -20134, 18037: -1679, 27835: 3288, 22315: -10272, 13032: 9697, -20215: 3797, -12773: -983, 25848: -4873, 19596: 9706, 8030: -28925, 30246: 12946, 7467: -25254, -10731: 6363, 18631: 8976, 1414: -13096, 1779: 15953, -3595: 21321, 339: -8066, -7639: 14039, 20195: 12164, 7156: -11669, 16411: -8927, 13534: -14503, 13577: 17546, -27772: -32545, -6421: -3173, -12316: 16200, -31884: 603, 12395: 3034, 22659: 25898, 30481: -23170, -16623: 20360, -20279: 30762, 3968: -13181, -2313: -4445, -13314: 13183, 17186: -472, -25465: -11926, -12985: 12936, -17260: 21153, 14971: 366, 5035: 29873, 29: 19702, -29547: -10586, -10368: 11518, -13759: -4543, -29208: -4931, 1605: -15282, 22500: 24270, -25324: -150, -24578: -5930, -25949: 21945, -10053: 2314, 19195: 24191, -6760: 32697, -8885: 28695, 12676: -18931, -24963: 5956, -11667: -32632, 3496: -7015, -3422: 24361, 17031: -19643, -21362: 28410, 11868: -24693, 26928: -25916, -8771: -10298, -19434: 29046, 16057: -21815, -28508: -1488, 17240: -23998, 3146: 4003, -8669: 1658, -2885: 3442, 19212: -25066, 8584: -30453, -19749: 25649, 12925: 1864, -7982: -17592, -18312: -6020, 26066: -12698, 10168: 2258, 23411: -27324, 20913: 2058, -17161: -2704, -28674: -8941, 19334: -154, 29314: -18570, -4291: 13987, 27890: -10595, -6139: -19690, -2185: 29099, -19246: -21481, 18345: -7746, 8792: 32374, -12093: -11963, 27898: 28419, -2679: 31973, -6053: -9814, 28750: -1279, 5512: -22468, 24559: 13801, 29152: 10421, -8834: 21875, -11673: 15773, 28602: -9755, -5742: 6786, 13086: 15119, -10716: 23940, -31277: 6551, -12006: 16878, 31399: 15139, -3499: -14162, -7428: -10133, 31533: -4236, -20111: 23374, -13506: -28699, 31291: 27230, -32598: -7092, -5972: 31899, 15397: -8419, 15791: -2952, 24123: 9853, -32197: -7823, 12564: -18593, 16139: 21230, -23524: -28360, 6509: 20623, -8275: 31514, -6607: -5333, 5101: 31408, 23166: 21657, -12672: 8924, 1406: -11027, -24417: -3430, 27934: -17823, -7960: -29901, -20662: 24784, 9478: -22265, -3096: -26803, -5897: 23795, 29566: 26527, -19057: -10328, -22202: 18967, 11290: 32741, 14225: 4804, -31177: 15798, -23514: -7563, 21445: 15844, 14156: 8570, -23968: -24474, 12089: 5498, -14198: -26135, 12664: -23411, 11111: 27354, 15998: 11423, 2891: 21555, -3889: 17061, 32491: -4625, 110: -9137, -20559: -6986, -28721: 3288, 6697: -23898, 8774: -6890, -24838: 20366, 31820: 27280, 14127: 10447, 605: -23336, -28271: -9387, -1486: -28143, 1623: 19882, 30022: -7494, 16398: 31225, -20320: -23582, -23295: -17336, -14291: -775, 3270: 20106, 11662: 16973, 29041: 3377, 7387: -16397, 18767: 32565, 5022: 19191, 16397: -31024, -16106: 13405, -31898: -23690, -25746: 17046, -8847: -29236, 28656: 21644, -11311: -25314, 4515: -19390, -15847: -1245, -5025: 24474, 24302: 28820, -31534: 24028, -14548: -21272, 20722: -27070, -24083: 29927, -27812: 19042, -18194: 5028, -29732: -8181, 20316: 16946, 3176: -32144, -30223: -25654, 202: 22052, -20234: 6669, 18732: 15730, 7127: -27128, -2948: -22493, -21733: 27859, 25166: -31535, -27174: 28732, -14476: 5256, 20346: -27358, 6308: 18033, -10411: 12780, -5469: -28028, 4884: -15738, -12442: -3065, 24311: -21682, 18679: -10632, -13091: 25595, -18882: 31353, 23626: 20687, -17201: 13186, 4270: 16793, -22089: 5358, 4374: -23552, -13011: 5661, -14593: 1052, -10586: -18438, 9093: -3136, -19492: -30355, -5066: 24396, -9852: 13836, 8770: 30757, -18672: -13421, 16224: -10802, 21800: 12639, -213: 28223, 22311: -6756, 7182: 31529, 19224: 16315, 20067: -19940, 10720: -12330, 8384: 14353, 27730: -24075, -18309: 4570, 5808: -32765, 14330: -24746, -19632: -3605, 4228: 25887, 28783: -30008, 16483: -20439, 16655: 26861, -10047: -14259, 30091: 29732, 29182: -13397, -26897: 14659, -17202: 16830, -15265: -16433, 18554: 18464, 3269: -15505, -11054: -20924, -5253: 3749, 14888: -553, 15310: 29010, 3194: 31220, -13770: 21130, 4236: -15365, 13546: -11695, 32688: -16898, 24524: -8344, -2968: 25207, 1449: 26456, 29046: -5209, 12133: -27981, -27130: -21148, -3586: -24606}, index_rand = 6181253659715007859 +xs 3094145122 1848048556 41621330 1587738279 # shrinks to ref input = {25109: 17547, 13167: -24835, 32450: -27886, 28704: 27530, -29237: -31051, 17202: -31179, -22358: 15751, -17715: -2518, 82: -27363, -26280: -12489, -10711: 1113, 28197: -29265, -12233: 15499, 1578: 18570, -10956: 7886, 957: -15131, -26652: -19109, -1698: 7038, -3697: -2352, -18762: 4688, 2143: -17488, -30936: -28216, 26547: 20891, 20001: -10566, 20162: 12139, -15042: 4332, 23226: 835, -1720: 26602, -9048: -19721, -29320: -13680, 30000: -7286, -3693: -16312, -30022: -21864, 29541: 16785, 4006: -20908, -29599: 14040, -17690: 24907, -3766: 16608, 22217: -29766, -29552: -3913, -4046: -20703, -26412: 21205, -15898: 17844, -4553: 32030, 30908: 18124, -1065: 27619, 1642: -19186, 31516: 28398, -22847: 5892, -31043: 21198, -20284: 25965, -27740: 4090, -750: 29603, 29546: -7601, 19831: 16923, -27337: 27061, -5052: -22512, 19028: 22656, -6128: -20716, -5324: -2624, 7273: 5987, 26259: 28589, -5682: 24455, 19425: -13458, -8687: 1837, -29081: -5536, -5126: 19859, -23172: -26061, -17454: -9093, -14495: -19415, 124: 27981, -214: -15589, 17580: 24995, -22303: 227, -2043: -17283, 13309: -29027, -22094: -31943, -1826: 12330, -26959: 19945, 22155: 4915, 16: 1005, -6802: -8951, -29879: 4766, 21350: 7196, -4292: -29428, -17591: 7350, -23475: 20767, 23372: 13739, -16316: -30392, 17391: 5141, -10827: 27764, -11304: 7731, -4247: -21446, 8251: -19738, -568: 8414, 14787: 5321, 2403: -17445, -19412: -16874, 16247: -30651, 11946: -29414, -7725: -10389, -2002: -20578, -12689: -21992, 15800: -451, 32435: 1683, 16805: 11493, -8068: 32206, 27386: 26184, -14311: 21859, 7208: 19308, -13115: 24029, 32222: 19098, -3951: 20703, 10184: 5095, -3235: 29199, 7358: 3163, -9539: 23015, 17802: -31374, -12478: 18169, 21253: 2717, -4126: 30376, 31545: 13768, 14466: 10983, 26903: -7058, -8377: 21868, -15947: 21121, 31358: -30749, -22714: 23423, 17855: 9349, 7118: -3573, 20807: 30872, -19809: 19037, 3084: 622, -13442: -19023, -9314: 14811, 19551: 9175, 13945: -24551, -9482: 14832, 4058: -11363, -29175: 3097, 26866: -6501, -19528: 16419, 13884: -10693, -30894: 18387, 2434: -11471, -29588: 8302, 9537: 26353, 11223: -4669, 32503: -8454, -17566: -12769, 2898: 31182, -19042: 2208, 18941: -22060, -22700: -31888, -11067: -21667, -23130: -13776, 29835: 5369, -15197: -21652, -31889: 23653, 19121: -20925, -4888: 11878, -23301: -32625, -12188: 18858, 7983: -19066, 30772: 18792, 18565: -29423, -30448: -28531, -29781: -27670, -23123: 24404, -8686: -5154, 1956: 28781, -7050: -19514, -21874: -15534, 27434: 2933, 11568: 8591, 8645: -32175, -24288: -32065, 23708: -16804, -102: -20155, -21298: -10486, -5606: 25010, -6095: -10305, -19200: -11318, -2702: -31591, 10484: -30488, 12966: 18734, 19351: -29225, -10379: 28706, -13211: 13219, -30684: -30410, 12809: 3245, -9528: -14612, -13917: 30016, 15751: 14348, -16078: -20918, 21568: 22488, 18004: 30534, -19602: 18121, 13959: 22532, -9411: 17916, -13153: -12283, -16441: 24688, -31877: -25633, -10943: 21681, -12241: 25973, 18048: -16131, -32576: 16074, -23799: 30191, -27572: -4842, -9917: 17632, 28907: 26864, 1029: -8790, -15458: 5122, 617: 31966, 5083: 20195, 26118: -27966, -31719: 261, -30897: 26416, -28104: 25353, -25183: 10371, -25051: -9876, -8676: -2203, -25965: -25244, 14552: -27117, -6195: -9440, 6733: -15895, -16548: 22340, 7795: -7156, -5548: -8170, 1975: 11313, 26002: 13579, -1090: 16028, 3119: -22116, -26790: 3213, -12524: -21450, 19788: -30362, -11778: 7254, -24041: 18664, 10038: 10500, 12731: 10291, 19886: 8630, -13579: 4280, -10199: 16578, -10637: 18165, -3835: 6271, 14929: 24076, 27938: -31473, -14770: 5512, 15441: -3706, -17185: 2295, 15932: 20222, 13258: -18255, 24353: -11049, 24897: -6737, 365: -23551, 23329: 30521, -31648: -13380, -1552: -25692, -5206: -1325, -27419: 31094, -51: -28413, 12361: -29699, 5402: 26930, -27529: 7188, -12050: -7233, -7996: 20657, -18903: -31229, 2184: -27864, -22198: 8189, -14333: -3151, -8819: 32208, -25427: -1465, -13361: 23768, 25140: -13818, -18482: 5019, -9847: -31791, -17654: -16678, -18171: -25938, 24839: -22327, -10299: 17415, -517: -9938, 11604: 19413, -20522: 25880, -16853: 12843, -19711: 6243, -2217: 17848, 31544: -23358, 32481: -20104, 916: -13297, 21632: 27432, -20301: -905, -28748: -18375, -18946: -26872, -27139: 23619, -28341: -2690, -14751: 3261, -31340: -5866, 14129: -1873, -17466: -19221, -27794: -25683, -16132: -26856, -6446: 21798, -26329: -20765, -19511: 31669, -25708: -5275, 10217: 797, -9016: -17110, 7696: 13723, 6083: -19072, 31100: 8435, 8017: 10175, -23973: -199, 25418: 21954, -5106: 15703, -29119: -14678, -23448: -14905, -1334: 27615, -25389: 21402, 5764: -14910, -25059: -20274, 32586: -21603, 27022: 24446, 30370: -23901, -31423: 31764, -21135: -21011, -6284: 14914, -20672: -4657, 3691: 9397, 1305: -26046, -29806: 1663, 11409: -9037, -25440: 12737, -16350: -30111, -15664: 4544, 29290: -19087, -10773: -15820, -1299: 31105, -9945: -24879, 25445: -1393, 17568: -11207, 2868: 11240, -14478: -5443, -29749: 22046, 30402: 18906, -14676: 28148, -12434: 19407, -8904: -31377, 32723: 19548, 26961: -12468, -20695: 24529, -11186: -16253, 17983: -16005, -22681: 29406, -32124: -28864, 4551: -32279, 16423: 21410, -29467: 30297, -32316: -11084, 19168: 13447, 31777: -17253, -20788: 30789, 10397: 26717, -16290: 10403, 3436: -20939, 24973: 21047, -23977: 19143, -21115: 16465, -32140: -27035, 29494: 19758, -31925: 16559, 25544: 14705, 16117: 2902, 16076: 1994, 1259: -4130, 11871: -31322, 31923: -12428, 6485: 16367, -15055: 17454, -32536: -23142, 19287: -30036, 19046: -6360, 30467: -20193, -1352: 19442, -24389: -32203, -25508: 28905, 13432: -28476, 15794: -2020, 7907: 12590, 19319: -31856, -10096: -8759, 9365: 24849, -11559: 25438, 23762: 21598, -7248: 22542, -16926: 12934, -24708: 4222, 2179: 3309, 1855: -8693, 10786: 29825, 18783: 25809, -5169: 5570, -8235: -4664, -20234: 26252, 18273: -26922, -4496: 19147, 4458: -20329, -18952: -31435, 22439: -27690, -3304: -7512, -17425: 6385, 2885: -18520, 2478: -17666, -16036: 22920, -8658: -18048, -7204: -25509, 28983: 4786, -9146: 16439, -26893: -27056, -31037: 17541, 643: 17042, 27085: 11808, 26037: 20956, 4234: 1346, -14815: -6582, 25700: -8577, -10298: -23247, 5728: 10020, -25496: 10378, -27275: 28186, 24689: -21421, 32092: -15135, 17254: -370, 13808: 18349, 19084: -163, 16447: -25693, -22306: 26140, -1695: 3490, 32119: -6821, 25084: 21803, 10922: -26376, 27134: 21743, 30570: 8146, -12987: 6435, -20456: -22516, -31704: 12485, -23916: 4096, -26088: 20130, -19159: -28657, -3808: -29934, 21346: 18600, -17642: 22758, -9589: 9627, -12541: -16450, 3120: -31143, -5758: -4025, -14764: 22952, 26792: -16315, 12268: -8062, -31344: 20767, -10729: 652, 32354: 30556, 10533: 27076, 18563: 31611, -15395: -16343, -7271: 28710, 28693: -28840, 19304: -31194, 4838: -28332, -15421: 18530, 24139: -28363, -31872: 15347, 17464: -17470, 30063: -21708, -6516: -17705, 14553: 20142, 29460: -4329, -9381: -14281, 3286: 26530, -25478: 18858, 8614: 12250, 3087: 21051, -32628: 24370, -15651: -18351, 8024: 4382, 15805: -11203, -1077: 8609, 32285: -11583, -27614: 7211, -10535: 22639, -20099: 16870, 21230: 28095, 612: -23352, -5544: -26504, -25887: 2679, 14181: -26845, -31967: -7583, 26010: -15169, -6467: 12825, 24107: 4381, 3800: -2605, 2010: -21114, -1414: 6971, -12659: -21065, 20831: 9711, 20073: -8964, -24951: -3223, -6740: -32200, -8304: -23492, 27109: -8227, -17744: -25257, -28537: 18637, -18411: -15041, -25173: 928, -25903: -13895, -21831: -3009, -25678: 1895, 30480: 17166, -25850: 16586, 12531: -10102, 19095: -6338, -26672: -9944, 11671: 1505, -13311: 12087, 8454: 19381, -12936: -31002, -17139: 19189, 11596: 20259, -25535: 3542, 20951: -18777, -6500: -18332, 30742: -277, 31676: -30490, -27517: -19880, -25374: 32088, 21483: -10823, -16979: -18696, 14561: 13047, -13368: -16548, 4720: -14672, -29316: -19115, 1395: 9605, -10992: -10275, -21747: 8507, -4734: -6057, -30595: 16035, -24700: 22816, -2210: 19173, 7671: 24589, 27460: 5788, -10899: -21848, -26840: -3095, -28802: -2572, -3431: -5783, -21943: -31626, -22611: 26127, 3213: 396, -15957: 17787, -11959: 17422, 1613: 22455, 32292: -9957, -23718: -32341, 2795: 4614, -15162: 2211, 26391: 18246, 885: -15549, -29735: 26493, -17763: -9509, 832: 15026, -23215: 22609, 28230: 20969, -32629: 28951, 10402: -11520, 26729: 11732, 14065: -4855, -12988: 5456, -24309: -15464, -20942: -11584, -18355: 1571, 16650: -13337, -7873: -13362, 11313: -19130, 20194: -6007, -9755: -26600, -25013: 21165, -14900: 26513, 17728: 17821, -28277: -25003, -14757: 5100, 13577: -9806, -22115: 27298, 14668: -23429, -25174: -28161, 2367: 4067, -23795: 27843, -3780: 5571, 30910: -13600, 11355: -21254, -7086: 2278, -13419: 3221, 22732: 21622, 24582: 15497, -4771: -18262, -705: -24363, -6490: 13550, -3098: -31941, -20378: -12040, 25336: -18191, 21299: 822, -30797: -23895, -17162: 18699, 228: -17254, -12250: -21242, 4730: -2067, 8150: -16241, 15707: -29248, 6042: 32137, -26556: 15175, 14154: -28226, 9935: -23158, -29846: -22516, 9461: -29500, 11475: -19325, 31974: 2561, 1330: 8660, -1271: -17382, 3482: -8519, -25956: 15786, 25713: 3023, -394: -27817, 19478: 32434, -12289: 12678, -2608: 9330, -26485: -7465, -27840: 12092, -31666: 3630, 15748: -11979, 30892: 30006, -21505: -30879, 10340: 14885, 11619: 5575, -7216: -30397, -15140: -11637, 16761: -16433, -21925: 12562, 28429: 18057, -12739: -25584, 13377: -24419, -3752: 22641, 21444: -30136, -27669: 23044, 521: 28473, 9286: 5030, 29721: -14329, 10899: 8578, 9145: 15065, -30537: -15209, -21221: -5525, -16581: -17871, 27355: 23268, 56: 17851, -2659: 22647, -1630: 31617, -30759: -18270, -28584: -4801, 1875: 10171, -8604: -27218, -16634: -19036, -17802: -16413, 13379: -6140, 23704: 6880, 8765: -1719, -21255: -6806, -19546: 23388, -22379: -4391, -17126: -18724, -21340: -9110, 18182: -10221, -2471: 2014, 13850: 25597, 18153: -5252, 13325: -21738, -27130: 19737, 8324: -57, 16162: 17766, 30735: -1934, -13008: 18027, -14177: -26344, -3410: -15352, -22373: 13456, 23820: 30037, -16682: -8556, 2771: 32686, 7700: 2288, -15586: 23950, -23520: -30119, 24085: -27227, 28343: -27847, 11661: 11000, -2690: 6058, -30191: 21458, -10655: -20377, -18377: 8672, 15970: 29352, 13854: -28243, -12566: 12732, -11424: -5467, -13021: 19087, 4285: -20833, 4850: 15552, -28485: -26386, 8290: 259, -11749: 19444, 26075: -905, 30605: -1488, 6438: 27983, 9535: 25448, 10668: -26317, 9228: 2787, -9342: 6996, 3077: 2077, 14575: -17406, -13263: -28914, -16497: -8505, 17807: 29989, 17642: 27683, -7320: 22167, -28413: 23955, -29262: 1610, -7611: 20341, 13742: -22167, 1948: -3978, -26335: -18254, 7765: 4432, 22110: -27003, -3021: -16057, 15606: -23087, 8263: -28114, -28389: 28514, -24292: -3802, 593: -22012, -11632: 18700, -8493: -17690, -24000: 29402, -30405: 18870, 2054: -12353, 6302: 13902, 14627: 20456, -20713: -6796, 59: -27945, 15401: 3763, -31282: 2136, -30080: -21448, 596: 31173, -3777: 10969, -27062: -12955, 10983: -10220, 23508: 7525, 18741: -17043, -2752: -3564, 1045: 29156, -23741: -18438, -20412: -20083, 31569: 5108, -19554: 24719, -31716: -26184, 3254: 30063, -23755: -474, -10974: 24808, 32587: 24856, 13274: -13294, -23140: -5331, -1612: -8780, -12950: 16875, -7602: -1367, -8407: 24480, -18043: -18814, 5557: -14426, 23239: -32629, 12839: 10100, -23881: -9397, 9000: 1367, -16739: 24959, 27731: -23120, 1404: 16785, 26722: 2067, 13575: 21126, -4894: 14658, 13344: -7459, -3522: 8125, 10021: -14961, -10653: -5225, -23802: 25545, -6938: -12602, 3949: -14698, 29660: 11675, -2952: -7008, -30398: 12733, 24591: -27470, -8108: -1693, 8378: 6293, 19409: 107, -24293: 13979, -26643: 24382, -8928: 14933, -15145: -3845, -22551: 10211, 425: -15224, 16478: 7707, 2338: 16763, -23791: 31613, -8916: 7382, -5384: -31297, 10300: -1373, -27891: 1916, 2999: -30008, 1165: 24301, -397: -18055, -4201: -8619, -23959: -1718, 16219: -26007, -15100: -24529, -32527: -12160, 19770: -292, -10008: 22619, -26772: 3604, 236: 105, -7879: 31666, 19242: 10567, -6348: 14664, 5832: 13312, 1492: 10163, 8927: 21565, -26318: -18183, -10174: -25158, 9807: -26056, 26076: 17814, -15366: -19761, 2621: 12814, 30193: -31344, 4206: -18921, 7126: 22715, 16128: -10023, 25936: -31820}, index_rand = 5224467844040644997 +xs 361304641 2604218693 3136857884 1914902562 # shrinks to ref input = {-19354: 24819, -16292: -12090, -14434: -17000, 7065: 3299, -18458: 22292, 19194: 12574, 1: 18507, 32098: 548, 3309: 3711, 30631: 31499, -9540: -31601, 29472: 15053, 28278: 16574, 10805: -6409, 1937: -29445, -27617: -19598, 14618: -13991, -31216: -14546, -8002: -19976, 24690: -11392, 19023: 6532, -4475: -15383, -3276: 3043, -22021: -831, 7566: 28669, 7414: 7538, 3289: 1498, 32294: 11245, 27957: -24717, 394: -5551, -25550: 7578, -10781: 17801, -15265: 22301, -22600: -27228, 18049: 28811, -5680: -4765, 6393: -26312, -3763: 19239, 12387: -7834, -17270: 15102, -849: -18294, -11185: -8909, 5848: 28816, 4822: -1284, 9283: 17434, 5749: 13204, 11282: 18054, -30054: -1590, -5733: -8222, 27256: -17099, 25828: 27982, -26680: -20087, -31170: -3715, -27215: 20014, -3297: -27491, -4237: -9165, -3803: 6289, -13220: -7922, -31962: 28987, 15542: 18604, -17133: -25302, 13426: -25405, 2685: 15869, 5642: -8384, -8618: -21494, 696: -6333, 30169: 22735, -31498: -2698, -16350: -30346, 23455: -30868, 24880: 8411, 12752: -26951, 807: 5479, -31915: -6948, -6797: 32084, -27450: -5011, 12562: -16186, 16308: 9586, 8802: -8309, 22958: 1367, 5967: -7809, 7342: 9794, -21809: -30257, 22051: -8714, 11489: 27098, 9636: -24412, -22926: 4643, 16522: 3404, -13679: 20161, -20645: -4604, -27194: 2276, -1203: -23043, 15177: -16488, 17368: 19938, 18129: 13518, 29506: 13683, 30487: 29314, 22806: 20773, -1727: -29216, 8206: -19496, 7127: -23074, -2964: 1656, -8043: -15180, 31783: -24797, -14997: -8251, -9625: -985, -3485: -1572, 3259: 1018, 4124: 31363, -6871: 11567, -15128: -13650, -30770: 9112, -2638: 21963, -19057: 16043, 20685: 214, 17778: 6821, 27947: 8329, -13235: -3670, -15954: -21158, 12517: 13054, 23898: 16751, 16216: -18722, 15237: -7624, -31732: 21365, 30822: -28157, -17438: -30023, -26596: 3301, -13414: 5061, 17372: -8376, 30362: 28469, -20309: 143, 24393: 10508, -6411: 32337, -18972: 19110, 30365: 10104, -5140: 19909, 11898: 18406, -14442: -15467, -32552: 22492, -11355: 5350, -8307: -18294, 17475: 7093, 22597: 1992, 20469: 30777, -32614: -6165, 32573: 8339, 1514: 25969, 10701: -20617, -3021: -12256, 6587: 18950, -25402: 12031, -9936: 16285, -29946: 22912, -14064: -10944, 671: 13716, 5073: 7865, 5197: -26128, 19416: 9507, -30681: 8287, -21677: 28198, 3770: -21258, 14103: -8796, 21840: 6932, -14302: -3120, 18835: -21353, -19863: -30682, 30904: -24579, 23767: -2876, 14140: -7923, 23444: -8002, 20015: 24236, -8959: -10261, 19803: 10542, 13739: 29511, -28569: -14754, -3714: -30519, -14450: 8383, -11394: -30165, -32079: -13880, 13248: -30479, 11781: 9474, -10436: -2853, 6759: 27954, 25845: 29391, -31738: -26454, 30132: -23278, -18345: -23422, -25979: 16664, 9607: 29137, 8336: 22464, 20324: -23583, 15078: 31805, -28529: -17128, -12412: 9041, 5972: -27525, 10224: -32042, -6332: 7448, 26995: 20876, -12473: -28199, -23999: -23159, -18299: 21242, -14408: -31328, -29246: -10044, -10164: -28095, -27052: -5400, 10173: -25267, 23822: -17900, -23953: -13219, 28791: -8090, -21909: 21407, 17530: 26269, 29655: 29973, -16374: -16957, 13982: -24366, 11639: -20136, -18021: -4470, -28776: -14271, -19637: 20591, 17096: -6224, 19899: -7035, 10911: -124, 5706: -16549, 2364: -24950, -10944: 31678, 31723: 11433, 6413: 4440, 32675: 19466, 27096: -13819, -10806: 6633, -4937: 28751, -27140: -13550, -12557: 13547, 8629: 3152, 3413: 2565, -25866: 10729, -15566: -15218, -3621: -23194, 7527: -27521, -24127: -29997, 12909: -25868, 31772: 4680, 31014: 29821, 18678: -16508, 30298: 9039, 14505: -3668, 22669: -10595, 26152: -16178, 24944: -8114, 16694: -19338, -14047: 24498, -30270: 26317, -16665: -26461, -30656: 20249, 25517: -20809, -23571: 1882, 23007: 17866, -25659: 8076, -23717: -5810, 6904: 2115, 11784: -31335, 30197: 18033, 12572: -30508, 17268: -18072, 10674: -22655, 29365: 24132, -17185: 10599, 8749: -31736, -3334: 32668, 21915: -2453, 17556: -26978, -9373: 26250, 22616: 30289, 2165: 15435, 10766: 1818, 13715: -20952, 2935: -9271, 25227: 15051, 13045: 23934, 13260: 30812, 10690: -10114, 824: 8266, -14298: -13127, 11000: -14100, -18008: 21650, -8299: 6540, 3128: -12265, -7224: -8911, 19209: 14023, -8038: 24840, -26622: -26079, 14895: 22828, 31625: 20961, -2636: 19675, -17021: -28086, -5946: 15939, -32313: -153, -14012: 30196, 31144: 31395, 7996: 24091, 28923: -29327, -9247: 15709, -26391: -9285, -14883: 27089, -15544: -12422, 1374: 28261, -22870: -12032, 26286: -20763, 4080: 2040, -14599: 9484, 32660: -3226, -22977: 5487, 18067: 3363, -6489: -21852, -10804: -13137, 27933: 20036, 15275: -12004, -13892: -676, 16130: 22039, -24538: 21841, 24641: -3642, 21784: -26054, -20651: -27826, 5295: 32093, -24305: -3414, -18446: 10556, 4517: 526, 24294: 10881, 24194: 26364, -13901: 18395, -12783: -27360, -713: -29957, 8644: 14950, -6324: 9260, 9506: -30362, -29129: 6181, -3784: 18178, -28466: -21361, -18659: 3987, -10595: -19837, 7499: 30194, -12558: 7406, 28463: 12837, 27107: -2298, -6932: 4389, -32374: 25500, 23110: -23112, 8747: -22926, 4097: -2613, 3462: 30698, 3398: 31612, 30467: 23139, -1641: -3740, 3293: -19082, -20228: 31473, 20793: -17194, 17724: -25522, 8074: 32013, 23712: 19733, 31907: 8354, 12744: 28197, -24606: -11268, 23637: 3704, -3436: -24423, -2739: 10852, -4260: 18850, 12969: 6263, -26425: -6431, -28020: 25049, 31644: -1993, -20327: -6272, 22470: 17788, -28205: 31716, -21534: 32498, -4889: 19628, -825: 16644, -30248: -31584, -26932: -3743, -28597: 27796, 10641: 29403, 18736: 11379, 17445: 4741, 15954: -22253, 28955: 3994, -18758: -20179, -16666: -22951, -23409: 7546, 28441: 28286, -6600: 29204, 245: 5060, 21723: -31646, 13693: -28832, 17526: 19157, -3421: -30798, -12920: 25702, -13396: 4699, 25125: -17956, -378: 30900, -29352: 13943, 21551: -27295, -31207: 316, -5104: -20171, 10981: -14599, 13127: 7748, 12536: 20062, 15315: -493, 10111: 24216, 3207: -31216, 18499: -20515, 4815: 26753, 24865: -18658, 28562: -27549, -14256: -3818, 22292: 9007, 9550: -22562, -18174: -5902, 18354: -4282, -14416: 6361, -20722: -24289, 31715: 29227, 29704: 15935, -5533: -8673, 10845: -30941, 14160: 12144, 1992: 1318, -11404: 28138, -5428: 18711, -1624: 3223, -20437: 19171, -13983: -15469, 29721: -11600, -32689: 14340, -12675: 7713, -21501: 21229, -3729: 27686, 13580: -5131, -17708: 16700, 20809: 25221, -28564: -3272, 29509: 26850, -9889: -9564, 938: 25880, -17223: 18566, -20452: -799, -4292: -17811, -19061: -11617, 25764: -11388, -3347: -14170, 29220: -7185, -21149: -4187, -8341: -13996, -9012: -22916, 5303: -18306, 14513: 21706, -4815: 9868, 4316: 3968, 28688: -1524, -19338: 14733, -13386: -14098, 18253: 3130, -1221: -5690, 5093: 24217, -12424: -8733, 25791: 31206, 6697: 29204, 31192: 12158, 31407: 749, 17618: -3504, -3199: -3206, -11293: -20357, -16165: -3563, -27497: -25700, -27297: -3825, -23521: -23715, 4652: -29245, -17313: 10246, 22202: 28783, 12621: 7793, -25616: -9539, -8209: 11244, 2018: -23988, -29161: 7278, -17743: 748, 6678: -15931, -31969: -10178, 11253: -18267, 9135: -23204, -31002: 27729, 22133: 28453, -31372: 16243, 29200: -18504, 27344: -7996}, index_rand = 12865908526723545602 +xs 2514330554 4021224636 4249159765 809946243 # shrinks to ref input = {22983: 25567, -21524: 12652, -31419: -14369, 24781: -3215, -6098: -3626, -4344: 6615, 11513: -5995, -32129: -25765, 19648: -32475, 5272: 26666, 6416: 22836, 27222: -3403, -4042: 3636, 13253: -27848, 27331: -4442, 666: -14459, 13044: -27108, 2407: -18269, -11769: -23455, 6186: 23587, 3702: 7914, 29676: -21600, 12424: 12219, 27941: -5207, 15122: -12497, -11158: -27362, -8282: 26473, 3415: 26408, 12831: 17512, 5795: 28896, 21721: -11462, 20429: 9497, -12438: 9683, -3959: -13001, -25293: -23380, 5700: 24227, -21071: 9692, -18808: -24549, -27808: -4112, 14687: -13091, -14445: 10864, 8680: 29230, 28793: 2289, 572: 22804, -12907: -22882, 19549: 29926, -24247: -3077, -96: 16251, 8929: 32524, 18444: -31578, 24622: 19896, -20594: 13891, -22943: 19132, 31425: -2940, -12580: 30389, -526: 2891, -10880: -20465, -20861: -9108, -1990: -1706, -14673: -3333, -12415: 12446, 1711: -3619, 2889: 26166, 5135: -9934, 9761: 7314, -13727: -30121, 23167: -14068, 7972: -16912, 792: -2110, -23816: -11162, -14613: -11944, 2276: 16327, -1710: -513, 14501: 12803, -14424: 12359, 8166: 23242, 7132: -5033, 2661: 18395, -29564: -10169, -24378: -28753, -6535: -12561, 8864: 16922, 5509: 24075, 6948: -31451, 9166: -16562, -15552: -22739, -23577: -11089, -23262: 15724, 7935: -226, -15831: 22789, 19431: 12267, -32692: 13439, 8190: -27259, 5177: 21511, -25935: -29614, -23804: -9779, -5144: -13329, 13090: -1785, -24277: 11514, 23943: -7920, -5978: -7247, -10397: -26707, 25026: -2168, 16104: 8686, 1807: -29851, -24649: -22813, -19629: 11095, 22893: -20902, -23916: 17574, 1476: -25217, -24340: -19076, 28100: 15570, -22175: 22320, -6586: 6492, -18649: 11816, 16251: -21463, 17368: 3798, -20189: 3235, 16961: -6580, -8404: 20372, 16047: -15304, 29490: -3055, -24776: 15119, 27563: 16145, -22311: -2158, -15739: -32392, 2484: 14964, 21250: 7246, -9967: -28930, 31387: 5103, 14859: -2042, 16259: 31622, 29267: 26762, 6688: -2894, -25600: -27724, -22795: -11228, 2779: -25135, 3592: -29746, 2684: 25084, -14032: -6792, 16004: -29800, 10914: 6250, -15582: -26248, 21285: 13207, 22458: 2337, -13517: 14340, -29653: -16328, -9174: 8207, 6822: -22380, -13230: -5805, -24662: -20758, 23527: 6218, 21957: -1144, -29983: -14789, -25776: -10625, 29489: -29112, -634: -1687, 16362: -5095, 24103: 17173, -28568: 4122, -27366: -2615, -3220: 25064, 990: -31755, -14609: 23575, 31478: -24182, -15842: 9193, 7823: -20861, 32558: 23623, 28629: 20621, -27884: 26432, -14903: -17295, -20813: -25646, -14902: -25559, -13309: -1218, -12300: -17285, 31853: -3859, 1399: -7893, -26296: -29878, 19179: 13265, 15479: 17728, -25448: -8456, 13588: 27559, -24783: -7128, -32103: 29322, -1758: -3572, 13728: 31962, -17236: 5243, -21230: 27588, 20742: -27977, -20661: 4578, 9198: -15494, 5045: 25517, 29565: 31629, 20558: -6873, 24626: -30679, -7805: -9759, -3591: -19001, 28566: 18547, -13063: -28236, -19655: -4068, -9420: -16081, 25403: 23876, -17448: 2581, -26642: 1171, -24759: -17468, 20219: 24202, -30341: 13934, 27839: -18353, -545: -28904, 381: 6631, -14539: 19857, -2539: 19520, 31691: -3655, 1385: -507, 30959: -12761, -16041: 8706, 21997: -15520, -11702: 28136, -19969: -15001, -575: -19615, 15183: 2436, 5198: -26540, -18493: 24520, -17505: -5183, -2493: -30253, -25067: -4479, -1283: -3796, 31471: 3428, 25734: 30828, -12627: -6061, 11155: -26067, -26923: 20405, -24052: 21789, -435: -23207, 30135: -13145, -15985: 11367, 16307: 15640, 28752: -18459, 22594: 7750, 22206: -269, 12789: 803, 5691: -26452, 31114: 1532, -15192: -30273, 23101: 3141, 6407: 15910, -1158: -18687, -25606: 29881, 17713: 19127, -1122: -12940, -6489: -9054, 15743: 3691, 21427: -22498, 10898: 19136, -15369: 8230, 30219: 3776, 1353: 27070, 31264: 29339, 31831: -20760, -9233: -18316, 24841: -26176, -12699: 3016, -22370: -9549, -6545: -22728, -8574: -14535, -31864: -12833, 768: 15313, -19955: -22453, -30880: 9396, 29543: 755, -9778: -32702, -22077: -25372, -2605: 16746, -30839: 29080, 32699: 16318, 2417: -12052, -31380: 12651, 24376: -19710, -32686: 761, 5677: 30160, 12035: 12228, 32125: -20315, -20314: 5439, 11493: -17794, -26680: 11610, -28132: -20467, 16900: -25287, 25461: -31865, 24573: -32602, 9200: -1505, 27518: -25693, 12990: -27271, -9397: -803, 14105: 1387, 2651: 8640, 17112: 30678, -969: 19205, 19710: 31993, 1893: 5361, -17816: 24812, 2765: 16979, 1966: -21769, -26954: -1952, 29816: -1928, 26782: -29372, 18567: -22726, -10111: 5989, 14917: 22916, -14570: -2257, 1263: -4715, 18190: 30641, 11528: 12151, 4035: 20675, 20933: 20327, 20055: -30733, -14881: 6272, -26276: -44, 10879: -30096, -9294: -16413, 2817: 13299, 643: 15982, -7677: 4313, -20647: 31903, 3668: 29744, -895: 14661, -17897: -17401, -11844: -19818, -10186: 29763, -32372: 29925, -28816: 10622, 31355: 10910, -17637: -27328, 9535: -27794, 12855: 2934, -3109: 3109, -6427: -16454, -15442: 8398, -23169: 31026, 12834: -25030, 10930: -16079, -12447: 9572, 398: -5332, -11374: 27256, -12183: 32336, -14535: 14519, 12753: -3875, 8795: -11151, -3712: -16993, -26508: 14252, 20375: -14368, -13681: -745, -30307: -5112, 13277: 25773, -7944: -31433, -28425: -12788, 20210: 15294, 17797: -5799, -19999: -7498, 31427: -21005, 11063: 16683, -12187: -11576, 25180: 1372, 12244: -7444, 27900: 20262, 28587: 7083, 18724: 8161, -20180: 25818, 15692: -31648, -28303: 17209, -720: 21874, -16321: 31013, -454: 5366, 31803: 29349, 13754: 24292, 21162: -20849, -23732: -27863, 25477: -6654, -26061: -12152, 20032: -20593, -12006: 28036, 6291: -26468, 14737: 5272, 32728: 5626, -1731: -29345, 24503: 19404, -24868: -21379, -6468: -22831, 22287: 10296, 2631: -26020, 14590: 19330, -9565: 26433, -15283: 5147, 6630: 31769, -17396: -21499, -25553: -10823, 13619: -10207, 23182: -25363, -23069: -32662, 19477: 15524, -1868: 5359, 7929: 27049, -12723: 9380, -16172: -20285, -10286: -10075, -9506: 31490, -25795: 13824, -17148: -32529, -21164: -9272, 20979: 9504, -18600: -2080, 27700: -20006, 9823: 31533, -6997: -19415, 28861: 17091, 26758: -15191, 24983: -24729, -28254: -1130, 25914: -26157, -24819: 405, 20339: 9923, 30368: 1691, -21613: -748, 1453: -19462, 3731: 13394, -32452: 3223, 24913: -6930, -21912: 19356, -24594: 21413, -4422: -29373, -15940: -23075, 27267: 7024, 2732: -24160, -28400: 18241, -24538: 1422, -426: 12283, -10915: -11143, -22114: 31517, 28357: 14424, 19009: 15527, -11167: -4468, 22854: -18910, -23106: 19639, 10382: 23860, 6220: -23926, -26385: -10089, -7503: -5631, 22781: -1889, 16878: -26298, 18982: 21243, 31681: 22201, -7993: 27285, -7299: 25550, 610: 16890, 8167: 21304, -16920: -617, -22339: 30620, 11333: -26987, -26992: -20496, -7985: -22986, 10141: -7469, 372: -21212, 17081: -17544, -11618: -922, 27971: 8305, -28364: -29445, 15932: 3403, 20712: -21072, 14139: 24028, -1589: -1905, 32372: -17183, -21555: 12537, 31409: 17560, 3035: -19927, -5300: 22560, -4845: 21856, 15699: -25855, 7642: 27579, 30284: -15949, -30974: -30226, 15786: 8546, -5179: 30950, 5765: 5052, 1410: -23757, -2705: -31393, 4012: 30468, -1359: -31879, -24808: 31414, 7542: 20843, -26533: -25712, 16975: 8303, -3145: -28727, 30626: -4547, 7331: -22347, -229: -15652, 26743: 8164, -28242: -12747, -13570: 28103, -31635: -32305, 25882: -22303, 392: -21213, -3910: -419, -24637: -4685, 15423: -4564, 16842: -5323, 2530: -6191, -28954: -20857, 12709: -1223, -29605: -31941, -15037: 9147, -2441: -9869, -30549: -24089, -2045: -24975, -6257: 5642, 19458: -26673, -11026: -32379, 11073: -2714, -16340: 29939, 22558: -389, -282: -29137, -8915: 10668, 13276: -26492, -6567: 15209, 18167: 6255, 18833: 9305, 23382: 9685, 22344: -6270, -5200: -17657, -27124: -17742, -19079: -568, 31073: -16882, 28075: 23525, -27683: -6870, -4980: 20988, 15716: -12047, -17167: -27903, 14047: 1751, 18332: 17369, -4584: -13960, -19312: -7004, 24390: -26226, -31358: -20950, 2846: 8574, 23256: -28403, -12965: -970, -10968: 6290, 31485: 3696, -14595: -24510, 8331: -24508, 16660: -6434, -21947: -11573, -13276: 18857, -11196: 13858, 20146: 29787, 26780: 16229, 22109: -21982, 3218: 12243, 20958: -15577, -25637: -8935, -29695: -30458, -27502: -9512, 6608: -10482, 260: -12910, 7060: 3640, 20729: -5920, 9177: 17672, 23669: 9673, -4719: -23531, 12804: -12848, -29031: -3714, 17216: -27527, -23101: 8400, -6250: 26869, -26842: -26986, -21952: 31092, 14811: 3573, -6081: 2717, -10912: -16202, -24595: 20431, -11358: -22184, 21588: -21605, -6061: 3518, 18275: -24618, 24224: 28119, -32273: 6717, -25485: -19967, -21076: -16695, -16947: -17173, 6350: -31349, 21046: 2696, 16207: -13750, -6710: 6770, 24774: -11316, -26121: -7976, 24586: -1831, -28350: -32385, -28591: 6607, 19897: 5582, 10787: -15060, 10497: -6872, -10294: 17802, -8472: 16304, -25702: 1771, 24559: 25237, -22562: 12409, 5848: 32381, 6698: 29851, -29088: -2362, -25758: -7282, 13364: 9287, 9286: -21108, -5875: 7021, 10384: -19100, -14947: -31087, 9224: -30160, 10825: 11627, 15906: 24744, -2491: 14682, 25078: -8675, -1487: 9277, 20301: -16262, -16721: 3749, 12876: 2719, -17183: 4920, -7383: -20989, 587: -29137, 1359: -18302, -31714: 5165, -10671: 13375, -1014: 25286, -5237: 14127, -20162: -15366, -17597: -27172, -16427: 24301, 21080: 29359, -16296: 21156, -27123: 17636, -14475: -17380, 3677: 3071, -13795: -14542, 25583: 2939, -18388: 26695, -30563: -10031, -19535: 16570, 22004: 14784, 4240: 16012, -26396: -7757, 1009: -24215, 10291: 31948, 31730: 31672, -27181: 4692, -7558: 15578, 8628: 18466, 15093: -25146, 15115: -23111, -25498: 19694, -29510: -6893, 10810: -20013, -7953: 24646, 17484: -6921, -22020: 317, 6794: 31084, 3107: 30850, 31725: 21696, -27069: -15468, 20231: -10374, 13074: -27686, -5761: 4056, 6032: 974, -515: -19247, -21834: -21830, 12853: -24945, -12244: 15573, 22762: -30055, 21333: 27246, 17857: -18844, 7569: -30916, 2863: 30220, 24301: -32097, -26608: -8747, -32337: -4850, 27215: 16975, -28845: 5184, 29948: 16776, -8096: -19809, 28922: 1579, -22399: -10320, 23633: 9402, 25594: -10014, -19789: 21539, 7783: -5857, 6413: 28988, 18148: 24286, 16425: -21685, -2117: 24914, 22809: -2465, -4052: 29220, -17437: -20536, 1701: -13236, 3559: -26792, 13260: 28650, 24280: 28935, -31390: 4155, -27444: 448, -15557: -22317, -26261: 14775, 8621: -19065, 854: -24623, -13346: -13154, 28008: 7670, 8308: -26926, -15207: -30554, -4728: -30539, 19116: -14938, -31105: 13428, -17085: 28001, 640: 29984, -30694: -21836, 31336: 29388, -23090: 26134, -22064: -8217, 23023: 25281, 28377: 3055, -826: 32149, -10250: 30089, -21073: -18570, -18476: -26801, -26910: -26764, -23220: -30649, 11262: 14325, 3587: 12688, -20447: -11553, -14604: -1133, 3267: 12700, -30988: -604, 31066: -5487, 4192: 1516, -9863: 26649, -12142: 839, -5180: -23733, 4771: 18192, -30173: 21726, 5816: -6256, -332: -23918, 9971: 21833, 368: 10035, 7709: 315, 18131: 27655, -12214: -2422, 8036: -21700, -12127: 30496, -17331: 23521, -5948: -28752, 9996: -22175, -12256: -9599, 12127: -14043, 8773: 23434, -24251: 31338, -30890: 4170, 796: 22060, -9480: -23318, 30137: -12439, -11200: -14846, -20960: -6630, -11449: -12059, 1710: -25246, 27339: -29509, 23266: -11878, 11424: 13957, -31513: -6604, 29223: 6248, 18427: 26701, -12933: -29661, -22958: 17397, -20885: -7075, -12532: 11832, -11207: -31040, -25413: -32634, -24423: 1136, 27748: -23097, 6865: -20862, 18880: -20717, -10317: -13842, -13186: -15707, 26939: -25776, 28970: 10404, -5636: 14068, -20214: 17872, 24853: 30283, 9956: 8484, 9398: -6284, -16839: 21664, 22800: -14869, 6033: 9989, -4795: -32223, 7279: -20473, 1275: -11857, 22338: 29810, 27015: -1704, -19258: 30646, 29954: 8034, -25853: 14141, 3311: -18597, -23320: -20940, -29480: 24564, 10547: 5534, -242: -13465, 24209: -1327, 10490: -5572, 7640: -20006, -8432: 5032, -11149: -24754, -4663: -23686, -10592: -7167, -25371: 22450, 4522: 7837, 6151: 19181, -18379: -20567, -31877: -18894, 17881: 7374, 24203: -4232, -15566: 16796, 5510: -31735, 15169: -20736, -29601: -27463, 7747: -430, 25280: -6754, -15509: 2251, -3086: -2933, 5884: 27703, -11157: -24312, 14484: -912, -3230: -9668, 16082: -25169, -137: 14744, -2665: -8726, 32412: 31615, -7276: -27566, 6279: 1989, -25300: -15901, 2440: 7619, 31956: 264, -5369: 16171, 14418: 1610, 18599: 4848, 20977: -22077, -6321: -4946, -8343: -22193, 1775: -19058, 26761: -28761, -12920: 27027, 4448: -11253, 25002: 4314, -22369: 23526, -12022: -7474, 32105: -12895, 1455: -4159, 15674: -28876, 11387: 18072, -27516: -8671, -10452: 32061, -29518: 28392, 29722: -20187, 15094: -22775, -31173: 17747, 28936: -12104, -19139: -6836, 10489: -818, -19250: 2431, -24391: 29686, 5886: 4259, 11123: 7634, 14067: 14441}, index_rand = 8788646705830835008 +xs 1144700111 3351133221 1701312047 4140849688 # shrinks to ref input = {-995: -18367, -30184: -27030, 4338: -17464, -26495: 18470, -23875: 6714, 11043: 22383, -7998: 11935, 16847: 5368, -9936: 1676, 469: -14105, -25789: -439, 2949: -19822, -13219: -11532, -13024: 24096, 7755: -32141, 5267: 20461, 13213: 5297, -7746: 31930, -24638: 20376, 11502: 161, 28692: -9359, -5352: 788, 17858: 16574, -4832: 26375, 3089: 1666, -27646: -21448, -29415: 27692, 5699: -11459, 9914: -14535, 10779: 11740, -29883: 790, 1921: -17804, -2606: 26661, 355: 10341, -9220: -21783, 10130: 2847, -28778: -8331, -26138: 21104, 19481: -11787, 23407: -22704, -13780: 6006, 7248: 6188, 9583: -27582, -19931: 21871, 7757: 32217, 7030: 24321, 13903: -28335, -6040: -8746, -16956: 3084, -27320: 10074, -11931: 23573, -14684: -2347, 25890: 13771, 770: -22088, 3703: -21750, -20005: -1416, -7260: -3308, -13212: 5663, 11568: -1211, -31546: -12571, 1625: -28634, 29510: -27517, -14067: -32392, -6952: -15279, 32194: -28535, 22530: -9153, 23590: -10792, -24830: 4545, -1413: 4698, 13676: -29216, -22119: 20809, 11493: -23219, 30324: -19957, -19740: 9364, -28332: 23760, 7598: -15700, 5250: 5262, 8892: -11149, 512: 21208, -26713: -22645, 15901: -16244, -11774: 25184, -27782: 31736, 1932: 28625, -19899: -15534, -14500: 28168, -31943: -10376, 5096: -6393, -12529: -28083, 15871: -31782, 24491: 9705, -13197: -2280, 20267: 26985, -2805: -7895, -12439: -25986, -1013: 18461, 1975: 32395, 22412: 8807, 18620: -21921, 18836: -11655, 20099: 15576, -15176: -556, -16690: 10393, -20701: -25137, 16023: 6541, 6323: 30693, 22672: 4962, 6262: -6543, 16070: 8710, 16145: 28518, -1209: -18693, -28389: -24853, 17412: -24261, 3497: 10996, 9187: -19998, -32168: 10884, 3560: 7346, 22807: 23444, -23068: 18732, -26136: -17299, 4558: -4291, 16805: 25070, 23084: 30635, -25411: 22895, -2902: 31559, -7150: -27951, -20232: 1338, 6838: 27765, -31069: -28409, 11606: -29065, -13760: 30312, -2036: -14916, 25218: 18519, -10854: -7745, 27820: 15149, 102: 7496, 804: 9488, 30201: -8547, 32678: 20708, -25202: 31329, -5584: -22884, -5108: 30003, 25093: -865, 27335: 6724, -10328: 15249, 5215: -12859, 25426: -6436, 4131: 8277, -19570: 7708, 20395: 7626, 3155: 12890, 19644: 581, -19031: -9366, -7803: 24805, 6673: -15061, -10892: -20442, -28410: 17433, -18136: 18606, 16432: 31698, -9848: 7414, 10831: 4060, -19606: -19806, -26041: -14198, 7826: 18579, -12900: -19535, -21442: 30662, -9253: -13676, 4185: -25497, -32472: -11113, -20772: -21936, 30731: 247, -17401: -28973, -11698: -26755, -17077: -5017, 22536: -3777, 13939: 16609, -8959: -24782, 29183: 15322, 28738: -31932, 12914: -31447, 27024: 19561, -6230: -2767, -18069: 12291, -3808: -532, 8699: -30308, -13072: 26305, -24174: -1772, 5083: -26578, 32374: -29090, -32055: 12554, 8496: -6213, 3295: 7339, 13897: 31817, -32448: -28910, 16533: 26195, 16795: -8295, 23292: -32385, 15102: 2439, 9462: 19663, 24237: 21643, 5357: 20413, 2361: 5794, 25247: -17229, -4187: 5207, -21262: 19783, -24684: -4240, -24679: -18791, 2368: -8363, 12208: -20319, 23264: 16664, -13617: 1275, -19198: -25513, 5092: 16212, 15124: 28714, 21439: -1196, -4432: 30044, 9557: -4855, -22916: 1046, -26280: 25826, -27674: -20014, -13633: 27408, -10975: -4991, 26520: -9235, -6589: 27583, -31631: -21487, 31832: 8595, -18451: -12811, -10412: -24981, 17602: -10428, -25014: 15888, 21325: 14946, 7746: 2626, -29626: -22668, 29538: -5978, 21901: 5842, 13851: 31830, -11034: 29385, -3586: 7536, -6063: 32614, -11727: 16659, 29320: -1367, -21326: 9220, 3205: -1974, -4787: 12852, 30793: 2568, 25796: 9433, 19016: -13799, -9621: -14129, 20136: 20434, -18060: -13251, -634: 18285, 15435: 22675, 29971: 5174, 31997: -29557, 18450: 7875, 22519: -12860, -10973: -20277, -26809: 31348, 6220: 11504, -178: 22232, 9592: -1419, -13548: 27708, 6172: 20899, 27648: 15593, -12157: 24765, -3131: 27366, -1827: -2958, 18365: 18538, -17861: -8596, -25217: -20668, -4257: -9796, -27958: -17570, -11603: -23589, -17591: -21385, 23905: 22546, -6098: 13776, -26132: 18512, 8204: 14798, 29533: 4545, 62: 22711, -9020: -8280, 11140: -8181, 1781: 10516, -1334: 15284, -7224: 7160, -28987: 22020, -4891: 8434, -4403: 19578, -20394: 14965, 29827: -30255, -560: 29091, -23917: -11862, -13868: -21175, -10219: 16295, 2577: 3128, 9484: -11742, 8668: 21789, -25813: -8178, -21404: 29342, -21751: 13687, 18052: 7524, -19144: -30345, 24903: -25167, 30700: 1834, -28266: 27752, -30375: 954, -11219: -5836, 28011: 8806, 20451: -23577, 10616: -15512, 6848: 4786, -5701: -16618, 10552: -612, 14323: -30855, 25785: -3039, -423: -22087, 20028: 21248, -31919: 15338, -19884: 15952, -22678: -176}, index_rand = 4536586039788573449 +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 888006417 2608449019 3789353629 478040202 # shrinks to ref m = {0: 0} diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/ord/map.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/ord/map.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/ord/map.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/ord/map.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 888006417 2608449019 3789353629 478040202 # shrinks to ref m = {0: 0} diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/ser.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/ser.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/ser.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/ser.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 3983395997 40281418 114824171 2339847213 # shrinks to ref v = {1285771567, -841112960, -2090277076, 1080385872, 900828884, 615148720, -333870035, -1551786909, -1167746969, -1453736382, -1747821313, 367596715, 1982056530, -1495713558} +xs 2832291072 3367532499 2480853836 1445020057 # shrinks to ref v = {-1006265241: 1190299023, -874470135: -656918271, -747552887: -119701798, -446035143: 289470610, -38617499: -70412299, -28555422: 742423513, 549345238: -1218765301, 1006459863: 373426025, 1730586809: 1217890615, 1741069766: 1330906833} +xs 497222929 1550339526 1868828736 2852494662 # shrinks to ref v = {-33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, 0} +xs 3367619631 4093181880 814513877 3641392342 # shrinks to ref v = {-33: 0, -32: 0, -31: 0, -30: 0, -29: 0, -28: 0, -27: 0, -26: 0, -25: 0, -24: 0, -23: 0, -22: 0, -21: 0, -20: 0, -19: 0, -18: 0, -17: 0, -16: 0, -15: 0, -14: 0, -13: 0, -12: 0, -11: 0, -10: 0, -9: 0, -8: 0, -7: 0, -6: 0, -5: 0, -4: 0, -3: 0, -2: 0, 0: 0} diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/sort.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/sort.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/sort.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/sort.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 1397459766 1987461941 1386942626 306293423 # shrinks to ref input = [0, 777418683, 1143505337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1422499358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1143505337, 0, -275943289, -1, 0, 0, 0, 777418684, 0, 777418684] diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/tests/vector.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/tests/vector.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/tests/vector.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/tests/vector.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc a81c870198d194d869b85a541fca54b5a3f3ea4e84705bfdede6212ad7451789 # shrinks to actions = [PushFront(0), PushFront(0), PushFront(0), PushFront(0), PushFront(0), PushFront(0), SplitLeft(0), PushFront(0), PushFront(0), PushFront(0), Remove(0), PopFront, PushFront(0), PushFront(0), PushFront(0), PushFront(0), PushFront(0), PushFront(0), SplitLeft(1026178654884686841), PushFront(0), PushFront(0), SplitLeft(2673257349917114567), PushFront(0), PushFront(0), PushFront(0), PushFront(0), JoinLeft([0, 0, 0, 0, 0, 0, 0]), PushFront(0), PushFront(0), SplitRight(6380212717721778205), JoinLeft([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), PopFront, Insert(0, 0), PushFront(0), PushFront(0), SplitRight(12236220624414400388), Insert(0, 0), PushFront(0), JoinLeft([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), SplitLeft(13848748256934322935), JoinLeft([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), JoinLeft([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), JoinLeft([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), SplitLeft(13115524110820767241), Insert(0, 0), JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), PushFront(0), PopFront, PopFront, Remove(0), Insert(0, 0), PopFront, JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), PopFront, PushFront(0), PopFront, PushFront(0), PushFront(0), Remove(0), SplitLeft(9383655485369749481), JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), PopBack, PushFront(0), Insert(455053961473158936, 0), SplitRight(676041696221001931), PushBack(0), PopFront, JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), JoinRight([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), PushFront(0), PushFront(0), PushFront(0), JoinLeft([0])] +cc bae4a6aa243531a345cb36883fda4aebc84848fffe12d051df4e24ff22af3689 # shrinks to actions = let mut vec = Vector::new(); let mut vec_new = Vector::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); vec_new.append(vec); vec = vec_new; vec = vec.split_off(6); vec.pop_front(); vec.pop_front(); vec.push_front(0); vec.pop_front(); vec.push_front(0); vec.append(Vector::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])); vec.split_off(141); let mut vec_new = Vector::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); vec_new.append(vec); vec = vec_new; vec.insert(41, 0); vec.pop_front(); vec.pop_front(); vec = vec.split_off(5); vec.pop_front(); vec.append(Vector::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])); vec.append(Vector::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])); vec.push_front(0); vec.push_front(0); let mut vec_new = Vector::from([0]); vec_new.append(vec); vec = vec_new; diff -Nru cargo-0.33.0/vendor/im-rc/proptest-regressions/vector/mod.txt cargo-0.35.0/vendor/im-rc/proptest-regressions/vector/mod.txt --- cargo-0.33.0/vendor/im-rc/proptest-regressions/vector/mod.txt 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/proptest-regressions/vector/mod.txt 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,11 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +xs 781088174 2402437932 46071810 3445483747 # shrinks to ref vec = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +xs 1236163365 497060525 1875560600 3785939576 +xs 2440477773 3871129562 3025797391 1057174199 # shrinks to ref vec1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ref vec2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +xs 3956050500 706730731 3245945489 2502775722 # shrinks to ref vec1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ref vec2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +cc cf2875f6f7c5648d87ffcab4ccac7f8a8f720c93ee377e89f8c86e542cc643bc diff -Nru cargo-0.33.0/vendor/im-rc/src/hash/map.rs cargo-0.35.0/vendor/im-rc/src/hash/map.rs --- cargo-0.33.0/vendor/im-rc/src/hash/map.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/hash/map.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,10 +13,8 @@ //! [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq]. //! //! Map entries will have a predictable order based on the hasher -//! being used. Unless otherwise specified, all maps will use the -//! default [`RandomState`][std::collections::hash_map::RandomState] -//! hasher, which will produce consistent hashes for the duration of -//! its lifetime, but not between restarts of your program. +//! being used. Unless otherwise specified, this will be the standard +//! [`RandomState`][std::collections::hash_map::RandomState] hasher. //! //! [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie //! [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html @@ -33,11 +31,11 @@ use std::mem; use std::ops::{Add, Index, IndexMut}; -use nodes::hamt::{ +use crate::nodes::hamt::{ hash_key, Drain as NodeDrain, HashBits, HashValue, Iter as NodeIter, IterMut as NodeIterMut, Node, }; -use util::Ref; +use crate::util::Ref; /// Construct a hash map from a sequence of key/value pairs. /// @@ -89,22 +87,15 @@ /// [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq]. /// /// Map entries will have a predictable order based on the hasher -/// being used. Unless otherwise specified, all maps will share an -/// instance of the default -/// [`RandomState`][std::collections::hash_map::RandomState] hasher, -/// which will produce consistent hashes for the duration of its -/// lifetime, but not between restarts of your program. +/// being used. Unless otherwise specified, this will be the standard +/// [`RandomState`][std::collections::hash_map::RandomState] hasher. /// /// [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie /// [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html /// [std::hash::Hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html /// [std::collections::hash_map::RandomState]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html -pub struct HashMap -where - K: Clone, - V: Clone, -{ +pub struct HashMap { size: usize, root: Ref>, hasher: Ref, @@ -112,8 +103,7 @@ impl HashValue for (K, V) where - K: Eq + Clone, - V: Clone, + K: Eq, { type Key = K; @@ -126,18 +116,20 @@ } } -impl HashMap -where - K: Hash + Eq + Clone, - V: Clone, -{ +impl HashMap { /// Construct an empty hash map. #[inline] #[must_use] pub fn new() -> Self { Self::default() } +} +impl HashMap +where + K: Hash + Eq + Clone, + V: Clone, +{ /// Construct a hash map with a single mapping. /// /// This method has been deprecated; use [`unit`][unit] instead. @@ -172,11 +164,7 @@ } } -impl HashMap -where - K: Clone, - V: Clone, -{ +impl HashMap { /// Test whether a hash map is empty. /// /// Time: O(1) @@ -223,35 +211,6 @@ pub fn len(&self) -> usize { self.size } -} - -impl HashMap -where - K: Hash + Eq + Clone, - V: Clone, - S: BuildHasher, -{ - fn test_eq(&self, other: &Self) -> bool - where - V: PartialEq, - { - if self.len() != other.len() { - return false; - } - let mut seen = collections::HashSet::new(); - for (key, value) in self.iter() { - if Some(value) != other.get(&key) { - return false; - } - seen.insert(key); - } - for key in other.keys() { - if !seen.contains(&key) { - return false; - } - } - true - } /// Construct an empty hash map using the provided hasher. #[inline] @@ -306,22 +265,6 @@ } } - /// Get a mutable iterator over the values of a hash map. - /// - /// Please note that the order is consistent between maps using - /// the same hasher, but no other ordering guarantee is offered. - /// Items will not come out in insertion order or sort order. - /// They will, however, come out in the same order every time for - /// the same map. - #[inline] - #[must_use] - pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { - let root = Ref::make_mut(&mut self.root); - IterMut { - it: NodeIterMut::new(root, self.size), - } - } - /// Get an iterator over a hash map's keys. /// /// Please note that the order is consistent between maps using @@ -352,6 +295,60 @@ } } + /// Discard all elements from the map. + /// + /// This leaves you with an empty map, and all elements that + /// were previously inside it are dropped. + /// + /// Time: O(n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::HashMap; + /// # fn main() { + /// let mut map = hashmap![1=>1, 2=>2, 3=>3]; + /// map.clear(); + /// assert!(map.is_empty()); + /// # } + /// ``` + pub fn clear(&mut self) { + if !self.is_empty() { + self.root = Default::default(); + self.size = 0; + } + } +} + +impl HashMap +where + K: Hash + Eq, + S: BuildHasher, +{ + fn test_eq(&self, other: &Self) -> bool + where + K: Hash + Eq, + V: PartialEq, + { + if self.len() != other.len() { + return false; + } + let mut seen = collections::HashSet::new(); + for (key, value) in self.iter() { + if Some(value) != other.get(&key) { + return false; + } + seen.insert(key); + } + for key in other.keys() { + if !seen.contains(&key) { + return false; + } + } + true + } + /// Get the value for a key from a hash map. /// /// Time: O(log n) @@ -380,8 +377,7 @@ .map(|&(_, ref v)| v) } - /// Get a mutable reference to the value for a key from a hash - /// map. + /// Test for the presence of a key in a hash map. /// /// Time: O(log n) /// @@ -392,26 +388,142 @@ /// # use im::hashmap::HashMap; /// # fn main() { /// let map = hashmap!{123 => "lol"}; - /// assert_eq!( - /// map.get(&123), - /// Some(&"lol") + /// assert!( + /// map.contains_key(&123) + /// ); + /// assert!( + /// !map.contains_key(&321) /// ); /// # } /// ``` + #[inline] #[must_use] - pub fn get_mut(&mut self, key: &BK) -> Option<&mut V> + pub fn contains_key(&self, k: &BK) -> bool where BK: Hash + Eq + ?Sized, K: Borrow, { + self.get(k).is_some() + } + + /// Test whether a map is a submap of another map, meaning that + /// all keys in our map must also be in the other map, with the + /// same values. + /// + /// Use the provided function to decide whether values are equal. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_submap_by(&self, other: RM, mut cmp: F) -> bool + where + F: FnMut(&V, &B) -> bool, + RM: Borrow>, + { + self.iter() + .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false)) + } + + /// Test whether a map is a proper submap of another map, meaning + /// that all keys in our map must also be in the other map, with + /// the same values. To be a proper submap, ours must also contain + /// fewer keys than the other map. + /// + /// Use the provided function to decide whether values are equal. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_proper_submap_by(&self, other: RM, cmp: F) -> bool + where + F: FnMut(&V, &B) -> bool, + RM: Borrow>, + { + self.len() != other.borrow().len() && self.is_submap_by(other, cmp) + } + + /// Test whether a map is a submap of another map, meaning that + /// all keys in our map must also be in the other map, with the + /// same values. + /// + /// Time: O(n log n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::hashmap::HashMap; + /// # fn main() { + /// let map1 = hashmap!{1 => 1, 2 => 2}; + /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3}; + /// assert!(map1.is_submap(map2)); + /// # } + /// ``` + #[inline] + #[must_use] + pub fn is_submap(&self, other: RM) -> bool + where + V: PartialEq, + RM: Borrow, + { + self.is_submap_by(other.borrow(), PartialEq::eq) + } + + /// Test whether a map is a proper submap of another map, meaning + /// that all keys in our map must also be in the other map, with + /// the same values. To be a proper submap, ours must also contain + /// fewer keys than the other map. + /// + /// Time: O(n log n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::hashmap::HashMap; + /// # fn main() { + /// let map1 = hashmap!{1 => 1, 2 => 2}; + /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3}; + /// assert!(map1.is_proper_submap(map2)); + /// + /// let map3 = hashmap!{1 => 1, 2 => 2}; + /// let map4 = hashmap!{1 => 1, 2 => 2}; + /// assert!(!map3.is_proper_submap(map4)); + /// # } + /// ``` + #[inline] + #[must_use] + pub fn is_proper_submap(&self, other: RM) -> bool + where + V: PartialEq, + RM: Borrow, + { + self.is_proper_submap_by(other.borrow(), PartialEq::eq) + } +} + +impl HashMap +where + K: Hash + Eq + Clone, + V: Clone, + S: BuildHasher, +{ + /// Get a mutable iterator over the values of a hash map. + /// + /// Please note that the order is consistent between maps using + /// the same hasher, but no other ordering guarantee is offered. + /// Items will not come out in insertion order or sort order. + /// They will, however, come out in the same order every time for + /// the same map. + #[inline] + #[must_use] + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { let root = Ref::make_mut(&mut self.root); - match root.get_mut(hash_key(&*self.hasher, key), 0, key) { - None => None, - Some(&mut (_, ref mut value)) => Some(value), + IterMut { + it: NodeIterMut::new(root, self.size), } } - /// Test for the presence of a key in a hash map. + /// Get a mutable reference to the value for a key from a hash + /// map. /// /// Time: O(log n) /// @@ -422,22 +534,23 @@ /// # use im::hashmap::HashMap; /// # fn main() { /// let map = hashmap!{123 => "lol"}; - /// assert!( - /// map.contains_key(&123) - /// ); - /// assert!( - /// !map.contains_key(&321) + /// assert_eq!( + /// map.get(&123), + /// Some(&"lol") /// ); /// # } /// ``` - #[inline] #[must_use] - pub fn contains_key(&self, k: &BK) -> bool + pub fn get_mut(&mut self, key: &BK) -> Option<&mut V> where BK: Hash + Eq + ?Sized, K: Borrow, { - self.get(k).is_some() + let root = Ref::make_mut(&mut self.root); + match root.get_mut(hash_key(&*self.hasher, key), 0, key) { + None => None, + Some(&mut (_, ref mut value)) => Some(value), + } } /// Insert a key/value mapping into a map. @@ -534,31 +647,6 @@ result } - /// Discard all elements from the map. - /// - /// This leaves you with an empty map, and all elements that - /// were previously inside it are dropped. - /// - /// Time: O(n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::HashMap; - /// # fn main() { - /// let mut map = hashmap![1=>1, 2=>2, 3=>3]; - /// map.clear(); - /// assert!(map.is_empty()); - /// # } - /// ``` - pub fn clear(&mut self) { - if !self.is_empty() { - self.root = Default::default(); - self.size = 0; - } - } - /// Get the [`Entry`][Entry] for a key in the map for in-place manipulation. /// /// Time: O(log n) @@ -856,7 +944,7 @@ S: Default, I: IntoIterator, { - i.into_iter().fold(Self::default(), |a, b| a.union(b)) + i.into_iter().fold(Self::default(), Self::union) } /// Construct the union of a sequence of maps, using a function to @@ -1063,101 +1151,6 @@ } out } - - /// Test whether a map is a submap of another map, meaning that - /// all keys in our map must also be in the other map, with the - /// same values. - /// - /// Use the provided function to decide whether values are equal. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_submap_by(&self, other: RM, mut cmp: F) -> bool - where - B: Clone, - F: FnMut(&V, &B) -> bool, - RM: Borrow>, - { - self.iter() - .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false)) - } - - /// Test whether a map is a proper submap of another map, meaning - /// that all keys in our map must also be in the other map, with - /// the same values. To be a proper submap, ours must also contain - /// fewer keys than the other map. - /// - /// Use the provided function to decide whether values are equal. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_proper_submap_by(&self, other: RM, cmp: F) -> bool - where - B: Clone, - F: FnMut(&V, &B) -> bool, - RM: Borrow>, - { - self.len() != other.borrow().len() && self.is_submap_by(other, cmp) - } - - /// Test whether a map is a submap of another map, meaning that - /// all keys in our map must also be in the other map, with the - /// same values. - /// - /// Time: O(n log n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::hashmap::HashMap; - /// # fn main() { - /// let map1 = hashmap!{1 => 1, 2 => 2}; - /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3}; - /// assert!(map1.is_submap(map2)); - /// # } - /// ``` - #[inline] - #[must_use] - pub fn is_submap(&self, other: RM) -> bool - where - V: PartialEq, - RM: Borrow, - { - self.is_submap_by(other.borrow(), PartialEq::eq) - } - - /// Test whether a map is a proper submap of another map, meaning - /// that all keys in our map must also be in the other map, with - /// the same values. To be a proper submap, ours must also contain - /// fewer keys than the other map. - /// - /// Time: O(n log n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::hashmap::HashMap; - /// # fn main() { - /// let map1 = hashmap!{1 => 1, 2 => 2}; - /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3}; - /// assert!(map1.is_proper_submap(map2)); - /// - /// let map3 = hashmap!{1 => 1, 2 => 2}; - /// let map4 = hashmap!{1 => 1, 2 => 2}; - /// assert!(!map3.is_proper_submap(map4)); - /// # } - /// ``` - #[inline] - #[must_use] - pub fn is_proper_submap(&self, other: RM) -> bool - where - V: PartialEq, - RM: Borrow, - { - self.is_proper_submap_by(other.borrow(), PartialEq::eq) - } } // Entries @@ -1368,8 +1361,8 @@ #[cfg(not(has_specialisation))] impl PartialEq for HashMap where - K: Hash + Eq + Clone, - V: PartialEq + Clone, + K: Hash + Eq, + V: PartialEq, S: BuildHasher, { fn eq(&self, other: &Self) -> bool { @@ -1380,8 +1373,8 @@ #[cfg(has_specialisation)] impl PartialEq for HashMap where - K: Hash + Eq + Clone, - V: PartialEq + Clone, + K: Hash + Eq, + V: PartialEq, S: BuildHasher, { default fn eq(&self, other: &Self) -> bool { @@ -1392,8 +1385,8 @@ #[cfg(has_specialisation)] impl PartialEq for HashMap where - K: Hash + Eq + Clone, - V: Eq + Clone, + K: Hash + Eq, + V: Eq, S: BuildHasher, { fn eq(&self, other: &Self) -> bool { @@ -1406,8 +1399,8 @@ impl Eq for HashMap where - K: Hash + Eq + Clone, - V: Eq + Clone, + K: Hash + Eq, + V: Eq, S: BuildHasher, { } @@ -1446,8 +1439,8 @@ impl Hash for HashMap where - K: Hash + Eq + Clone, - V: Hash + Clone, + K: Hash + Eq, + V: Hash, S: BuildHasher, { fn hash(&self, state: &mut H) @@ -1462,8 +1455,6 @@ impl Default for HashMap where - K: Hash + Eq + Clone, - V: Clone, S: BuildHasher + Default, { #[inline] @@ -1535,8 +1526,7 @@ impl<'a, BK, K, V, S> Index<&'a BK> for HashMap where BK: Hash + Eq + ?Sized, - K: Hash + Eq + Clone + Borrow, - V: Clone, + K: Hash + Eq + Borrow, S: BuildHasher, { type Output = V; @@ -1568,8 +1558,8 @@ #[cfg(not(has_specialisation))] impl Debug for HashMap where - K: Hash + Eq + Clone + Debug, - V: Debug + Clone, + K: Hash + Eq + Debug, + V: Debug, S: BuildHasher, { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -1584,8 +1574,8 @@ #[cfg(has_specialisation)] impl Debug for HashMap where - K: Hash + Eq + Clone + Debug, - V: Debug + Clone, + K: Hash + Eq + Debug, + V: Debug, S: BuildHasher, { default fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -1600,8 +1590,8 @@ #[cfg(has_specialisation)] impl Debug for HashMap where - K: Hash + Eq + Clone + Ord + Debug, - V: Debug + Clone, + K: Hash + Eq + Ord + Debug, + V: Debug, S: BuildHasher, { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -1684,7 +1674,7 @@ impl Iterator for ConsumingIter where - A: HashValue, + A: HashValue + Clone, { type Item = A; @@ -1697,9 +1687,9 @@ } } -impl ExactSizeIterator for ConsumingIter where A: HashValue {} +impl ExactSizeIterator for ConsumingIter where A: HashValue + Clone {} -impl FusedIterator for ConsumingIter where A: HashValue {} +impl FusedIterator for ConsumingIter where A: HashValue + Clone {} // An iterator over the keys of a map. pub struct Keys<'a, K: 'a, V: 'a> { @@ -1745,8 +1735,7 @@ impl<'a, K, V, S> IntoIterator for &'a HashMap where - K: Hash + Eq + Clone, - V: Clone, + K: Hash + Eq, S: BuildHasher, { type Item = &'a (K, V); @@ -1775,7 +1764,7 @@ } } -// // Conversions +// Conversions impl FromIterator<(K, V)> for HashMap where @@ -1795,11 +1784,7 @@ } } -impl AsRef> for HashMap -where - K: Clone, - V: Clone, -{ +impl AsRef> for HashMap { #[inline] fn as_ref(&self) -> &Self { self @@ -1934,7 +1919,7 @@ #[cfg(any(test, feature = "proptest"))] pub mod proptest { use super::*; - use proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; + use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; use std::ops::Range; /// A strategy for a hash map of a given size. @@ -1973,10 +1958,10 @@ #[cfg(test)] mod test { use super::*; - use proptest::collection; - use proptest::num::{i16, usize}; + use crate::test::LolHasher; + use ::proptest::num::{i16, usize}; + use ::proptest::{collection, proptest}; use std::hash::BuildHasherDefault; - use test::LolHasher; #[test] fn safe_mutation() { diff -Nru cargo-0.33.0/vendor/im-rc/src/hash/set.rs cargo-0.35.0/vendor/im-rc/src/hash/set.rs --- cargo-0.33.0/vendor/im-rc/src/hash/set.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/hash/set.rs 2019-05-15 11:26:24.000000000 +0000 @@ -12,11 +12,9 @@ //! you don't mind that values will need to implement //! [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq]. //! -//! Values will have a predictable order based on the hasher being -//! used. Unless otherwise specified, all sets will use the default -//! [`RandomState`][std::collections::hash_map::RandomState] hasher, -//! which will produce consistent hashes for the duration of its -//! lifetime, but not between restarts of your program. +//! Values will have a predictable order based on the hasher +//! being used. Unless otherwise specified, this will be the standard +//! [`RandomState`][std::collections::hash_map::RandomState] hasher. //! //! [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie //! [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html @@ -33,11 +31,11 @@ use std::iter::{FromIterator, IntoIterator, Sum}; use std::ops::{Add, Deref, Mul}; -use nodes::hamt::{ +use crate::nodes::hamt::{ hash_key, Drain as NodeDrain, HashValue, Iter as NodeIter, IterMut as NodeIterMut, Node, }; -use ordset::OrdSet; -use util::Ref; +use crate::ordset::OrdSet; +use crate::util::Ref; /// Construct a set from a sequence of values. /// @@ -84,11 +82,9 @@ /// you don't mind that values will need to implement /// [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq]. /// -/// Values will have a predictable order based on the hasher being -/// used. Unless otherwise specified, all sets will use the default -/// [`RandomState`][std::collections::hash_map::RandomState] hasher, -/// which will produce consistent hashes for the duration of its -/// lifetime, but not between restarts of your program. +/// Values will have a predictable order based on the hasher +/// being used. Unless otherwise specified, this will be the standard +/// [`RandomState`][std::collections::hash_map::RandomState] hasher. /// /// [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie /// [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html @@ -114,7 +110,7 @@ // for `A`, we have to use the `Value` indirection. impl HashValue for Value where - A: Hash + Eq + Clone, + A: Hash + Eq, { type Key = A; @@ -127,16 +123,18 @@ } } -impl HashSet -where - A: Hash + Eq + Clone, -{ +impl HashSet { /// Construct an empty set. #[must_use] pub fn new() -> Self { Self::default() } +} +impl HashSet +where + A: Hash + Eq + Clone, +{ /// Construct a set with a single value. /// /// This method has been deprecated; use [`unit`][unit] instead. @@ -212,31 +210,6 @@ pub fn len(&self) -> usize { self.size } -} - -impl HashSet -where - A: Hash + Eq + Clone, - S: BuildHasher, -{ - fn test_eq(&self, other: &Self) -> bool { - if self.len() != other.len() { - return false; - } - let mut seen = collections::HashSet::new(); - for value in self.iter() { - if !other.contains(&value) { - return false; - } - seen.insert(value); - } - for value in other.iter() { - if !seen.contains(&value) { - return false; - } - } - true - } /// Construct an empty hash set using the provided hasher. #[inline] @@ -274,6 +247,31 @@ } } + /// Discard all elements from the set. + /// + /// This leaves you with an empty set, and all elements that + /// were previously inside it are dropped. + /// + /// Time: O(n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::HashSet; + /// # fn main() { + /// let mut set = hashset![1, 2, 3]; + /// set.clear(); + /// assert!(set.is_empty()); + /// # } + /// ``` + pub fn clear(&mut self) { + if !self.is_empty() { + self.root = Default::default(); + self.size = 0; + } + } + /// Get an iterator over the values in a hash set. /// /// Please note that the order is consistent between sets using @@ -287,19 +285,30 @@ it: NodeIter::new(&self.root, self.size), } } +} - /// Get a mutable iterator over the values in a hash set. - /// - /// Please note that the order is consistent between sets using the same - /// hasher, but no other ordering guarantee is offered. Items will not come - /// out in insertion order or sort order. They will, however, come out in - /// the same order every time for the same set. - #[must_use] - pub fn iter_mut(&mut self) -> IterMut<'_, A> { - let root = Ref::make_mut(&mut self.root); - IterMut { - it: NodeIterMut::new(root, self.size), +impl HashSet +where + A: Hash + Eq, + S: BuildHasher, +{ + fn test_eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + let mut seen = collections::HashSet::new(); + for value in self.iter() { + if !other.contains(&value) { + return false; + } + seen.insert(value); } + for value in other.iter() { + if !seen.contains(&value) { + return false; + } + } + true } /// Test if a value is part of a set. @@ -314,6 +323,52 @@ self.root.get(hash_key(&*self.hasher, a), 0, a).is_some() } + /// Test whether a set is a subset of another set, meaning that + /// all values in our set must also be in the other set. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_subset(&self, other: RS) -> bool + where + RS: Borrow, + { + let o = other.borrow(); + self.iter().all(|a| o.contains(&a)) + } + + /// Test whether a set is a proper subset of another set, meaning + /// that all values in our set must also be in the other set. A + /// proper subset must also be smaller than the other set. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_proper_subset(&self, other: RS) -> bool + where + RS: Borrow, + { + self.len() != other.borrow().len() && self.is_subset(other) + } +} + +impl HashSet +where + A: Hash + Eq + Clone, + S: BuildHasher, +{ + /// Get a mutable iterator over the values in a hash set. + /// + /// Please note that the order is consistent between sets using the same + /// hasher, but no other ordering guarantee is offered. Items will not come + /// out in insertion order or sort order. They will, however, come out in + /// the same order every time for the same set. + #[must_use] + pub fn iter_mut(&mut self) -> IterMut<'_, A> { + let root = Ref::make_mut(&mut self.root); + IterMut { + it: NodeIterMut::new(root, self.size), + } + } + /// Insert a value into a set. /// /// Time: O(log n) @@ -346,31 +401,6 @@ result.map(|v| v.0) } - /// Discard all elements from the set. - /// - /// This leaves you with an empty set, and all elements that - /// were previously inside it are dropped. - /// - /// Time: O(n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::HashSet; - /// # fn main() { - /// let mut set = hashset![1, 2, 3]; - /// set.clear(); - /// assert!(set.is_empty()); - /// # } - /// ``` - pub fn clear(&mut self) { - if !self.is_empty() { - self.root = Default::default(); - self.size = 0; - } - } - /// Construct a new set from the current set with the given value /// added. /// @@ -466,7 +496,7 @@ I: IntoIterator, S: Default, { - i.into_iter().fold(Self::default(), |a, b| a.union(b)) + i.into_iter().fold(Self::default(), Self::union) } /// Construct the difference between two sets. @@ -521,32 +551,6 @@ } out } - - /// Test whether a set is a subset of another set, meaning that - /// all values in our set must also be in the other set. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_subset(&self, other: RS) -> bool - where - RS: Borrow, - { - let o = other.borrow(); - self.iter().all(|a| o.contains(&a)) - } - - /// Test whether a set is a proper subset of another set, meaning - /// that all values in our set must also be in the other set. A - /// proper subset must also be smaller than the other set. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_proper_subset(&self, other: RS) -> bool - where - RS: Borrow, - { - self.len() != other.borrow().len() && self.is_subset(other) - } } // Core traits @@ -566,7 +570,7 @@ impl PartialEq for HashSet where - A: Hash + Eq + Clone, + A: Hash + Eq, S: BuildHasher + Default, { fn eq(&self, other: &Self) -> bool { @@ -576,7 +580,7 @@ impl Eq for HashSet where - A: Hash + Eq + Clone, + A: Hash + Eq, S: BuildHasher + Default, { } @@ -613,7 +617,7 @@ impl Hash for HashSet where - A: Hash + Eq + Clone, + A: Hash + Eq, S: BuildHasher + Default, { fn hash(&self, state: &mut H) @@ -628,7 +632,6 @@ impl Default for HashSet where - A: Hash + Eq + Clone, S: BuildHasher + Default, { fn default() -> Self { @@ -719,7 +722,7 @@ #[cfg(not(has_specialisation))] impl Debug for HashSet where - A: Hash + Eq + Clone + Debug, + A: Hash + Eq + Debug, S: BuildHasher, { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -730,7 +733,7 @@ #[cfg(has_specialisation)] impl Debug for HashSet where - A: Hash + Eq + Clone + Debug, + A: Hash + Eq + Debug, S: BuildHasher, { default fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -741,7 +744,7 @@ #[cfg(has_specialisation)] impl Debug for HashSet where - A: Hash + Eq + Clone + Debug + Ord, + A: Hash + Eq + Debug + Ord, S: BuildHasher, { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { @@ -761,7 +764,7 @@ impl<'a, A> Iterator for Iter<'a, A> where - A: 'a + Clone, + A: 'a, { type Item = &'a A; @@ -774,9 +777,9 @@ } } -impl<'a, A> ExactSizeIterator for Iter<'a, A> where A: Clone {} +impl<'a, A> ExactSizeIterator for Iter<'a, A> {} -impl<'a, A> FusedIterator for Iter<'a, A> where A: Clone {} +impl<'a, A> FusedIterator for Iter<'a, A> {} // A mutable iterator over the elements of a set. pub struct IterMut<'a, A> @@ -853,7 +856,7 @@ impl<'a, A, S> IntoIterator for &'a HashSet where - A: Hash + Eq + Clone, + A: Hash + Eq, S: BuildHasher, { type Item = &'a A; @@ -994,7 +997,7 @@ #[cfg(any(test, feature = "proptest"))] pub mod proptest { use super::*; - use proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; + use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; use std::ops::Range; /// A strategy for a hash set of a given size. @@ -1030,9 +1033,10 @@ mod test { use super::proptest::*; use super::*; - use proptest::num::i16; + use crate::test::LolHasher; + use ::proptest::num::i16; + use ::proptest::proptest; use std::hash::BuildHasherDefault; - use test::LolHasher; #[test] fn insert_failing() { @@ -1064,12 +1068,12 @@ #[test] fn issue_60_drain_iterator_memory_corruption() { - use test::MetroHashBuilder; + use crate::test::MetroHashBuilder; for i in 0..1000 { let mut lhs = vec![0, 1, 2]; lhs.sort(); - let mut hasher = Ref::from(MetroHashBuilder::new(i)); + let hasher = Ref::from(MetroHashBuilder::new(i)); let mut iset: HashSet<_, MetroHashBuilder> = HashSet::with_hasher(hasher.clone()); for &i in &lhs { iset.insert(i); diff -Nru cargo-0.33.0/vendor/im-rc/src/lib.rs cargo-0.35.0/vendor/im-rc/src/lib.rs --- cargo-0.33.0/vendor/im-rc/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -335,35 +335,11 @@ #![deny(unsafe_code)] #![cfg_attr(has_specialisation, feature(specialization))] -#![cfg_attr(docs_rs_workaround, feature(slice_get_slice))] - -extern crate typenum; #[cfg(test)] #[macro_use] extern crate pretty_assertions; -#[cfg(feature = "quickcheck")] -extern crate quickcheck; - -#[cfg(any(test, feature = "proptest"))] -#[macro_use] -extern crate proptest; - -#[cfg(feature = "proptest")] -proptest! {} - -#[cfg(any(test, feature = "serde"))] -extern crate serde; -#[cfg(test)] -extern crate serde_json; - -#[cfg(all(threadsafe, any(test, feature = "rayon")))] -extern crate rayon; - -#[cfg(test)] -extern crate metrohash; - mod config; mod nodes; mod sort; @@ -372,13 +348,13 @@ #[macro_use] mod ord; -pub use ord::map as ordmap; -pub use ord::set as ordset; +pub use crate::ord::map as ordmap; +pub use crate::ord::set as ordset; #[macro_use] mod hash; -pub use hash::map as hashmap; -pub use hash::set as hashset; +pub use crate::hash::map as hashmap; +pub use crate::hash::set as hashset; #[macro_use] pub mod vector; @@ -388,17 +364,22 @@ #[cfg(any(test, feature = "serde"))] pub mod ser; -pub use nodes::sized_chunk as chunk; +#[deprecated(since = "12.3.1", note = "please use the `sized_chunks` crate instead")] +pub use sized_chunks::sized_chunk as chunk; -pub use hashmap::HashMap; -pub use hashset::HashSet; -pub use ordmap::OrdMap; -pub use ordset::OrdSet; -pub use vector::Vector; +pub use crate::hashmap::HashMap; +pub use crate::hashset::HashSet; +pub use crate::ordmap::OrdMap; +pub use crate::ordset::OrdSet; +#[doc(inline)] +pub use crate::vector::Vector; #[cfg(test)] mod test; +#[cfg(test)] +mod tests; + /// Update a value inside multiple levels of data structures. /// /// This macro takes a [`Vector`][Vector], [`OrdMap`][OrdMap] or [`HashMap`][HashMap], diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/bitmap.rs cargo-0.35.0/vendor/im-rc/src/nodes/bitmap.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/bitmap.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/bitmap.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use nodes::types::Bits; - -pub struct Bitmap { - data: Size::Store, -} - -impl Clone for Bitmap { - fn clone(&self) -> Self { - Bitmap { data: self.data } - } -} - -impl Copy for Bitmap {} - -impl Default for Bitmap { - fn default() -> Self { - Bitmap { - data: Size::Store::default(), - } - } -} - -impl PartialEq for Bitmap { - fn eq(&self, other: &Self) -> bool { - self.data == other.data - } -} - -use std::fmt; - -impl fmt::Debug for Bitmap { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.data.fmt(f) - } -} - -impl Bitmap { - #[inline] - pub fn new() -> Self { - Self::default() - } - - #[inline] - pub fn get(self, index: usize) -> bool { - Size::get(&self.data, index) - } - - #[inline] - pub fn set(&mut self, index: usize, value: bool) -> bool { - Size::set(&mut self.data, index, value) - } - - #[inline] - pub fn len(self) -> usize { - Size::len(&self.data) - } - - #[inline] - pub fn first_index(self) -> Option { - Size::first_index(&self.data) - } -} - -impl IntoIterator for Bitmap { - type Item = usize; - type IntoIter = Iter; - - fn into_iter(self) -> Self::IntoIter { - Iter { - index: 0, - data: self.data, - } - } -} - -pub struct Iter { - index: usize, - data: Size::Store, -} - -impl Iterator for Iter { - type Item = usize; - - fn next(&mut self) -> Option { - if self.index >= Size::USIZE { - return None; - } - if Size::get(&self.data, self.index) { - self.index += 1; - Some(self.index - 1) - } else { - self.index += 1; - self.next() - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use proptest::collection::btree_set; - use typenum::U64; - - proptest! { - #[test] - fn get_set_and_iter(bits in btree_set(0..64usize, 0..64)) { - let mut bitmap = Bitmap::::new(); - for i in &bits { - bitmap.set(*i, true); - } - for i in 0..64 { - assert_eq!(bitmap.get(i), bits.contains(&i)); - } - assert!(bitmap.into_iter().eq(bits.into_iter())); - } - } -} diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/btree.rs cargo-0.35.0/vendor/im-rc/src/nodes/btree.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/btree.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/btree.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,9 +9,9 @@ use typenum::{Add1, Unsigned}; -use config::OrdChunkSize as NodeSize; -use nodes::sized_chunk::Chunk; -use util::{clone_ref, Ref}; +use crate::config::OrdChunkSize as NodeSize; +use crate::nodes::sized_chunk::Chunk; +use crate::util::{clone_ref, Ref}; use self::Insert::*; use self::InsertAction::*; @@ -19,14 +19,17 @@ const NODE_SIZE: usize = NodeSize::USIZE; const MEDIAN: usize = (NODE_SIZE + 1) >> 1; -pub trait BTreeValue: Clone { +pub trait BTreeValue { type Key; fn ptr_eq(&self, other: &Self) -> bool; fn search_key(slice: &[Self], key: &BK) -> Result where BK: Ord + ?Sized, + Self: Sized, Self::Key: Borrow; - fn search_value(slice: &[Self], value: &Self) -> Result; + fn search_value(slice: &[Self], value: &Self) -> Result + where + Self: Sized; fn cmp_keys(&self, other: &BK) -> Ordering where BK: Ord + ?Sized, @@ -90,10 +93,7 @@ } } -impl Node -where - A: Clone, -{ +impl Node { #[inline] fn has_room(&self) -> bool { self.keys.len() < NODE_SIZE @@ -180,6 +180,7 @@ pub fn lookup_mut(&mut self, key: &BK) -> Option<&mut A> where + A: Clone, BK: Ord + ?Sized, A::Key: Borrow, { @@ -424,7 +425,10 @@ self.children.push_back(child); } - pub fn insert(&mut self, value: A) -> Insert { + pub fn insert(&mut self, value: A) -> Insert + where + A: Clone, + { if self.keys.is_empty() { self.keys.push_back(value); self.children.push_back(None); @@ -437,7 +441,7 @@ } // Key is adjacent to some key in node Err(index) => { - let mut has_room = self.has_room(); + let has_room = self.has_room(); let action = match self.children[index] { // No child at location, this is the target node. None => InsertAt, @@ -484,6 +488,7 @@ pub fn remove(&mut self, key: &BK) -> Remove where + A: Clone, BK: Ord + ?Sized, A::Key: Borrow, { @@ -493,6 +498,7 @@ fn remove_index(&mut self, index: Result, key: &BK) -> Remove where + A: Clone, BK: Ord + ?Sized, A::Key: Borrow, { @@ -564,7 +570,7 @@ Remove::Removed(pair) } RemoveAction::PullUp(target_index, pull_to, child_index) => { - let mut children = &mut self.children; + let children = &mut self.children; let mut update = None; let mut value; if let Some(&mut Some(ref mut child_ref)) = children.get_mut(child_index) { @@ -618,8 +624,8 @@ unreachable!() } }); - let mut left = Ref::make_mut(children.next().unwrap()); - let mut child = Ref::make_mut(children.next().unwrap()); + let left = Ref::make_mut(children.next().unwrap()); + let child = Ref::make_mut(children.next().unwrap()); // Prepare the rebalanced node. child.push_min( left.children.last().unwrap().clone(), @@ -664,8 +670,8 @@ unreachable!() } }); - let mut child = Ref::make_mut(children.next().unwrap()); - let mut right = Ref::make_mut(children.next().unwrap()); + let child = Ref::make_mut(children.next().unwrap()); + let right = Ref::make_mut(children.next().unwrap()); // Prepare the rebalanced node. child.push_max(right.children[0].clone(), self.keys[index].clone()); match child.remove(key) { @@ -1001,7 +1007,7 @@ impl Iterator for ConsumingIter where - A: BTreeValue, + A: BTreeValue + Clone, { type Item = A; @@ -1037,7 +1043,7 @@ impl DoubleEndedIterator for ConsumingIter where - A: BTreeValue, + A: BTreeValue + Clone, { fn next_back(&mut self) -> Option { loop { @@ -1065,7 +1071,7 @@ } } -impl ExactSizeIterator for ConsumingIter {} +impl ExactSizeIterator for ConsumingIter {} // DiffIter diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/hamt.rs cargo-0.35.0/vendor/im-rc/src/nodes/hamt.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/hamt.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/hamt.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,10 +11,10 @@ use typenum::{Pow, Unsigned, U2}; -use config::HashLevelSize; -use nodes::sparse_chunk::{Iter as ChunkIter, IterMut as ChunkIterMut, SparseChunk}; -use nodes::types::Bits; -use util::{clone_ref, Ref}; +use crate::config::HashLevelSize; +use crate::nodes::sparse_chunk::{Iter as ChunkIter, IterMut as ChunkIterMut, SparseChunk}; +use crate::nodes::types::Bits; +use crate::util::{clone_ref, Ref}; pub type HashWidth = >::Output; pub type HashBits = ::Store; // a uint of HASH_SIZE bits @@ -33,7 +33,7 @@ hash >> shift & HASH_MASK } -pub trait HashValue: Clone { +pub trait HashValue { type Key: Eq; fn extract_key(&self) -> &Self::Key; @@ -95,13 +95,13 @@ } } -impl Default for Node { +impl Default for Node { fn default() -> Self { Self::new() } } -impl Node { +impl Node { #[inline] pub fn new() -> Self { Node { @@ -110,6 +110,11 @@ } #[inline] + fn len(&self) -> usize { + self.data.len() + } + + #[inline] pub fn unit(index: usize, value: Entry) -> Self { Node { data: SparseChunk::unit(index, value), @@ -130,15 +135,12 @@ } } - #[inline] - fn len(&self) -> usize { - self.data.len() - } - fn pop(&mut self) -> Entry { self.data.pop().unwrap() } +} +impl Node { fn merge_values(value1: A, hash1: HashBits, value2: A, hash2: HashBits, shift: usize) -> Self { let index1 = mask(hash1, shift) as usize; let index2 = mask(hash2, shift) as usize; @@ -188,6 +190,7 @@ pub fn get_mut(&mut self, hash: HashBits, shift: usize, key: &BK) -> Option<&mut A> where + A: Clone, BK: Eq + ?Sized, A::Key: Borrow, { @@ -215,7 +218,10 @@ } } - pub fn insert(&mut self, hash: HashBits, shift: usize, value: A) -> Option { + pub fn insert(&mut self, hash: HashBits, shift: usize, value: A) -> Option + where + A: Clone, + { let index = mask(hash, shift) as usize; if let Some(entry) = self.data.get_mut(index) { let mut fallthrough = false; @@ -278,6 +284,7 @@ pub fn remove(&mut self, hash: HashBits, shift: usize, key: &BK) -> Option where + A: Clone, BK: Eq + ?Sized, A::Key: Borrow, { @@ -293,7 +300,7 @@ } // Otherwise, fall through to the removal. } Entry::Collision(ref mut coll_ref) => { - let mut coll = Ref::make_mut(coll_ref); + let coll = Ref::make_mut(coll_ref); removed = coll.remove(key); if coll.len() == 1 { new_node = Some(coll.pop()); @@ -597,7 +604,7 @@ impl Iterator for Drain where - A: HashValue, + A: HashValue + Clone, { type Item = (A, HashBits); @@ -644,9 +651,9 @@ } } -impl ExactSizeIterator for Drain {} +impl ExactSizeIterator for Drain where A: Clone {} -impl FusedIterator for Drain {} +impl FusedIterator for Drain where A: Clone {} impl fmt::Debug for Node { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/mod.rs cargo-0.35.0/vendor/im-rc/src/nodes/mod.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,11 +2,18 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -pub mod bitmap; pub mod btree; pub mod hamt; pub mod rrb; -mod types; -mod unsafe_chunks; -pub use self::unsafe_chunks::{chunk, sized_chunk, sparse_chunk}; +pub use sized_chunks::*; + +pub mod chunk { + use crate::config::VectorChunkSize; + use sized_chunks as sc; + use typenum::Unsigned; + + pub type Chunk = sc::sized_chunk::Chunk; + pub type Iter = sc::sized_chunk::Iter; + pub const CHUNK_SIZE: usize = VectorChunkSize::USIZE; +} diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/rrb.rs cargo-0.35.0/vendor/im-rc/src/nodes/rrb.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/rrb.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/rrb.rs 2019-05-15 11:26:24.000000000 +0000 @@ -6,8 +6,8 @@ use std::mem::replace; use std::ops::Range; -use nodes::chunk::{Chunk, CHUNK_SIZE}; -use util::{ +use crate::nodes::chunk::{Chunk, CHUNK_SIZE}; +use crate::util::{ clone_ref, Ref, Side::{self, Left, Right}, }; @@ -91,7 +91,8 @@ let size_table = Ref::make_mut(size_ref); match side { Left => { - debug_assert_eq!(value, size_table.pop_front()); + let first = size_table.pop_front(); + debug_assert_eq!(value, first); for entry in size_table.iter_mut() { *entry -= value; } @@ -120,7 +121,7 @@ } pub enum PushResult { - Full(A), + Full(A, usize), Done, } @@ -292,7 +293,7 @@ let size = if node.is_dense() { Size::Size(node.len()) } else { - let mut size_table = Chunk::unit(node.len()); + let size_table = Chunk::unit(node.len()); Size::Table(Ref::from(size_table)) }; let children = Chunk::unit(node); @@ -340,7 +341,7 @@ pub fn len(&self) -> usize { match self.children { Entry::Nodes(Size::Size(size), _) => size, - Entry::Nodes(Size::Table(ref size_table), _) => *(size_table.last().unwrap()), + Entry::Nodes(Size::Table(ref size_table), _) => *(size_table.last().unwrap_or(&0)), Entry::Values(ref values) => values.len(), Entry::Empty => 0, } @@ -358,6 +359,10 @@ self.children.is_full() } + pub fn number_of_children(&self) -> usize { + self.children.len() + } + pub fn first_child(&self) -> &Ref { self.children.unwrap_nodes().first().unwrap() } @@ -430,7 +435,7 @@ return None; } if let Entry::Nodes(Size::Table(ref size_table), _) = self.children { - if size_table[target_idx] <= index { + while size_table[target_idx] <= index { target_idx += 1; if target_idx >= size_table.len() { return None; @@ -547,17 +552,16 @@ } PushResult::Done } else { - PushResult::Full(chunk) + PushResult::Full(chunk, 0) } } } else if level == 1 { // If rightmost existing node has any room, merge as much as // possible over from the new node. - match side { + let num_drained = match side { Side::Right => { if let Entry::Nodes(ref mut size, ref mut children) = self.children { - let mut rightmost = - Ref::make_mut(Ref::make_mut(children).last_mut().unwrap()); + let rightmost = Ref::make_mut(Ref::make_mut(children).last_mut().unwrap()); let old_size = rightmost.len(); let chunk = Ref::make_mut(&mut chunk); let values = rightmost.children.unwrap_values_mut(); @@ -565,12 +569,14 @@ values.drain_from_front(chunk, to_drain); size.pop(Side::Right, old_size); size.push(Side::Right, values.len()); + to_drain + } else { + 0 } } Side::Left => { if let Entry::Nodes(ref mut size, ref mut children) = self.children { - let mut leftmost = - Ref::make_mut(Ref::make_mut(children).first_mut().unwrap()); + let leftmost = Ref::make_mut(Ref::make_mut(children).first_mut().unwrap()); let old_size = leftmost.len(); let chunk = Ref::make_mut(&mut chunk); let values = leftmost.children.unwrap_values_mut(); @@ -578,14 +584,29 @@ values.drain_from_back(chunk, to_drain); size.pop(Side::Left, old_size); size.push(Side::Left, values.len()); + to_drain + } else { + 0 } } - } + }; if is_full { - PushResult::Full(chunk) + PushResult::Full(chunk, num_drained) } else { - self.push_size(side, chunk.len()); - self.push_child_node(side, Ref::new(Node::from_chunk(0, chunk))); + // If the chunk is empty after being drained, there might be + // more space in existing chunks. To keep the middle dense, we + // do not add it here. + if !chunk.is_empty() { + if side == Left && chunk.len() < NODE_SIZE { + if let Entry::Nodes(ref mut size, _) = self.children { + if let Size::Size(value) = *size { + *size = Size::table_from_size(level, value); + } + } + } + self.push_size(side, chunk.len()); + self.push_child_node(side, Ref::new(Node::from_chunk(0, chunk))); + } PushResult::Done } } else { @@ -599,9 +620,28 @@ let child = Ref::make_mut(&mut children[index]); match child.push_chunk(level - 1, side, chunk) { PushResult::Done => None, - PushResult::Full(chunk) => { + PushResult::Full(chunk, num_drained) => { + // Our chunk was too large for `child`, so it could not + // be pushed there. However, exactly `num_drained` + // elements were added to the child. We need to reflect + // that change in the size field of the node. + match side { + Right => match self.children { + Entry::Nodes(Size::Table(ref mut sizes), _) => { + let sizes = Ref::make_mut(sizes); + sizes[index] += num_drained; + } + Entry::Nodes(Size::Size(ref mut size), _) => { + *size += num_drained; + } + Entry::Values(_) | Entry::Empty => (), + }, + Left => { + self.update_size(0, num_drained as isize); + } + } if is_full { - return PushResult::Full(chunk); + return PushResult::Full(chunk, 0); } else { Some(Node::from_chunk(level - 1, chunk)) } @@ -919,6 +959,39 @@ } } + pub fn assert_invariants(&self) -> usize { + // Verifies that the size table matches reality. + match self.children { + Entry::Empty => 0, + Entry::Values(ref values) => { + // An empty value node is pointless and should never occur. + assert_ne!(0, values.len()); + values.len() + } + Entry::Nodes(ref size, ref children) => { + // A parent node with no children should never occur. + assert_ne!(0, children.len()); + let mut lengths = Vec::new(); + for child in &**children { + lengths.push(child.assert_invariants()); + } + match size { + Size::Size(size) => { + let total: usize = lengths.iter().sum(); + assert_eq!(*size, total); + } + Size::Table(ref table) => { + for (index, current) in table.iter().enumerate() { + let expected: usize = lengths.iter().take(index + 1).sum(); + assert_eq!(expected, *current); + } + } + } + lengths.iter().sum() + } + } + } + // pub fn print(&self, f: &mut W, indent: usize, level: usize) -> Result<(), fmt::Error> // where // W: fmt::Write, diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/types.rs cargo-0.35.0/vendor/im-rc/src/nodes/types.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/types.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/types.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use std::fmt::Debug; -use std::marker::PhantomData; - -use typenum::*; - -// Chunk sizes - -pub trait ChunkLength: Unsigned { - type SizedType; -} - -impl ChunkLength for UTerm { - type SizedType = (); -} - -#[doc(hidden)] -#[allow(dead_code)] -pub struct SizeEven { - parent1: B, - parent2: B, - _marker: PhantomData, -} - -#[doc(hidden)] -#[allow(dead_code)] -pub struct SizeOdd { - parent1: B, - parent2: B, - data: A, -} - -impl ChunkLength for UInt -where - N: ChunkLength, -{ - type SizedType = SizeEven; -} - -impl ChunkLength for UInt -where - N: ChunkLength, -{ - type SizedType = SizeOdd; -} - -// Bit field sizes - -pub trait Bits: Unsigned { - type Store: Default + Copy + PartialEq + Debug; - - fn get(bits: &Self::Store, index: usize) -> bool; - fn set(bits: &mut Self::Store, index: usize, value: bool) -> bool; - fn len(bits: &Self::Store) -> usize; - fn first_index(bits: &Self::Store) -> Option; -} - -macro_rules! bits_for { - ($num:ty, $result:ty) => { - impl Bits for $num { - type Store = $result; - - fn get(bits: &$result, index: usize) -> bool { - debug_assert!(index < Self::USIZE); - bits & (1 << index) != 0 - } - - fn set(bits: &mut $result, index: usize, value: bool) -> bool { - debug_assert!(index < Self::USIZE); - let mask = 1 << index; - let prev = *bits & mask; - if value { - *bits |= mask; - } else { - *bits &= !mask; - } - prev != 0 - } - - fn len(bits: &$result) -> usize { - bits.count_ones() as usize - } - - fn first_index(bits: &$result) -> Option { - if *bits == 0 { - None - } else { - Some(bits.trailing_zeros() as usize) - } - } - } - }; -} - -bits_for!(U1, u8); -bits_for!(U2, u8); -bits_for!(U3, u8); -bits_for!(U4, u8); -bits_for!(U5, u8); -bits_for!(U6, u8); -bits_for!(U7, u8); -bits_for!(U8, u8); -bits_for!(U9, u16); -bits_for!(U10, u16); -bits_for!(U11, u16); -bits_for!(U12, u16); -bits_for!(U13, u16); -bits_for!(U14, u16); -bits_for!(U15, u16); -bits_for!(U16, u16); -bits_for!(U17, u32); -bits_for!(U18, u32); -bits_for!(U19, u32); -bits_for!(U20, u32); -bits_for!(U21, u32); -bits_for!(U22, u32); -bits_for!(U23, u32); -bits_for!(U24, u32); -bits_for!(U25, u32); -bits_for!(U26, u32); -bits_for!(U27, u32); -bits_for!(U28, u32); -bits_for!(U29, u32); -bits_for!(U30, u32); -bits_for!(U31, u32); -bits_for!(U32, u32); -bits_for!(U33, u64); -bits_for!(U34, u64); -bits_for!(U35, u64); -bits_for!(U36, u64); -bits_for!(U37, u64); -bits_for!(U38, u64); -bits_for!(U39, u64); -bits_for!(U40, u64); -bits_for!(U41, u64); -bits_for!(U42, u64); -bits_for!(U43, u64); -bits_for!(U44, u64); -bits_for!(U45, u64); -bits_for!(U46, u64); -bits_for!(U47, u64); -bits_for!(U48, u64); -bits_for!(U49, u64); -bits_for!(U50, u64); -bits_for!(U51, u64); -bits_for!(U52, u64); -bits_for!(U53, u64); -bits_for!(U54, u64); -bits_for!(U55, u64); -bits_for!(U56, u64); -bits_for!(U57, u64); -bits_for!(U58, u64); -bits_for!(U59, u64); -bits_for!(U60, u64); -bits_for!(U61, u64); -bits_for!(U62, u64); -bits_for!(U63, u64); -bits_for!(U64, u64); -// No u128 because stdlib hashes are only u64. diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/mod.rs cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/mod.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#![allow(unsafe_code)] - -pub mod sized_chunk; -pub mod sparse_chunk; - -pub mod chunk { - use super::sized_chunk as sc; - use config::VectorChunkSize; - use typenum::Unsigned; - - pub type Chunk = sc::Chunk; - pub type Iter = sc::Iter; - pub const CHUNK_SIZE: usize = VectorChunkSize::USIZE; -} diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/sized_chunk.rs cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/sized_chunk.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/sized_chunk.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/sized_chunk.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1155 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -//! A fixed capacity smart array. -//! -//! See [`Chunk`](struct.Chunk.html) - -use std::borrow::{Borrow, BorrowMut}; -use std::cmp::Ordering; -use std::fmt::{Debug, Error, Formatter}; -use std::hash::{Hash, Hasher}; -use std::io; -use std::iter::{FromIterator, FusedIterator}; -use std::mem::{self, replace, ManuallyDrop}; -use std::ops::{Deref, DerefMut, Index, IndexMut}; -use std::ptr; -use std::slice::{ - from_raw_parts, from_raw_parts_mut, Iter as SliceIter, IterMut as SliceIterMut, SliceIndex, -}; - -use typenum::U64; - -use nodes::types::ChunkLength; - -/// A fixed capacity smart array. -/// -/// An inline array of items with a variable length but a fixed, preallocated -/// capacity given by the `N` type, which must be an [`Unsigned`][Unsigned] type -/// level numeral. -/// -/// It's 'smart' because it's able to reorganise its contents based on expected -/// behaviour. If you construct one using `push_back`, it will be laid out like -/// a `Vec` with space at the end. If you `push_front` it will start filling in -/// values from the back instead of the front, so that you still get linear time -/// push as long as you don't reverse direction. If you do, and there's no room -/// at the end you're pushing to, it'll shift its contents over to the other -/// side, creating more space to push into. This technique is tuned for -/// `Chunk`'s expected use case: usually, chunks always see either `push_front` -/// or `push_back`, but not both unless they move around inside the tree, in -/// which case they're able to reorganise themselves with reasonable efficiency -/// to suit their new usage patterns. -/// -/// It maintains a `left` index and a `right` index instead of a simple length -/// counter in order to accomplish this, much like a ring buffer would, except -/// that the `Chunk` keeps all its items sequentially in memory so that you can -/// always get a `&[A]` slice for them, at the price of the occasional -/// reordering operation. -/// -/// This technique also lets us choose to shift the shortest side to account for -/// the inserted or removed element when performing insert and remove -/// operations, unlike `Vec` where you always need to shift the right hand side. -/// -/// Unlike a `Vec`, the `Chunk` has a fixed capacity and cannot grow beyond it. -/// Being intended for low level use, it expects you to know or test whether -/// you're pushing to a full array, and has an API more geared towards panics -/// than returning `Option`s, on the assumption that you know what you're doing. -/// -/// # Examples -/// -/// ```rust -/// # #[macro_use] extern crate im_rc as im; -/// # extern crate typenum; -/// # use im::chunk::Chunk; -/// # use typenum::U64; -/// # fn main() { -/// // Construct a chunk with a 64 item capacity -/// let mut chunk = Chunk::::new(); -/// // Fill it with descending numbers -/// chunk.extend((0..64).rev()); -/// // It derefs to a slice so we can use standard slice methods -/// chunk.sort(); -/// // It's got all the amenities like `FromIterator` and `Eq` -/// let expected: Chunk = (0..64).collect(); -/// assert_eq!(expected, chunk); -/// # } -/// ``` -/// -/// [Unsigned]: https://docs.rs/typenum/1.10.0/typenum/marker_traits/trait.Unsigned.html -pub struct Chunk -where - N: ChunkLength, -{ - left: usize, - right: usize, - data: ManuallyDrop, -} - -impl Drop for Chunk -where - N: ChunkLength, -{ - fn drop(&mut self) { - if mem::needs_drop::() { - for i in self.left..self.right { - unsafe { Chunk::force_drop(i, self) } - } - } - } -} - -impl Clone for Chunk -where - A: Clone, - N: ChunkLength, -{ - fn clone(&self) -> Self { - let mut out = Self::new(); - out.left = self.left; - out.right = self.right; - for index in self.left..self.right { - unsafe { Chunk::force_write(index, self.values()[index].clone(), &mut out) } - } - out - } -} - -impl Chunk -where - N: ChunkLength, -{ - /// Construct a new empty chunk. - pub fn new() -> Self { - let mut chunk: Self; - unsafe { - chunk = mem::uninitialized(); - ptr::write(&mut chunk.left, 0); - ptr::write(&mut chunk.right, 0); - } - chunk - } - - /// Construct a new chunk with one item. - pub fn unit(value: A) -> Self { - let mut chunk: Self; - unsafe { - chunk = mem::uninitialized(); - ptr::write(&mut chunk.left, 0); - ptr::write(&mut chunk.right, 1); - Chunk::force_write(0, value, &mut chunk); - } - chunk - } - - /// Construct a new chunk with two items. - pub fn pair(left: A, right: A) -> Self { - let mut chunk: Self; - unsafe { - chunk = mem::uninitialized(); - ptr::write(&mut chunk.left, 0); - ptr::write(&mut chunk.right, 2); - Chunk::force_write(0, left, &mut chunk); - Chunk::force_write(1, right, &mut chunk); - } - chunk - } - - /// Construct a new chunk and move every item from `other` into the new - /// chunk. - /// - /// Time: O(n) - pub fn drain_from(other: &mut Self) -> Self { - let other_len = other.len(); - Self::from_front(other, other_len) - } - - /// Construct a new chunk and populate it by taking `count` items from the - /// iterator `iter`. - /// - /// Panics if the iterator contains less than `count` items. - /// - /// Time: O(n) - pub fn collect_from(iter: &mut I, mut count: usize) -> Self - where - I: Iterator, - { - let mut chunk = Self::new(); - while count > 0 { - count -= 1; - chunk.push_back( - iter.next() - .expect("Chunk::collect_from: underfull iterator"), - ); - } - chunk - } - - /// Construct a new chunk and populate it by taking `count` items from the - /// front of `other`. - /// - /// Time: O(n) for the number of items moved - pub fn from_front(other: &mut Self, count: usize) -> Self { - let other_len = other.len(); - debug_assert!(count <= other_len); - let mut chunk = Self::new(); - unsafe { Chunk::force_copy_to(other.left, 0, count, other, &mut chunk) }; - chunk.right = count; - other.left += count; - chunk - } - - /// Construct a new chunk and populate it by taking `count` items from the - /// back of `other`. - /// - /// Time: O(n) for the number of items moved - pub fn from_back(other: &mut Self, count: usize) -> Self { - let other_len = other.len(); - debug_assert!(count <= other_len); - let mut chunk = Self::new(); - unsafe { Chunk::force_copy_to(other.right - count, 0, count, other, &mut chunk) }; - chunk.right = count; - other.right -= count; - chunk - } - - /// Get the length of the chunk. - #[inline] - pub fn len(&self) -> usize { - self.right - self.left - } - - /// Test if the chunk is empty. - #[inline] - pub fn is_empty(&self) -> bool { - self.left == self.right - } - - /// Test if the chunk is at capacity. - #[inline] - pub fn is_full(&self) -> bool { - self.left == 0 && self.right == N::USIZE - } - - #[inline] - fn values(&self) -> &[A] { - unsafe { - from_raw_parts( - &self.data as *const ManuallyDrop as *const A, - N::USIZE, - ) - } - } - - #[inline] - fn values_mut(&mut self) -> &mut [A] { - unsafe { - from_raw_parts_mut( - &mut self.data as *mut ManuallyDrop as *mut A, - N::USIZE, - ) - } - } - - /// Copy the value at an index, discarding ownership of the copied value - #[inline] - unsafe fn force_read(index: usize, chunk: &mut Self) -> A { - ptr::read(&chunk.values()[index]) - } - - /// Write a value at an index without trying to drop what's already there - #[inline] - unsafe fn force_write(index: usize, value: A, chunk: &mut Self) { - ptr::write(&mut chunk.values_mut()[index], value) - } - - /// Drop the value at an index - #[inline] - unsafe fn force_drop(index: usize, chunk: &mut Self) { - ptr::drop_in_place(&mut chunk.values_mut()[index]) - } - - /// Copy a range within a chunk - #[inline] - unsafe fn force_copy(from: usize, to: usize, count: usize, chunk: &mut Self) { - if count > 0 { - ptr::copy(&chunk.values()[from], &mut chunk.values_mut()[to], count) - } - } - - /// Copy a range between chunks - #[inline] - unsafe fn force_copy_to( - from: usize, - to: usize, - count: usize, - chunk: &mut Self, - other: &mut Self, - ) { - if count > 0 { - ptr::copy_nonoverlapping(&chunk.values()[from], &mut other.values_mut()[to], count) - } - } - - /// Push an item to the front of the chunk. - /// - /// Panics if the capacity of the chunk is exceeded. - /// - /// Time: O(1) if there's room at the front, O(n) otherwise - pub fn push_front(&mut self, value: A) { - if self.is_full() { - panic!("Chunk::push_front: can't push to full chunk"); - } - if self.is_empty() { - self.left = N::USIZE; - self.right = N::USIZE; - } else if self.left == 0 { - self.left = N::USIZE - self.right; - unsafe { Chunk::force_copy(0, self.left, self.right, self) }; - self.right = N::USIZE; - } - self.left -= 1; - unsafe { Chunk::force_write(self.left, value, self) } - } - - /// Push an item to the back of the chunk. - /// - /// Panics if the capacity of the chunk is exceeded. - /// - /// Time: O(1) if there's room at the back, O(n) otherwise - pub fn push_back(&mut self, value: A) { - if self.is_full() { - panic!("Chunk::push_back: can't push to full chunk"); - } - if self.is_empty() { - self.left = 0; - self.right = 0; - } else if self.right == N::USIZE { - unsafe { Chunk::force_copy(self.left, 0, self.len(), self) }; - self.right = N::USIZE - self.left; - self.left = 0; - } - unsafe { Chunk::force_write(self.right, value, self) } - self.right += 1; - } - - /// Pop an item off the front of the chunk. - /// - /// Panics if the chunk is empty. - /// - /// Time: O(1) - pub fn pop_front(&mut self) -> A { - if self.is_empty() { - panic!("Chunk::pop_front: can't pop from empty chunk"); - } else { - let value = unsafe { Chunk::force_read(self.left, self) }; - self.left += 1; - value - } - } - - /// Pop an item off the back of the chunk. - /// - /// Panics if the chunk is empty. - /// - /// Time: O(1) - pub fn pop_back(&mut self) -> A { - if self.is_empty() { - panic!("Chunk::pop_back: can't pop from empty chunk"); - } else { - self.right -= 1; - unsafe { Chunk::force_read(self.right, self) } - } - } - - /// Discard all items up to but not including `index`. - /// - /// Panics if `index` is out of bounds. - /// - /// Time: O(n) for the number of items dropped - pub fn drop_left(&mut self, index: usize) { - if index > 0 { - if index > self.len() { - panic!("Chunk::drop_left: index out of bounds"); - } - let start = self.left; - for i in start..(start + index) { - unsafe { Chunk::force_drop(i, self) } - } - self.left += index; - } - } - - /// Discard all items from `index` onward. - /// - /// Panics if `index` is out of bounds. - /// - /// Time: O(n) for the number of items dropped - pub fn drop_right(&mut self, index: usize) { - if index > self.len() { - panic!("Chunk::drop_right: index out of bounds"); - } - if index == self.len() { - return; - } - let start = self.left + index; - for i in start..self.right { - unsafe { Chunk::force_drop(i, self) } - } - self.right = start; - } - - /// Split a chunk into two, the original chunk containing - /// everything up to `index` and the returned chunk containing - /// everything from `index` onwards. - /// - /// Panics if `index` is out of bounds. - /// - /// Time: O(n) for the number of items in the new chunk - pub fn split_off(&mut self, index: usize) -> Self { - if index > self.len() { - panic!("Chunk::split: index out of bounds"); - } - if index == self.len() { - return Self::new(); - } - let mut right_chunk = Self::new(); - let start = self.left + index; - let len = self.right - start; - unsafe { Chunk::force_copy_to(start, 0, len, self, &mut right_chunk) }; - right_chunk.right = len; - self.right = start; - right_chunk - } - - /// Remove all items from `other` and append them to the back of `self`. - /// - /// Panics if the capacity of the chunk is exceeded. - /// - /// Time: O(n) for the number of items moved - pub fn append(&mut self, other: &mut Self) { - let self_len = self.len(); - let other_len = other.len(); - if self_len + other_len > N::USIZE { - panic!("Chunk::append: chunk size overflow"); - } - if self.right + other_len > N::USIZE { - unsafe { Chunk::force_copy(self.left, 0, self_len, self) }; - self.right -= self.left; - self.left = 0; - } - unsafe { Chunk::force_copy_to(other.left, self.right, other_len, other, self) }; - self.right += other_len; - other.left = 0; - other.right = 0; - } - - /// Remove `count` items from the front of `other` and append them to the - /// back of `self`. - /// - /// Panics if `self` doesn't have `count` items left, or if `other` has - /// fewer than `count` items. - /// - /// Time: O(n) for the number of items moved - pub fn drain_from_front(&mut self, other: &mut Self, count: usize) { - let self_len = self.len(); - let other_len = other.len(); - debug_assert!(self_len + count <= N::USIZE); - debug_assert!(other_len >= count); - if self.right + count > N::USIZE { - unsafe { Chunk::force_copy(self.left, 0, self_len, self) }; - self.right -= self.left; - self.left = 0; - } - unsafe { Chunk::force_copy_to(other.left, self.right, count, other, self) }; - self.right += count; - other.left += count; - } - - /// Remove `count` items from the back of `other` and append them to the - /// front of `self`. - /// - /// Panics if `self` doesn't have `count` items left, or if `other` has - /// fewer than `count` items. - /// - /// Time: O(n) for the number of items moved - pub fn drain_from_back(&mut self, other: &mut Self, count: usize) { - let self_len = self.len(); - let other_len = other.len(); - debug_assert!(self_len + count <= N::USIZE); - debug_assert!(other_len >= count); - if self.left < count { - self.left = N::USIZE - self.right; - unsafe { Chunk::force_copy(0, self.left, self.right, self) }; - self.right = N::USIZE; - } - unsafe { Chunk::force_copy_to(other.right - count, self.left - count, count, other, self) }; - self.left -= count; - other.right -= count; - } - - /// Update the value at index `index`, returning the old value. - /// - /// Panics if `index` is out of bounds. - /// - /// Time: O(1) - pub fn set(&mut self, index: usize, value: A) -> A { - replace(&mut self[index], value) - } - - /// Insert a new value at index `index`, shifting all the following values - /// to the right. - /// - /// Panics if the index is out of bounds. - /// - /// Time: O(n) for the number of items shifted - pub fn insert(&mut self, index: usize, value: A) { - if self.is_full() { - panic!("Chunk::insert: chunk is full"); - } - if index > self.len() { - panic!("Chunk::insert: index out of bounds"); - } - let real_index = index + self.left; - let left_size = index; - let right_size = self.right - real_index; - if self.right == N::USIZE || (self.left > 0 && left_size < right_size) { - unsafe { - Chunk::force_copy(self.left, self.left - 1, left_size, self); - Chunk::force_write(real_index - 1, value, self); - } - self.left -= 1; - } else { - unsafe { - Chunk::force_copy(real_index, real_index + 1, right_size, self); - Chunk::force_write(real_index, value, self); - } - self.right += 1; - } - } - - /// Remove the value at index `index`, shifting all the following values to - /// the left. - /// - /// Returns the removed value. - /// - /// Panics if the index is out of bounds. - /// - /// Time: O(n) for the number of items shifted - pub fn remove(&mut self, index: usize) -> A { - if index >= self.len() { - panic!("Chunk::remove: index out of bounds"); - } - let real_index = index + self.left; - let value = unsafe { Chunk::force_read(real_index, self) }; - let left_size = index; - let right_size = self.right - real_index - 1; - if left_size < right_size { - unsafe { Chunk::force_copy(self.left, self.left + 1, left_size, self) }; - self.left += 1; - } else { - unsafe { Chunk::force_copy(real_index + 1, real_index, right_size, self) }; - self.right -= 1; - } - value - } - - /// Construct an iterator that drains values from the front of the chunk. - pub fn drain(&mut self) -> Drain<'_, A, N> { - Drain { chunk: self } - } - - /// Discard the contents of the chunk. - /// - /// Time: O(n) - pub fn clear(&mut self) { - self.drop_right(0); - self.left = 0; - self.right = 0; - } - - /// Get a reference to the contents of the chunk as a slice. - pub fn as_slice(&self) -> &[A] { - unsafe { - from_raw_parts( - (&self.data as *const ManuallyDrop as *const A).add(self.left), - self.len(), - ) - } - } - - /// Get a reference to the contents of the chunk as a mutable slice. - pub fn as_mut_slice(&mut self) -> &mut [A] { - unsafe { - from_raw_parts_mut( - (&mut self.data as *mut ManuallyDrop as *mut A).add(self.left), - self.len(), - ) - } - } -} - -impl Default for Chunk -where - N: ChunkLength, -{ - fn default() -> Self { - Self::new() - } -} - -impl Index for Chunk -where - I: SliceIndex<[A]>, - N: ChunkLength, -{ - type Output = I::Output; - fn index(&self, index: I) -> &Self::Output { - self.as_slice().index(index) - } -} - -impl IndexMut for Chunk -where - I: SliceIndex<[A]>, - N: ChunkLength, -{ - fn index_mut(&mut self, index: I) -> &mut Self::Output { - self.as_mut_slice().index_mut(index) - } -} - -impl Debug for Chunk -where - A: Debug, - N: ChunkLength, -{ - fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - f.write_str("Chunk")?; - f.debug_list().entries(self.iter()).finish() - } -} - -impl Hash for Chunk -where - A: Hash, - N: ChunkLength, -{ - fn hash(&self, hasher: &mut H) - where - H: Hasher, - { - for item in self { - item.hash(hasher) - } - } -} - -impl PartialEq for Chunk -where - A: PartialEq, - N: ChunkLength, -{ - fn eq(&self, other: &Self) -> bool { - self.len() == other.len() && self.iter().eq(other.iter()) - } -} - -impl Eq for Chunk -where - A: Eq, - N: ChunkLength, -{ -} - -impl PartialOrd for Chunk -where - A: PartialOrd, - N: ChunkLength, -{ - fn partial_cmp(&self, other: &Self) -> Option { - self.iter().partial_cmp(other.iter()) - } -} - -impl Ord for Chunk -where - A: Ord, - N: ChunkLength, -{ - fn cmp(&self, other: &Self) -> Ordering { - self.iter().cmp(other.iter()) - } -} - -impl io::Write for Chunk -where - N: ChunkLength, -{ - fn write(&mut self, buf: &[u8]) -> io::Result { - let old_len = self.len(); - self.extend(buf.iter().cloned().take(N::USIZE - old_len)); - Ok(self.len() - old_len) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl Borrow<[A]> for Chunk -where - N: ChunkLength, -{ - fn borrow(&self) -> &[A] { - self.as_slice() - } -} - -impl BorrowMut<[A]> for Chunk -where - N: ChunkLength, -{ - fn borrow_mut(&mut self) -> &mut [A] { - self.as_mut_slice() - } -} - -impl AsRef<[A]> for Chunk -where - N: ChunkLength, -{ - fn as_ref(&self) -> &[A] { - self.as_slice() - } -} - -impl AsMut<[A]> for Chunk -where - N: ChunkLength, -{ - fn as_mut(&mut self) -> &mut [A] { - self.as_mut_slice() - } -} - -impl Deref for Chunk -where - N: ChunkLength, -{ - type Target = [A]; - - fn deref(&self) -> &Self::Target { - self.as_slice() - } -} - -impl DerefMut for Chunk -where - N: ChunkLength, -{ - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut_slice() - } -} - -impl FromIterator for Chunk -where - N: ChunkLength, -{ - fn from_iter(it: I) -> Self - where - I: IntoIterator, - { - let mut chunk = Self::new(); - for item in it { - chunk.push_back(item); - } - chunk - } -} - -impl<'a, A, N> IntoIterator for &'a Chunk -where - N: ChunkLength, -{ - type Item = &'a A; - type IntoIter = SliceIter<'a, A>; - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a, A, N> IntoIterator for &'a mut Chunk -where - N: ChunkLength, -{ - type Item = &'a mut A; - type IntoIter = SliceIterMut<'a, A>; - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() - } -} - -impl Extend for Chunk -where - N: ChunkLength, -{ - /// Append the contents of the iterator to the back of the chunk. - /// - /// Panics if the chunk exceeds its capacity. - /// - /// Time: O(n) for the length of the iterator - fn extend(&mut self, it: I) - where - I: IntoIterator, - { - for item in it { - self.push_back(item); - } - } -} - -impl<'a, A, N> Extend<&'a A> for Chunk -where - A: 'a + Copy, - N: ChunkLength, -{ - /// Append the contents of the iterator to the back of the chunk. - /// - /// Panics if the chunk exceeds its capacity. - /// - /// Time: O(n) for the length of the iterator - fn extend(&mut self, it: I) - where - I: IntoIterator, - { - for item in it { - self.push_back(*item); - } - } -} - -pub struct Iter -where - N: ChunkLength, -{ - chunk: Chunk, -} - -impl Iterator for Iter -where - N: ChunkLength, -{ - type Item = A; - fn next(&mut self) -> Option { - if self.chunk.is_empty() { - None - } else { - Some(self.chunk.pop_front()) - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.chunk.len(), Some(self.chunk.len())) - } -} - -impl DoubleEndedIterator for Iter -where - N: ChunkLength, -{ - fn next_back(&mut self) -> Option { - if self.chunk.is_empty() { - None - } else { - Some(self.chunk.pop_back()) - } - } -} - -impl ExactSizeIterator for Iter where N: ChunkLength {} - -impl FusedIterator for Iter where N: ChunkLength {} - -impl IntoIterator for Chunk -where - N: ChunkLength, -{ - type Item = A; - type IntoIter = Iter; - - fn into_iter(self) -> Self::IntoIter { - Iter { chunk: self } - } -} - -pub struct Drain<'a, A, N> -where - A: 'a, - N: ChunkLength + 'a, -{ - chunk: &'a mut Chunk, -} - -impl<'a, A, N> Iterator for Drain<'a, A, N> -where - A: 'a, - N: ChunkLength + 'a, -{ - type Item = A; - - fn next(&mut self) -> Option { - if self.chunk.is_empty() { - None - } else { - Some(self.chunk.pop_front()) - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.chunk.len(), Some(self.chunk.len())) - } -} - -impl<'a, A, N> ExactSizeIterator for Drain<'a, A, N> -where - A: 'a, - N: ChunkLength + 'a, -{ -} - -impl<'a, A, N> FusedIterator for Drain<'a, A, N> -where - A: 'a, - N: ChunkLength + 'a, -{ -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn is_full() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - assert_eq!(false, chunk.is_full()); - chunk.push_back(i); - } - assert_eq!(true, chunk.is_full()); - } - - #[test] - fn push_back_front() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 12..20 { - chunk.push_back(i); - } - assert_eq!(8, chunk.len()); - for i in (0..12).rev() { - chunk.push_front(i); - } - assert_eq!(20, chunk.len()); - for i in 20..32 { - chunk.push_back(i); - } - assert_eq!(32, chunk.len()); - let right: Vec = chunk.into_iter().collect(); - let left: Vec = (0..32).collect(); - assert_eq!(left, right); - } - - #[test] - fn push_and_pop() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - chunk.push_back(i); - } - for i in 0..64 { - assert_eq!(i, chunk.pop_front()); - } - for i in 0..64 { - chunk.push_front(i); - } - for i in 0..64 { - assert_eq!(i, chunk.pop_back()); - } - } - - #[test] - fn drop_left() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..6 { - chunk.push_back(i); - } - chunk.drop_left(3); - let vec: Vec = chunk.into_iter().collect(); - assert_eq!(vec![3, 4, 5], vec); - } - - #[test] - fn drop_right() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..6 { - chunk.push_back(i); - } - chunk.drop_right(3); - let vec: Vec = chunk.into_iter().collect(); - assert_eq!(vec![0, 1, 2], vec); - } - - #[test] - fn split_off() { - let mut left = Chunk::<_, U64>::new(); - for i in 0..6 { - left.push_back(i); - } - let right = left.split_off(3); - let left_vec: Vec = left.into_iter().collect(); - let right_vec: Vec = right.into_iter().collect(); - assert_eq!(vec![0, 1, 2], left_vec); - assert_eq!(vec![3, 4, 5], right_vec); - } - - #[test] - fn append() { - let mut left = Chunk::<_, U64>::new(); - for i in 0..32 { - left.push_back(i); - } - let mut right = Chunk::<_, U64>::new(); - for i in (32..64).rev() { - right.push_front(i); - } - left.append(&mut right); - let out_vec: Vec = left.into_iter().collect(); - let should_vec: Vec = (0..64).collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn ref_iter() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - chunk.push_back(i); - } - let out_vec: Vec<&i32> = chunk.iter().collect(); - let should_vec_p: Vec = (0..64).collect(); - let should_vec: Vec<&i32> = should_vec_p.iter().collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn mut_ref_iter() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - chunk.push_back(i); - } - let out_vec: Vec<&mut i32> = chunk.iter_mut().collect(); - let mut should_vec_p: Vec = (0..64).collect(); - let should_vec: Vec<&mut i32> = should_vec_p.iter_mut().collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn consuming_iter() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - chunk.push_back(i); - } - let out_vec: Vec = chunk.into_iter().collect(); - let should_vec: Vec = (0..64).collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn insert_middle() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..32 { - chunk.push_back(i); - } - for i in 33..64 { - chunk.push_back(i); - } - chunk.insert(32, 32); - let out_vec: Vec = chunk.into_iter().collect(); - let should_vec: Vec = (0..64).collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn insert_back() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..63 { - chunk.push_back(i); - } - chunk.insert(63, 63); - let out_vec: Vec = chunk.into_iter().collect(); - let should_vec: Vec = (0..64).collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn insert_front() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 1..64 { - chunk.push_front(64 - i); - } - chunk.insert(0, 0); - let out_vec: Vec = chunk.into_iter().collect(); - let should_vec: Vec = (0..64).collect(); - assert_eq!(should_vec, out_vec); - } - - #[test] - fn remove_value() { - let mut chunk = Chunk::<_, U64>::new(); - for i in 0..64 { - chunk.push_back(i); - } - chunk.remove(32); - let out_vec: Vec = chunk.into_iter().collect(); - let should_vec: Vec = (0..32).chain(33..64).collect(); - assert_eq!(should_vec, out_vec); - } - - use std::sync::atomic::{AtomicUsize, Ordering}; - - struct DropTest<'a> { - counter: &'a AtomicUsize, - } - - impl<'a> DropTest<'a> { - fn new(counter: &'a AtomicUsize) -> Self { - counter.fetch_add(1, Ordering::Relaxed); - DropTest { counter } - } - } - - impl<'a> Drop for DropTest<'a> { - fn drop(&mut self) { - self.counter.fetch_sub(1, Ordering::Relaxed); - } - } - - #[test] - fn dropping() { - let counter = AtomicUsize::new(0); - { - let mut chunk: Chunk = Chunk::new(); - for _i in 0..20 { - chunk.push_back(DropTest::new(&counter)) - } - for _i in 0..20 { - chunk.push_front(DropTest::new(&counter)) - } - assert_eq!(40, counter.load(Ordering::Relaxed)); - for _i in 0..10 { - chunk.pop_back(); - } - assert_eq!(30, counter.load(Ordering::Relaxed)); - } - assert_eq!(0, counter.load(Ordering::Relaxed)); - } -} diff -Nru cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/sparse_chunk.rs cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/sparse_chunk.rs --- cargo-0.33.0/vendor/im-rc/src/nodes/unsafe_chunks/sparse_chunk.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/nodes/unsafe_chunks/sparse_chunk.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -use std::mem::{self, ManuallyDrop}; -use std::ops::Index; -use std::ops::IndexMut; -use std::ptr; -use std::slice::{from_raw_parts, from_raw_parts_mut}; - -use nodes::bitmap::{Bitmap, Iter as BitmapIter}; -use nodes::types::{Bits, ChunkLength}; - -pub struct SparseChunk> { - map: Bitmap, - data: ManuallyDrop, -} - -impl> Drop for SparseChunk { - fn drop(&mut self) { - if mem::needs_drop::() { - for index in self.map { - unsafe { SparseChunk::force_drop(index, self) } - } - } - } -} - -impl> Clone for SparseChunk { - fn clone(&self) -> Self { - let mut out = Self::new(); - for index in self.map { - out.insert(index, self[index].clone()); - } - out - } -} - -impl> SparseChunk { - #[inline] - fn values(&self) -> &[A] { - unsafe { - from_raw_parts( - &self.data as *const ManuallyDrop as *const A, - N::USIZE, - ) - } - } - - #[inline] - fn values_mut(&mut self) -> &mut [A] { - unsafe { - from_raw_parts_mut( - &mut self.data as *mut ManuallyDrop as *mut A, - N::USIZE, - ) - } - } - - /// Copy the value at an index, discarding ownership of the copied value - #[inline] - unsafe fn force_read(index: usize, chunk: &Self) -> A { - ptr::read(&chunk.values()[index as usize]) - } - - /// Write a value at an index without trying to drop what's already there - #[inline] - unsafe fn force_write(index: usize, value: A, chunk: &mut Self) { - ptr::write(&mut chunk.values_mut()[index as usize], value) - } - - /// Drop the value at an index - #[inline] - unsafe fn force_drop(index: usize, chunk: &mut Self) { - ptr::drop_in_place(&mut chunk.values_mut()[index]) - } - - pub fn new() -> Self { - let mut chunk: Self; - unsafe { - chunk = mem::uninitialized(); - ptr::write(&mut chunk.map, Bitmap::new()); - } - chunk - } - - pub fn unit(index: usize, value: A) -> Self { - let mut chunk = Self::new(); - chunk.insert(index, value); - chunk - } - - pub fn pair(index1: usize, value1: A, index2: usize, value2: A) -> Self { - let mut chunk = Self::new(); - chunk.insert(index1, value1); - chunk.insert(index2, value2); - chunk - } - - #[inline] - pub fn len(&self) -> usize { - self.map.len() - } - - pub fn insert(&mut self, index: usize, value: A) -> Option { - if index >= N::USIZE { - panic!("SparseChunk::insert: index out of bounds"); - } - let prev = if self.map.set(index, true) { - Some(unsafe { SparseChunk::force_read(index, self) }) - } else { - None - }; - unsafe { SparseChunk::force_write(index, value, self) }; - prev - } - - pub fn remove(&mut self, index: usize) -> Option { - if index >= N::USIZE { - panic!("SparseChunk::remove: index out of bounds"); - } - if self.map.set(index, false) { - Some(unsafe { SparseChunk::force_read(index, self) }) - } else { - None - } - } - - pub fn pop(&mut self) -> Option { - self.first_index().and_then(|index| self.remove(index)) - } - - pub fn get(&self, index: usize) -> Option<&A> { - if index >= N::USIZE { - return None; - } - if self.map.get(index) { - Some(&self.values()[index]) - } else { - None - } - } - - pub fn get_mut(&mut self, index: usize) -> Option<&mut A> { - if index >= N::USIZE { - return None; - } - if self.map.get(index) { - Some(&mut self.values_mut()[index]) - } else { - None - } - } - - pub fn indices(&self) -> BitmapIter { - self.map.into_iter() - } - - pub fn first_index(&self) -> Option { - self.map.first_index() - } - - pub fn iter(&self) -> Iter<'_, A, N> { - Iter { - indices: self.indices(), - chunk: self, - } - } - - pub fn iter_mut(&mut self) -> IterMut<'_, A, N> { - IterMut { - indices: self.indices(), - chunk: self, - } - } - - pub fn drain(self) -> Drain { - Drain { chunk: self } - } -} - -impl> Index for SparseChunk { - type Output = A; - - #[inline] - fn index(&self, index: usize) -> &Self::Output { - self.get(index).unwrap() - } -} - -impl> IndexMut for SparseChunk { - #[inline] - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - self.get_mut(index).unwrap() - } -} - -impl> IntoIterator for SparseChunk { - type Item = A; - type IntoIter = Drain; - - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.drain() - } -} - -pub struct Iter<'a, A: 'a, N: 'a + Bits + ChunkLength> { - indices: BitmapIter, - chunk: &'a SparseChunk, -} - -impl<'a, A, N: Bits + ChunkLength> Iterator for Iter<'a, A, N> { - type Item = &'a A; - - fn next(&mut self) -> Option { - self.indices.next().map(|index| &self.chunk.values()[index]) - } -} - -pub struct IterMut<'a, A: 'a, N: 'a + Bits + ChunkLength> { - indices: BitmapIter, - chunk: &'a mut SparseChunk, -} - -impl<'a, A, N: Bits + ChunkLength> Iterator for IterMut<'a, A, N> { - type Item = &'a mut A; - - fn next(&mut self) -> Option { - if let Some(index) = self.indices.next() { - unsafe { - let p: *mut A = &mut self.chunk.values_mut()[index]; - Some(&mut *p) - } - } else { - None - } - } -} - -pub struct Drain> { - chunk: SparseChunk, -} - -impl<'a, A, N: Bits + ChunkLength> Iterator for Drain { - type Item = A; - - fn next(&mut self) -> Option { - self.chunk.pop() - } -} - -#[cfg(test)] -mod test { - use super::*; - use typenum::U32; - - #[test] - fn insert_remove_iterate() { - let mut chunk: SparseChunk<_, U32> = SparseChunk::new(); - assert_eq!(None, chunk.insert(5, 5)); - assert_eq!(None, chunk.insert(1, 1)); - assert_eq!(None, chunk.insert(24, 42)); - assert_eq!(None, chunk.insert(22, 22)); - assert_eq!(Some(42), chunk.insert(24, 24)); - assert_eq!(None, chunk.insert(31, 31)); - assert_eq!(Some(24), chunk.remove(24)); - assert_eq!(4, chunk.len()); - let indices: Vec<_> = chunk.indices().collect(); - assert_eq!(vec![1, 5, 22, 31], indices); - let values: Vec<_> = chunk.into_iter().collect(); - assert_eq!(vec![1, 5, 22, 31], values); - } - - #[test] - fn clone_chunk() { - let mut chunk: SparseChunk<_, U32> = SparseChunk::new(); - assert_eq!(None, chunk.insert(5, 5)); - assert_eq!(None, chunk.insert(1, 1)); - assert_eq!(None, chunk.insert(24, 42)); - assert_eq!(None, chunk.insert(22, 22)); - let cloned = chunk.clone(); - let right_indices: Vec<_> = chunk.indices().collect(); - let left_indices: Vec<_> = cloned.indices().collect(); - let right: Vec<_> = chunk.into_iter().collect(); - let left: Vec<_> = cloned.into_iter().collect(); - assert_eq!(left, right); - assert_eq!(left_indices, right_indices); - assert_eq!(vec![1, 5, 22, 24], left_indices); - assert_eq!(vec![1, 5, 22, 24], right_indices); - } -} diff -Nru cargo-0.33.0/vendor/im-rc/src/ord/map.rs cargo-0.35.0/vendor/im-rc/src/ord/map.rs --- cargo-0.33.0/vendor/im-rc/src/ord/map.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/ord/map.rs 2019-05-15 11:26:24.000000000 +0000 @@ -26,13 +26,13 @@ use std::mem; use std::ops::{Add, Index, IndexMut, RangeBounds}; -use hashmap::HashMap; -use nodes::btree::{BTreeValue, Insert, Node, Remove}; +use crate::hashmap::HashMap; +use crate::nodes::btree::{BTreeValue, Insert, Node, Remove}; #[cfg(has_specialisation)] -use util::linear_search_by; -use util::Ref; +use crate::util::linear_search_by; +use crate::util::Ref; -pub use nodes::btree::{ConsumingIter, DiffItem, DiffIter, Iter as RangedIter}; +pub use crate::nodes::btree::{ConsumingIter, DiffItem, DiffIter, Iter as RangedIter}; /// Construct a map from a sequence of key/value pairs. /// @@ -66,7 +66,7 @@ } #[cfg(not(has_specialisation))] -impl BTreeValue for (K, V) { +impl BTreeValue for (K, V) { type Key = K; fn ptr_eq(&self, _other: &Self) -> bool { @@ -99,7 +99,7 @@ } #[cfg(has_specialisation)] -impl BTreeValue for (K, V) { +impl BTreeValue for (K, V) { type Key = K; fn ptr_eq(&self, _other: &Self) -> bool { @@ -132,7 +132,7 @@ } #[cfg(has_specialisation)] -impl BTreeValue for (K, V) { +impl BTreeValue for (K, V) { fn search_key(slice: &[Self], key: &BK) -> Result where BK: Ord + ?Sized, @@ -164,11 +164,7 @@ root: Ref>, } -impl OrdMap -where - K: Ord + Clone, - V: Clone, -{ +impl OrdMap { /// Construct an empty map. #[must_use] pub fn new() -> Self { @@ -261,6 +257,36 @@ self.size } + /// Discard all elements from the map. + /// + /// This leaves you with an empty map, and all elements that + /// were previously inside it are dropped. + /// + /// Time: O(n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::OrdMap; + /// # fn main() { + /// let mut map = ordmap![1=>1, 2=>2, 3=>3]; + /// map.clear(); + /// assert!(map.is_empty()); + /// # } + /// ``` + pub fn clear(&mut self) { + if !self.is_empty() { + self.root = Default::default(); + self.size = 0; + } + } +} + +impl OrdMap +where + K: Ord, +{ /// Get the largest key in a map, along with its value. If the map /// is empty, return `None`. /// @@ -380,16 +406,6 @@ self.root.lookup(key).map(|(_, v)| v) } - #[must_use] - fn get_mut(&mut self, key: &BK) -> Option<&mut V> - where - BK: Ord + ?Sized, - K: Borrow, - { - let root = Ref::make_mut(&mut self.root); - root.lookup_mut(key).map(|(_, v)| v) - } - /// Test for the presence of a key in a map. /// /// Time: O(log n) @@ -418,6 +434,113 @@ self.get(k).is_some() } + /// Test whether a map is a submap of another map, meaning that + /// all keys in our map must also be in the other map, with the + /// same values. + /// + /// Use the provided function to decide whether values are equal. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_submap_by(&self, other: RM, mut cmp: F) -> bool + where + F: FnMut(&V, &B) -> bool, + RM: Borrow>, + { + self.iter() + .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false)) + } + + /// Test whether a map is a proper submap of another map, meaning + /// that all keys in our map must also be in the other map, with + /// the same values. To be a proper submap, ours must also contain + /// fewer keys than the other map. + /// + /// Use the provided function to decide whether values are equal. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_proper_submap_by(&self, other: RM, cmp: F) -> bool + where + F: FnMut(&V, &B) -> bool, + RM: Borrow>, + { + self.len() != other.borrow().len() && self.is_submap_by(other, cmp) + } + + /// Test whether a map is a submap of another map, meaning that + /// all keys in our map must also be in the other map, with the + /// same values. + /// + /// Time: O(n log n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::ordmap::OrdMap; + /// # fn main() { + /// let map1 = ordmap!{1 => 1, 2 => 2}; + /// let map2 = ordmap!{1 => 1, 2 => 2, 3 => 3}; + /// assert!(map1.is_submap(map2)); + /// # } + /// ``` + #[must_use] + pub fn is_submap(&self, other: RM) -> bool + where + V: PartialEq, + RM: Borrow, + { + self.is_submap_by(other.borrow(), PartialEq::eq) + } + + /// Test whether a map is a proper submap of another map, meaning + /// that all keys in our map must also be in the other map, with + /// the same values. To be a proper submap, ours must also contain + /// fewer keys than the other map. + /// + /// Time: O(n log n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::ordmap::OrdMap; + /// # fn main() { + /// let map1 = ordmap!{1 => 1, 2 => 2}; + /// let map2 = ordmap!{1 => 1, 2 => 2, 3 => 3}; + /// assert!(map1.is_proper_submap(map2)); + /// + /// let map3 = ordmap!{1 => 1, 2 => 2}; + /// let map4 = ordmap!{1 => 1, 2 => 2}; + /// assert!(!map3.is_proper_submap(map4)); + /// # } + /// ``` + #[must_use] + pub fn is_proper_submap(&self, other: RM) -> bool + where + V: PartialEq, + RM: Borrow, + { + self.is_proper_submap_by(other.borrow(), PartialEq::eq) + } +} + +impl OrdMap +where + K: Ord + Clone, + V: Clone, +{ + #[must_use] + fn get_mut(&mut self, key: &BK) -> Option<&mut V> + where + BK: Ord + ?Sized, + K: Borrow, + { + let root = Ref::make_mut(&mut self.root); + root.lookup_mut(key).map(|(_, v)| v) + } + /// Insert a key/value mapping into a map. /// /// This is a copy-on-write operation, so that the parts of the @@ -519,31 +642,6 @@ removed_value } - /// Discard all elements from the map. - /// - /// This leaves you with an empty map, and all elements that - /// were previously inside it are dropped. - /// - /// Time: O(n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::OrdMap; - /// # fn main() { - /// let mut map = ordmap![1=>1, 2=>2, 3=>3]; - /// map.clear(); - /// assert!(map.is_empty()); - /// # } - /// ``` - pub fn clear(&mut self) { - if !self.is_empty() { - self.root = Default::default(); - self.size = 0; - } - } - /// Construct a new map by inserting a key/value mapping into a /// map. /// @@ -812,7 +910,7 @@ where I: IntoIterator, { - i.into_iter().fold(Self::default(), |a, b| a.union(b)) + i.into_iter().fold(Self::default(), Self::union) } /// Construct the union of a sequence of maps, using a function to @@ -1014,99 +1112,6 @@ out } - /// Test whether a map is a submap of another map, meaning that - /// all keys in our map must also be in the other map, with the - /// same values. - /// - /// Use the provided function to decide whether values are equal. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_submap_by(&self, other: RM, mut cmp: F) -> bool - where - B: Clone, - F: FnMut(&V, &B) -> bool, - RM: Borrow>, - { - self.iter() - .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false)) - } - - /// Test whether a map is a proper submap of another map, meaning - /// that all keys in our map must also be in the other map, with - /// the same values. To be a proper submap, ours must also contain - /// fewer keys than the other map. - /// - /// Use the provided function to decide whether values are equal. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_proper_submap_by(&self, other: RM, cmp: F) -> bool - where - B: Clone, - F: FnMut(&V, &B) -> bool, - RM: Borrow>, - { - self.len() != other.borrow().len() && self.is_submap_by(other, cmp) - } - - /// Test whether a map is a submap of another map, meaning that - /// all keys in our map must also be in the other map, with the - /// same values. - /// - /// Time: O(n log n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::ordmap::OrdMap; - /// # fn main() { - /// let map1 = ordmap!{1 => 1, 2 => 2}; - /// let map2 = ordmap!{1 => 1, 2 => 2, 3 => 3}; - /// assert!(map1.is_submap(map2)); - /// # } - /// ``` - #[must_use] - pub fn is_submap(&self, other: RM) -> bool - where - V: PartialEq, - RM: Borrow, - { - self.is_submap_by(other.borrow(), PartialEq::eq) - } - - /// Test whether a map is a proper submap of another map, meaning - /// that all keys in our map must also be in the other map, with - /// the same values. To be a proper submap, ours must also contain - /// fewer keys than the other map. - /// - /// Time: O(n log n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::ordmap::OrdMap; - /// # fn main() { - /// let map1 = ordmap!{1 => 1, 2 => 2}; - /// let map2 = ordmap!{1 => 1, 2 => 2, 3 => 3}; - /// assert!(map1.is_proper_submap(map2)); - /// - /// let map3 = ordmap!{1 => 1, 2 => 2}; - /// let map4 = ordmap!{1 => 1, 2 => 2}; - /// assert!(!map3.is_proper_submap(map4)); - /// # } - /// ``` - #[must_use] - pub fn is_proper_submap(&self, other: RM) -> bool - where - V: PartialEq, - RM: Borrow, - { - self.is_proper_submap_by(other.borrow(), PartialEq::eq) - } - /// Split a map into two, with the left hand map containing keys /// which are smaller than `split`, and the right hand map /// containing keys which are larger than `split`. @@ -1389,8 +1394,8 @@ #[cfg(not(has_specialisation))] impl PartialEq for OrdMap where - K: Ord + PartialEq + Clone, - V: PartialEq + Clone, + K: Ord + PartialEq, + V: PartialEq, { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.diff(other).next().is_none() @@ -1400,8 +1405,8 @@ #[cfg(has_specialisation)] impl PartialEq for OrdMap where - K: Ord + Clone + PartialEq, - V: Clone + PartialEq, + K: Ord + PartialEq, + V: PartialEq, { default fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.diff(other).next().is_none() @@ -1411,8 +1416,8 @@ #[cfg(has_specialisation)] impl PartialEq for OrdMap where - K: Ord + Eq + Clone, - V: Eq + Clone, + K: Ord + Eq, + V: Eq, { fn eq(&self, other: &Self) -> bool { Ref::ptr_eq(&self.root, &other.root) @@ -1420,12 +1425,12 @@ } } -impl Eq for OrdMap {} +impl Eq for OrdMap {} impl PartialOrd for OrdMap where - K: Ord + Clone, - V: PartialOrd + Clone, + K: Ord, + V: PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { self.iter().partial_cmp(other.iter()) @@ -1434,8 +1439,8 @@ impl Ord for OrdMap where - K: Ord + Clone, - V: Ord + Clone, + K: Ord, + V: Ord, { fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other.iter()) @@ -1444,8 +1449,8 @@ impl Hash for OrdMap where - K: Ord + Clone + Hash, - V: Clone + Hash, + K: Ord + Hash, + V: Hash, { fn hash(&self, state: &mut H) where @@ -1457,11 +1462,7 @@ } } -impl Default for OrdMap -where - K: Ord + Clone, - V: Clone, -{ +impl Default for OrdMap { fn default() -> Self { Self::new() } @@ -1522,8 +1523,7 @@ impl<'a, BK, K, V> Index<&'a BK> for OrdMap where BK: Ord + ?Sized, - K: Ord + Clone + Borrow, - V: Clone, + K: Ord + Borrow, { type Output = V; @@ -1552,8 +1552,8 @@ impl Debug for OrdMap where - K: Ord + Clone + Debug, - V: Clone + Debug, + K: Ord + Debug, + V: Debug, { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { let mut d = f.debug_map(); @@ -1602,8 +1602,8 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { type Item = &'a K; @@ -1621,8 +1621,8 @@ impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { fn next_back(&mut self) -> Option { match self.it.next_back() { @@ -1634,8 +1634,8 @@ impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { } @@ -1645,8 +1645,8 @@ impl<'a, K, V> Iterator for Values<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { type Item = &'a V; @@ -1664,8 +1664,8 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { fn next_back(&mut self) -> Option { match self.it.next_back() { @@ -1677,8 +1677,8 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> where - K: 'a + Ord + Clone, - V: 'a + Clone, + K: 'a + Ord, + V: 'a, { } @@ -1701,8 +1701,7 @@ impl<'a, K, V> IntoIterator for &'a OrdMap where - K: Ord + Clone, - V: Clone, + K: Ord, { type Item = &'a (K, V); type IntoIter = Iter<'a, (K, V)>; @@ -1872,7 +1871,7 @@ #[cfg(any(test, feature = "proptest"))] pub mod proptest { use super::*; - use proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; + use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; use std::ops::Range; /// A strategy for a map of a given size. @@ -1912,11 +1911,10 @@ mod test { use super::proptest::*; use super::*; - use nodes::btree::DiffItem; - use proptest::bool; - use proptest::collection; - use proptest::num::{i16, usize}; - use test::is_sorted; + use crate::nodes::btree::DiffItem; + use crate::test::is_sorted; + use ::proptest::num::{i16, usize}; + use ::proptest::{bool, collection, proptest}; #[test] fn iterates_in_order() { @@ -2009,8 +2007,8 @@ let p1 = Vec::::new(); let p2 = Vec::::new(); assert_eq!(p1, p2); - let c1 = OrdMap::singleton(v1, p1); - let c2 = OrdMap::singleton(v2, p2); + let c1 = OrdMap::unit(v1, p1); + let c2 = OrdMap::unit(v2, p2); assert_eq!(c1, c2); } @@ -2018,7 +2016,7 @@ fn insert_remove_single_mut() { let mut m = OrdMap::new(); m.insert(0, 0); - assert_eq!(OrdMap::singleton(0, 0), m); + assert_eq!(OrdMap::unit(0, 0), m); m.remove(&0); assert_eq!(OrdMap::new(), m); } diff -Nru cargo-0.33.0/vendor/im-rc/src/ord/set.rs cargo-0.35.0/vendor/im-rc/src/ord/set.rs --- cargo-0.33.0/vendor/im-rc/src/ord/set.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/ord/set.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,16 +25,16 @@ use std::iter::{FromIterator, IntoIterator, Sum}; use std::ops::{Add, Deref, Mul, RangeBounds}; -use hashset::HashSet; -use nodes::btree::{ - BTreeValue, ConsumingIter as ConsumingNodeIter, DiffItem as NodeDiffItem, - DiffIter as NodeDiffIter, Insert, Iter as NodeIter, Node, Remove, +use crate::hashset::HashSet; +use crate::nodes::btree::{ + BTreeValue, ConsumingIter as ConsumingNodeIter, DiffIter as NodeDiffIter, Insert, + Iter as NodeIter, Node, Remove, }; #[cfg(has_specialisation)] -use util::linear_search_by; -use util::Ref; +use crate::util::linear_search_by; +use crate::util::Ref; -pub type DiffItem<'a, A> = NodeDiffItem<'a, A>; +pub use crate::nodes::btree::DiffItem; /// Construct a set from a sequence of values. /// @@ -76,7 +76,7 @@ // FIXME lacking specialisation, we can't simply implement `BTreeValue` // for `A`, we have to use the `Value` indirection. #[cfg(not(has_specialisation))] -impl BTreeValue for Value { +impl BTreeValue for Value { type Key = A; fn ptr_eq(&self, _other: &Self) -> bool { @@ -109,7 +109,7 @@ } #[cfg(has_specialisation)] -impl BTreeValue for Value { +impl BTreeValue for Value { type Key = A; fn ptr_eq(&self, _other: &Self) -> bool { @@ -142,7 +142,7 @@ } #[cfg(has_specialisation)] -impl BTreeValue for Value { +impl BTreeValue for Value { fn search_key(slice: &[Self], key: &BK) -> Result where BK: Ord + ?Sized, @@ -175,10 +175,7 @@ root: Ref>>, } -impl OrdSet -where - A: Ord + Clone, -{ +impl OrdSet { /// Construct an empty set. #[must_use] pub fn new() -> Self { @@ -264,6 +261,36 @@ self.size } + /// Discard all elements from the set. + /// + /// This leaves you with an empty set, and all elements that + /// were previously inside it are dropped. + /// + /// Time: O(n) + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::OrdSet; + /// # fn main() { + /// let mut set = ordset![1, 2, 3]; + /// set.clear(); + /// assert!(set.is_empty()); + /// # } + /// ``` + pub fn clear(&mut self) { + if !self.is_empty() { + self.root = Default::default(); + self.size = 0; + } + } +} + +impl OrdSet +where + A: Ord, +{ /// Get the smallest value in a set. /// /// If the set is empty, returns `None`. @@ -344,6 +371,37 @@ self.root.lookup(a).is_some() } + /// Test whether a set is a subset of another set, meaning that + /// all values in our set must also be in the other set. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_subset(&self, other: RS) -> bool + where + RS: Borrow, + { + let o = other.borrow(); + self.iter().all(|a| o.contains(&a)) + } + + /// Test whether a set is a proper subset of another set, meaning + /// that all values in our set must also be in the other set. A + /// proper subset must also be smaller than the other set. + /// + /// Time: O(n log n) + #[must_use] + pub fn is_proper_subset(&self, other: RS) -> bool + where + RS: Borrow, + { + self.len() != other.borrow().len() && self.is_subset(other) + } +} + +impl OrdSet +where + A: Ord + Clone, +{ /// Insert a value into a set. /// /// Time: O(log n) @@ -435,31 +493,6 @@ self.remove(&key) } - /// Discard all elements from the set. - /// - /// This leaves you with an empty set, and all elements that - /// were previously inside it are dropped. - /// - /// Time: O(n) - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::OrdSet; - /// # fn main() { - /// let mut set = ordset![1, 2, 3]; - /// set.clear(); - /// assert!(set.is_empty()); - /// # } - /// ``` - pub fn clear(&mut self) { - if !self.is_empty() { - self.root = Default::default(); - self.size = 0; - } - } - /// Construct a new set from the current set with the given value /// added. /// @@ -556,7 +589,7 @@ where I: IntoIterator, { - i.into_iter().fold(Self::default(), |a, b| a.union(b)) + i.into_iter().fold(Self::default(), Self::union) } /// Construct the difference between two sets. @@ -612,32 +645,6 @@ out } - /// Test whether a set is a subset of another set, meaning that - /// all values in our set must also be in the other set. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_subset(&self, other: RS) -> bool - where - RS: Borrow, - { - let o = other.borrow(); - self.iter().all(|a| o.contains(&a)) - } - - /// Test whether a set is a proper subset of another set, meaning - /// that all values in our set must also be in the other set. A - /// proper subset must also be smaller than the other set. - /// - /// Time: O(n log n) - #[must_use] - pub fn is_proper_subset(&self, other: RS) -> bool - where - RS: Borrow, - { - self.len() != other.borrow().len() && self.is_subset(other) - } - /// Split a set into two, with the left hand set containing values /// which are smaller than `split`, and the right hand set /// containing values which are larger than `split`. @@ -719,28 +726,28 @@ } } -impl PartialEq for OrdSet { +impl PartialEq for OrdSet { fn eq(&self, other: &Self) -> bool { Ref::ptr_eq(&self.root, &other.root) || (self.len() == other.len() && self.diff(other).next().is_none()) } } -impl Eq for OrdSet {} +impl Eq for OrdSet {} -impl PartialOrd for OrdSet { +impl PartialOrd for OrdSet { fn partial_cmp(&self, other: &Self) -> Option { self.iter().partial_cmp(other.iter()) } } -impl Ord for OrdSet { +impl Ord for OrdSet { fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other.iter()) } } -impl Hash for OrdSet { +impl Hash for OrdSet { fn hash(&self, state: &mut H) where H: Hasher, @@ -751,10 +758,7 @@ } } -impl Default for OrdSet -where - A: Ord + Clone, -{ +impl Default for OrdSet { fn default() -> Self { OrdSet::new() } @@ -815,7 +819,7 @@ } } -impl Debug for OrdSet { +impl Debug for OrdSet { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { f.debug_set().entries(self.iter()).finish() } @@ -833,7 +837,7 @@ impl<'a, A> Iterator for Iter<'a, A> where - A: 'a + Ord + Clone, + A: 'a + Ord, { type Item = &'a A; @@ -848,14 +852,14 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> where - A: 'a + Ord + Clone, + A: 'a + Ord, { fn next_back(&mut self) -> Option { self.it.next_back().map(Deref::deref) } } -impl<'a, A> ExactSizeIterator for Iter<'a, A> where A: 'a + Ord + Clone {} +impl<'a, A> ExactSizeIterator for Iter<'a, A> where A: 'a + Ord {} // A ranged iterator over the elements of a set. // @@ -871,7 +875,7 @@ impl<'a, A> Iterator for RangedIter<'a, A> where - A: 'a + Ord + Clone, + A: 'a + Ord, { type Item = &'a A; @@ -886,7 +890,7 @@ impl<'a, A> DoubleEndedIterator for RangedIter<'a, A> where - A: 'a + Ord + Clone, + A: 'a + Ord, { fn next_back(&mut self) -> Option { self.it.next_back().map(Deref::deref) @@ -916,18 +920,18 @@ impl<'a, A> Iterator for DiffIter<'a, A> where - A: 'a + Ord + Clone + PartialEq, + A: 'a + Ord + PartialEq, { type Item = DiffItem<'a, A>; fn next(&mut self) -> Option { self.it.next().map(|item| match item { - NodeDiffItem::Add(v) => NodeDiffItem::Add(v.deref()), - NodeDiffItem::Update { old, new } => NodeDiffItem::Update { + DiffItem::Add(v) => DiffItem::Add(v.deref()), + DiffItem::Update { old, new } => DiffItem::Update { old: old.deref(), new: new.deref(), }, - NodeDiffItem::Remove(v) => NodeDiffItem::Remove(v.deref()), + DiffItem::Remove(v) => DiffItem::Remove(v.deref()), }) } } @@ -950,7 +954,7 @@ impl<'a, A> IntoIterator for &'a OrdSet where - A: 'a + Ord + Clone, + A: 'a + Ord, { type Item = &'a A; type IntoIter = Iter<'a, A>; @@ -1060,7 +1064,7 @@ #[cfg(any(test, feature = "proptest"))] pub mod proptest { use super::*; - use proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; + use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; use std::ops::Range; /// A strategy for a set of a given size. @@ -1096,6 +1100,7 @@ mod test { use super::proptest::*; use super::*; + use ::proptest::proptest; #[test] fn match_strings_with_string_slices() { diff -Nru cargo-0.33.0/vendor/im-rc/src/ser.rs cargo-0.35.0/vendor/im-rc/src/ser.rs --- cargo-0.33.0/vendor/im-rc/src/ser.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/ser.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,11 +9,11 @@ use std::marker::PhantomData; use std::ops::Deref; -use hashmap::HashMap; -use hashset::HashSet; -use ordmap::OrdMap; -use ordset::OrdSet; -use vector::Vector; +use crate::hashmap::HashMap; +use crate::hashset::HashSet; +use crate::ordmap::OrdMap; +use crate::ordset::OrdSet; +use crate::vector::Vector; struct SeqVisitor<'de, S, A> where @@ -259,13 +259,14 @@ #[cfg(test)] mod test { use super::*; - use hashmap::proptest::hash_map; - use hashset::proptest::hash_set; - use ordmap::proptest::ord_map; - use ordset::proptest::ord_set; - use proptest::num::i32; + use crate::hashmap::proptest::hash_map; + use crate::hashset::proptest::hash_set; + use crate::ordmap::proptest::ord_map; + use crate::ordset::proptest::ord_set; + use crate::vector::proptest::vector; + use ::proptest::num::i32; + use ::proptest::proptest; use serde_json::{from_str, to_string}; - use vector::proptest::vector; proptest! { #[test] diff -Nru cargo-0.33.0/vendor/im-rc/src/sort.rs cargo-0.35.0/vendor/im-rc/src/sort.rs --- cargo-0.33.0/vendor/im-rc/src/sort.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/sort.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,8 +2,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +use crate::vector::FocusMut; use std::cmp::Ordering; -use vector::FocusMut; // Ported from the Java version at: // http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf @@ -73,9 +73,10 @@ #[cfg(test)] mod test { use super::*; - use proptest::num::i32; - use test::is_sorted; - use vector::proptest::vector; + use crate::test::is_sorted; + use crate::vector::proptest::vector; + use ::proptest::num::i32; + use ::proptest::proptest; proptest! { #[test] diff -Nru cargo-0.33.0/vendor/im-rc/src/tests/hashset.rs cargo-0.35.0/vendor/im-rc/src/tests/hashset.rs --- cargo-0.33.0/vendor/im-rc/src/tests/hashset.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/tests/hashset.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,85 @@ +#![allow(clippy::unit_arg)] + +use std::collections::HashSet as NatSet; +use std::fmt::{Debug, Error, Formatter, Write}; +use std::hash::Hash; + +use crate::HashSet; + +use proptest::proptest; +use proptest_derive::Arbitrary; + +#[derive(Arbitrary, Debug)] +enum Action { + Insert(A), + Remove(A), +} + +#[derive(Arbitrary)] +struct Actions(Vec>) +where + A: Hash + Eq + Clone; + +impl Debug for Actions +where + A: Hash + Eq + Debug + Clone, +{ + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + let mut out = String::new(); + let mut expected = NatSet::new(); + writeln!(out, "let mut set = HashSet::new();")?; + for action in &self.0 { + match action { + Action::Insert(ref value) => { + expected.insert(value.clone()); + writeln!(out, "set.insert({:?});", value)?; + } + Action::Remove(ref value) => { + expected.remove(value); + writeln!(out, "set.remove({:?});", value)?; + } + } + } + writeln!( + out, + "let expected = vec!{:?};", + expected.into_iter().collect::>() + )?; + writeln!(out, "assert_eq!(HashSet::from(expected), set);")?; + write!(f, "{}", super::code_fmt(&out)) + } +} + +proptest! { + #[test] + fn comprehensive(actions: Actions) { + let mut set = HashSet::new(); + let mut nat = NatSet::new(); + for action in actions.0 { + match action { + Action::Insert(value) => { + let len = nat.len() + if nat.contains(&value) { + 0 + } else { + 1 + }; + nat.insert(value); + set.insert(value); + assert_eq!(len, set.len()); + } + Action::Remove(value) => { + let len = nat.len() - if nat.contains(&value) { + 1 + } else { + 0 + }; + nat.remove(&value); + set.remove(&value); + assert_eq!(len, set.len()); + } + } + assert_eq!(nat.len(), set.len()); + assert_eq!(HashSet::from(nat.clone()), set); + } + } +} diff -Nru cargo-0.33.0/vendor/im-rc/src/tests/mod.rs cargo-0.35.0/vendor/im-rc/src/tests/mod.rs --- cargo-0.33.0/vendor/im-rc/src/tests/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/tests/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,23 @@ +mod hashset; +mod ordset; +mod vector; + +fn code_fmt(code: &str) -> String { + use syntect::easy::HighlightLines; + use syntect::highlighting::{Style, ThemeSet}; + use syntect::parsing::SyntaxSet; + use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings}; + + let ps = SyntaxSet::load_defaults_newlines(); + let ts = ThemeSet::load_defaults(); + let syntax = ps.find_syntax_by_extension("rs").unwrap(); + let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]); + let mut out = String::from("\n\n"); + for line in LinesWithEndings::from(&code) { + let ranges: Vec<(Style, &str)> = h.highlight(line, &ps); + let escaped = as_24_bit_terminal_escaped(&ranges[..], false); + out += &escaped; + } + out += "\n\x1b[0m"; + out +} diff -Nru cargo-0.33.0/vendor/im-rc/src/tests/ordset.rs cargo-0.35.0/vendor/im-rc/src/tests/ordset.rs --- cargo-0.33.0/vendor/im-rc/src/tests/ordset.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/tests/ordset.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,85 @@ +#![allow(clippy::unit_arg)] + +use std::collections::BTreeSet; +use std::fmt::{Debug, Error, Formatter, Write}; + +use crate::OrdSet; + +use proptest::proptest; +use proptest_derive::Arbitrary; + +#[derive(Arbitrary, Debug)] +enum Action { + Insert(A), + Remove(A), +} + +#[derive(Arbitrary)] +struct Actions(Vec>) +where + A: Ord + Clone; + +impl Debug for Actions +where + A: Ord + Debug + Clone, +{ + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + let mut out = String::new(); + let mut expected = BTreeSet::new(); + writeln!(out, "let mut set = OrdSet::new();")?; + for action in &self.0 { + match action { + Action::Insert(ref value) => { + expected.insert(value.clone()); + writeln!(out, "set.insert({:?});", value)?; + } + Action::Remove(ref value) => { + expected.remove(value); + writeln!(out, "set.remove({:?});", value)?; + } + } + } + writeln!( + out, + "let expected = vec!{:?};", + expected.into_iter().collect::>() + )?; + writeln!(out, "assert_eq!(OrdSet::from(expected), set);")?; + write!(f, "{}", super::code_fmt(&out)) + } +} + +proptest! { + #[test] + fn comprehensive(actions: Actions) { + let mut set = OrdSet::new(); + let mut nat = BTreeSet::new(); + for action in actions.0 { + match action { + Action::Insert(value) => { + let len = nat.len() + if nat.contains(&value) { + 0 + } else { + 1 + }; + nat.insert(value); + set.insert(value); + assert_eq!(len, set.len()); + } + Action::Remove(value) => { + let len = nat.len() - if nat.contains(&value) { + 1 + } else { + 0 + }; + nat.remove(&value); + set.remove(&value); + assert_eq!(len, set.len()); + } + } + assert_eq!(nat.len(), set.len()); + assert_eq!(OrdSet::from(nat.clone()), set); + assert!(nat.iter().eq(set.iter())); + } + } +} diff -Nru cargo-0.33.0/vendor/im-rc/src/tests/vector.rs cargo-0.35.0/vendor/im-rc/src/tests/vector.rs --- cargo-0.33.0/vendor/im-rc/src/tests/vector.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/tests/vector.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,219 @@ +#![allow(clippy::unit_arg)] + +use std::fmt::{Debug, Error, Formatter, Write}; +use std::iter::FromIterator; + +use crate::Vector; + +use proptest::proptest; +use proptest_derive::Arbitrary; + +#[derive(Arbitrary, Debug)] +enum Action { + PushFront(A), + PushBack(A), + PopFront, + PopBack, + Insert(usize, A), + Remove(usize), + JoinLeft(Vec), + JoinRight(Vec), + SplitLeft(usize), + SplitRight(usize), +} + +#[derive(Arbitrary)] +struct Actions(Vec>) +where + A: Clone; + +impl Debug for Actions +where + A: Debug + Clone, +{ + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + let mut out = String::new(); + let mut expected = vec![]; + writeln!(out, "let mut vec = Vector::new();")?; + for action in &self.0 { + match action { + Action::PushFront(ref value) => { + expected.insert(0, value.clone()); + writeln!(out, "vec.push_front({:?});", value)? + } + Action::PushBack(ref value) => { + expected.push(value.clone()); + writeln!(out, "vec.push_back({:?});", value)? + } + Action::PopFront => { + if !expected.is_empty() { + expected.remove(0); + } + writeln!(out, "vec.pop_front();")? + } + Action::PopBack => { + expected.pop(); + writeln!(out, "vec.pop_back();")? + } + Action::Insert(ref index, ref value) => { + let index = cap_index(expected.len(), *index); + expected.insert(index, value.clone()); + writeln!(out, "vec.insert({:?}, {:?});", index, value)? + } + Action::Remove(ref index) => { + if !expected.is_empty() { + let index = cap_index(expected.len(), *index); + expected.remove(index); + writeln!(out, "vec.remove({:?})", index)? + } else { + continue; + } + } + Action::JoinLeft(ref vec) => { + let mut vec_new = vec.clone(); + vec_new.append(&mut expected); + expected = vec_new; + writeln!( + out, + "let mut vec_new = Vector::from(vec!{:?}); // size {:?}", + vec, + vec.len() + )?; + writeln!(out, "vec_new.append(vec);")?; + writeln!(out, "vec = vec_new;")? + } + Action::JoinRight(ref vec) => { + expected.append(&mut vec.clone()); + writeln!( + out, + "vec.append(Vector::from(vec!{:?})); // size {:?}", + vec, + vec.len() + )? + } + Action::SplitLeft(ref index) => { + let index = cap_index(expected.len(), *index); + expected.split_off(index); + writeln!(out, "vec.split_off({:?});", index)? + } + Action::SplitRight(ref index) => { + let index = cap_index(expected.len(), *index); + expected = expected.split_off(index); + writeln!(out, "vec = vec.split_off({:?});", index)? + } + } + writeln!(out, "// len = {:?}", expected.len())?; + } + writeln!(out, "let expected = vec!{:?};", expected)?; + writeln!(out, "assert_eq!(Vector::from(expected), vec);")?; + write!(f, "{}", super::code_fmt(&out)) + } +} + +fn cap_index(len: usize, index: usize) -> usize { + if len == 0 { + 0 + } else { + index % len + } +} + +proptest! { + #[test] + fn comprehensive(actions: Actions) { + let mut vec = Vector::new(); + let mut nat = Vec::new(); + vec.assert_invariants(); + for action in actions.0 { + match action { + Action::PushFront(value) => { + let len = vec.len(); + nat.insert(0, value); + vec.push_front(value); + assert_eq!(len + 1, vec.len()); + } + Action::PushBack(value) => { + let len = vec.len(); + nat.push(value); + vec.push_back(value); + assert_eq!(len + 1, vec.len()); + } + Action::PopFront => { + if vec.is_empty() { + assert_eq!(None, vec.pop_front()); + } else { + let len = vec.len(); + assert_eq!(nat.remove(0), vec.pop_front().unwrap()); + assert_eq!(len - 1, vec.len()); + } + } + Action::PopBack => { + if vec.is_empty() { + assert_eq!(None, vec.pop_back()); + } else { + let len = vec.len(); + assert_eq!(nat.pop(), vec.pop_back()); + assert_eq!(len - 1, vec.len()); + } + } + Action::Insert(index, value) => { + let index = cap_index(vec.len(), index); + let len = vec.len(); + nat.insert(index, value); + vec.insert(index, value); + assert_eq!(len + 1, vec.len()); + } + Action::Remove(index) => { + if vec.is_empty() { + continue; + } + let index = cap_index(vec.len(), index); + let len = vec.len(); + assert_eq!(nat.remove(index), vec.remove(index)); + assert_eq!(len - 1, vec.len()); + } + Action::JoinLeft(mut new_nat) => { + let mut new_vec = Vector::from_iter(new_nat.iter().cloned()); + let add_len = new_nat.len(); + let len = vec.len(); + new_vec.append(vec); + vec = new_vec; + new_nat.append(&mut nat); + nat = new_nat; + assert_eq!(len + add_len, vec.len()); + } + Action::JoinRight(mut new_nat) => { + let new_vec = Vector::from_iter(new_nat.iter().cloned()); + let add_len = new_nat.len(); + let len = vec.len(); + vec.append(new_vec); + nat.append(&mut new_nat); + assert_eq!(len + add_len, vec.len()); + } + Action::SplitLeft(index) => { + let index = cap_index(vec.len(), index); + let len = vec.len(); + let vec_right = vec.split_off(index); + let nat_right = nat.split_off(index); + assert_eq!(index, vec.len()); + assert_eq!(len - index, vec_right.len()); + assert_eq!(Vector::from_iter(nat_right.iter().cloned()), vec_right); + } + Action::SplitRight(index) => { + let index = cap_index(vec.len(), index); + let len = vec.len(); + let vec_right = vec.split_off(index); + let nat_right = nat.split_off(index); + assert_eq!(index, vec.len()); + assert_eq!(len - index, vec_right.len()); + assert_eq!(Vector::from_iter(nat.iter().cloned()), vec); + vec = vec_right; + nat = nat_right; + } + } + vec.assert_invariants(); + assert_eq!(nat.len(),vec.len()); + assert_eq!(Vector::from_iter(nat.iter().cloned()), vec); + } + } +} diff -Nru cargo-0.33.0/vendor/im-rc/src/vector/focus.rs cargo-0.35.0/vendor/im-rc/src/vector/focus.rs --- cargo-0.33.0/vendor/im-rc/src/vector/focus.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/vector/focus.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,10 +7,10 @@ use std::ptr::null; use std::sync::atomic::{AtomicPtr, Ordering}; -use nodes::chunk::Chunk; -use sync::Lock; -use util::{to_range, Ref}; -use vector::{Iter, IterMut, Vector, RRB}; +use crate::nodes::chunk::Chunk; +use crate::sync::Lock; +use crate::util::{to_range, Ref}; +use crate::vector::{Iter, IterMut, Vector, RRB}; /// Focused indexing over a [`Vector`][Vector]. /// @@ -86,6 +86,8 @@ A: 'a, { #[doc(hidden)] + Empty, + #[doc(hidden)] Single(&'a [A]), #[doc(hidden)] Full(TreeFocus), @@ -100,6 +102,7 @@ /// [Vector]: enum.Vector.html pub fn new(vector: &'a Vector) -> Self { match vector { + Vector::Empty => Focus::Empty, Vector::Single(chunk) => Focus::Single(chunk), Vector::Full(tree) => Focus::Full(TreeFocus::new(tree)), } @@ -110,6 +113,7 @@ /// [Vector]: enum.Vector.html pub fn len(&self) -> usize { match self { + Focus::Empty => 0, Focus::Single(chunk) => chunk.len(), Focus::Full(tree) => tree.len(), } @@ -125,6 +129,7 @@ /// Get a reference to the value at a given index. pub fn get(&mut self, index: usize) -> Option<&A> { match self { + Focus::Empty => None, Focus::Single(chunk) => chunk.get(index), Focus::Full(tree) => tree.get(index), } @@ -147,6 +152,7 @@ panic!("vector::Focus::chunk_at: index out of bounds"); } match self { + Focus::Empty => (0..0, &[]), Focus::Single(chunk) => (0..len, chunk), Focus::Full(tree) => tree.get_chunk(index), } @@ -184,6 +190,7 @@ panic!("vector::Focus::narrow: range out of bounds"); } match self { + Focus::Empty => Focus::Empty, Focus::Single(chunk) => Focus::Single(&chunk[r]), Focus::Full(tree) => Focus::Full(tree.narrow(r)), } @@ -224,6 +231,7 @@ panic!("vector::Focus::split_at: index out of bounds"); } match self { + Focus::Empty => (Focus::Empty, Focus::Empty), Focus::Single(chunk) => { let (left, right) = chunk.split_at(index); (Focus::Single(left), Focus::Single(right)) @@ -254,6 +262,7 @@ { fn clone(&self) -> Self { match self { + Focus::Empty => Focus::Empty, Focus::Single(chunk) => Focus::Single(chunk), Focus::Full(tree) => Focus::Full(tree.clone()), } @@ -424,12 +433,16 @@ /// # fn main() { /// let mut vec = Vector::from_iter(0..1000); /// let focus1 = vec.focus_mut(); -/// // Fails here because you already have a focus +/// // Fails here in 2015 edition because you're creating +/// // two mutable references to the same thing. /// let focus2 = vec.focus_mut(); +/// // Fails here in 2018 edition because creating focus2 +/// // made focus1's lifetime go out of scope. +/// assert_eq!(Some(&0), focus1.get(0)); /// # } /// ``` /// -/// On the other hand, you can split that one focus into multiple sub-foci, +/// On the other hand, you can split that one focus into multiple sub-focuses, /// which is safe because they can't overlap: /// /// ```rust @@ -439,7 +452,9 @@ /// # fn main() { /// let mut vec = Vector::from_iter(0..1000); /// let focus = vec.focus_mut(); -/// let (left, right) = focus.split_at(500); +/// let (mut left, mut right) = focus.split_at(500); +/// assert_eq!(Some(&0), left.get(0)); +/// assert_eq!(Some(&500), right.get(0)); /// # } /// ``` /// @@ -459,6 +474,7 @@ /// // `left` and `right` are still in scope even if `focus` isn't, so we can't /// // create another focus: /// let focus2 = vec.focus_mut(); +/// assert_eq!(Some(&0), left.get(0)); /// # } /// ``` /// @@ -468,6 +484,8 @@ A: 'a, { #[doc(hidden)] + Empty, + #[doc(hidden)] Single(&'a mut [A]), #[doc(hidden)] Full(TreeFocusMut<'a, A>), @@ -480,6 +498,7 @@ /// Construct a `FocusMut` for a `Vector`. pub fn new(vector: &'a mut Vector) -> Self { match vector { + Vector::Empty => FocusMut::Empty, Vector::Single(chunk) => FocusMut::Single(Ref::make_mut(chunk).as_mut_slice()), Vector::Full(tree) => FocusMut::Full(TreeFocusMut::new(tree)), } @@ -488,6 +507,7 @@ /// Get the length of the focused `Vector`. pub fn len(&self) -> usize { match self { + FocusMut::Empty => 0, FocusMut::Single(chunk) => chunk.len(), FocusMut::Full(tree) => tree.len(), } @@ -506,6 +526,7 @@ /// Get a mutable reference to the value at a given index. pub fn get_mut(&mut self, index: usize) -> Option<&mut A> { match self { + FocusMut::Empty => None, FocusMut::Single(chunk) => chunk.get_mut(index), FocusMut::Full(tree) => tree.get(index), } @@ -624,6 +645,7 @@ panic!("vector::FocusMut::chunk_at: index out of bounds"); } match self { + FocusMut::Empty => (0..0, &mut []), FocusMut::Single(chunk) => (0..len, chunk), FocusMut::Full(tree) => { let (range, chunk) = tree.get_chunk(index); @@ -664,6 +686,7 @@ panic!("vector::FocusMut::narrow: range out of bounds"); } match self { + FocusMut::Empty => FocusMut::Empty, FocusMut::Single(chunk) => FocusMut::Single(&mut chunk[r]), FocusMut::Full(tree) => FocusMut::Full(tree.narrow(r)), } @@ -711,6 +734,7 @@ panic!("vector::FocusMut::split_at: index out of bounds"); } match self { + FocusMut::Empty => (FocusMut::Empty, FocusMut::Empty), FocusMut::Single(chunk) => { let (left, right) = chunk.split_at_mut(index); (FocusMut::Single(left), FocusMut::Single(right)) @@ -725,6 +749,7 @@ /// Convert a `FocusMut` into a `Focus`. pub fn unmut(self) -> Focus<'a, A> { match self { + FocusMut::Empty => Focus::Empty, FocusMut::Single(chunk) => Focus::Single(chunk), FocusMut::Full(mut tree) => Focus::Full(TreeFocus { tree: { diff -Nru cargo-0.33.0/vendor/im-rc/src/vector/mod.rs cargo-0.35.0/vendor/im-rc/src/vector/mod.rs --- cargo-0.33.0/vendor/im-rc/src/vector/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/im-rc/src/vector/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -52,12 +52,14 @@ use std::mem::{replace, swap}; use std::ops::{Add, Index, IndexMut, RangeBounds}; -use nodes::chunk::{Chunk, Iter as ChunkIter, CHUNK_SIZE}; -use nodes::rrb::{ConsumingIter as ConsumingNodeIter, Node, PopResult, PushResult, SplitResult}; -use sort; -use util::{clone_ref, swap_indices, to_range, Ref, Side}; +use crate::nodes::chunk::{Chunk, Iter as ChunkIter, CHUNK_SIZE}; +use crate::nodes::rrb::{ + ConsumingIter as ConsumingNodeIter, Node, PopResult, PushResult, SplitResult, +}; +use crate::sort; +use crate::util::{clone_ref, swap_indices, to_range, Ref, Side}; -use self::Vector::{Full, Single}; +use self::Vector::{Empty, Full, Single}; mod focus; @@ -136,6 +138,8 @@ /// [VecDeque]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html pub enum Vector { #[doc(hidden)] + Empty, + #[doc(hidden)] Single(Ref>), #[doc(hidden)] Full(RRB), @@ -167,18 +171,28 @@ } impl Vector { - /// True if a vector is a full single chunk, ie. must be promoted to grow - /// further. + /// True if a vector is empty or a full single chunk, ie. must be promoted + /// to grow further. fn needs_promotion(&self) -> bool { match self { + Empty => true, Single(chunk) if chunk.is_full() => true, _ => false, } } - /// Promote a single to a full, with the single chunk becomming inner_f. + /// Promote an empty to a single. + fn promote_empty(&mut self) { + if let Empty = self { + *self = Single(Ref::new(Chunk::new())) + } + } + + /// Promote a single to a full, with the single chunk becomming inner_f, or + /// promote an empty to a single. fn promote_front(&mut self) { let chunk = match self { + Empty => return self.promote_empty(), Single(chunk) => chunk.clone(), _ => return, }; @@ -193,9 +207,11 @@ }) } - /// Promote a single to a full, with the single chunk becomming inner_b. + /// Promote a single to a full, with the single chunk becomming inner_b, or + /// promote an empty to a single. fn promote_back(&mut self) { let chunk = match self { + Empty => return self.promote_empty(), Single(chunk) => chunk.clone(), _ => return, }; @@ -213,41 +229,7 @@ /// Construct an empty vector. #[must_use] pub fn new() -> Self { - Single(Ref::new(Chunk::new())) - } - - /// Construct a vector with a single value. - /// - /// This method has been deprecated; use [`unit`][unit] instead. - /// - /// [unit]: #method.unit - #[inline] - #[must_use] - #[deprecated(since = "12.3.0", note = "renamed to `unit` for consistency")] - pub fn singleton(a: A) -> Self { - Self::unit(a) - } - - /// Construct a vector with a single value. - /// - /// # Examples - /// - /// ``` - /// # #[macro_use] extern crate im_rc as im; - /// # use im::vector::Vector; - /// # fn main() { - /// let vec = Vector::unit(1337); - /// assert_eq!(1, vec.len()); - /// assert_eq!( - /// vec.get(0), - /// Some(&1337) - /// ); - /// # } - /// ``` - #[inline] - #[must_use] - pub fn unit(a: A) -> Self { - Single(Ref::new(Chunk::unit(a))) + Empty } /// Get the length of a vector. @@ -266,6 +248,7 @@ #[must_use] pub fn len(&self) -> usize { match self { + Empty => 0, Single(chunk) => chunk.len(), Full(tree) => tree.length, } @@ -420,6 +403,7 @@ } match self { + Empty => None, Single(chunk) => chunk.get(index), Full(tree) => { let mut local_index = index; @@ -478,6 +462,7 @@ } match self { + Empty => None, Single(chunk) => Ref::make_mut(chunk).get_mut(index), Full(tree) => { let mut local_index = index; @@ -653,6 +638,133 @@ self.index_of(value).is_some() } + /// Discard all elements from the vector. + /// + /// This leaves you with an empty vector, and all elements that + /// were previously inside it are dropped. + /// + /// Time: O(n) + pub fn clear(&mut self) { + if !self.is_empty() { + *self = Single(Ref::new(Chunk::new())); + } + } + + /// Binary search a sorted vector for a given element using a comparator + /// function. + /// + /// Assumes the vector has already been sorted using the same comparator + /// function, eg. by using [`sort_by`][sort_by]. + /// + /// If the value is found, it returns `Ok(index)` where `index` is the index + /// of the element. If the value isn't found, it returns `Err(index)` where + /// `index` is the index at which the element would need to be inserted to + /// maintain sorted order. + /// + /// Time: O(log n) + /// + /// [sort_by]: #method.sort_by + #[must_use] + pub fn binary_search_by(&self, mut f: F) -> Result + where + F: FnMut(&A) -> Ordering, + { + let mut size = self.len(); + if size == 0 { + return Err(0); + } + let mut base = 0; + while size > 1 { + let half = size / 2; + let mid = base + half; + base = match f(&self[mid]) { + Ordering::Greater => base, + _ => mid, + }; + size -= half; + } + match f(&self[base]) { + Ordering::Equal => Ok(base), + Ordering::Greater => Err(base), + Ordering::Less => Err(base + 1), + } + } + + /// Binary search a sorted vector for a given element. + /// + /// If the value is found, it returns `Ok(index)` where `index` is the index + /// of the element. If the value isn't found, it returns `Err(index)` where + /// `index` is the index at which the element would need to be inserted to + /// maintain sorted order. + /// + /// Time: O(log n) + #[must_use] + pub fn binary_search(&self, value: &A) -> Result + where + A: Ord, + { + self.binary_search_by(|e| e.cmp(value)) + } + + /// Binary search a sorted vector for a given element with a key extract + /// function. + /// + /// Assumes the vector has already been sorted using the same key extract + /// function, eg. by using [`sort_by_key`][sort_by_key]. + /// + /// If the value is found, it returns `Ok(index)` where `index` is the index + /// of the element. If the value isn't found, it returns `Err(index)` where + /// `index` is the index at which the element would need to be inserted to + /// maintain sorted order. + /// + /// Time: O(log n) + /// + /// [sort_by_key]: #method.sort_by_key + #[must_use] + pub fn binary_search_by_key(&self, b: &B, mut f: F) -> Result + where + F: FnMut(&A) -> B, + B: Ord, + { + self.binary_search_by(|k| f(k).cmp(b)) + } +} + +impl Vector { + /// Construct a vector with a single value. + /// + /// This method has been deprecated; use [`unit`][unit] instead. + /// + /// [unit]: #method.unit + #[inline] + #[must_use] + #[deprecated(since = "12.3.0", note = "renamed to `unit` for consistency")] + pub fn singleton(a: A) -> Self { + Self::unit(a) + } + + /// Construct a vector with a single value. + /// + /// # Examples + /// + /// ``` + /// # #[macro_use] extern crate im_rc as im; + /// # use im::vector::Vector; + /// # fn main() { + /// let vec = Vector::unit(1337); + /// assert_eq!(1, vec.len()); + /// assert_eq!( + /// vec.get(0), + /// Some(&1337) + /// ); + /// # } + /// ``` + #[inline] + #[must_use] + pub fn unit(a: A) -> Self { + Single(Ref::new(Chunk::unit(a))) + } + /// Create a new vector with the value at index `index` updated. /// /// Panics if the index is out of bounds. @@ -715,6 +827,7 @@ self.promote_back(); } match self { + Empty => unreachable!("promote should have promoted the Empty"), Single(chunk) => Ref::make_mut(chunk).push_front(value), Full(tree) => tree.push_front(value), } @@ -740,6 +853,7 @@ self.promote_front(); } match self { + Empty => unreachable!("promote should have promoted the Empty"), Single(chunk) => Ref::make_mut(chunk).push_back(value), Full(tree) => tree.push_back(value), } @@ -765,6 +879,7 @@ None } else { match self { + Empty => None, Single(chunk) => Some(Ref::make_mut(chunk).pop_front()), Full(tree) => tree.pop_front(), } @@ -791,6 +906,7 @@ None } else { match self { + Empty => None, Single(chunk) => Some(Ref::make_mut(chunk).pop_back()), Full(tree) => tree.pop_back(), } @@ -828,6 +944,7 @@ .expect("Vector length overflow"); match self { + Empty => unreachable!("empty vecs are handled before this"), Single(left) => { match other { // If both are single chunks and left has room for right: directly @@ -994,6 +1111,7 @@ assert!(index <= self.len()); match self { + Empty => Empty, Single(chunk) => Single(Ref::new(Ref::make_mut(chunk).split_off(index))), Full(tree) => { let mut local_index = index; @@ -1232,97 +1350,6 @@ } } - /// Discard all elements from the vector. - /// - /// This leaves you with an empty vector, and all elements that - /// were previously inside it are dropped. - /// - /// Time: O(n) - pub fn clear(&mut self) { - if !self.is_empty() { - *self = Single(Ref::new(Chunk::new())); - } - } - - /// Binary search a sorted vector for a given element using a comparator - /// function. - /// - /// Assumes the vector has already been sorted using the same comparator - /// function, eg. by using [`sort_by`][sort_by]. - /// - /// If the value is found, it returns `Ok(index)` where `index` is the index - /// of the element. If the value isn't found, it returns `Err(index)` where - /// `index` is the index at which the element would need to be inserted to - /// maintain sorted order. - /// - /// Time: O(log n) - /// - /// [sort_by]: #method.sort_by - #[must_use] - pub fn binary_search_by(&self, mut f: F) -> Result - where - F: FnMut(&A) -> Ordering, - { - let mut size = self.len(); - if size == 0 { - return Err(0); - } - let mut base = 0; - while size > 1 { - let half = size / 2; - let mid = base + half; - base = match f(&self[mid]) { - Ordering::Greater => base, - _ => mid, - }; - size -= half; - } - match f(&self[base]) { - Ordering::Equal => Ok(base), - Ordering::Greater => Err(base), - Ordering::Less => Err(base + 1), - } - } - - /// Binary search a sorted vector for a given element. - /// - /// If the value is found, it returns `Ok(index)` where `index` is the index - /// of the element. If the value isn't found, it returns `Err(index)` where - /// `index` is the index at which the element would need to be inserted to - /// maintain sorted order. - /// - /// Time: O(log n) - #[must_use] - pub fn binary_search(&self, value: &A) -> Result - where - A: Ord, - { - self.binary_search_by(|e| e.cmp(value)) - } - - /// Binary search a sorted vector for a given element with a key extract - /// function. - /// - /// Assumes the vector has already been sorted using the same key extract - /// function, eg. by using [`sort_by_key`][sort_by_key]. - /// - /// If the value is found, it returns `Ok(index)` where `index` is the index - /// of the element. If the value isn't found, it returns `Err(index)` where - /// `index` is the index at which the element would need to be inserted to - /// maintain sorted order. - /// - /// Time: O(log n) - /// - /// [sort_by_key]: #method.sort_by_key - #[must_use] - pub fn binary_search_by_key(&self, b: &B, mut f: F) -> Result - where - F: FnMut(&A) -> B, - B: Ord, - { - self.binary_search_by(|k| f(k).cmp(b)) - } - /// Insert an element into a sorted vector. /// /// Insert an element into a vector in sorted order, assuming the vector is @@ -1397,6 +1424,13 @@ sort::quicksort(&mut self.focus_mut(), 0, len - 1, &cmp); } } + + #[allow(dead_code)] + pub(crate) fn assert_invariants(&self) { + if let Vector::Full(ref tree) = self { + tree.middle.assert_invariants(); + } + } } // Implementation details @@ -1528,7 +1562,7 @@ let middle = Ref::make_mut(&mut self.middle); match middle.push_chunk(self.middle_level, side, chunk) { PushResult::Done => return, - PushResult::Full(chunk) => Ref::from({ + PushResult::Full(chunk, _num_drained) => Ref::from({ match side { Side::Left => Node::from_chunk(self.middle_level, chunk) .join_branches(middle.clone(), self.middle_level), @@ -1577,6 +1611,7 @@ impl Clone for Vector { fn clone(&self) -> Self { match self { + Empty => Empty, Single(chunk) => Single(chunk.clone()), Full(tree) => Full(tree.clone()), } @@ -1972,6 +2007,7 @@ /// A consuming iterator over vectors with values of type `A`. pub enum ConsumingIter { + Empty, Single(ChunkIter), Full( Chain< @@ -1984,6 +2020,7 @@ impl ConsumingIter { fn new(seq: Vector) -> Self { match seq { + Empty => ConsumingIter::Empty, Single(chunk) => ConsumingIter::Single(clone_ref(chunk).into_iter()), Full(tree) => ConsumingIter::Full(tree.into_iter()), } @@ -1998,6 +2035,7 @@ /// Time: O(1)* fn next(&mut self) -> Option { match self { + ConsumingIter::Empty => None, ConsumingIter::Single(iter) => iter.next(), ConsumingIter::Full(iter) => iter.next(), } @@ -2005,6 +2043,7 @@ fn size_hint(&self) -> (usize, Option) { match self { + ConsumingIter::Empty => (0, Some(0)), ConsumingIter::Single(iter) => iter.size_hint(), ConsumingIter::Full(iter) => iter.size_hint(), } @@ -2017,6 +2056,7 @@ /// Time: O(1)* fn next_back(&mut self) -> Option { match self { + ConsumingIter::Empty => None, ConsumingIter::Single(iter) => iter.next_back(), ConsumingIter::Full(iter) => iter.next_back(), } @@ -2150,8 +2190,10 @@ pub mod rayon { use super::*; - use rayon::iter::plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer}; - use rayon::iter::{ + use ::rayon::iter::plumbing::{ + bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer, + }; + use ::rayon::iter::{ IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator, }; @@ -2330,8 +2372,11 @@ mod test { use super::super::*; use super::proptest::vector; - use proptest::num::i32; - use rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator}; + use ::proptest::num::i32; + use ::proptest::proptest; + use ::rayon::iter::{ + IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator, + }; proptest! { #[test] @@ -2342,8 +2387,8 @@ #[test] fn par_mut_iter(ref mut input in vector(i32::ANY, 0..10000)) { let mut vec = input.clone(); - vec.par_iter_mut().for_each(|i| *i += 1); - let expected: Vector = input.clone().into_iter().map(|i| i + 1).collect(); + vec.par_iter_mut().for_each(|i| *i = i.overflowing_add(1).0); + let expected: Vector = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect(); assert_eq!(expected, vec); } } @@ -2366,8 +2411,8 @@ #[cfg(any(test, feature = "proptest"))] pub mod proptest { use super::*; - use proptest::collection::vec; - use proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; + use ::proptest::collection::vec; + use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree}; use std::ops::Range; /// A strategy for generating a vector of a certain size. @@ -2400,27 +2445,9 @@ mod test { use super::proptest::vector; use super::*; - use proptest::collection::vec; - use proptest::num::{i32, usize}; - - // #[test] - // fn push_and_pop_things() { - // let mut seq = Vector::new(); - // for i in 0..1000 { - // seq.push_back(i); - // } - // for i in 0..1000 { - // assert_eq!(Some(i), seq.pop_front()); - // } - // assert!(seq.is_empty()); - // for i in 0..1000 { - // seq.push_front(i); - // } - // for i in 0..1000 { - // assert_eq!(Some(i), seq.pop_back()); - // } - // assert!(seq.is_empty()); - // } + use ::proptest::collection::vec; + use ::proptest::num::{i32, usize}; + use ::proptest::proptest; #[test] fn macro_allows_trailing_comma() { @@ -2498,6 +2525,111 @@ vec1.append(vec2); } + #[test] + fn issue_70() { + let mut x = Vector::new(); + for _ in 0..262 { + x.push_back(0); + } + for _ in 0..97 { + x.pop_front(); + } + for &offset in &[160, 163, 160] { + x.remove(offset); + } + for _ in 0..64 { + x.push_back(0); + } + // At this point middle contains three chunks of size 64, 64 and 1 + // respectively. Previously the next `push_back()` would append another + // zero-sized chunk to middle even though there is enough space left. + match x { + Vector::Full(ref tree) => { + assert_eq!(129, tree.middle.len()); + assert_eq!(3, tree.middle.number_of_children()); + } + _ => unreachable!(), + } + x.push_back(0); + match x { + Vector::Full(ref tree) => { + assert_eq!(131, tree.middle.len()); + assert_eq!(3, tree.middle.number_of_children()) + } + _ => unreachable!(), + } + for _ in 0..64 { + x.push_back(0); + } + for _ in x.iter() {} + } + + #[test] + fn issue_67() { + let mut l = Vector::unit(4100); + for i in (0..4099).rev() { + let mut tmp = Vector::unit(i); + tmp.append(l); + l = tmp; + } + assert_eq!(4100, l.len()); + let len = l.len(); + let tail = l.slice(1..len); + assert_eq!(1, l.len()); + assert_eq!(4099, tail.len()); + assert_eq!(Some(&0), l.get(0)); + assert_eq!(Some(&1), tail.get(0)); + } + + #[test] + fn issue_74_simple_size() { + use crate::nodes::rrb::NODE_SIZE; + let mut x = Vector::new(); + for _ in 0..(CHUNK_SIZE + * ( + 1 // inner_f + + (2 * NODE_SIZE) // middle: two full Entry::Nodes (4096 elements each) + + 1 // inner_b + + 1 + // outer_b + )) + { + x.push_back(0u32); + } + let middle_first_node_start = CHUNK_SIZE; + let middle_second_node_start = middle_first_node_start + NODE_SIZE * CHUNK_SIZE; + // This reduces the size of the second node to 4095. + x.remove(middle_second_node_start); + // As outer_b is full, this will cause inner_b (length 64) to be pushed + // to middle. The first element will be merged into the second node, the + // remaining 63 elements will end up in a new node. + x.push_back(0u32); + match x { + Vector::Full(tree) => { + assert_eq!(3, tree.middle.number_of_children()); + assert_eq!( + 2 * NODE_SIZE * CHUNK_SIZE + CHUNK_SIZE - 1, + tree.middle.len() + ); + } + _ => unreachable!(), + } + } + + #[test] + fn issue_77() { + let mut x = Vector::new(); + for _ in 0..44 { x.push_back(0); } + for _ in 0..20 { x.insert(0, 0); } + x.insert(1, 0); + for _ in 0..441 { x.push_back(0); } + for _ in 0..58 { x.insert(0, 0); } + x.insert(514, 0); + for _ in 0..73 { x.push_back(0); } + for _ in 0..10 { x.insert(0, 0); } + x.insert(514, 0); + } + proptest! { #[test] fn iter(ref vec in vec(i32::ANY, 0..1000)) { @@ -2618,10 +2750,10 @@ let mut vec = input.clone(); { for p in vec.iter_mut() { - *p += 1; + *p = p.overflowing_add(1).0; } } - let expected: Vector = input.clone().into_iter().map(|i| i+1).collect(); + let expected: Vector = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect(); assert_eq!(expected, vec); } @@ -2632,10 +2764,10 @@ let mut focus = vec.focus_mut(); for i in 0..input.len() { let p = focus.index_mut(i); - *p += 1; + *p = p.overflowing_add(1).0; } } - let expected: Vector = input.clone().into_iter().map(|i| i+1).collect(); + let expected: Vector = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect(); assert_eq!(expected, vec); } @@ -2647,7 +2779,7 @@ let len = focus.len(); if len < 8 { for p in focus { - *p += 1; + *p = p.overflowing_add(1).0; } } else { let (left, right) = focus.split_at(len / 2); @@ -2658,16 +2790,16 @@ split_down(vec.focus_mut()); - let expected: Vector = input.clone().into_iter().map(|i| i+1).collect(); + let expected: Vector = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect(); assert_eq!(expected, vec); } #[test] fn chunks(ref input in vector(i32::ANY, 0..10000)) { - let output: Vector<_> = input.chunks().flat_map(|a|a).cloned().collect(); + let output: Vector<_> = input.leaves().flat_map(|a|a).cloned().collect(); assert_eq!(input, &output); let rev_in: Vector<_> = input.iter().rev().cloned().collect(); - let rev_out: Vector<_> = input.chunks().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect(); + let rev_out: Vector<_> = input.leaves().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect(); assert_eq!(rev_in, rev_out); } @@ -2675,10 +2807,10 @@ fn chunks_mut(ref mut input_src in vector(i32::ANY, 0..10000)) { let mut input = input_src.clone(); #[allow(clippy::map_clone)] - let output: Vector<_> = input.chunks_mut().flat_map(|a| a).map(|v| *v).collect(); + let output: Vector<_> = input.leaves_mut().flat_map(|a| a).map(|v| *v).collect(); assert_eq!(input, output); let rev_in: Vector<_> = input.iter().rev().cloned().collect(); - let rev_out: Vector<_> = input.chunks_mut().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect(); + let rev_out: Vector<_> = input.leaves_mut().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect(); assert_eq!(rev_in, rev_out); } diff -Nru cargo-0.33.0/vendor/iovec/appveyor.yml cargo-0.35.0/vendor/iovec/appveyor.yml --- cargo-0.33.0/vendor/iovec/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/appveyor.yml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,16 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-msvc + +install: + - curl -sSf -o rustup-init.exe https://win.rustup.rs/ + - rustup-init.exe -y --default-host %TARGET% + - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin + - rustc -V + - cargo -V + +build: false + +test_script: + - cargo build + - cargo test diff -Nru cargo-0.33.0/vendor/iovec/.cargo-checksum.json cargo-0.35.0/vendor/iovec/.cargo-checksum.json --- cargo-0.33.0/vendor/iovec/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/iovec/Cargo.toml cargo-0.35.0/vendor/iovec/Cargo.toml --- cargo-0.33.0/vendor/iovec/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,28 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "iovec" +version = "0.1.2" +authors = ["Carl Lerche "] +description = "Portable buffer type for scatter/gather I/O operations\n" +homepage = "https://github.com/carllerche/iovec" +documentation = "https://docs.rs/iovec" +readme = "README.md" +keywords = ["scatter", "gather", "vectored", "io", "networking"] +categories = ["network-programming", "api-bindings"] +license = "MIT/Apache-2.0" +repository = "https://github.com/carllerche/iovec" +[target."cfg(unix)".dependencies.libc] +version = "0.2" +[target."cfg(windows)".dependencies] +winapi = { version = "0.3", features = ["minwindef", "ws2def"] } diff -Nru cargo-0.33.0/vendor/iovec/CHANGELOG.md cargo-0.35.0/vendor/iovec/CHANGELOG.md --- cargo-0.33.0/vendor/iovec/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,11 @@ +# 0.1.2 (January 26th, 2018) + +* Add support for non-windows/unix targets (#10) + +# 0.1.1 (October 5th, 2017) + +* Fix soundness bug: Assert slice lengths are always > 0 (#5) + +# 0.1.0 (March 14th, 2017) + +* Initial release diff -Nru cargo-0.33.0/vendor/iovec/debian/patches/b90b433-backport.patch cargo-0.35.0/vendor/iovec/debian/patches/b90b433-backport.patch --- cargo-0.33.0/vendor/iovec/debian/patches/b90b433-backport.patch 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/debian/patches/b90b433-backport.patch 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,30 @@ +From b90b433f58fb8d64ad6c67d8080cf3da1fce3543 Mon Sep 17 00:00:00 2001 +From: Steffen Butzer +Date: Thu, 21 Dec 2017 15:51:01 +0100 +Subject: [PATCH] migrate to winapi 0.3 + +--- + Cargo.toml | 2 +- + src/sys/windows.rs | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Cargo.toml b/Cargo.toml +index 25ff582..ee1c0d3 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -17,3 +17,3 @@ categories = ["network-programming", "api-bindings"] + version = "0.2" +-[target."cfg(windows)".dependencies.winapi] +-version = "0.2" ++[target."cfg(windows)".dependencies] ++winapi = { version = "0.3", features = ["minwindef", "ws2def"] } +diff --git a/src/sys/windows.rs b/src/sys/windows.rs +index 18681a4..8cc6351 100644 +--- a/src/sys/windows.rs ++++ b/src/sys/windows.rs +@@ -1,3 +1,4 @@ +-use winapi::{WSABUF, DWORD}; ++use winapi::shared::minwindef::DWORD; ++use winapi::shared::ws2def::WSABUF; + use std::{mem, slice, u32}; + diff -Nru cargo-0.33.0/vendor/iovec/debian/patches/series cargo-0.35.0/vendor/iovec/debian/patches/series --- cargo-0.33.0/vendor/iovec/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/debian/patches/series 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +b90b433-backport.patch diff -Nru cargo-0.33.0/vendor/iovec/LICENSE-APACHE cargo-0.35.0/vendor/iovec/LICENSE-APACHE --- cargo-0.33.0/vendor/iovec/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/LICENSE-APACHE 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2017 Carl Lerche + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff -Nru cargo-0.33.0/vendor/iovec/LICENSE-MIT cargo-0.35.0/vendor/iovec/LICENSE-MIT --- cargo-0.33.0/vendor/iovec/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/LICENSE-MIT 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,25 @@ +Copyright (c) 2017 Carl Lerche + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff -Nru cargo-0.33.0/vendor/iovec/.pc/applied-patches cargo-0.35.0/vendor/iovec/.pc/applied-patches --- cargo-0.33.0/vendor/iovec/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/applied-patches 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +b90b433-backport.patch diff -Nru cargo-0.33.0/vendor/iovec/.pc/b90b433-backport.patch/Cargo.toml cargo-0.35.0/vendor/iovec/.pc/b90b433-backport.patch/Cargo.toml --- cargo-0.33.0/vendor/iovec/.pc/b90b433-backport.patch/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/b90b433-backport.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,28 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "iovec" +version = "0.1.2" +authors = ["Carl Lerche "] +description = "Portable buffer type for scatter/gather I/O operations\n" +homepage = "https://github.com/carllerche/iovec" +documentation = "https://docs.rs/iovec" +readme = "README.md" +keywords = ["scatter", "gather", "vectored", "io", "networking"] +categories = ["network-programming", "api-bindings"] +license = "MIT/Apache-2.0" +repository = "https://github.com/carllerche/iovec" +[target."cfg(unix)".dependencies.libc] +version = "0.2" +[target."cfg(windows)".dependencies.winapi] +version = "0.2" diff -Nru cargo-0.33.0/vendor/iovec/.pc/b90b433-backport.patch/src/sys/windows.rs cargo-0.35.0/vendor/iovec/.pc/b90b433-backport.patch/src/sys/windows.rs --- cargo-0.33.0/vendor/iovec/.pc/b90b433-backport.patch/src/sys/windows.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/b90b433-backport.patch/src/sys/windows.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,56 @@ +use winapi::{WSABUF, DWORD}; +use std::{mem, slice, u32}; + +pub struct IoVec { + inner: [u8], +} + +pub const MAX_LENGTH: usize = u32::MAX as usize; + +impl IoVec { + pub fn as_ref(&self) -> &[u8] { + unsafe { + let vec = self.wsabuf(); + slice::from_raw_parts(vec.buf as *const u8, vec.len as usize) + } + } + + pub fn as_mut(&mut self) -> &mut [u8] { + unsafe { + let vec = self.wsabuf(); + slice::from_raw_parts_mut(vec.buf as *mut u8, vec.len as usize) + } + } + + unsafe fn wsabuf(&self) -> WSABUF { + mem::transmute(&self.inner) + } +} + +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(src: &'a [u8]) -> Self { + assert!(src.len() > 0); + assert!(src.len() <= MAX_LENGTH); + + unsafe { + mem::transmute(WSABUF { + buf: src.as_ptr() as *mut _, + len: src.len() as DWORD, + }) + } + } +} + +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(src: &'a mut [u8]) -> Self { + assert!(src.len() > 0); + assert!(src.len() <= MAX_LENGTH); + + unsafe { + mem::transmute(WSABUF { + buf: src.as_ptr() as *mut _, + len: src.len() as DWORD, + }) + } + } +} diff -Nru cargo-0.33.0/vendor/iovec/.pc/.quilt_patches cargo-0.35.0/vendor/iovec/.pc/.quilt_patches --- cargo-0.33.0/vendor/iovec/.pc/.quilt_patches 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/.quilt_patches 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +debian/patches diff -Nru cargo-0.33.0/vendor/iovec/.pc/.quilt_series cargo-0.35.0/vendor/iovec/.pc/.quilt_series --- cargo-0.33.0/vendor/iovec/.pc/.quilt_series 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/.quilt_series 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +series diff -Nru cargo-0.33.0/vendor/iovec/.pc/.version cargo-0.35.0/vendor/iovec/.pc/.version --- cargo-0.33.0/vendor/iovec/.pc/.version 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/.pc/.version 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +2 diff -Nru cargo-0.33.0/vendor/iovec/README.md cargo-0.35.0/vendor/iovec/README.md --- cargo-0.33.0/vendor/iovec/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,35 @@ +# IoVec + +A specialized byte slice type for performing vectored I/O operations. + +[![Crates.io](https://img.shields.io/crates/v/iovec.svg?maxAge=2592000)](https://crates.io/crates/iovec) +[![Build Status](https://travis-ci.org/carllerche/iovec.svg?branch=master)](https://travis-ci.org/carllerche/iovec) + +[Documentation](https://docs.rs/iovec) + +## Usage + +To use `iovec`, first add this to your `Cargo.toml`: + +```toml +[dependencies] +iovec = "0.1" +``` + +Next, add this to your crate: + +```rust +extern crate iovec; + +use iovec::IoVec; +``` + +For more detail, see [documentation](https://docs.rs/iovec). + +# License + +`iovec` is primarily distributed under the terms of both the MIT license and the +Apache License (Version 2.0), with portions covered by various BSD-like +licenses. + +See LICENSE-APACHE, and LICENSE-MIT for details. diff -Nru cargo-0.33.0/vendor/iovec/src/lib.rs cargo-0.35.0/vendor/iovec/src/lib.rs --- cargo-0.33.0/vendor/iovec/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,164 @@ +//! A specialized byte slice type for performing vectored I/O operations. +//! +//! For more detail, see [`IoVec`] documentation. +//! +//! [`IoVec`]: struct.IoVec.html + +#[cfg(unix)] +extern crate libc; + +#[cfg(windows)] +extern crate winapi; + +mod sys; + +use std::{ops, mem}; + +#[cfg(unix)] +pub mod unix; + +/// Max length of an `IoVec` slice. +/// +/// Attempts to convert slices longer than this value will result in a panic. +pub const MAX_LENGTH: usize = sys::MAX_LENGTH; + +/// A specialized byte slice type for performing vectored I/O operations. +/// +/// On all systems, the types needed to perform vectored I/O systems have the +/// same size as Rust's [`slice`]. However, the layout is not necessarily the +/// same. `IoVec` provides a portable compatibility layer. +/// +/// The `IoVec` behaves like a Rust [`slice`], providing the same functions. +/// It also provides conversion functions to and from the OS specific vectored +/// types. +/// +/// [`slice`]: https://doc.rust-lang.org/std/primitive.slice.html +/// +/// # Examples +/// +/// ``` +/// use iovec::IoVec; +/// +/// let mut data = vec![]; +/// data.extend_from_slice(b"hello"); +/// +/// let iovec: &IoVec = data.as_slice().into(); +/// +/// assert_eq!(&iovec[..], &b"hello"[..]); +/// ``` +/// +/// # Panics +/// +/// Attempting to convert a zero-length slice or a slice longer than +/// [`MAX_LENGTH`] to an `IoVec` will result in a panic. +/// +/// [`MAX_LENGTH`]: constant.MAX_LENGTH.html +pub struct IoVec { + sys: sys::IoVec, +} + +impl IoVec { + pub fn from_bytes(slice: &[u8]) -> Option<&IoVec> { + if slice.len() == 0 { + return None + } + unsafe { + let iovec: &sys::IoVec = slice.into(); + Some(mem::transmute(iovec)) + } + } + + pub fn from_bytes_mut(slice: &mut [u8]) -> Option<&mut IoVec> { + if slice.len() == 0 { + return None + } + unsafe { + let iovec: &mut sys::IoVec = slice.into(); + Some(mem::transmute(iovec)) + } + } + + #[deprecated(since = "0.1.0", note = "deref instead")] + #[doc(hidden)] + pub fn as_bytes(&self) -> &[u8] { + &**self + } + + #[deprecated(since = "0.1.0", note = "deref instead")] + #[doc(hidden)] + pub fn as_mut_bytes(&mut self) -> &mut [u8] { + &mut **self + } +} + +impl ops::Deref for IoVec { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.sys.as_ref() + } +} + +impl ops::DerefMut for IoVec { + fn deref_mut(&mut self) -> &mut [u8] { + self.sys.as_mut() + } +} + +#[doc(hidden)] +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(bytes: &'a [u8]) -> &'a IoVec { + IoVec::from_bytes(bytes) + .expect("this crate accidentally accepted 0-sized slices \ + originally but this was since discovered as a soundness \ + hole, it's recommended to use the `from_bytes` \ + function instead") + } +} + +#[doc(hidden)] +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(bytes: &'a mut [u8]) -> &'a mut IoVec { + IoVec::from_bytes_mut(bytes) + .expect("this crate accidentally accepted 0-sized slices \ + originally but this was since discovered as a soundness \ + hole, it's recommended to use the `from_bytes_mut` \ + function instead") + } +} + +#[doc(hidden)] +impl<'a> Default for &'a IoVec { + fn default() -> Self { + panic!("this implementation was accidentally provided but is \ + unfortunately unsound, it's recommended to stop using \ + `IoVec::default` or construct a vector with a nonzero length"); + } +} + +#[doc(hidden)] +impl<'a> Default for &'a mut IoVec { + fn default() -> Self { + panic!("this implementation was accidentally provided but is \ + unfortunately unsound, it's recommended to stop using \ + `IoVec::default` or construct a vector with a nonzero length"); + } +} + +#[cfg(test)] +mod test { + use super::IoVec; + + #[test] + fn convert_ref() { + let buf: &IoVec = (&b"hello world"[..]).into(); + assert_eq!(buf[..], b"hello world"[..]); + } + + #[test] + fn convert_mut() { + let mut buf: Vec = b"hello world".to_vec(); + let buf: &mut IoVec = (&mut buf[..]).into(); + assert_eq!(buf[..], b"hello world"[..]); + } +} diff -Nru cargo-0.33.0/vendor/iovec/src/sys/mod.rs cargo-0.35.0/vendor/iovec/src/sys/mod.rs --- cargo-0.33.0/vendor/iovec/src/sys/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/sys/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,26 @@ +#[cfg(unix)] +mod unix; + +#[cfg(unix)] +pub use self::unix::{ + IoVec, + MAX_LENGTH, +}; + +#[cfg(windows)] +mod windows; + +#[cfg(windows)] +pub use self::windows::{ + IoVec, + MAX_LENGTH, +}; + +#[cfg(not(any(windows, unix)))] +mod unknown; + +#[cfg(not(any(windows, unix)))] +pub use self::unknown::{ + IoVec, + MAX_LENGTH, +}; diff -Nru cargo-0.33.0/vendor/iovec/src/sys/unix.rs cargo-0.35.0/vendor/iovec/src/sys/unix.rs --- cargo-0.33.0/vendor/iovec/src/sys/unix.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/sys/unix.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,52 @@ +use libc; +use std::{mem, slice, usize}; + +pub struct IoVec { + inner: [u8], +} + +pub const MAX_LENGTH: usize = usize::MAX; + +impl IoVec { + pub fn as_ref(&self) -> &[u8] { + unsafe { + let vec = self.iovec(); + slice::from_raw_parts(vec.iov_base as *const u8, vec.iov_len) + } + } + + pub fn as_mut(&mut self) -> &mut [u8] { + unsafe { + let vec = self.iovec(); + slice::from_raw_parts_mut(vec.iov_base as *mut u8, vec.iov_len) + } + } + + unsafe fn iovec(&self) -> libc::iovec { + mem::transmute(&self.inner) + } +} + +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(src: &'a [u8]) -> Self { + assert!(src.len() > 0); + unsafe { + mem::transmute(libc::iovec { + iov_base: src.as_ptr() as *mut _, + iov_len: src.len(), + }) + } + } +} + +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(src: &'a mut [u8]) -> Self { + assert!(src.len() > 0); + unsafe { + mem::transmute(libc::iovec { + iov_base: src.as_ptr() as *mut _, + iov_len: src.len(), + }) + } + } +} diff -Nru cargo-0.33.0/vendor/iovec/src/sys/unknown.rs cargo-0.35.0/vendor/iovec/src/sys/unknown.rs --- cargo-0.33.0/vendor/iovec/src/sys/unknown.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/sys/unknown.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,57 @@ +use std::{mem, slice, usize}; + +#[derive(Clone)] +pub struct WasmIoVec { + ptr: *const u8, + len: usize, +} + +pub struct IoVec { + inner: [u8], +} + +pub const MAX_LENGTH: usize = usize::MAX; + +impl IoVec { + pub fn as_ref(&self) -> &[u8] { + unsafe { + let vec = self.iovec(); + slice::from_raw_parts(vec.ptr as *const u8, vec.len) + } + } + + pub fn as_mut(&mut self) -> &mut [u8] { + unsafe { + let vec = self.iovec(); + slice::from_raw_parts_mut(vec.ptr as *mut u8, vec.len) + } + } + + unsafe fn iovec(&self) -> WasmIoVec { + mem::transmute(&self.inner) + } +} + +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(src: &'a [u8]) -> Self { + assert!(src.len() > 0); + unsafe { + mem::transmute(WasmIoVec { + ptr: src.as_ptr() as *mut _, + len: src.len(), + }) + } + } +} + +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(src: &'a mut [u8]) -> Self { + assert!(src.len() > 0); + unsafe { + mem::transmute(WasmIoVec { + ptr: src.as_ptr() as *mut _, + len: src.len(), + }) + } + } +} diff -Nru cargo-0.33.0/vendor/iovec/src/sys/windows.rs cargo-0.35.0/vendor/iovec/src/sys/windows.rs --- cargo-0.33.0/vendor/iovec/src/sys/windows.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/sys/windows.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,57 @@ +use winapi::shared::minwindef::DWORD; +use winapi::shared::ws2def::WSABUF; +use std::{mem, slice, u32}; + +pub struct IoVec { + inner: [u8], +} + +pub const MAX_LENGTH: usize = u32::MAX as usize; + +impl IoVec { + pub fn as_ref(&self) -> &[u8] { + unsafe { + let vec = self.wsabuf(); + slice::from_raw_parts(vec.buf as *const u8, vec.len as usize) + } + } + + pub fn as_mut(&mut self) -> &mut [u8] { + unsafe { + let vec = self.wsabuf(); + slice::from_raw_parts_mut(vec.buf as *mut u8, vec.len as usize) + } + } + + unsafe fn wsabuf(&self) -> WSABUF { + mem::transmute(&self.inner) + } +} + +impl<'a> From<&'a [u8]> for &'a IoVec { + fn from(src: &'a [u8]) -> Self { + assert!(src.len() > 0); + assert!(src.len() <= MAX_LENGTH); + + unsafe { + mem::transmute(WSABUF { + buf: src.as_ptr() as *mut _, + len: src.len() as DWORD, + }) + } + } +} + +impl<'a> From<&'a mut [u8]> for &'a mut IoVec { + fn from(src: &'a mut [u8]) -> Self { + assert!(src.len() > 0); + assert!(src.len() <= MAX_LENGTH); + + unsafe { + mem::transmute(WSABUF { + buf: src.as_ptr() as *mut _, + len: src.len() as DWORD, + }) + } + } +} diff -Nru cargo-0.33.0/vendor/iovec/src/unix.rs cargo-0.35.0/vendor/iovec/src/unix.rs --- cargo-0.33.0/vendor/iovec/src/unix.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/iovec/src/unix.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,68 @@ +//! IoVec extensions for Unix platforms. +//! +//! These functions provide conversions to unix specific representations of the +//! vectored data. +//! +//! # Examples +//! +//! ``` +//! use iovec::IoVec; +//! use iovec::unix; +//! +//! let a = b"hello".to_vec(); +//! let b = b"world".to_vec(); +//! +//! let bufs: &[&IoVec] = &[(&a[..]).into(), (&b[..]).into()]; +//! let os_bufs = unix::as_os_slice(&bufs[..]); +//! +//! // Use the `os_bufs` slice with `writev`. +//! ``` + +use IoVec; +use libc; + +use std::mem; + +/// Convert a slice of `IoVec` refs to a slice of `libc::iovec`. +/// +/// The return value can be passed to `writev` bindings. +/// +/// # Examples +/// +/// ``` +/// use iovec::IoVec; +/// use iovec::unix; +/// +/// let a = b"hello".to_vec(); +/// let b = b"world".to_vec(); +/// +/// let bufs: &[&IoVec] = &[a[..].into(), b[..].into()]; +/// let os_bufs = unix::as_os_slice(bufs); +/// +/// // Use the `os_bufs` slice with `writev`. +/// ``` +pub fn as_os_slice<'a>(iov: &'a [&IoVec]) -> &'a [libc::iovec] { + unsafe { mem::transmute(iov) } +} + +/// Convert a mutable slice of `IoVec` refs to a mutable slice of `libc::iovec`. +/// +/// The return value can be passed to `readv` bindings. +/// +/// # Examples +/// +/// ``` +/// use iovec::IoVec; +/// use iovec::unix; +/// +/// let mut a = [0; 10]; +/// let mut b = [0; 10]; +/// +/// let bufs: &mut [&mut IoVec] = &mut [(&mut a[..]).into(), (&mut b[..]).into()]; +/// let os_bufs = unix::as_os_slice_mut(bufs); +/// +/// // Use the `os_bufs` slice with `readv`. +/// ``` +pub fn as_os_slice_mut<'a>(iov: &'a mut [&mut IoVec]) -> &'a mut [libc::iovec] { + unsafe { mem::transmute(iov) } +} diff -Nru cargo-0.33.0/vendor/itoa/benches/bench.rs cargo-0.35.0/vendor/itoa/benches/bench.rs --- cargo-0.33.0/vendor/itoa/benches/bench.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/benches/bench.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,3 @@ -#![cfg_attr(feature = "i128", feature(i128_type, i128))] #![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))] #![feature(test)] #![allow(non_snake_case)] diff -Nru cargo-0.33.0/vendor/itoa/.cargo-checksum.json cargo-0.35.0/vendor/itoa/.cargo-checksum.json --- cargo-0.33.0/vendor/itoa/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"} \ No newline at end of file +{"files":{},"package":"501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/itoa/Cargo.toml cargo-0.35.0/vendor/itoa/Cargo.toml --- cargo-0.33.0/vendor/itoa/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "itoa" -version = "0.4.3" +version = "0.4.4" authors = ["David Tolnay "] exclude = ["performance.png"] description = "Fast functions for printing integer primitives to an io::Write" diff -Nru cargo-0.33.0/vendor/itoa/README.md cargo-0.35.0/vendor/itoa/README.md --- cargo-0.33.0/vendor/itoa/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -3,41 +3,63 @@ [![Build Status](https://api.travis-ci.org/dtolnay/itoa.svg?branch=master)](https://travis-ci.org/dtolnay/itoa) [![Latest Version](https://img.shields.io/crates/v/itoa.svg)](https://crates.io/crates/itoa) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/itoa) This crate provides fast functions for printing integer primitives to an -[`io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html) or a -[`fmt::Write`](https://doc.rust-lang.org/core/fmt/trait.Write.html). The -implementation comes straight from -[libcore](https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254) -but avoids the performance penalty of going through -[`fmt::Formatter`](https://doc.rust-lang.org/std/fmt/struct.Formatter.html). +[`io::Write`] or a [`fmt::Write`]. The implementation comes straight from +[libcore] but avoids the performance penalty of going through +[`fmt::Formatter`]. + +See also [`dtoa`] for printing floating point primitives. + +*Version requirement: rustc 1.0+* + +[`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +[`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html +[libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 +[`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +[`dtoa`]: https://github.com/dtolnay/dtoa -See also [`dtoa`](https://github.com/dtolnay/dtoa) for printing floating point -primitives. +```toml +[dependencies] +itoa = "0.4" +``` + +
## Performance (lower is better) ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) -## Functions +
+ +## Examples ```rust -extern crate itoa; +use std::{fmt, io}; -// write to a vector or other io::Write -let mut buf = Vec::new(); -itoa::write(&mut buf, 128u64)?; -println!("{:?}", buf); - -// write to a stack buffer -let mut bytes = [b'\0'; 20]; -let n = itoa::write(&mut bytes[..], 128u64)?; -println!("{:?}", &bytes[..n]); - -// write to a String -let mut s = String::new(); -itoa::fmt(&mut s, 128u64)?; -println!("{}", s); +fn demo_itoa_write() -> io::Result<()> { + // Write to a vector or other io::Write. + let mut buf = Vec::new(); + itoa::write(&mut buf, 128u64)?; + println!("{:?}", buf); + + // Write to a stack buffer. + let mut bytes = [0u8; 20]; + let n = itoa::write(&mut bytes[..], 128u64)?; + println!("{:?}", &bytes[..n]); + + Ok(()) +} + +fn demo_itoa_fmt() -> fmt::Result { + // Write to a string. + let mut s = String::new(); + itoa::fmt(&mut s, 128u64)?; + println!("{}", s); + + Ok(()) +} ``` The function signatures are: @@ -48,35 +70,26 @@ fn fmt(writer: W, value: V) -> fmt::Result; ``` -where `itoa::Integer` is implemented for `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, -`i64`, `u64`, `i128`, `u128`, `isize` and `usize`. 128-bit integer support is -only available with the nightly compiler when the `i128` feature is enabled for -this crate. The return value gives the number of bytes written. +where `itoa::Integer` is implemented for i8, u8, i16, u16, i32, u32, i64, u64, +i128, u128, isize and usize. 128-bit integer support requires rustc 1.26+ and +the `i128` feature of this crate enabled. The `write` function is only available when the `std` feature is enabled -(default is enabled). - -## Dependency - -Itoa is available on [crates.io](https://crates.io/crates/itoa). Use the -following in `Cargo.toml`: - -```toml -[dependencies] -itoa = "0.4" -``` - -## License +(default is enabled). The return value gives the number of bytes written. -Licensed under either of +
- * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +#### License -at your option. + +Licensed under either of
Apache License, Version +2.0 or MIT license at your option. + -### Contribution +
+ Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in itoa by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff -Nru cargo-0.33.0/vendor/itoa/src/lib.rs cargo-0.35.0/vendor/itoa/src/lib.rs --- cargo-0.33.0/vendor/itoa/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,16 +1,59 @@ -// Copyright 2016 Itoa Developers -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. +//! This crate provides fast functions for printing integer primitives to an +//! [`io::Write`] or a [`fmt::Write`]. The implementation comes straight from +//! [libcore] but avoids the performance penalty of going through +//! [`fmt::Formatter`]. +//! +//! See also [`dtoa`] for printing floating point primitives. +//! +//! [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html +//! [`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html +//! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 +//! [`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +//! [`dtoa`]: https://github.com/dtolnay/dtoa +//! +//!
+//! +//! # Performance (lower is better) +//! +//! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) +//! +//!
+//! +//! # Examples +//! +//! ```edition2018 +//! use std::{fmt, io}; +//! +//! fn demo_itoa_write() -> io::Result<()> { +//! // Write to a vector or other io::Write. +//! let mut buf = Vec::new(); +//! itoa::write(&mut buf, 128u64)?; +//! println!("{:?}", buf); +//! +//! // Write to a stack buffer. +//! let mut bytes = [0u8; 20]; +//! let n = itoa::write(&mut bytes[..], 128u64)?; +//! println!("{:?}", &bytes[..n]); +//! +//! Ok(()) +//! } +//! +//! fn demo_itoa_fmt() -> fmt::Result { +//! // Write to a string. +//! let mut s = String::new(); +//! itoa::fmt(&mut s, 128u64)?; +//! println!("{}", s); +//! +//! Ok(()) +//! } +//! ``` -#![doc(html_root_url = "https://docs.rs/itoa/0.4.3")] +#![doc(html_root_url = "https://docs.rs/itoa/0.4.4")] #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr( feature = "cargo-clippy", - allow(cast_lossless, unreadable_literal) + allow(const_static_lifetime, transmute_ptr_to_ptr), )] #[cfg(feature = "i128")] @@ -43,7 +86,7 @@ /// /// # Example /// -/// ```rust +/// ``` /// let mut buffer = itoa::Buffer::new(); /// let printed = buffer.format(1234); /// assert_eq!(printed, "1234"); @@ -95,7 +138,7 @@ pub trait Integer: private::Sealed { // Not public API. #[doc(hidden)] - fn write<'a>(self, buf: &'a mut Buffer) -> &'a str; + fn write(self, buf: &mut Buffer) -> &str; } trait IntegerPrivate { @@ -115,7 +158,7 @@ ($max_len:expr, $t:ident) => { impl Integer for $t { #[inline] - fn write<'a>(self, buf: &'a mut Buffer) -> &'a str { + fn write(self, buf: &mut Buffer) -> &str { unsafe { debug_assert!($max_len <= I128_MAX_LEN); let buf = mem::transmute::<&mut [u8; I128_MAX_LEN], &mut [u8; $max_len]>( diff -Nru cargo-0.33.0/vendor/itoa/src/udiv128.rs cargo-0.35.0/vendor/itoa/src/udiv128.rs --- cargo-0.33.0/vendor/itoa/src/udiv128.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/src/udiv128.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,25 +1,23 @@ -// Copyright 2009-2016 compiler-builtins Developers -// -// The compiler-builtins crate is dual licensed under both the University of -// Illinois "BSD-Like" license and the MIT license. As a user of this code you may -// choose to use it under either license. As a contributor, you agree to allow -// your code to be used under both. +// The code in this file is based on Rust's compiler-builtins crate. The Rust +// compiler automatically links programs against this crate for target-specific +// runtime support. We have copied the implementation of `__udivmodti4()` which +// is an intrinsic implementing division with remainder for architectures +// without 128-bit integers. This implementation works around some poor codegen +// by LLVM (https://github.com/rust-lang/rust/issues/44545) and allows for +// inlining which does not happen with the intrinsic. // -// Full text of the relevant licenses is found here: +// The compiler-builtins crate carries the following license, which is available +// in full at: // https://github.com/rust-lang-nursery/compiler-builtins/blob/master/LICENSE.TXT // +// --- // +// Copyright 2009-2016 compiler-builtins Developers // -// The following code is based on Rust’s [compiler-builtins crate] -// (https://github.com/rust-lang-nursery/compiler-builtins) which -// provides runtime functions for the Rust programs. The Rust -// compiler will automatically link your programs against this crate. -// -// We copied the implementation of '__udivmodti4()' which is an intrinsic -// implementing division with remainder for architectures without 128-bit integer support. -// We have done this two reasons, to work around [bad optimization by LLVM] -// (https://github.com/rust-lang/rust/issues/44545) and to allow function -// inlining which doesn’t happen with the intrinsic. +// The compiler-builtins crate is dual licensed under both the University of +// Illinois "BSD-Like" license and the MIT license. As a user of this code you +// may choose to use it under either license. As a contributor, you agree to +// allow your code to be used under both. #[inline] pub fn udivmod_1e19(n: u128) -> (u128, u64) { diff -Nru cargo-0.33.0/vendor/itoa/tests/test.rs cargo-0.35.0/vendor/itoa/tests/test.rs --- cargo-0.33.0/vendor/itoa/tests/test.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/itoa/tests/test.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,3 @@ -#![cfg_attr(feature = "i128", feature(i128_type, i128))] #![cfg_attr( feature = "cargo-clippy", allow(cast_lossless, string_lit_as_bytes) diff -Nru cargo-0.33.0/vendor/jobserver/.cargo-checksum.json cargo-0.35.0/vendor/jobserver/.cargo-checksum.json --- cargo-0.33.0/vendor/jobserver/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"dd80e58f77e0cdea53ba96acc5e04479e5ffc5d869626a6beafe50fed867eace"} \ No newline at end of file +{"files":{},"package":"b3d51e24009d966c8285d524dbaf6d60926636b2a89caee9ce0bd612494ddc16"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/jobserver/Cargo.toml cargo-0.35.0/vendor/jobserver/Cargo.toml --- cargo-0.33.0/vendor/jobserver/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "jobserver" -version = "0.1.12" +version = "0.1.13" authors = ["Alex Crichton "] description = "An implementation of the GNU make jobserver for Rust\n" homepage = "https://github.com/alexcrichton/jobserver-rs" diff -Nru cargo-0.33.0/vendor/jobserver/debian/patches/relax-dep-version.patch cargo-0.35.0/vendor/jobserver/debian/patches/relax-dep-version.patch --- cargo-0.33.0/vendor/jobserver/debian/patches/relax-dep-version.patch 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/debian/patches/relax-dep-version.patch 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +--- a/Cargo.toml 2018-08-03 01:58:48.002962262 -0700 ++++ b/Cargo.toml 2018-08-03 01:58:54.275006248 -0700 +@@ -61,4 +61,4 @@ + [target."cfg(unix)".dependencies.libc] + version = "0.2" + [target."cfg(windows)".dependencies.rand] +-version = "0.4" ++version = "< 0.6, >= 0.4" diff -Nru cargo-0.33.0/vendor/jobserver/debian/patches/series cargo-0.35.0/vendor/jobserver/debian/patches/series --- cargo-0.33.0/vendor/jobserver/debian/patches/series 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/debian/patches/series 2019-05-15 11:26:24.000000000 +0000 @@ -1 +0,0 @@ -relax-dep-version.patch diff -Nru cargo-0.33.0/vendor/jobserver/.pc/applied-patches cargo-0.35.0/vendor/jobserver/.pc/applied-patches --- cargo-0.33.0/vendor/jobserver/.pc/applied-patches 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -relax-dep-version.patch diff -Nru cargo-0.33.0/vendor/jobserver/README.md cargo-0.35.0/vendor/jobserver/README.md --- cargo-0.33.0/vendor/jobserver/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -2,7 +2,7 @@ An implementation of the GNU make jobserver for Rust -[![Build Status](https://travis-ci.org/alexcrichton/jobserver-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/jobserver-rs) +[![Build Status](https://travis-ci.com/alexcrichton/jobserver-rs.svg?branch=master)](https://travis-ci.com/alexcrichton/jobserver-rs) [![Build status](https://ci.appveyor.com/api/projects/status/h5jc30hohp7ejd9c/branch/master?svg=true)](https://ci.appveyor.com/project/alexcrichton/jobserver-rs/branch/master) [![Crates.io](https://img.shields.io/crates/v/jobserver.svg?maxAge=2592000)](https://crates.io/crates/jobserver) diff -Nru cargo-0.33.0/vendor/jobserver/src/lib.rs cargo-0.35.0/vendor/jobserver/src/lib.rs --- cargo-0.33.0/vendor/jobserver/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -351,11 +351,31 @@ tx: Some(tx), }) } + + /// Blocks the current thread until a token is acquired. + /// + /// This is the same as `acquire`, except that it doesn't return an RAII + /// helper. If successful the process will need to guarantee that + /// `release_raw` is called in the future. + pub fn acquire_raw(&self) -> io::Result<()> { + self.inner.acquire()?; + Ok(()) + } + + /// Releases a jobserver token back to the original jobserver. + /// + /// This is intended to be paired with `acquire_raw` if it was called, but + /// in some situations it could also be called to relinquish a process's + /// implicit token temporarily which is then re-acquired later. + pub fn release_raw(&self) -> io::Result<()> { + self.inner.release(None)?; + Ok(()) + } } impl Drop for Acquired { fn drop(&mut self) { - drop(self.client.release(&self.data)); + drop(self.client.release(Some(&self.data))); } } @@ -540,12 +560,13 @@ } } - pub fn release(&self, data: &Acquired) -> io::Result<()> { + pub fn release(&self, data: Option<&Acquired>) -> io::Result<()> { // Note that the fd may be nonblocking but we're going to go ahead // and assume that the writes here are always nonblocking (we can // always quickly release a token). If that turns out to not be the // case we'll get an error anyway! - match (&self.write).write(&[data.byte])? { + let byte = data.map(|d| d.byte).unwrap_or(b'+'); + match (&self.write).write(&[byte])? { 1 => Ok(()), _ => Err(io::Error::new(io::ErrorKind::Other, "failed to write token back to jobserver")), @@ -849,7 +870,7 @@ } } - pub fn release(&self, _data: &Acquired) -> io::Result<()> { + pub fn release(&self, _data: Option<&Acquired>) -> io::Result<()> { unsafe { let r = ReleaseSemaphore(self.sem.0, 1, ptr::null_mut()); if r != 0 { diff -Nru cargo-0.33.0/vendor/jobserver/tests/client.rs cargo-0.35.0/vendor/jobserver/tests/client.rs --- cargo-0.33.0/vendor/jobserver/tests/client.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/jobserver/tests/client.rs 2019-05-15 11:26:24.000000000 +0000 @@ -103,6 +103,16 @@ assert!(hit.load(Ordering::SeqCst)); }, }, + Test { + name: "acquire_raw", + make_args: &["-j2"], + rule: &|me| format!("+{}", me), + f: &|| { + let c = unsafe { Client::from_env().unwrap() }; + c.acquire_raw().unwrap(); + c.release_raw().unwrap(); + }, + }, ]; fn main() { diff -Nru cargo-0.33.0/vendor/kernel32-sys/build.rs cargo-0.35.0/vendor/kernel32-sys/build.rs --- cargo-0.33.0/vendor/kernel32-sys/build.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/kernel32-sys/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,6 @@ +// Copyright © 2015, Peter Atashian +// Licensed under the MIT License +extern crate build; +fn main() { + build::link("kernel32", false) +} diff -Nru cargo-0.33.0/vendor/kernel32-sys/.cargo-checksum.json cargo-0.35.0/vendor/kernel32-sys/.cargo-checksum.json --- cargo-0.33.0/vendor/kernel32-sys/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/kernel32-sys/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/kernel32-sys/Cargo.toml cargo-0.35.0/vendor/kernel32-sys/Cargo.toml --- cargo-0.33.0/vendor/kernel32-sys/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/kernel32-sys/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,17 @@ +[package] +name = "kernel32-sys" +version = "0.2.2" +authors = ["Peter Atashian "] +description = "Contains function definitions for the Windows API library kernel32. See winapi for types and constants." +documentation = "https://retep998.github.io/doc/kernel32/" +repository = "https://github.com/retep998/winapi-rs" +readme = "README.md" +keywords = ["windows", "ffi", "win32"] +license = "MIT" +build = "build.rs" +[lib] +name = "kernel32" +[dependencies] +winapi = { version = "0.2.5", path = "../.." } +[build-dependencies] +winapi-build = { version = "0.1.1", path = "../../build" } diff -Nru cargo-0.33.0/vendor/kernel32-sys/README.md cargo-0.35.0/vendor/kernel32-sys/README.md --- cargo-0.33.0/vendor/kernel32-sys/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/kernel32-sys/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +# kernel32 # +Contains function definitions for the Windows API library kernel32. See winapi for types and constants. + +```toml +[dependencies] +kernel32-sys = "0.2.1" +``` + +```rust +extern crate kernel32; +``` + +[Documentation](https://retep998.github.io/doc/kernel32/) diff -Nru cargo-0.33.0/vendor/kernel32-sys/src/lib.rs cargo-0.35.0/vendor/kernel32-sys/src/lib.rs --- cargo-0.33.0/vendor/kernel32-sys/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/kernel32-sys/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2754 @@ +// Copyright © 2015, Peter Atashian +// Licensed under the MIT License +//! FFI bindings to kernel32. +#![cfg(windows)] +extern crate winapi; +use winapi::*; +extern "system" { + pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK); + pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK); + pub fn ActivateActCtx(hActCtx: HANDLE, lpCookie: *mut ULONG_PTR) -> BOOL; + pub fn AddAtomA(lpString: LPCSTR) -> ATOM; + pub fn AddAtomW(lpString: LPCWSTR) -> ATOM; + pub fn AddConsoleAliasA(Source: LPSTR, Target: LPSTR, ExeName: LPSTR) -> BOOL; + pub fn AddConsoleAliasW(Source: LPWSTR, Target: LPWSTR, ExeName: LPWSTR) -> BOOL; + pub fn AddDllDirectory(NewDirectory: PCWSTR) -> DLL_DIRECTORY_COOKIE; + pub fn AddIntegrityLabelToBoundaryDescriptor( + BoundaryDescriptor: *mut HANDLE, IntegrityLabel: PSID, + ) -> BOOL; + // pub fn AddLocalAlternateComputerNameA(); + // pub fn AddLocalAlternateComputerNameW(); + pub fn AddRefActCtx(hActCtx: HANDLE); + pub fn AddResourceAttributeAce( + pAcl: PACL, dwAceRevision: DWORD, AceFlags: DWORD, AccessMask: DWORD, pSid: PSID, + pAttributeInfo: PCLAIM_SECURITY_ATTRIBUTES_INFORMATION, pReturnLength: PDWORD, + ) -> BOOL; + pub fn AddSIDToBoundaryDescriptor(BoundaryDescriptor: *mut HANDLE, RequiredSid: PSID) -> BOOL; + pub fn AddScopedPolicyIDAce( + pAcl: PACL, dwAceRevision: DWORD, AceFlags: DWORD, AccessMask: DWORD, pSid: PSID, + ) -> BOOL; + pub fn AddSecureMemoryCacheCallback(pfnCallBack: PSECURE_MEMORY_CACHE_CALLBACK) -> BOOL; + pub fn AddVectoredContinueHandler(First: ULONG, Handler: PVECTORED_EXCEPTION_HANDLER) -> PVOID; + pub fn AddVectoredExceptionHandler( + First: ULONG, Handler: PVECTORED_EXCEPTION_HANDLER, + ) -> PVOID; + pub fn AllocConsole() -> BOOL; + pub fn AllocateUserPhysicalPages( + hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, + ) -> BOOL; + pub fn AllocateUserPhysicalPagesNuma( + hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, nndPreferred: DWORD, + ) -> BOOL; + // pub fn AppXGetOSMaxVersionTested(); + pub fn ApplicationRecoveryFinished(bSuccess: BOOL); + pub fn ApplicationRecoveryInProgress(pbCancelled: PBOOL) -> HRESULT; + pub fn AreFileApisANSI() -> BOOL; + pub fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL; + pub fn AttachConsole(dwProcessId: DWORD) -> BOOL; + pub fn BackupRead( + hFile: HANDLE, lpBuffer: LPBYTE, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, + bAbort: BOOL, bProcessSecurity: BOOL, lpContext: *mut LPVOID, + ) -> BOOL; + pub fn BackupSeek( + hFile: HANDLE, dwLowBytesToSeek: DWORD, dwHighBytesToSeek: DWORD, + lpdwLowByteSeeked: LPDWORD, lpdwHighByteSeeked: LPDWORD, lpContext: *mut LPVOID, + ) -> BOOL; + pub fn BackupWrite( + hFile: HANDLE, lpBuffer: LPBYTE, nNumberOfBytesToWrite: DWORD, + lpNumberOfBytesWritten: LPDWORD, bAbort: BOOL, bProcessSecurity: BOOL, + lpContext: *mut LPVOID, + ) -> BOOL; + // pub fn BaseSetLastNTError(); + pub fn Beep(dwFreq: DWORD, dwDuration: DWORD) -> BOOL; + pub fn BeginUpdateResourceA(pFileName: LPCSTR, bDeleteExistingResources: BOOL) -> HANDLE; + pub fn BeginUpdateResourceW(pFileName: LPCWSTR, bDeleteExistingResources: BOOL) -> HANDLE; + pub fn BindIoCompletionCallback( + FileHandle: HANDLE, Function: LPOVERLAPPED_COMPLETION_ROUTINE, Flags: ULONG, + ) -> BOOL; + pub fn BuildCommDCBA(lpDef: LPCSTR, lpDCB: LPDCB) -> BOOL; + pub fn BuildCommDCBAndTimeoutsA( + lpDef: LPCSTR, lpDCB: LPDCB, lpCommTimeouts: LPCOMMTIMEOUTS, + ) -> BOOL; + pub fn BuildCommDCBAndTimeoutsW( + lpDef: LPCWSTR, lpDCB: LPDCB, lpCommTimeouts: LPCOMMTIMEOUTS, + ) -> BOOL; + pub fn BuildCommDCBW(lpDef: LPCWSTR, lpDCB: LPDCB) -> BOOL; + pub fn CallNamedPipeA( + lpNamedPipeName: LPCSTR, lpInBuffer: LPVOID, nInBufferSize: DWORD, lpOutBuffer: LPVOID, + nOutBufferSize: DWORD, lpBytesRead: LPDWORD, nTimeOut: DWORD, + ) -> BOOL; + pub fn CallNamedPipeW( + lpNamedPipeName: LPCWSTR, lpInBuffer: LPVOID, nInBufferSize: DWORD, lpOutBuffer: LPVOID, + nOutBufferSize: DWORD, lpBytesRead: LPDWORD, nTimeOut: DWORD, + ) -> BOOL; + pub fn CallbackMayRunLong(pci: PTP_CALLBACK_INSTANCE) -> BOOL; + pub fn CalloutOnFiberStack( + lpFiber: PVOID, lpStartAddress: PFIBER_CALLOUT_ROUTINE, lpParameter: PVOID, + ) -> PVOID; + pub fn CancelDeviceWakeupRequest(hDevice: HANDLE) -> BOOL; + pub fn CancelIo(hFile: HANDLE) -> BOOL; + pub fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) -> BOOL; + pub fn CancelSynchronousIo(hThread: HANDLE) -> BOOL; + pub fn CancelThreadpoolIo(pio: PTP_IO); + pub fn CancelTimerQueueTimer(TimerQueue: HANDLE, Timer: HANDLE) -> BOOL; + pub fn CancelWaitableTimer(hTimer: HANDLE) -> BOOL; + pub fn CeipIsOptedIn() -> BOOL; + pub fn ChangeTimerQueueTimer( + TimerQueue: HANDLE, Timer: HANDLE, DueTime: ULONG, Period: ULONG, + ) -> BOOL; + // pub fn CheckElevation(); + // pub fn CheckElevationEnabled(); + pub fn CheckNameLegalDOS8Dot3A( + lpName: LPCSTR, lpOemName: LPSTR, OemNameSize: DWORD, pbNameContainsSpaces: PBOOL, + pbNameLegal: PBOOL, + ) -> BOOL; + pub fn CheckNameLegalDOS8Dot3W( + lpName: LPCWSTR, lpOemName: LPSTR, OemNameSize: DWORD, pbNameContainsSpaces: PBOOL, + pbNameLegal: PBOOL, + ) -> BOOL; + pub fn CheckRemoteDebuggerPresent(hProcess: HANDLE, pbDebuggerPresent: PBOOL) -> BOOL; + pub fn CheckTokenCapability( + TokenHandle: HANDLE, CapabilitySidToCheck: PSID, HasCapability: PBOOL, + ) -> BOOL; + pub fn CheckTokenMembershipEx( + TokenHandle: HANDLE, SidToCheck: PSID, Flags: DWORD, IsMember: PBOOL, + ) -> BOOL; + pub fn ClearCommBreak(hFile: HANDLE) -> BOOL; + pub fn ClearCommError(hFile: HANDLE, lpErrors: LPDWORD, lpStat: LPCOMSTAT) -> BOOL; + pub fn CloseHandle(hObject: HANDLE) -> BOOL; + // pub fn ClosePackageInfo(); + pub fn ClosePrivateNamespace(Handle: HANDLE, Flags: ULONG) -> BOOLEAN; + // pub fn CloseState(); + pub fn CloseThreadpool(ptpp: PTP_POOL); + pub fn CloseThreadpoolCleanupGroup(ptpcg: PTP_CLEANUP_GROUP); + pub fn CloseThreadpoolCleanupGroupMembers( + ptpcg: PTP_CLEANUP_GROUP, fCancelPendingCallbacks: BOOL, pvCleanupContext: PVOID, + ); + pub fn CloseThreadpoolIo(pio: PTP_IO); + pub fn CloseThreadpoolTimer(pti: PTP_TIMER); + pub fn CloseThreadpoolWait(pwa: PTP_WAIT); + pub fn CloseThreadpoolWork(pwk: PTP_WORK); + pub fn CommConfigDialogA(lpszName: LPCSTR, hWnd: HWND, lpCC: LPCOMMCONFIG) -> BOOL; + pub fn CommConfigDialogW(lpszName: LPCWSTR, hWnd: HWND, lpCC: LPCOMMCONFIG) -> BOOL; + pub fn CompareFileTime(lpFileTime1: *const FILETIME, lpFileTime2: *const FILETIME) -> LONG; + pub fn CompareStringA( + Locale: LCID, dwCmpFlags: DWORD, lpString1: PCNZCH, cchCount1: c_int, lpString2: PCNZCH, + cchCount2: c_int, + ) -> c_int; + pub fn CompareStringEx( + lpLocaleName: LPCWSTR, dwCmpFlags: DWORD, lpString1: LPCWCH, cchCount1: c_int, + lpString2: LPCWCH, cchCount2: c_int, lpVersionInformation: LPNLSVERSIONINFO, + lpReserved: LPVOID, lParam: LPARAM, + ) -> c_int; + pub fn CompareStringOrdinal( + lpString1: LPCWCH, cchCount1: c_int, lpString2: LPCWCH, cchCount2: c_int, bIgnoreCase: BOOL, + ) -> c_int; + pub fn CompareStringW( + Locale: LCID, dwCmpFlags: DWORD, lpString1: PCNZWCH, cchCount1: c_int, lpString2: PCNZWCH, + cchCount2: c_int, + ) -> c_int; + pub fn ConnectNamedPipe(hNamedPipe: HANDLE, lpOverlapped: LPOVERLAPPED) -> BOOL; + pub fn ContinueDebugEvent( + dwProcessId: DWORD, dwThreadId: DWORD, dwContinueStatus: DWORD, + ) -> BOOL; + pub fn ConvertDefaultLocale(Locale: LCID) -> LCID; + pub fn ConvertFiberToThread() -> BOOL; + pub fn ConvertThreadToFiber(lpParameter: LPVOID) -> LPVOID; + pub fn ConvertThreadToFiberEx(lpParameter: LPVOID, dwFlags: DWORD) -> LPVOID; + pub fn CopyContext(Destination: PCONTEXT, ContextFlags: DWORD, Source: PCONTEXT) -> BOOL; + pub fn CopyFile2( + pwszExistingFileName: PCWSTR, pwszNewFileName: PCWSTR, + pExtendedParameters: *mut COPYFILE2_EXTENDED_PARAMETERS, + ) -> HRESULT; + pub fn CopyFileA( + lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, bFailIfExists: BOOL + ) -> BOOL; + pub fn CopyFileExA( + lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD, + ) -> BOOL; + pub fn CopyFileExW( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD, + ) -> BOOL; + pub fn CopyFileTransactedA( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn CopyFileTransactedW( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, pbCancel: LPBOOL, dwCopyFlags: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn CopyFileW( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, bFailIfExists: BOOL + ) -> BOOL; + pub fn CreateActCtxA(pActCtx: PCACTCTXA) -> HANDLE; + pub fn CreateActCtxW(pActCtx: PCACTCTXW) -> HANDLE; + pub fn CreateBoundaryDescriptorA(Name: LPCSTR, Flags: ULONG) -> HANDLE; + pub fn CreateBoundaryDescriptorW(Name: LPCWSTR, Flags: ULONG) -> HANDLE; + pub fn CreateConsoleScreenBuffer( + dwDesiredAccess: DWORD, dwShareMode: DWORD, + lpSecurityAttributes: *const SECURITY_ATTRIBUTES, dwFlags: DWORD, + lpScreenBufferData: LPVOID, + ) -> HANDLE; + pub fn CreateDirectoryA( + lpPathName: LPCSTR, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateDirectoryExA( + lpTemplateDirectory: LPCSTR, lpNewDirectory: LPCSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateDirectoryExW( + lpTemplateDirectory: LPCWSTR, lpNewDirectory: LPCWSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateDirectoryTransactedA( + lpTemplateDirectory: LPCSTR, lpNewDirectory: LPCSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, hTransaction: HANDLE, + ) -> BOOL; + pub fn CreateDirectoryTransactedW( + lpTemplateDirectory: LPCWSTR, lpNewDirectory: LPCWSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, hTransaction: HANDLE, + ) -> BOOL; + pub fn CreateDirectoryW( + lpPathName: LPCWSTR, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateEventA( + lpEventAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, bInitialState: BOOL, + lpName: LPCSTR, + ) -> HANDLE; + pub fn CreateEventW( + lpEventAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, bInitialState: BOOL, + lpName: LPCWSTR, + ) -> HANDLE; + pub fn CreateEventExA( + lpEventAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateEventExW( + lpEventAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCWSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateFiber( + dwStackSize: SIZE_T, lpStartAddress: LPFIBER_START_ROUTINE, lpParameter: LPVOID, + ) -> LPVOID; + pub fn CreateFiberEx( + dwStackCommitSize: SIZE_T, dwStackReserveSize: SIZE_T, dwFlags: DWORD, + lpStartAddress: LPFIBER_START_ROUTINE, lpParameter: LPVOID, + ) -> LPVOID; + pub fn CreateFile2( + lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, + dwCreationDisposition: DWORD, pCreateExParams: LPCREATEFILE2_EXTENDED_PARAMETERS, + ) -> HANDLE; + pub fn CreateFileA( + lpFileName: LPCSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, + ) -> HANDLE; + pub fn CreateFileMappingA( + hFile: HANDLE, lpAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, + dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCSTR, + ) -> HANDLE; + pub fn CreateFileMappingFromApp( + hFile: HANDLE, SecurityAttributes: PSECURITY_ATTRIBUTES, PageProtection: ULONG, + MaximumSize: ULONG64, Name: PCWSTR, + ) -> HANDLE; + pub fn CreateFileMappingNumaA( + hFile: HANDLE, lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, + dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCSTR, nndPreferred: DWORD, + ) -> HANDLE; + pub fn CreateFileMappingNumaW( + hFile: HANDLE, lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, + dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCWSTR, nndPreferred: DWORD, + ) -> HANDLE; + pub fn CreateFileMappingW( + hFile: HANDLE, lpAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, + dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCWSTR, + ) -> HANDLE; + pub fn CreateFileTransactedA( + lpFileName: LPCSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, hTransaction: HANDLE, + pusMiniVersion: PUSHORT, lpExtendedParameter: PVOID, + ) -> HANDLE; + pub fn CreateFileTransactedW( + lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, hTransaction: HANDLE, + pusMiniVersion: PUSHORT, lpExtendedParameter: PVOID, + ) -> HANDLE; + pub fn CreateFileW( + lpFileName: LPCWSTR, dwDesiredAccess: DWORD, dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, + ) -> HANDLE; + pub fn CreateHardLinkA( + lpFileName: LPCSTR, lpExistingFileName: LPCSTR, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateHardLinkTransactedA( + lpFileName: LPCSTR, lpExistingFileName: LPCSTR, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + hTransaction: HANDLE, + ) -> BOOL; + pub fn CreateHardLinkTransactedW( + lpFileName: LPCWSTR, lpExistingFileName: LPCWSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, hTransaction: HANDLE, + ); + pub fn CreateHardLinkW( + lpFileName: LPCWSTR, lpExistingFileName: LPCWSTR, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> BOOL; + pub fn CreateIoCompletionPort( + FileHandle: HANDLE, ExistingCompletionPort: HANDLE, CompletionKey: ULONG_PTR, + NumberOfConcurrentThreads: DWORD, + ) -> HANDLE; + pub fn CreateJobObjectA(lpJobAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCSTR) -> HANDLE; + pub fn CreateJobObjectW(lpJobAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCWSTR) -> HANDLE; + pub fn CreateJobSet(NumJob: ULONG, UserJobSet: PJOB_SET_ARRAY, Flags: ULONG) -> BOOL; + pub fn CreateMailslotA( + lpName: LPCSTR, nMaxMessageSize: DWORD, lReadTimeout: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> HANDLE; + pub fn CreateMailslotW( + lpName: LPCWSTR, nMaxMessageSize: DWORD, lReadTimeout: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> HANDLE; + pub fn CreateMemoryResourceNotification( + NotificationType: MEMORY_RESOURCE_NOTIFICATION_TYPE, + ) -> HANDLE; + pub fn CreateMutexA( + lpMutexAttributes: LPSECURITY_ATTRIBUTES, bInitialOwner: BOOL, lpName: LPCSTR, + ) -> HANDLE; + pub fn CreateMutexExA( + lpMutexAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateMutexExW( + lpMutexAttributes: LPSECURITY_ATTRIBUTES, lpName: LPCWSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateMutexW( + lpMutexAttributes: LPSECURITY_ATTRIBUTES, bInitialOwner: BOOL, lpName: LPCWSTR, + ) -> HANDLE; + pub fn CreateNamedPipeA( + lpName: LPCSTR, dwOpenMode: DWORD, dwPipeMode: DWORD, nMaxInstances: DWORD, + nOutBufferSize: DWORD, nInBufferSize: DWORD, nDefaultTimeOut: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> HANDLE; + pub fn CreateNamedPipeW( + lpName: LPCWSTR, dwOpenMode: DWORD, dwPipeMode: DWORD, nMaxInstances: DWORD, + nOutBufferSize: DWORD, nInBufferSize: DWORD, nDefaultTimeOut: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + ) -> HANDLE; + pub fn CreatePipe( + hReadPipe: PHANDLE, hWritePipe: PHANDLE, lpPipeAttributes: LPSECURITY_ATTRIBUTES, + nSize: DWORD, + ) -> BOOL; + pub fn CreatePrivateNamespaceA( + lpPrivateNamespaceAttributes: LPSECURITY_ATTRIBUTES, lpBoundaryDescriptor: LPVOID, + lpAliasPrefix: LPCSTR, + ) -> HANDLE; + pub fn CreatePrivateNamespaceW( + lpPrivateNamespaceAttributes: LPSECURITY_ATTRIBUTES, lpBoundaryDescriptor: LPVOID, + lpAliasPrefix: LPCWSTR, + ) -> HANDLE; + pub fn CreateProcessA( + lpApplicationName: LPCSTR, lpCommandLine: LPSTR, lpProcessAttributes: LPSECURITY_ATTRIBUTES, + lpThreadAttributes: LPSECURITY_ATTRIBUTES, bInheritHandles: BOOL, dwCreationFlags: DWORD, + lpEnvironment: LPVOID, lpCurrentDirectory: LPCSTR, lpStartupInfo: LPSTARTUPINFOA, + lpProcessInformation: LPPROCESS_INFORMATION, + ) -> BOOL; + pub fn CreateProcessW( + lpApplicationName: LPCWSTR, lpCommandLine: LPWSTR, + lpProcessAttributes: LPSECURITY_ATTRIBUTES, lpThreadAttributes: LPSECURITY_ATTRIBUTES, + bInheritHandles: BOOL, dwCreationFlags: DWORD, lpEnvironment: LPVOID, + lpCurrentDirectory: LPCWSTR, lpStartupInfo: LPSTARTUPINFOW, + lpProcessInformation: LPPROCESS_INFORMATION, + ) -> BOOL; + pub fn CreateRemoteThread( + hProcess: HANDLE, lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, + lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: LPVOID, dwCreationFlags: DWORD, + lpThreadId: LPDWORD, + ) -> HANDLE; + pub fn CreateRemoteThreadEx( + hProcess: HANDLE, lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, + lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: LPVOID, dwCreationFlags: DWORD, + lpAttributeList: LPPROC_THREAD_ATTRIBUTE_LIST, lpThreadId: LPDWORD, + ) -> HANDLE; + pub fn CreateSemaphoreA( + lpSemaphoreAttributes: LPSECURITY_ATTRIBUTES, lInitialCount: LONG, lMaximumCount: LONG, + lpName: LPCSTR, + ) -> HANDLE; + pub fn CreateSemaphoreExA( + lpSemaphoreAttributes: LPSECURITY_ATTRIBUTES, lInitialCount: LONG, lMaximumCount: LONG, + lpName: LPCSTR, dwFlags: DWORD, dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateSemaphoreExW( + lpSemaphoreAttributes: LPSECURITY_ATTRIBUTES, lInitialCount: LONG, lMaximumCount: LONG, + lpName: LPCWSTR, dwFlags: DWORD, dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateSemaphoreW( + lpSemaphoreAttributes: LPSECURITY_ATTRIBUTES, lInitialCount: LONG, lMaximumCount: LONG, + lpName: LPCWSTR, + ) -> HANDLE; + pub fn CreateSymbolicLinkA( + lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR, dwFlags: DWORD, + ) -> BOOLEAN; + pub fn CreateSymbolicLinkTransactedA( + lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR, dwFlags: DWORD, hTransaction: HANDLE, + ) -> BOOLEAN; + pub fn CreateSymbolicLinkTransactedW( + lpSymlinkFileName: LPCWSTR, lpTargetFileName: LPCWSTR, dwFlags: DWORD, hTransaction: HANDLE, + ) -> BOOLEAN; + pub fn CreateSymbolicLinkW( + lpSymlinkFileName: LPCWSTR, lpTargetFileName: LPCWSTR, dwFlags: DWORD, + ) -> BOOLEAN; + pub fn CreateTapePartition( + hDevice: HANDLE, dwPartitionMethod: DWORD, dwCount: DWORD, dwSize: DWORD, + ) -> DWORD; + pub fn CreateThread( + lpThreadAttributes: LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, + lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: LPVOID, dwCreationFlags: DWORD, + lpThreadId: LPDWORD, + ) -> HANDLE; + pub fn CreateThreadpool(reserved: PVOID) -> PTP_POOL; + pub fn CreateThreadpoolCleanupGroup() -> PTP_CLEANUP_GROUP; + pub fn CreateThreadpoolIo( + fl: HANDLE, pfnio: PTP_WIN32_IO_CALLBACK, pv: PVOID, pcbe: PTP_CALLBACK_ENVIRON, + ) -> PTP_IO; + pub fn CreateThreadpoolTimer( + pfnti: PTP_TIMER_CALLBACK, pv: PVOID, pcbe: PTP_CALLBACK_ENVIRON, + ) -> PTP_TIMER; + pub fn CreateThreadpoolWait( + pfnwa: PTP_WAIT_CALLBACK, pv: PVOID, pcbe: PTP_CALLBACK_ENVIRON, + ) -> PTP_WAIT; + pub fn CreateThreadpoolWork( + pfnwk: PTP_WORK_CALLBACK, pv: PVOID, pcbe: PTP_CALLBACK_ENVIRON, + ) -> PTP_WORK; + pub fn CreateTimerQueue() -> HANDLE; + pub fn CreateTimerQueueTimer( + phNewTimer: PHANDLE, TimerQueue: HANDLE, Callback: WAITORTIMERCALLBACK, Parameter: PVOID, + DueTime: DWORD, Period: DWORD, Flags: ULONG, + ) -> BOOL; + pub fn CreateToolhelp32Snapshot(dwFlags: DWORD, th32ProcessID: DWORD) -> HANDLE; + #[cfg(target_arch = "x86_64")] + pub fn CreateUmsCompletionList(UmsCompletionList: *mut PUMS_COMPLETION_LIST) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn CreateUmsThreadContext(lpUmsThread: *mut PUMS_CONTEXT) -> BOOL; + pub fn CreateWaitableTimerA( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, lpTimerName: LPCSTR, + ) -> HANDLE; + pub fn CreateWaitableTimerExA( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, lpTimerName: LPCSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateWaitableTimerExW( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, lpTimerName: LPCWSTR, dwFlags: DWORD, + dwDesiredAccess: DWORD, + ) -> HANDLE; + pub fn CreateWaitableTimerW( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, bManualReset: BOOL, lpTimerName: LPCWSTR, + ) -> HANDLE; + // pub fn CtrlRoutine(); + pub fn DeactivateActCtx(dwFlags: DWORD, ulCookie: ULONG_PTR) -> BOOL; + pub fn DebugActiveProcess(dwProcessId: DWORD) -> BOOL; + pub fn DebugActiveProcessStop(dwProcessId: DWORD) -> BOOL; + pub fn DebugBreak(); + pub fn DebugBreakProcess(Process: HANDLE) -> BOOL; + pub fn DebugSetProcessKillOnExit(KillOnExit: BOOL) -> BOOL; + pub fn DecodePointer(Ptr: PVOID) -> PVOID; + pub fn DecodeSystemPointer(Ptr: PVOID) -> PVOID; + pub fn DefineDosDeviceA(dwFlags: DWORD, lpDeviceName: LPCSTR, lpTargetPath: LPCSTR) -> BOOL; + pub fn DefineDosDeviceW(dwFlags: DWORD, lpDeviceName: LPCWSTR, lpTargetPath: LPCWSTR) -> BOOL; + pub fn DelayLoadFailureHook(pszDllName: LPCSTR, pszProcName: LPCSTR) -> FARPROC; + pub fn DeleteAtom(nAtom: ATOM) -> ATOM; + pub fn DeleteBoundaryDescriptor(BoundaryDescriptor: HANDLE); + pub fn DeleteCriticalSection(lpCriticalSection: LPCRITICAL_SECTION); + pub fn DeleteFiber(lpFiber: LPVOID); + pub fn DeleteFileA(lpFileName: LPCSTR) -> BOOL; + pub fn DeleteFileTransactedA(lpFileName: LPCSTR, hTransaction: HANDLE) -> BOOL; + pub fn DeleteFileTransactedW(lpFileName: LPCWSTR, hTransaction: HANDLE) -> BOOL; + pub fn DeleteFileW(lpFileName: LPCWSTR) -> BOOL; + pub fn DeleteProcThreadAttributeList(lpAttributeList: LPPROC_THREAD_ATTRIBUTE_LIST); + pub fn DeleteSynchronizationBarrier(lpBarrier: LPSYNCHRONIZATION_BARRIER) -> BOOL; + pub fn DeleteTimerQueue(TimerQueue: HANDLE) -> BOOL; + pub fn DeleteTimerQueueEx(TimerQueue: HANDLE, CompletionEvent: HANDLE) -> BOOL; + pub fn DeleteTimerQueueTimer( + TimerQueue: HANDLE, Timer: HANDLE, CompletionEvent: HANDLE, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn DeleteUmsCompletionList(UmsCompletionList: PUMS_COMPLETION_LIST) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn DeleteUmsThreadContext(UmsThread: PUMS_CONTEXT) -> BOOL; + pub fn DeleteVolumeMountPointA(lpszVolumeMountPoint: LPCSTR) -> BOOL; + pub fn DeleteVolumeMountPointW(lpszVolumeMountPoint: LPCWSTR) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn DequeueUmsCompletionListItems( + UmsCompletionList: PUMS_COMPLETION_LIST, WaitTimeOut: DWORD, + UmsThreadList: *mut PUMS_CONTEXT, + ) -> BOOL; + pub fn DeviceIoControl( + hDevice: HANDLE, dwIoControlCode: DWORD, lpInBuffer: LPVOID, nInBufferSize: DWORD, + lpOutBuffer: LPVOID, nOutBufferSize: DWORD, lpBytesReturned: LPDWORD, + lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn DisableThreadLibraryCalls(hLibModule: HMODULE) -> BOOL; + pub fn DisableThreadProfiling(PerformanceDataHandle: HANDLE) -> DWORD; + pub fn DisassociateCurrentThreadFromCallback(pci: PTP_CALLBACK_INSTANCE); + pub fn DisconnectNamedPipe(hNamedPipe: HANDLE) -> BOOL; + pub fn DnsHostnameToComputerNameA( + Hostname: LPCSTR, ComputerName: LPCSTR, nSize: LPDWORD, + ) -> BOOL; + pub fn DnsHostnameToComputerNameExW( + Hostname: LPCWSTR, ComputerName: LPWSTR, nSize: LPDWORD, + ) -> BOOL; + pub fn DnsHostnameToComputerNameW( + Hostname: LPCWSTR, ComputerName: LPWSTR, nSize: LPDWORD, + ) -> BOOL; + pub fn DosDateTimeToFileTime(wFatDate: WORD, wFatTime: WORD, lpFileTime: LPFILETIME) -> BOOL; + // pub fn DosPathToSessionPathW(); + pub fn DuplicateHandle( + hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, + lpTargetHandle: LPHANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD, + ) -> BOOL; + pub fn EnableThreadProfiling( + ThreadHandle: HANDLE, Flags: DWORD, HardwareCounters: DWORD64, + PerformanceDataHandle: *mut HANDLE, + ) -> BOOL; + pub fn EncodePointer(Ptr: PVOID) -> PVOID; + pub fn EncodeSystemPointer(Ptr: PVOID) -> PVOID; + pub fn EndUpdateResourceA(hUpdate: HANDLE, fDiscard: BOOL) -> BOOL; + pub fn EndUpdateResourceW(hUpdate: HANDLE, fDiscard: BOOL) -> BOOL; + pub fn EnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION); + pub fn EnterSynchronizationBarrier( + lpBarrier: LPSYNCHRONIZATION_BARRIER, dwFlags: DWORD, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn EnterUmsSchedulingMode(SchedulerStartupInfo: PUMS_SCHEDULER_STARTUP_INFO) -> BOOL; + pub fn EnumCalendarInfoA( + lpCalInfoEnumProc: CALINFO_ENUMPROCA, Locale: LCID, Calendar: CALID, CalType: CALTYPE, + ) -> BOOL; + pub fn EnumCalendarInfoExA( + lpCalInfoEnumProcEx: CALINFO_ENUMPROCEXA, Locale: LCID, Calendar: CALID, CalType: CALTYPE, + ) -> BOOL; + pub fn EnumCalendarInfoExEx( + pCalInfoEnumProcExEx: CALINFO_ENUMPROCEXEX, lpLocaleName: LPCWSTR, Calendar: CALID, + lpReserved: LPCWSTR, CalType: CALTYPE, lParam: LPARAM, + ) -> BOOL; + pub fn EnumCalendarInfoExW( + lpCalInfoEnumProcEx: CALINFO_ENUMPROCEXW, Locale: LCID, Calendar: CALID, CalType: CALTYPE, + ) -> BOOL; + pub fn EnumCalendarInfoW( + lpCalInfoEnumProc: CALINFO_ENUMPROCW, Locale: LCID, Calendar: CALID, CalType: CALTYPE, + ) -> BOOL; + pub fn EnumDateFormatsA( + lpDateFmtEnumProc: DATEFMT_ENUMPROCA, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumDateFormatsExA( + lpDateFmtEnumProcEx: DATEFMT_ENUMPROCEXA, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumDateFormatsExEx( + lpDateFmtEnumProcExEx: DATEFMT_ENUMPROCEXEX, lpLocaleName: LPCWSTR, dwFlags: DWORD, + lParam: LPARAM, + ) -> BOOL; + pub fn EnumDateFormatsExW( + lpDateFmtEnumProcEx: DATEFMT_ENUMPROCEXW, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumDateFormatsW( + lpDateFmtEnumProc: DATEFMT_ENUMPROCW, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumLanguageGroupLocalesA( + lpLangGroupLocaleEnumProc: LANGGROUPLOCALE_ENUMPROCA, LanguageGroup: LGRPID, dwFlags: DWORD, + lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumLanguageGroupLocalesW( + lpLangGroupLocaleEnumProc: LANGGROUPLOCALE_ENUMPROCW, LanguageGroup: LGRPID, dwFlags: DWORD, + lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceLanguagesA( + hModule: HMODULE, lpType: LPCSTR, lpName: LPCSTR, lpEnumFunc: ENUMRESLANGPROCA, + lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceLanguagesExA( + hModule: HMODULE, lpType: LPCSTR, lpName: LPCSTR, lpEnumFunc: ENUMRESLANGPROCA, + lParam: LONG_PTR, dwFlags: DWORD, LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceLanguagesExW( + hModule: HMODULE, lpType: LPCWSTR, lpName: LPCWSTR, lpEnumFunc: ENUMRESLANGPROCW, + lParam: LONG_PTR, dwFlags: DWORD, LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceLanguagesW( + hModule: HMODULE, lpType: LPCWSTR, lpName: LPCWSTR, lpEnumFunc: ENUMRESLANGPROCW, + lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceNamesA( + hModule: HMODULE, lpType: LPCSTR, lpEnumFunc: ENUMRESNAMEPROCA, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceNamesExA( + hModule: HMODULE, lpType: LPCSTR, lpEnumFunc: ENUMRESNAMEPROCA, lParam: LONG_PTR, + dwFlags: DWORD, LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceNamesExW( + hModule: HMODULE, lpType: LPCWSTR, lpEnumFunc: ENUMRESNAMEPROCW, lParam: LONG_PTR, + dwFlags: DWORD, LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceNamesW( + hModule: HMODULE, lpType: LPCWSTR, lpEnumFunc: ENUMRESNAMEPROCW, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceTypesA( + hModule: HMODULE, lpEnumFunc: ENUMRESTYPEPROCA, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumResourceTypesExA( + hModule: HMODULE, lpEnumFunc: ENUMRESTYPEPROCA, lParam: LONG_PTR, dwFlags: DWORD, + LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceTypesExW( + hModule: HMODULE, lpEnumFunc: ENUMRESTYPEPROCW, lParam: LONG_PTR, dwFlags: DWORD, + LangId: LANGID, + ) -> BOOL; + pub fn EnumResourceTypesW( + hModule: HMODULE, lpEnumFunc: ENUMRESTYPEPROCW, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumSystemCodePagesA(lpCodePageEnumProc: CODEPAGE_ENUMPROCA, dwFlags: DWORD) -> BOOL; + pub fn EnumSystemCodePagesW(lpCodePageEnumProc: CODEPAGE_ENUMPROCW, dwFlags: DWORD) -> BOOL; + pub fn EnumSystemFirmwareTables( + FirmwareTableProviderSignature: DWORD, pFirmwareTableEnumBuffer: PVOID, BufferSize: DWORD, + ) -> UINT; + pub fn EnumSystemGeoID( + GeoClass: GEOCLASS, ParentGeoId: GEOID, lpGeoEnumProc: GEO_ENUMPROC, + ) -> BOOL; + pub fn EnumSystemLanguageGroupsA( + lpLanguageGroupEnumProc: LANGUAGEGROUP_ENUMPROCA, dwFlags: DWORD, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumSystemLanguageGroupsW( + lpLanguageGroupEnumProc: LANGUAGEGROUP_ENUMPROCW, dwFlags: DWORD, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumSystemLocalesA(lpLocaleEnumProc: LOCALE_ENUMPROCA, dwFlags: DWORD) -> BOOL; + pub fn EnumSystemLocalesEx( + lpLocaleEnumProcEx: LOCALE_ENUMPROCEX, dwFlags: DWORD, lParam: LPARAM, lpReserved: LPVOID, + ) -> BOOL; + pub fn EnumSystemLocalesW(lpLocaleEnumProc: LOCALE_ENUMPROCW, dwFlags: DWORD) -> BOOL; + pub fn EnumTimeFormatsA( + lpTimeFmtEnumProc: TIMEFMT_ENUMPROCA, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumTimeFormatsEx( + lpTimeFmtEnumProcEx: TIMEFMT_ENUMPROCEX, lpLocaleName: LPCWSTR, dwFlags: DWORD, + lParam: LPARAM, + ) -> BOOL; + pub fn EnumTimeFormatsW( + lpTimeFmtEnumProc: TIMEFMT_ENUMPROCW, Locale: LCID, dwFlags: DWORD, + ) -> BOOL; + pub fn EnumUILanguagesA( + lpUILanguageEnumProc: UILANGUAGE_ENUMPROCA, dwFlags: DWORD, lParam: LONG_PTR, + ) -> BOOL; + pub fn EnumUILanguagesW( + lpUILanguageEnumProc: UILANGUAGE_ENUMPROCW, dwFlags: DWORD, lParam: LONG_PTR, + ) -> BOOL; + // pub fn EnumerateLocalComputerNamesA(); + // pub fn EnumerateLocalComputerNamesW(); + pub fn EraseTape(hDevice: HANDLE, dwEraseType: DWORD, bImmediate: BOOL) -> DWORD; + pub fn EscapeCommFunction(hFile: HANDLE, dwFunc: DWORD) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn ExecuteUmsThread(UmsThread: PUMS_CONTEXT) -> BOOL; + pub fn ExitProcess(uExitCode: UINT); + pub fn ExitThread(dwExitCode: DWORD); + pub fn ExpandEnvironmentStringsA(lpSrc: LPCSTR, lpDst: LPSTR, nSize: DWORD) -> DWORD; + pub fn ExpandEnvironmentStringsW(lpSrc: LPCWSTR, lpDst: LPWSTR, nSize: DWORD) -> DWORD; + pub fn FatalAppExitA(uAction: UINT, lpMessageText: LPCSTR); + pub fn FatalAppExitW(uAction: UINT, lpMessageText: LPCWSTR); + pub fn FatalExit(ExitCode: c_int); + pub fn FileTimeToDosDateTime( + lpFileTime: *const FILETIME, lpFatDate: LPWORD, lpFatTime: LPWORD, + ) -> BOOL; + pub fn FileTimeToLocalFileTime( + lpFileTime: *const FILETIME, lpLocalFileTime: LPFILETIME, + ) -> BOOL; + pub fn FileTimeToSystemTime( + lpFileTime: *const FILETIME, lpSystemTime: LPSYSTEMTIME, + ) -> BOOL; + pub fn FillConsoleOutputAttribute( + hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfAttrsWritten: LPDWORD, + ) -> BOOL; + pub fn FillConsoleOutputCharacterA( + hConsoleOutput: HANDLE, cCharacter: CHAR, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfCharsWritten: LPDWORD, + ) -> BOOL; + pub fn FillConsoleOutputCharacterW( + hConsoleOutput: HANDLE, cCharacter: WCHAR, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfCharsWritten: LPDWORD, + ) -> BOOL; + pub fn FindActCtxSectionGuid( + dwFlags: DWORD, lpExtensionGuid: *const GUID, ulSectionId: ULONG, lpGuidToFind: *const GUID, + ReturnedData: PACTCTX_SECTION_KEYED_DATA, + ) -> BOOL; + pub fn FindActCtxSectionStringA( + dwFlags: DWORD, lpExtensionGuid: *const GUID, ulSectionId: ULONG, lpStringToFind: LPCSTR, + ReturnedData: PACTCTX_SECTION_KEYED_DATA, + ) -> BOOL; + pub fn FindActCtxSectionStringW( + dwFlags: DWORD, lpExtensionGuid: *const GUID, ulSectionId: ULONG, lpStringToFind: LPCWSTR, + ReturnedData: PACTCTX_SECTION_KEYED_DATA, + ) -> BOOL; + pub fn FindAtomA(lpString: LPCSTR) -> ATOM; + pub fn FindAtomW(lpString: LPCWSTR) -> ATOM; + pub fn FindClose(hFindFile: HANDLE) -> BOOL; + pub fn FindCloseChangeNotification(hChangeHandle: HANDLE) -> BOOL; + pub fn FindFirstChangeNotificationA( + lpPathName: LPCSTR, bWatchSubtree: BOOL, dwNotifyFilter: DWORD, + ) -> HANDLE; + pub fn FindFirstChangeNotificationW( + lpPathName: LPCWSTR, bWatchSubtree: BOOL, dwNotifyFilter: DWORD, + ) -> HANDLE; + pub fn FindFirstFileA(lpFileName: LPCSTR, lpFindFileData: LPWIN32_FIND_DATAA) -> HANDLE; + pub fn FindFirstFileExA( + lpFileName: LPCSTR, fInfoLevelId: FINDEX_INFO_LEVELS, lpFindFileData: LPVOID, + fSearchOp: FINDEX_SEARCH_OPS, lpSearchFilter: LPVOID, dwAdditionalFlags: DWORD, + ) -> HANDLE; + pub fn FindFirstFileExW( + lpFileName: LPCWSTR, fInfoLevelId: FINDEX_INFO_LEVELS, lpFindFileData: LPVOID, + fSearchOp: FINDEX_SEARCH_OPS, lpSearchFilter: LPVOID, dwAdditionalFlags: DWORD, + ) -> HANDLE; + pub fn FindFirstFileNameTransactedW( + lpFileName: LPCWSTR, dwFlags: DWORD, StringLength: LPDWORD, LinkName: PWSTR, + hTransaction: HANDLE, + ) -> HANDLE; + pub fn FindFirstFileNameW( + lpFileName: LPCWSTR, dwFlags: DWORD, StringLength: LPDWORD, LinkName: PWSTR, + ) -> HANDLE; + pub fn FindFirstFileTransactedA( + lpFileName: LPCSTR, fInfoLevelId: FINDEX_INFO_LEVELS, lpFindFileData: LPVOID, + fSearchOp: FINDEX_SEARCH_OPS, lpSearchFilter: LPVOID, dwAdditionalFlags: DWORD, + hTransaction: HANDLE, + ) -> HANDLE; + pub fn FindFirstFileTransactedW( + lpFileName: LPCWSTR, fInfoLevelId: FINDEX_INFO_LEVELS, lpFindFileData: LPVOID, + fSearchOp: FINDEX_SEARCH_OPS, lpSearchFilter: LPVOID, dwAdditionalFlags: DWORD, + hTransaction: HANDLE, + ) -> HANDLE; + pub fn FindFirstFileW(lpFileName: LPCWSTR, lpFindFileData: LPWIN32_FIND_DATAW) -> HANDLE; + pub fn FindFirstStreamTransactedW( + lpFileName: LPCWSTR, InfoLevel: STREAM_INFO_LEVELS, lpFindStreamData: LPVOID, + dwFlags: DWORD, hTransaction: HANDLE, + ) -> HANDLE; + pub fn FindFirstStreamW( + lpFileName: LPCWSTR, InfoLevel: STREAM_INFO_LEVELS, lpFindStreamData: LPVOID, + dwFlags: DWORD, + ) -> HANDLE; + pub fn FindFirstVolumeA(lpszVolumeName: LPSTR, cchBufferLength: DWORD) -> HANDLE; + pub fn FindFirstVolumeMountPointA( + lpszRootPathName: LPCSTR, lpszVolumeMountPoint: LPSTR, cchBufferLength: DWORD, + ) -> HANDLE; + pub fn FindFirstVolumeMountPointW( + lpszRootPathName: LPCWSTR, lpszVolumeMountPoint: LPWSTR, cchBufferLength: DWORD, + ) -> HANDLE; + pub fn FindFirstVolumeW(lpszVolumeName: LPWSTR, cchBufferLength: DWORD) -> HANDLE; + pub fn FindNLSString( + Locale: LCID, dwFindNLSStringFlags: DWORD, lpStringSource: LPCWSTR, cchSource: c_int, + lpStringValue: LPCWSTR, cchValue: c_int, pcchFound: LPINT, + ) -> c_int; + pub fn FindNLSStringEx( + lpLocaleName: LPCWSTR, dwFindNLSStringFlags: DWORD, lpStringSource: LPCWSTR, + cchSource: c_int, lpStringValue: LPCWSTR, cchValue: c_int, pcchFound: LPINT, + lpVersionInformation: LPNLSVERSIONINFO, lpReserved: LPVOID, sortHandle: LPARAM, + ) -> c_int; + pub fn FindNextChangeNotification(hChangeHandle: HANDLE) -> BOOL; + pub fn FindNextFileA(hFindFile: HANDLE, lpFindFileData: LPWIN32_FIND_DATAA) -> BOOL; + pub fn FindNextFileNameW(hFindStream: HANDLE, StringLength: LPDWORD, LinkName: PWSTR) -> BOOL; + pub fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: LPWIN32_FIND_DATAW) -> BOOL; + pub fn FindNextStreamW(hFindStream: HANDLE, lpFindStreamData: LPVOID) -> BOOL; + pub fn FindNextVolumeA( + hFindVolume: HANDLE, lpszVolumeName: LPSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn FindNextVolumeMountPointA( + hFindVolumeMountPoint: HANDLE, lpszVolumeMountPoint: LPSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn FindNextVolumeMountPointW( + hFindVolumeMountPoint: HANDLE, lpszVolumeMountPoint: LPWSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn FindNextVolumeW( + hFindVolume: HANDLE, lpszVolumeName: LPWSTR, cchBufferLength: DWORD, + ) -> BOOL; + // pub fn FindPackagesByPackageFamily(); + pub fn FindResourceA(hModule: HMODULE, lpName: LPCSTR, lpType: LPCSTR) -> HRSRC; + pub fn FindResourceExA( + hModule: HMODULE, lpName: LPCSTR, lpType: LPCSTR, wLanguage: WORD, + ) -> HRSRC; + pub fn FindResourceExW( + hModule: HMODULE, lpName: LPCWSTR, lpType: LPCWSTR, wLanguage: WORD, + ) -> HRSRC; + pub fn FindResourceW(hModule: HMODULE, lpName: LPCWSTR, lpType: LPCWSTR) -> HRSRC; + pub fn FindStringOrdinal( + dwFindStringOrdinalFlags: DWORD, lpStringSource: LPCWSTR, cchSource: c_int, + lpStringValue: LPCWSTR, cchValue: c_int, bIgnoreCase: BOOL, + ) -> c_int; + pub fn FindVolumeClose(hFindVolume: HANDLE) -> BOOL; + pub fn FindVolumeMountPointClose(hFindVolumeMountPoint: HANDLE) -> BOOL; + pub fn FlsAlloc(lpCallback: PFLS_CALLBACK_FUNCTION) -> DWORD; + pub fn FlsFree(dwFlsIndex: DWORD) -> BOOL; + pub fn FlsGetValue(dwFlsIndex: DWORD) -> PVOID; + pub fn FlsSetValue(dwFlsIndex: DWORD, lpFlsData: PVOID) -> BOOL; + pub fn FlushConsoleInputBuffer(hConsoleInput: HANDLE) -> BOOL; + pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL; + pub fn FlushInstructionCache(hProcess: HANDLE, lpBaseAddress: LPCVOID, dwSize: SIZE_T) -> BOOL; + pub fn FlushProcessWriteBuffers(); + pub fn FlushViewOfFile(lpBaseAddress: LPCVOID, dwNumberOfBytesToFlush: SIZE_T) -> BOOL; + pub fn FoldStringA( + dwMapFlags: DWORD, lpSrcStr: LPCSTR, cchSrc: c_int, lpDestStr: LPSTR, cchDest: c_int, + ) -> c_int; + pub fn FoldStringW( + dwMapFlags: DWORD, lpSrcStr: LPCWCH, cchSrc: c_int, lpDestStr: LPWSTR, cchDest: c_int, + ) -> c_int; + // pub fn FormatApplicationUserModelId(); + pub fn FormatMessageA( + dwFlags: DWORD, lpSource: LPCVOID, dwMessageId: DWORD, dwLanguageId: DWORD, + lpBuffer: LPSTR, nSize: DWORD, Arguments: *mut va_list, + ) -> DWORD; + pub fn FormatMessageW( + dwFlags: DWORD, lpSource: LPCVOID, dwMessageId: DWORD, dwLanguageId: DWORD, + lpBuffer: LPWSTR, nSize: DWORD, Arguments: *mut va_list, + ) -> DWORD; + pub fn FreeConsole() -> BOOL; + pub fn FreeEnvironmentStringsA(penv: LPCH) -> BOOL; + pub fn FreeEnvironmentStringsW(penv: LPWCH) -> BOOL; + pub fn FreeLibrary(hLibModule: HMODULE) -> BOOL; + pub fn FreeLibraryAndExitThread(hLibModule: HMODULE, dwExitCode: DWORD); + pub fn FreeLibraryWhenCallbackReturns(pci: PTP_CALLBACK_INSTANCE, module: HMODULE); + pub fn FreeResource(hResData: HGLOBAL) -> BOOL; + pub fn FreeUserPhysicalPages( + hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, + ) -> BOOL; + pub fn GenerateConsoleCtrlEvent(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL; + pub fn GetACP() -> UINT; + pub fn GetActiveProcessorCount(GroupNumber: WORD) -> DWORD; + pub fn GetActiveProcessorGroupCount() -> WORD; + pub fn GetAppContainerAce( + Acl: PACL, StartingAceIndex: DWORD, AppContainerAce: *mut PVOID, + AppContainerAceIndex: *mut DWORD, + ) -> BOOL; + pub fn GetAppContainerNamedObjectPath( + Token: HANDLE, AppContainerSid: PSID, ObjectPathLength: ULONG, ObjectPath: LPWSTR, + ReturnLength: PULONG, + ) -> BOOL; + pub fn GetApplicationRecoveryCallback( + hProcess: HANDLE, pRecoveryCallback: *mut APPLICATION_RECOVERY_CALLBACK, + ppvParameter: *mut PVOID, pdwPingInterval: PDWORD, pdwFlags: PDWORD, + ) -> HRESULT; + pub fn GetApplicationRestartSettings( + hProcess: HANDLE, pwzCommandline: PWSTR, pcchSize: PDWORD, pdwFlags: PDWORD, + ) -> HRESULT; + // pub fn GetApplicationUserModelId(); + pub fn GetAtomNameA(nAtom: ATOM, lpBuffer: LPSTR, nSize: c_int) -> UINT; + pub fn GetAtomNameW(nAtom: ATOM, lpBuffer: LPWSTR, nSize: c_int) -> UINT; + pub fn GetBinaryTypeA(lpApplicationName: LPCSTR, lpBinaryType: LPDWORD) -> BOOL; + pub fn GetBinaryTypeW(lpApplicationName: LPCWSTR, lpBinaryType: LPDWORD) -> BOOL; + pub fn GetCPInfo(CodePage: UINT, lpCPInfo: LPCPINFO) -> BOOL; + pub fn GetCPInfoExA(CodePage: UINT, dwFlags: DWORD, lpCPInfoEx: LPCPINFOEXA) -> BOOL; + pub fn GetCPInfoExW(CodePage: UINT, dwFlags: DWORD, lpCPInfoEx: LPCPINFOEXW) -> BOOL; + pub fn GetCachedSigningLevel( + File: HANDLE, Flags: PULONG, SigningLevel: PULONG, Thumbprint: PUCHAR, + ThumbprintSize: PULONG, ThumbprintAlgorithm: PULONG, + ) -> BOOL; + pub fn GetCalendarInfoA( + Locale: LCID, Calendar: CALID, CalType: CALTYPE, lpCalData: LPSTR, cchData: c_int, + lpValue: LPDWORD, + ) -> c_int; + pub fn GetCalendarInfoEx( + lpLocaleName: LPCWSTR, Calendar: CALID, lpReserved: LPCWSTR, CalType: CALTYPE, + lpCalData: LPWSTR, cchData: c_int, lpValue: LPDWORD, + ) -> c_int; + pub fn GetCalendarInfoW( + Locale: LCID, Calendar: CALID, CalType: CALTYPE, lpCalData: LPWSTR, cchData: c_int, + lpValue: LPDWORD, + ) -> c_int; + pub fn GetCommConfig(hCommDev: HANDLE, lpCC: LPCOMMCONFIG, lpdwSize: LPDWORD) -> BOOL; + pub fn GetCommMask(hFile: HANDLE, lpEvtMask: LPDWORD) -> BOOL; + pub fn GetCommModemStatus(hFile: HANDLE, lpModemStat: LPDWORD) -> BOOL; + pub fn GetCommProperties(hFile: HANDLE, lpCommProp: LPCOMMPROP) -> BOOL; + pub fn GetCommState(hFile: HANDLE, lpDCB: LPDCB) -> BOOL; + pub fn GetCommTimeouts(hFile: HANDLE, lpCommTimeouts: LPCOMMTIMEOUTS) -> BOOL; + pub fn GetCommandLineA() -> LPSTR; + pub fn GetCommandLineW() -> LPWSTR; + pub fn GetCompressedFileSizeA(lpFileName: LPCSTR, lpFileSizeHigh: LPDWORD) -> DWORD; + pub fn GetCompressedFileSizeTransactedA( + lpFileName: LPCSTR, lpFileSizeHigh: LPDWORD, hTransaction: HANDLE, + ) -> DWORD; + pub fn GetCompressedFileSizeTransactedW( + lpFileName: LPCWSTR, lpFileSizeHigh: LPDWORD, hTransaction: HANDLE, + ); + pub fn GetCompressedFileSizeW(lpFileName: LPCWSTR, lpFileSizeHigh: LPDWORD) -> DWORD; + pub fn GetComputerNameA(lpBuffer: LPSTR, nSize: LPDWORD) -> BOOL; + pub fn GetComputerNameExA( + NameType: COMPUTER_NAME_FORMAT, lpBuffer: LPSTR, nSize: LPDWORD, + ) -> BOOL; + pub fn GetComputerNameExW( + NameType: COMPUTER_NAME_FORMAT, lpBuffer: LPWSTR, nSize: LPDWORD, + ) -> BOOL; + pub fn GetComputerNameW(lpBuffer: LPWSTR, nSize: LPDWORD) -> BOOL; + pub fn GetConsoleAliasA( + Source: LPSTR, TargetBuffer: LPSTR, TargetBufferLength: DWORD, ExeName: LPSTR, + ) -> DWORD; + pub fn GetConsoleAliasExesA(ExeNameBuffer: LPSTR, ExeNameBufferLength: DWORD) -> DWORD; + pub fn GetConsoleAliasExesLengthA() -> DWORD; + pub fn GetConsoleAliasExesLengthW() -> DWORD; + pub fn GetConsoleAliasExesW(ExeNameBuffer: LPWSTR, ExeNameBufferLength: DWORD) -> DWORD; + pub fn GetConsoleAliasW( + Source: LPWSTR, TargetBuffer: LPWSTR, TargetBufferLength: DWORD, ExeName: LPWSTR, + ) -> DWORD; + pub fn GetConsoleAliasesA( + AliasBuffer: LPSTR, AliasBufferLength: DWORD, ExeName: LPSTR, + ) -> DWORD; + pub fn GetConsoleAliasesLengthA(ExeName: LPSTR) -> DWORD; + pub fn GetConsoleAliasesLengthW(ExeName: LPWSTR) -> DWORD; + pub fn GetConsoleAliasesW( + AliasBuffer: LPWSTR, AliasBufferLength: DWORD, ExeName: LPWSTR, + ) -> DWORD; + pub fn GetConsoleCP() -> UINT; + pub fn GetConsoleCursorInfo( + hConsoleOutput: HANDLE, lpConsoleCursorInfo: PCONSOLE_CURSOR_INFO, + ) -> BOOL; + pub fn GetConsoleDisplayMode(lpModeFlags: LPDWORD) -> BOOL; + pub fn GetConsoleFontSize(hConsoleOutput: HANDLE, nFont: DWORD) -> COORD; + pub fn GetConsoleHistoryInfo(lpConsoleHistoryInfo: PCONSOLE_HISTORY_INFO) -> BOOL; + pub fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; + pub fn GetConsoleOriginalTitleA(lpConsoleTitle: LPSTR, nSize: DWORD) -> DWORD; + pub fn GetConsoleOriginalTitleW(lpConsoleTitle: LPWSTR, nSize: DWORD) -> DWORD; + pub fn GetConsoleOutputCP() -> UINT; + pub fn GetConsoleProcessList(lpdwProcessList: LPDWORD, dwProcessCount: DWORD) -> DWORD; + pub fn GetConsoleScreenBufferInfo( + hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO, + ) -> BOOL; + pub fn GetConsoleScreenBufferInfoEx( + hConsoleOutput: HANDLE, lpConsoleScreenBufferInfoEx: PCONSOLE_SCREEN_BUFFER_INFOEX, + ) -> BOOL; + pub fn GetConsoleSelectionInfo(lpConsoleSelectionInfo: PCONSOLE_SELECTION_INFO) -> BOOL; + pub fn GetConsoleTitleA(lpConsoleTitle: LPSTR, nSize: DWORD) -> DWORD; + pub fn GetConsoleTitleW(lpConsoleTitle: LPWSTR, nSize: DWORD) -> DWORD; + pub fn GetConsoleWindow() -> HWND; + pub fn GetCurrencyFormatA( + Locale: LCID, dwFlags: DWORD, lpValue: LPCSTR, lpFormat: *const CURRENCYFMTA, + lpCurrencyStr: LPSTR, cchCurrency: c_int, + ) -> c_int; + pub fn GetCurrencyFormatEx( + lpLocaleName: LPCWSTR, dwFlags: DWORD, lpValue: LPCWSTR, lpFormat: *const CURRENCYFMTW, + lpCurrencyStr: LPWSTR, cchCurrency: c_int, + ) -> c_int; + pub fn GetCurrencyFormatW( + Locale: LCID, dwFlags: DWORD, lpValue: LPCWSTR, lpFormat: *const CURRENCYFMTW, + lpCurrencyStr: LPWSTR, cchCurrency: c_int, + ) -> c_int; + pub fn GetCurrentActCtx(lphActCtx: *mut HANDLE) -> BOOL; + // pub fn GetCurrentApplicationUserModelId(); + pub fn GetCurrentConsoleFont( + hConsoleOutput: HANDLE, bMaximumWindow: BOOL, lpConsoleCurrentFont: PCONSOLE_FONT_INFO, + ) -> BOOL; + pub fn GetCurrentConsoleFontEx( + hConsoleOutput: HANDLE, bMaximumWindow: BOOL, lpConsoleCurrentFontEx: PCONSOLE_FONT_INFOEX, + ) -> BOOL; + pub fn GetCurrentDirectoryA(nBufferLength: DWORD, lpBuffer: LPSTR) -> DWORD; + pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; + // pub fn GetCurrentPackageFamilyName(); + // pub fn GetCurrentPackageFullName(); + // pub fn GetCurrentPackageId(); + // pub fn GetCurrentPackageInfo(); + // pub fn GetCurrentPackagePath(); + pub fn GetCurrentProcess() -> HANDLE; + pub fn GetCurrentProcessId() -> DWORD; + pub fn GetCurrentProcessorNumber() -> DWORD; + pub fn GetCurrentProcessorNumberEx(ProcNumber: PPROCESSOR_NUMBER); + pub fn GetCurrentThread() -> HANDLE; + pub fn GetCurrentThreadId() -> DWORD; + pub fn GetCurrentThreadStackLimits(LowLimit: PULONG_PTR, HighLimit: PULONG_PTR); + #[cfg(target_arch = "x86_64")] + pub fn GetCurrentUmsThread() -> PUMS_CONTEXT; + pub fn GetDateFormatA( + Locale: LCID, dwFlags: DWORD, lpDate: *const SYSTEMTIME, lpFormat: LPCSTR, lpDateStr: LPSTR, + cchDate: c_int, + ) -> c_int; + pub fn GetDateFormatEx( + lpLocaleName: LPCWSTR, dwFlags: DWORD, lpDate: *const SYSTEMTIME, lpFormat: LPCWSTR, + lpDateStr: LPWSTR, cchDate: c_int, lpCalendar: LPCWSTR, + ) -> c_int; + pub fn GetDateFormatW( + Locale: LCID, dwFlags: DWORD, lpDate: *const SYSTEMTIME, lpFormat: LPCWSTR, + lpDateStr: LPWSTR, cchDate: c_int, + ) -> c_int; + pub fn GetDefaultCommConfigA(lpszName: LPCSTR, lpCC: LPCOMMCONFIG, lpdwSize: LPDWORD) -> BOOL; + pub fn GetDefaultCommConfigW(lpszName: LPCWSTR, lpCC: LPCOMMCONFIG, lpdwSize: LPDWORD) -> BOOL; + pub fn GetDevicePowerState(hDevice: HANDLE, pfOn: *mut BOOL) -> BOOL; + pub fn GetDiskFreeSpaceA( + lpRootPathName: LPCSTR, lpSectorsPerCluster: LPDWORD, lpBytesPerSector: LPDWORD, + lpNumberOfFreeClusters: LPDWORD, lpTotalNumberOfClusters: LPDWORD, + ) -> BOOL; + pub fn GetDiskFreeSpaceExA( + lpDirectoryName: LPCSTR, lpFreeBytesAvailableToCaller: PULARGE_INTEGER, + lpTotalNumberOfBytes: PULARGE_INTEGER, lpTotalNumberOfFreeBytes: PULARGE_INTEGER, + ) -> BOOL; + pub fn GetDiskFreeSpaceExW( + lpDirectoryName: LPCWSTR, lpFreeBytesAvailableToCaller: PULARGE_INTEGER, + lpTotalNumberOfBytes: PULARGE_INTEGER, lpTotalNumberOfFreeBytes: PULARGE_INTEGER, + ) -> BOOL; + pub fn GetDiskFreeSpaceW( + lpRootPathName: LPCWSTR, lpSectorsPerCluster: LPDWORD, lpBytesPerSector: LPDWORD, + lpNumberOfFreeClusters: LPDWORD, lpTotalNumberOfClusters: LPDWORD, + ) -> BOOL; + pub fn GetDllDirectoryA(nBufferLength: DWORD, lpBuffer: LPSTR) -> DWORD; + pub fn GetDllDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; + pub fn GetDriveTypeA(lpRootPathName: LPCSTR) -> UINT; + pub fn GetDriveTypeW(lpRootPathName: LPCWSTR) -> UINT; + pub fn GetDurationFormat( + Locale: LCID, dwFlags: DWORD, lpDuration: *const SYSTEMTIME, ullDuration: ULONGLONG, + lpFormat: LPCWSTR, lpDurationStr: LPWSTR, cchDuration: c_int, + ) -> c_int; + pub fn GetDurationFormatEx( + lpLocaleName: LPCWSTR, dwFlags: DWORD, lpDuration: *const SYSTEMTIME, + ullDuration: ULONGLONG, lpFormat: LPCWSTR, lpDurationStr: LPWSTR, cchDuration: c_int, + ) -> c_int; + pub fn GetDynamicTimeZoneInformation( + pTimeZoneInformation: PDYNAMIC_TIME_ZONE_INFORMATION, + ) -> DWORD; + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn GetEnabledXStateFeatures() -> DWORD64; + pub fn GetEnvironmentStrings() -> LPCH; + pub fn GetEnvironmentStringsW() -> LPWCH; + pub fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) -> DWORD; + pub fn GetEnvironmentVariableW(lpName: LPCWSTR, lpBuffer: LPWSTR, nSize: DWORD) -> DWORD; + // pub fn GetEraNameCountedString(); + pub fn GetErrorMode() -> UINT; + pub fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL; + pub fn GetExitCodeThread(hThread: HANDLE, lpExitCode: LPDWORD) -> BOOL; + pub fn GetFileAttributesA(lpFileName: LPCSTR) -> DWORD; + pub fn GetFileAttributesExA( + lpFileName: LPCSTR, fInfoLevelId: GET_FILEEX_INFO_LEVELS, lpFileInformation: LPVOID, + ) -> BOOL; + pub fn GetFileAttributesExW( + lpFileName: LPCWSTR, fInfoLevelId: GET_FILEEX_INFO_LEVELS, lpFileInformation: LPVOID, + ) -> BOOL; + pub fn GetFileAttributesTransactedA( + lpFileName: LPCSTR, fInfoLevelId: GET_FILEEX_INFO_LEVELS, lpFileInformation: LPVOID, + hTransaction: HANDLE, + ) -> BOOL; + pub fn GetFileAttributesTransactedW( + lpFileName: LPCWSTR, fInfoLevelId: GET_FILEEX_INFO_LEVELS, lpFileInformation: LPVOID, + hTransaction: HANDLE, + ) -> BOOL; + pub fn GetFileAttributesW(lpFileName: LPCWSTR) -> DWORD; + pub fn GetFileBandwidthReservation( + hFile: HANDLE, lpPeriodMilliseconds: LPDWORD, lpBytesPerPeriod: LPDWORD, + pDiscardable: LPBOOL, lpTransferSize: LPDWORD, lpNumOutstandingRequests: LPDWORD, + ) -> BOOL; + pub fn GetFileInformationByHandle( + hFile: HANDLE, lpFileInformation: LPBY_HANDLE_FILE_INFORMATION, + ) -> BOOL; + pub fn GetFileInformationByHandleEx( + hFile: HANDLE, FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, lpFileInformation: LPVOID, + dwBufferSize: DWORD, + ) -> BOOL; + pub fn GetFileMUIInfo( + dwFlags: DWORD, pcwszFilePath: PCWSTR, pFileMUIInfo: PFILEMUIINFO, + pcbFileMUIInfo: *mut DWORD, + ) -> BOOL; + pub fn GetFileMUIPath( + dwFlags: DWORD, pcwszFilePath: PCWSTR, pwszLanguage: PWSTR, pcchLanguage: PULONG, + pwszFileMUIPath: PWSTR, pcchFileMUIPath: PULONG, pululEnumerator: PULONGLONG, + ) -> BOOL; + pub fn GetFileSize(hFile: HANDLE, lpFileSizeHigh: LPDWORD) -> DWORD; + pub fn GetFileSizeEx(hFile: HANDLE, lpFileSize: PLARGE_INTEGER) -> BOOL; + pub fn GetFileTime( + hFile: HANDLE, lpCreationTime: LPFILETIME, lpLastAccessTime: LPFILETIME, + lpLastWriteTime: LPFILETIME, + ) -> BOOL; + pub fn GetFileType(hFile: HANDLE) -> DWORD; + pub fn GetFinalPathNameByHandleA( + hFile: HANDLE, lpszFilePath: LPSTR, cchFilePath: DWORD, dwFlags: DWORD, + ) -> DWORD; + pub fn GetFinalPathNameByHandleW( + hFile: HANDLE, lpszFilePath: LPWSTR, cchFilePath: DWORD, dwFlags: DWORD, + ) -> DWORD; + pub fn GetFirmwareEnvironmentVariableA( + lpName: LPCSTR, lpGuid: LPCSTR, pBuffer: PVOID, nSize: DWORD, + ) -> DWORD; + pub fn GetFirmwareEnvironmentVariableExA( + lpName: LPCSTR, lpGuid: LPCSTR, pBuffer: PVOID, nSize: DWORD, pdwAttribubutes: PDWORD, + ) -> DWORD; + pub fn GetFirmwareEnvironmentVariableExW( + lpName: LPCWSTR, lpGuid: LPCWSTR, pBuffer: PVOID, nSize: DWORD, pdwAttribubutes: PDWORD, + ) -> DWORD; + pub fn GetFirmwareEnvironmentVariableW( + lpName: LPCWSTR, lpGuid: LPCWSTR, pBuffer: PVOID, nSize: DWORD, + ) -> DWORD; + pub fn GetFirmwareType(FirmwareType: PFIRMWARE_TYPE) -> BOOL; + pub fn GetFullPathNameA( + lpFileName: LPCSTR, nBufferLength: DWORD, lpBuffer: LPSTR, lpFilePart: *mut LPSTR, + ) -> DWORD; + pub fn GetFullPathNameTransactedA( + lpFileName: LPCSTR, nBufferLength: DWORD, lpBuffer: LPSTR, lpFilePart: *mut LPSTR, + hTransaction: HANDLE, + ) -> DWORD; + pub fn GetFullPathNameTransactedW( + lpFileName: LPCWSTR, nBufferLength: DWORD, lpBuffer: LPWSTR, lpFilePart: *mut LPWSTR, + hTransaction: HANDLE, + ); + pub fn GetFullPathNameW( + lpFileName: LPCWSTR, nBufferLength: DWORD, lpBuffer: LPWSTR, lpFilePart: *mut LPWSTR, + ) -> DWORD; + pub fn GetGeoInfoA( + Location: GEOID, GeoType: GEOTYPE, lpGeoData: LPSTR, cchData: c_int, LangId: LANGID, + ) -> c_int; + pub fn GetGeoInfoW( + Location: GEOID, GeoType: GEOTYPE, lpGeoData: LPWSTR, cchData: c_int, LangId: LANGID, + ) -> c_int; + pub fn GetHandleInformation(hObject: HANDLE, lpdwFlags: LPDWORD) -> BOOL; + pub fn GetLargePageMinimum() -> SIZE_T; + pub fn GetLargestConsoleWindowSize(hConsoleOutput: HANDLE) -> COORD; + pub fn GetLastError() -> DWORD; + pub fn GetLocalTime(lpSystemTime: LPSYSTEMTIME); + pub fn GetLocaleInfoA( + Locale: LCID, LCType: LCTYPE, lpLCData: LPSTR, cchData: c_int, + ) -> c_int; + pub fn GetLocaleInfoEx( + lpLocaleName: LPCWSTR, LCType: LCTYPE, lpLCData: LPWSTR, cchData: c_int, + ) -> c_int; + pub fn GetLocaleInfoW( + Locale: LCID, LCType: LCTYPE, lpLCData: LPWSTR, cchData: c_int, + ) -> c_int; + pub fn GetLogicalDriveStringsA(nBufferLength: DWORD, lpBuffer: LPSTR) -> DWORD; + pub fn GetLogicalDriveStringsW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; + pub fn GetLogicalDrives() -> DWORD; + pub fn GetLogicalProcessorInformation( + Buffer: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, ReturnedLength: PDWORD, + ) -> BOOL; + pub fn GetLogicalProcessorInformationEx( + RelationshipType: LOGICAL_PROCESSOR_RELATIONSHIP, + Buffer: PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, + ReturnedLength: PDWORD, + ) -> BOOL; + pub fn GetLongPathNameA(lpszShortPath: LPCSTR, lpszLongPath: LPSTR, cchBuffer: DWORD) -> DWORD; + pub fn GetLongPathNameTransactedA( + lpszShortPath: LPCSTR, lpszLongPath: LPSTR, cchBuffer: DWORD, hTransaction: HANDLE, + ) -> DWORD; + pub fn GetLongPathNameTransactedW( + lpszShortPath: LPCWSTR, lpszLongPath: LPWSTR, cchBuffer: DWORD, hTransaction: HANDLE, + ) -> DWORD; + pub fn GetLongPathNameW( + lpszShortPath: LPCWSTR, lpszLongPath: LPWSTR, cchBuffer: DWORD, + ) -> DWORD; + pub fn GetMailslotInfo( + hMailslot: HANDLE, lpMaxMessageSize: LPDWORD, lpNextSize: LPDWORD, lpMessageCount: LPDWORD, + lpReadTimeout: LPDWORD, + ) -> BOOL; + pub fn GetMaximumProcessorCount(GroupNumber: WORD) -> DWORD; + pub fn GetMaximumProcessorGroupCount() -> WORD; + pub fn GetMemoryErrorHandlingCapabilities(Capabilities: PULONG) -> BOOL; + pub fn GetModuleFileNameA( + hModule: HMODULE, lpFilename: LPSTR, nSize: DWORD, + ) -> DWORD; + pub fn GetModuleFileNameW( + hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn GetModuleHandleA(lpModuleName: LPCSTR) -> HMODULE; + pub fn GetModuleHandleExA( + dwFlags: DWORD, lpModuleName: LPCSTR, phModule: *mut HMODULE, + ) -> BOOL; + pub fn GetModuleHandleExW( + dwFlags: DWORD, lpModuleName: LPCWSTR, phModule: *mut HMODULE, + ) -> BOOL; + pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; + pub fn GetNLSVersion( + Function: NLS_FUNCTION, Locale: LCID, lpVersionInformation: LPNLSVERSIONINFO, + ) -> BOOL; + pub fn GetNLSVersionEx( + function: NLS_FUNCTION, lpLocaleName: LPCWSTR, lpVersionInformation: LPNLSVERSIONINFOEX, + ) -> BOOL; + // pub fn GetNamedPipeAttribute(); + pub fn GetNamedPipeClientComputerNameA( + Pipe: HANDLE, ClientComputerName: LPSTR, ClientComputerNameLength: ULONG, + ) -> BOOL; + pub fn GetNamedPipeClientComputerNameW( + Pipe: HANDLE, ClientComputerName: LPWSTR, ClientComputerNameLength: ULONG, + ) -> BOOL; + pub fn GetNamedPipeClientProcessId(Pipe: HANDLE, ClientProcessId: PULONG) -> BOOL; + pub fn GetNamedPipeClientSessionId(Pipe: HANDLE, ClientSessionId: PULONG) -> BOOL; + pub fn GetNamedPipeHandleStateA( + hNamedPipe: HANDLE, lpState: LPDWORD, lpCurInstances: LPDWORD, + lpMaxCollectionCount: LPDWORD, lpCollectDataTimeout: LPDWORD, lpUserName: LPSTR, + nMaxUserNameSize: DWORD, + ) -> BOOL; + pub fn GetNamedPipeHandleStateW( + hNamedPipe: HANDLE, lpState: LPDWORD, lpCurInstances: LPDWORD, + lpMaxCollectionCount: LPDWORD, lpCollectDataTimeout: LPDWORD, lpUserName: LPWSTR, + nMaxUserNameSize: DWORD, + ) -> BOOL; + pub fn GetNamedPipeInfo( + hNamedPipe: HANDLE, lpFlags: LPDWORD, lpOutBufferSize: LPDWORD, lpInBufferSize: LPDWORD, + lpMaxInstances: LPDWORD, + ) -> BOOL; + pub fn GetNamedPipeServerProcessId(Pipe: HANDLE, ServerProcessId: PULONG) -> BOOL; + pub fn GetNamedPipeServerSessionId(Pipe: HANDLE, ServerSessionId: PULONG) -> BOOL; + pub fn GetNativeSystemInfo(lpSystemInfo: LPSYSTEM_INFO); + #[cfg(target_arch = "x86_64")] + pub fn GetNextUmsListItem(UmsContext: PUMS_CONTEXT) -> PUMS_CONTEXT; + pub fn GetNumaAvailableMemoryNode(Node: UCHAR, AvailableBytes: PULONGLONG) -> BOOL; + pub fn GetNumaAvailableMemoryNodeEx(Node: USHORT, AvailableBytes: PULONGLONG) -> BOOL; + pub fn GetNumaHighestNodeNumber(HighestNodeNumber: PULONG) -> BOOL; + pub fn GetNumaNodeNumberFromHandle(hFile: HANDLE, NodeNumber: PUSHORT) -> BOOL; + pub fn GetNumaNodeProcessorMask(Node: UCHAR, ProcessorMask: PULONGLONG) -> BOOL; + pub fn GetNumaNodeProcessorMaskEx(Node: USHORT, ProcessorMask: PGROUP_AFFINITY) -> BOOL; + pub fn GetNumaProcessorNode(Processor: UCHAR, NodeNumber: PUCHAR) -> BOOL; + pub fn GetNumaProcessorNodeEx(Processor: PPROCESSOR_NUMBER, NodeNumber: PUSHORT) -> BOOL; + pub fn GetNumaProximityNode(ProximityId: ULONG, NodeNumber: PUCHAR) -> BOOL; + pub fn GetNumaProximityNodeEx(ProximityId: ULONG, NodeNumber: PUSHORT) -> BOOL; + pub fn GetNumberFormatA( + Locale: LCID, dwFlags: DWORD, lpValue: LPCSTR, lpFormat: *const NUMBERFMTA, + lpNumberStr: LPSTR, cchNumber: c_int, + ) -> c_int; + pub fn GetNumberFormatEx( + lpLocaleName: LPCWSTR, dwFlags: DWORD, lpValue: LPCWSTR, lpFormat: *const NUMBERFMTW, + lpNumberStr: LPWSTR, cchNumber: c_int, + ) -> c_int; + pub fn GetNumberFormatW( + Locale: LCID, dwFlags: DWORD, lpValue: LPCWSTR, lpFormat: *const NUMBERFMTW, + lpNumberStr: LPWSTR, cchNumber: c_int, + ) -> c_int; + pub fn GetNumberOfConsoleInputEvents(hConsoleInput: HANDLE, lpNumberOfEvents: LPDWORD) -> BOOL; + pub fn GetNumberOfConsoleMouseButtons(lpNumberOfMouseButtons: LPDWORD) -> BOOL; + pub fn GetOEMCP() -> UINT; + pub fn GetOverlappedResult( + hFile: HANDLE, lpOverlapped: LPOVERLAPPED, lpNumberOfBytesTransferred: LPDWORD, bWait: BOOL, + ) -> BOOL; + pub fn GetOverlappedResultEx( + hFile: HANDLE, lpOverlapped: LPOVERLAPPED, lpNumberOfBytesTransferred: LPDWORD, + dwMilliseconds: DWORD, bAlertable: BOOL, + ) -> BOOL; + // pub fn GetPackageApplicationIds(); + // pub fn GetPackageFamilyName(); + // pub fn GetPackageFullName(); + // pub fn GetPackageId(); + // pub fn GetPackageInfo(); + // pub fn GetPackagePath(); + // pub fn GetPackagePathByFullName(); + // pub fn GetPackagesByPackageFamily(); + pub fn GetPhysicallyInstalledSystemMemory(TotalMemoryInKilobytes: PULONGLONG) -> BOOL; + pub fn GetPriorityClass(hProcess: HANDLE) -> DWORD; + pub fn GetPrivateProfileIntA( + lpAppName: LPCSTR, lpKeyName: LPCSTR, nDefault: INT, lpFileName: LPCSTR, + ) -> UINT; + pub fn GetPrivateProfileIntW( + lpAppName: LPCWSTR, lpKeyName: LPCWSTR, nDefault: INT, lpFileName: LPCWSTR, + ) -> UINT; + pub fn GetPrivateProfileSectionA( + lpAppName: LPCSTR, lpReturnedString: LPSTR, nSize: DWORD, lpFileName: LPCSTR, + ) -> DWORD; + pub fn GetPrivateProfileSectionNamesA( + lpszReturnBuffer: LPSTR, nSize: DWORD, lpFileName: LPCSTR, + ) -> DWORD; + pub fn GetPrivateProfileSectionNamesW( + lpszReturnBuffer: LPWSTR, nSize: DWORD, lpFileName: LPCWSTR, + ) -> DWORD; + pub fn GetPrivateProfileSectionW( + lpAppName: LPCWSTR, lpReturnedString: LPWSTR, nSize: DWORD, lpFileName: LPCWSTR, + ) -> DWORD; + pub fn GetPrivateProfileStringA( + lpAppName: LPCSTR, lpKeyName: LPCSTR, lpDefault: LPCSTR, lpReturnedString: LPSTR, + nSize: DWORD, lpFileName: LPCSTR, + ) -> DWORD; + pub fn GetPrivateProfileStringW( + lpAppName: LPCWSTR, lpKeyName: LPCWSTR, lpDefault: LPCWSTR, lpReturnedString: LPWSTR, + nSize: DWORD, lpFileName: LPCWSTR, + ) -> DWORD; + pub fn GetPrivateProfileStructA( + lpszSection: LPCSTR, lpszKey: LPCSTR, lpStruct: LPVOID, uSizeStruct: UINT, szFile: LPCSTR, + ) -> BOOL; + pub fn GetPrivateProfileStructW( + lpszSection: LPCWSTR, lpszKey: LPCWSTR, lpStruct: LPVOID, uSizeStruct: UINT, + szFile: LPCWSTR, + ) -> BOOL; + pub fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> FARPROC; + pub fn GetProcessAffinityMask( + hProcess: HANDLE, lpProcessAffinityMask: PDWORD_PTR, lpSystemAffinityMask: PDWORD_PTR, + ) -> BOOL; + pub fn GetProcessDEPPolicy(hProcess: HANDLE, lpFlags: LPDWORD, lpPermanent: PBOOL) -> BOOL; + pub fn GetProcessGroupAffinity( + hProcess: HANDLE, GroupCount: PUSHORT, GroupArray: PUSHORT, + ) -> BOOL; + pub fn GetProcessHandleCount(hProcess: HANDLE, pdwHandleCount: PDWORD) -> BOOL; + pub fn GetProcessHeap() -> HANDLE; + pub fn GetProcessHeaps(NumberOfHeaps: DWORD, ProcessHeaps: PHANDLE) -> DWORD; + pub fn GetProcessId(Process: HANDLE) -> DWORD; + pub fn GetProcessIdOfThread(Thread: HANDLE) -> DWORD; + pub fn GetProcessInformation( + hProcess: HANDLE, ProcessInformationClass: PROCESS_INFORMATION_CLASS, + ProcessInformation: LPVOID, ProcessInformationSize: DWORD, + ) -> BOOL; + pub fn GetProcessIoCounters(hProcess: HANDLE, lpIoCounters: PIO_COUNTERS) -> BOOL; + pub fn GetProcessMitigationPolicy( + hProcess: HANDLE, MitigationPolicy: PROCESS_MITIGATION_POLICY, lpBuffer: PVOID, + dwLength: SIZE_T, + ) -> BOOL; + pub fn GetProcessPreferredUILanguages( + dwFlags: DWORD, pulNumLanguages: PULONG, pwszLanguagesBuffer: PZZWSTR, + pcchLanguagesBuffer: PULONG, + ) -> BOOL; + pub fn GetProcessPriorityBoost(hProcess: HANDLE, pDisablePriorityBoost: PBOOL) -> BOOL; + pub fn GetProcessShutdownParameters(lpdwLevel: LPDWORD, lpdwFlags: LPDWORD) -> BOOL; + pub fn GetProcessTimes( + hProcess: HANDLE, lpCreationTime: LPFILETIME, lpExitTime: LPFILETIME, + lpKernelTime: LPFILETIME, lpUserTime: LPFILETIME, + ) -> BOOL; + pub fn GetProcessVersion(ProcessId: DWORD) -> DWORD; + pub fn GetProcessWorkingSetSize( + hProcess: HANDLE, lpMinimumWorkingSetSize: PSIZE_T, lpMaximumWorkingSetSize: PSIZE_T, + ) -> BOOL; + pub fn GetProcessWorkingSetSizeEx( + hProcess: HANDLE, lpMinimumWorkingSetSize: PSIZE_T, lpMaximumWorkingSetSize: PSIZE_T, + Flags: PDWORD, + ) -> BOOL; + pub fn GetProcessorSystemCycleTime( + Group: USHORT, Buffer: PSYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION, ReturnedLength: PDWORD, + ) -> BOOL; + pub fn GetProductInfo( + dwOSMajorVersion: DWORD, dwOSMinorVersion: DWORD, dwSpMajorVersion: DWORD, + dwSpMinorVersion: DWORD, pdwReturnedProductType: PDWORD, + ) -> BOOL; + pub fn GetProfileIntA(lpAppName: LPCSTR, lpKeyName: LPCSTR, nDefault: INT) -> UINT; + pub fn GetProfileIntW(lpAppName: LPCWSTR, lpKeyName: LPCWSTR, nDefault: INT) -> UINT; + pub fn GetProfileSectionA(lpAppName: LPCSTR, lpReturnedString: LPSTR, nSize: DWORD) -> DWORD; + pub fn GetProfileSectionW(lpAppName: LPCWSTR, lpReturnedString: LPWSTR, nSize: DWORD) -> DWORD; + pub fn GetProfileStringA( + lpAppName: LPCSTR, lpKeyName: LPCSTR, lpDefault: LPCSTR, lpReturnedString: LPSTR, + nSize: DWORD, + ) -> DWORD; + pub fn GetProfileStringW( + lpAppName: LPCWSTR, lpKeyName: LPCWSTR, lpDefault: LPCWSTR, lpReturnedString: LPWSTR, + nSize: DWORD, + ) -> DWORD; + pub fn GetQueuedCompletionStatus( + CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: PULONG_PTR, + lpOverlapped: *mut LPOVERLAPPED, dwMilliseconds: DWORD, + ) -> BOOL; + pub fn GetQueuedCompletionStatusEx( + CompletionPort: HANDLE, lpCompletionPortEntries: LPOVERLAPPED_ENTRY, ulCount: ULONG, + ulNumEntriesRemoved: PULONG, dwMilliseconds: DWORD, fAlertable: BOOL, + ) -> BOOL; + pub fn GetShortPathNameA( + lpszLongPath: LPCSTR, lpszShortPath: LPSTR, cchBuffer: DWORD, + ) -> DWORD; + pub fn GetShortPathNameW( + lpszLongPath: LPCWSTR, lpszShortPath: LPWSTR, cchBuffer: DWORD, + ) -> DWORD; + // pub fn GetStagedPackagePathByFullName(); + pub fn GetStartupInfoA(lpStartupInfo: LPSTARTUPINFOA); + pub fn GetStartupInfoW(lpStartupInfo: LPSTARTUPINFOW); + // pub fn GetStateFolder(); + pub fn GetStdHandle(nStdHandle: DWORD) -> HANDLE; + pub fn GetStringScripts( + dwFlags: DWORD, lpString: LPCWSTR, cchString: c_int, lpScripts: LPWSTR, cchScripts: c_int, + ) -> c_int; + pub fn GetStringTypeA( + Locale: LCID, dwInfoType: DWORD, lpSrcStr: LPCSTR, cchSrc: c_int, lpCharType: LPWORD, + ) -> BOOL; + pub fn GetStringTypeExA( + Locale: LCID, dwInfoType: DWORD, lpSrcStr: LPCSTR, cchSrc: c_int, lpCharType: LPWORD, + ) -> BOOL; + pub fn GetStringTypeExW( + Locale: LCID, dwInfoType: DWORD, lpSrcStr: LPCWCH, cchSrc: c_int, lpCharType: LPWORD, + ) -> BOOL; + pub fn GetStringTypeW( + dwInfoType: DWORD, lpSrcStr: LPCWCH, cchSrc: c_int, lpCharType: LPWORD, + ) -> BOOL; + // pub fn GetSystemAppDataKey(); + pub fn GetSystemDEPPolicy() -> DEP_SYSTEM_POLICY_TYPE; + pub fn GetSystemDefaultLCID() -> LCID; + pub fn GetSystemDefaultLangID() -> LANGID; + pub fn GetSystemDefaultLocaleName(lpLocaleName: LPWSTR, cchLocaleName: c_int) -> c_int; + pub fn GetSystemDefaultUILanguage() -> LANGID; + pub fn GetSystemDirectoryA(lpBuffer: LPSTR, uSize: UINT) -> UINT; + pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; + pub fn GetSystemFileCacheSize( + lpMinimumFileCacheSize: PSIZE_T, lpMaximumFileCacheSize: PSIZE_T, lpFlags: PDWORD, + ) -> BOOL; + pub fn GetSystemFirmwareTable( + FirmwareTableProviderSignature: DWORD, FirmwareTableID: DWORD, pFirmwareTableBuffer: PVOID, + BufferSize: DWORD, + ) -> UINT; + pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO); + pub fn GetSystemPowerStatus(lpSystemPowerStatus: LPSYSTEM_POWER_STATUS) -> BOOL; + pub fn GetSystemPreferredUILanguages( + dwFlags: DWORD, pulNumLanguages: PULONG, pwszLanguagesBuffer: PZZWSTR, + pcchLanguagesBuffer: PULONG, + ) -> BOOL; + pub fn GetSystemRegistryQuota(pdwQuotaAllowed: PDWORD, pdwQuotaUsed: PDWORD) -> BOOL; + pub fn GetSystemTime(lpSystemTime: LPSYSTEMTIME); + pub fn GetSystemTimeAdjustment( + lpTimeAdjustment: PDWORD, lpTimeIncrement: PDWORD, lpTimeAdjustmentDisabled: PBOOL, + ) -> BOOL; + pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME); + pub fn GetSystemTimePreciseAsFileTime(lpSystemTimeAsFileTime: LPFILETIME); + pub fn GetSystemTimes( + lpIdleTime: LPFILETIME, lpKernelTime: LPFILETIME, lpUserTime: LPFILETIME, + ) -> BOOL; + pub fn GetSystemWindowsDirectoryA(lpBuffer: LPSTR, uSize: UINT) -> UINT; + pub fn GetSystemWindowsDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; + pub fn GetSystemWow64DirectoryA(lpBuffer: LPSTR, uSize: UINT) -> UINT; + pub fn GetSystemWow64DirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; + pub fn GetTapeParameters( + hDevice: HANDLE, dwOperation: DWORD, lpdwSize: LPDWORD, lpTapeInformation: LPVOID + ) -> DWORD; + pub fn GetTapePosition( + hDevice: HANDLE, dwPositionType: DWORD, lpdwPartition: LPDWORD, + lpdwOffsetLow: LPDWORD, lpdwOffsetHigh: LPDWORD + ) -> DWORD; + pub fn GetTapeStatus(hDevice: HANDLE) -> DWORD; + pub fn GetTempFileNameA( + lpPathName: LPCSTR, lpPrefixString: LPCSTR, uUnique: UINT, lpTempFileName: LPSTR, + ) -> UINT; + pub fn GetTempFileNameW( + lpPathName: LPCWSTR, lpPrefixString: LPCWSTR, uUnique: UINT, lpTempFileName: LPWSTR, + ) -> UINT; + pub fn GetTempPathA(nBufferLength: DWORD, lpBuffer: LPSTR) -> DWORD; + pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; + pub fn GetThreadContext(hThread: HANDLE, lpContext: LPCONTEXT) -> BOOL; + pub fn GetThreadErrorMode() -> DWORD; + pub fn GetThreadGroupAffinity(hThread: HANDLE, GroupAffinity: PGROUP_AFFINITY) -> BOOL; + pub fn GetThreadIOPendingFlag(hThread: HANDLE, lpIOIsPending: PBOOL) -> BOOL; + pub fn GetThreadId(Thread: HANDLE) -> DWORD; + pub fn GetThreadIdealProcessorEx(hThread: HANDLE, lpIdealProcessor: PPROCESSOR_NUMBER) -> BOOL; + pub fn GetThreadInformation( + hThread: HANDLE, ThreadInformationClass: THREAD_INFORMATION_CLASS, + ThreadInformation: LPVOID, ThreadInformationSize: DWORD, + ) -> BOOL; + pub fn GetThreadLocale() -> LCID; + pub fn GetThreadPreferredUILanguages( + dwFlags: DWORD, pulNumLanguages: PULONG, pwszLanguagesBuffer: PZZWSTR, + pcchLanguagesBuffer: PULONG, + ) -> BOOL; + pub fn GetThreadPriority(hThread: HANDLE) -> c_int; + pub fn GetThreadPriorityBoost(hThread: HANDLE, pDisablePriorityBoost: PBOOL) -> BOOL; + pub fn GetThreadSelectorEntry( + hThread: HANDLE, dwSelector: DWORD, lpSelectorEntry: LPLDT_ENTRY, + ) -> BOOL; + pub fn GetThreadTimes( + hThread: HANDLE, lpCreationTime: LPFILETIME, lpExitTime: LPFILETIME, + lpKernelTime: LPFILETIME, lpUserTime: LPFILETIME, + ) -> BOOL; + pub fn GetThreadUILanguage() -> LANGID; + pub fn GetTickCount() -> DWORD; + pub fn GetTickCount64() -> ULONGLONG; + pub fn GetTimeFormatA( + Locale: LCID, dwFlags: DWORD, lpTime: *const SYSTEMTIME, lpFormat: LPCSTR, + lpTimeStr: LPSTR, cchTime: c_int, + ) -> c_int; + pub fn GetTimeFormatEx( + lpLocaleName: LPCWSTR, dwFlags: DWORD, lpTime: *const SYSTEMTIME, lpFormat: LPCWSTR, + lpTimeStr: LPWSTR, cchTime: c_int, + ) -> c_int; + pub fn GetTimeFormatW( + Locale: LCID, dwFlags: DWORD, lpTime: *const SYSTEMTIME, lpFormat: LPCWSTR, + lpTimeStr: LPWSTR, cchTime: c_int, + ) -> c_int; + pub fn GetTimeZoneInformation(lpTimeZoneInformation: LPTIME_ZONE_INFORMATION) -> DWORD; + pub fn GetTimeZoneInformationForYear( + wYear: USHORT, pdtzi: PDYNAMIC_TIME_ZONE_INFORMATION, ptzi: LPTIME_ZONE_INFORMATION, + ) -> BOOL; + pub fn GetUILanguageInfo( + dwFlags: DWORD, pwmszLanguage: PCZZWSTR, pwszFallbackLanguages: PZZWSTR, + pcchFallbackLanguages: PDWORD, pAttributes: PDWORD, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn GetUmsCompletionListEvent( + UmsCompletionList: PUMS_COMPLETION_LIST, UmsCompletionEvent: PHANDLE, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn GetUmsSystemThreadInformation( + ThreadHandle: HANDLE, SystemThreadInfo: PUMS_SYSTEM_THREAD_INFORMATION, + ) -> BOOL; + pub fn GetUserDefaultLCID() -> LCID; + pub fn GetUserDefaultLangID() -> LANGID; + pub fn GetUserDefaultLocaleName(lpLocaleName: LPWSTR, cchLocaleName: c_int) -> c_int; + pub fn GetUserDefaultUILanguage() -> LANGID; + pub fn GetUserGeoID(GeoClass: GEOCLASS) -> GEOID; + pub fn GetUserPreferredUILanguages( + dwFlags: DWORD, pulNumLanguages: PULONG, pwszLanguagesBuffer: PZZWSTR, + pcchLanguagesBuffer: PULONG, + ) -> BOOL; + pub fn GetVersion() -> DWORD; + pub fn GetVersionExA(lpVersionInformation: LPOSVERSIONINFOA) -> BOOL; + pub fn GetVersionExW(lpVersionInformation: LPOSVERSIONINFOW) -> BOOL; + pub fn GetVolumeInformationA( + lpRootPathName: LPCSTR, lpVolumeNameBuffer: LPSTR, nVolumeNameSize: DWORD, + lpVolumeSerialNumber: LPDWORD, lpMaximumComponentLength: LPDWORD, + lpFileSystemFlags: LPDWORD, lpFileSystemNameBuffer: LPSTR, nFileSystemNameSize: DWORD, + ) -> BOOL; + pub fn GetVolumeInformationByHandleW( + hFile: HANDLE, lpVolumeNameBuffer: LPWSTR, nVolumeNameSize: DWORD, + lpVolumeSerialNumber: LPDWORD, lpMaximumComponentLength: LPDWORD, + lpFileSystemFlags: LPDWORD, lpFileSystemNameBuffer: LPWSTR, nFileSystemNameSize: DWORD, + ) -> BOOL; + pub fn GetVolumeInformationW( + lpRootPathName: LPCWSTR, lpVolumeNameBuffer: LPWSTR, nVolumeNameSize: DWORD, + lpVolumeSerialNumber: LPDWORD, lpMaximumComponentLength: LPDWORD, + lpFileSystemFlags: LPDWORD, lpFileSystemNameBuffer: LPWSTR, nFileSystemNameSize: DWORD, + ) -> BOOL; + pub fn GetVolumeNameForVolumeMountPointA( + lpszVolumeMountPoint: LPCSTR, lpszVolumeName: LPSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn GetVolumeNameForVolumeMountPointW( + lpszVolumeMountPoint: LPCWSTR, lpszVolumeName: LPWSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn GetVolumePathNameA( + lpszFileName: LPCSTR, lpszVolumePathName: LPSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn GetVolumePathNameW( + lpszFileName: LPCWSTR, lpszVolumePathName: LPWSTR, cchBufferLength: DWORD, + ) -> BOOL; + pub fn GetVolumePathNamesForVolumeNameA( + lpszVolumeName: LPCSTR, lpszVolumePathNames: LPCH, cchBufferLength: DWORD, + lpcchReturnLength: PDWORD, + ) -> BOOL; + pub fn GetVolumePathNamesForVolumeNameW( + lpszVolumeName: LPCWSTR, lpszVolumePathNames: LPWCH, cchBufferLength: DWORD, + lpcchReturnLength: PDWORD, + ) -> BOOL; + pub fn GetWindowsDirectoryA(lpBuffer: LPSTR, uSize: UINT) -> UINT; + pub fn GetWindowsDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; + pub fn GetWriteWatch( + dwFlags: DWORD, lpBaseAddress: PVOID, dwRegionSize: SIZE_T, lpAddresses: *mut PVOID, + lpdwCount: *mut ULONG_PTR, lpdwGranularity: LPDWORD, + ) -> UINT; + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn GetXStateFeaturesMask(Context: PCONTEXT, FeatureMask: PDWORD64) -> BOOL; + pub fn GlobalAddAtomA(lpString: LPCSTR) -> ATOM; + pub fn GlobalAddAtomExA(lpString: LPCSTR, Flags: DWORD) -> ATOM; + pub fn GlobalAddAtomExW(lpString: LPCWSTR, Flags: DWORD) -> ATOM; + pub fn GlobalAddAtomW(lpString: LPCWSTR) -> ATOM; + pub fn GlobalAlloc(uFlags: UINT, dwBytes: SIZE_T) -> HGLOBAL; + pub fn GlobalCompact(dwMinFree: DWORD) -> SIZE_T; + pub fn GlobalDeleteAtom(nAtom: ATOM) -> ATOM; + pub fn GlobalFindAtomA(lpString: LPCSTR) -> ATOM; + pub fn GlobalFindAtomW(lpString: LPCWSTR) -> ATOM; + pub fn GlobalFix(hMem: HGLOBAL); + pub fn GlobalFlags(hMem: HGLOBAL) -> UINT; + pub fn GlobalFree(hMem: HGLOBAL) -> HGLOBAL; + pub fn GlobalGetAtomNameA(nAtom: ATOM, lpBuffer: LPSTR, nSize: c_int) -> UINT; + pub fn GlobalGetAtomNameW(nAtom: ATOM, lpBuffer: LPWSTR, nSize: c_int) -> UINT; + pub fn GlobalHandle(pMem: LPCVOID) -> HGLOBAL; + pub fn GlobalLock(hMem: HGLOBAL) -> LPVOID; + pub fn GlobalMemoryStatus(lpBuffer: LPMEMORYSTATUS); + pub fn GlobalMemoryStatusEx(lpBuffer: LPMEMORYSTATUSEX) -> BOOL; + pub fn GlobalReAlloc(hMem: HGLOBAL, dwBytes: SIZE_T, uFlags: UINT) -> HGLOBAL; + pub fn GlobalSize(hMem: HGLOBAL) -> SIZE_T; + pub fn GlobalUnWire(hMem: HGLOBAL) -> BOOL; + pub fn GlobalUnfix(hMem: HGLOBAL); + pub fn GlobalUnlock(hMem: HGLOBAL) -> BOOL; + pub fn GlobalWire(hMem: HGLOBAL) -> LPVOID; + pub fn Heap32First(lphe: LPHEAPENTRY32, th32ProcessID: DWORD, th32HeapID: ULONG_PTR) -> BOOL; + pub fn Heap32ListFirst(hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL; + pub fn Heap32ListNext(hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL; + pub fn Heap32Next(lphe: LPHEAPENTRY32) -> BOOL; + pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; + pub fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) -> SIZE_T; + pub fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) -> HANDLE; + pub fn HeapDestroy(hHeap: HANDLE) -> BOOL; + pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; + pub fn HeapLock(hHeap: HANDLE) -> BOOL; + pub fn HeapQueryInformation( + HeapHandle: HANDLE, HeapInformationClass: HEAP_INFORMATION_CLASS, HeapInformation: PVOID, + HeapInformationLength: SIZE_T, ReturnLength: PSIZE_T, + ) -> BOOL; + pub fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; + pub fn HeapSetInformation( + HeapHandle: HANDLE, HeapInformationClass: HEAP_INFORMATION_CLASS, HeapInformation: PVOID, + HeapInformationLength: SIZE_T, + ) -> BOOL; + pub fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPCVOID) -> SIZE_T; + pub fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) -> BOOL; + pub fn HeapUnlock(hHeap: HANDLE) -> BOOL; + pub fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPCVOID) -> BOOL; + pub fn HeapWalk(hHeap: HANDLE, lpEntry: LPPROCESS_HEAP_ENTRY) -> BOOL; + pub fn InitAtomTable(nSize: DWORD) -> BOOL; + pub fn InitOnceBeginInitialize( + lpInitOnce: LPINIT_ONCE, dwFlags: DWORD, fPending: PBOOL, lpContext: *mut LPVOID, + ) -> BOOL; + pub fn InitOnceComplete( + lpInitOnce: LPINIT_ONCE, dwFlags: DWORD, lpContext: LPVOID, + ) -> BOOL; + pub fn InitOnceExecuteOnce( + InitOnce: PINIT_ONCE, InitFn: PINIT_ONCE_FN, Parameter: PVOID, Context: *mut LPVOID, + ) -> BOOL; + pub fn InitOnceInitialize(InitOnce: PINIT_ONCE); + pub fn InitializeConditionVariable(ConditionVariable: PCONDITION_VARIABLE); + pub fn InitializeContext( + Buffer: PVOID, ContextFlags: DWORD, Context: *mut PCONTEXT, ContextLength: PDWORD, + ) -> BOOL; + pub fn InitializeCriticalSection(lpCriticalSection: LPCRITICAL_SECTION); + pub fn InitializeCriticalSectionAndSpinCount( + lpCriticalSection: LPCRITICAL_SECTION, dwSpinCount: DWORD, + ) -> BOOL; + pub fn InitializeCriticalSectionEx( + lpCriticalSection: LPCRITICAL_SECTION, dwSpinCount: DWORD, Flags: DWORD, + ) -> BOOL; + pub fn InitializeProcThreadAttributeList( + lpAttributeList: LPPROC_THREAD_ATTRIBUTE_LIST, dwAttributeCount: DWORD, dwFlags: DWORD, + lpSize: PSIZE_T, + ) -> BOOL; + pub fn InitializeSListHead(ListHead: PSLIST_HEADER); + pub fn InitializeSRWLock(SRWLock: PSRWLOCK); + pub fn InitializeSynchronizationBarrier( + lpBarrier: LPSYNCHRONIZATION_BARRIER, lTotalThreads: LONG, lSpinCount: LONG, + ) -> BOOL; + pub fn InstallELAMCertificateInfo(ELAMFile: HANDLE) -> BOOL; + #[cfg(target_arch = "x86")] + pub fn InterlockedCompareExchange( + Destination: *mut LONG, ExChange: LONG, Comperand: LONG, + ) -> LONG; + #[cfg(target_arch = "x86")] + pub fn InterlockedCompareExchange64( + Destination: *mut LONG64, ExChange: LONG64, Comperand: LONG64, + ) -> LONG64; + #[cfg(target_arch = "x86")] + pub fn InterlockedDecrement(Addend: *mut LONG) -> LONG; + #[cfg(target_arch = "x86")] + pub fn InterlockedExchange(Target: *mut LONG, Value: LONG) -> LONG; + #[cfg(target_arch = "x86")] + pub fn InterlockedExchangeAdd(Addend: *mut LONG, Value: LONG) -> LONG; + pub fn InterlockedFlushSList(ListHead: PSLIST_HEADER) -> PSLIST_ENTRY; + #[cfg(target_arch = "x86")] + pub fn InterlockedIncrement(Addend: *mut LONG) -> LONG; + pub fn InterlockedPopEntrySList(ListHead: PSLIST_HEADER) -> PSLIST_ENTRY; + pub fn InterlockedPushEntrySList( + ListHead: PSLIST_HEADER, ListEntry: PSLIST_ENTRY, + ) -> PSLIST_ENTRY; + pub fn InterlockedPushListSListEx( + ListHead: PSLIST_HEADER, List: PSLIST_ENTRY, ListEnd: PSLIST_ENTRY, Count: ULONG, + ) -> PSLIST_ENTRY; + pub fn IsBadCodePtr(lpfn: FARPROC) -> BOOL; + pub fn IsBadHugeReadPtr(lp: *const VOID, ucb: UINT_PTR) -> BOOL; + pub fn IsBadHugeWritePtr(lp: LPVOID, ucb: UINT_PTR) -> BOOL; + pub fn IsBadReadPtr(lp: *const VOID, ucb: UINT_PTR) -> BOOL; + pub fn IsBadStringPtrA(lpsz: LPCSTR, ucchMax: UINT_PTR) -> BOOL; + pub fn IsBadStringPtrW(lpsz: LPCWSTR, ucchMax: UINT_PTR) -> BOOL; + pub fn IsBadWritePtr(lp: LPVOID, ucb: UINT_PTR) -> BOOL; + pub fn IsDBCSLeadByte(TestChar: BYTE) -> BOOL; + pub fn IsDBCSLeadByteEx(CodePage: UINT, TestChar: BYTE) -> BOOL; + pub fn IsDebuggerPresent() -> BOOL; + pub fn IsNLSDefinedString( + Function: NLS_FUNCTION, dwFlags: DWORD, lpVersionInformation: LPNLSVERSIONINFO, + lpString: LPCWSTR, cchStr: INT, + ) -> BOOL; + pub fn IsNativeVhdBoot(NativeVhdBoot: PBOOL) -> BOOL; + pub fn IsNormalizedString(NormForm: NORM_FORM, lpString: LPCWSTR, cwLength: c_int) -> BOOL; + pub fn IsProcessCritical(hProcess: HANDLE, Critical: PBOOL) -> BOOL; + pub fn IsProcessInJob(ProcessHandle: HANDLE, JobHandle: HANDLE, Result: PBOOL) -> BOOL; + pub fn IsProcessorFeaturePresent(ProcessorFeature: DWORD) -> BOOL; + pub fn IsSystemResumeAutomatic() -> BOOL; + pub fn IsThreadAFiber() -> BOOL; + pub fn IsThreadpoolTimerSet(pti: PTP_TIMER) -> BOOL; + pub fn IsValidCodePage(CodePage: UINT) -> BOOL; + pub fn IsValidLanguageGroup(LanguageGroup: LGRPID, dwFlags: DWORD) -> BOOL; + pub fn IsValidLocale(Locale: LCID, dwFlags: DWORD) -> BOOL; + pub fn IsValidLocaleName(lpLocaleName: LPCWSTR) -> BOOL; + pub fn IsValidNLSVersion( + function: NLS_FUNCTION, lpLocaleName: LPCWSTR, lpVersionInformation: LPNLSVERSIONINFOEX, + ) -> BOOL; + pub fn IsWow64Process(hProcess: HANDLE, Wow64Process: PBOOL) -> BOOL; + pub fn K32EmptyWorkingSet(hProcess: HANDLE) -> BOOL; + pub fn K32EnumDeviceDrivers(lpImageBase: *mut LPVOID, cb: DWORD, lpcbNeeded: LPDWORD) -> BOOL; + pub fn K32EnumPageFilesA( + pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID, + ) -> BOOL; + pub fn K32EnumPageFilesW( + pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID, + ) -> BOOL; + pub fn K32EnumProcessModules( + hProcess: HANDLE, lphModule: *mut HMODULE, cb: DWORD, lpcbNeeded: LPDWORD, + ) -> BOOL; + pub fn K32EnumProcessModulesEx( + hProcess: HANDLE, lphModule: *mut HMODULE, cb: DWORD, lpcbNeeded: LPDWORD, + dwFilterFlag: DWORD, + ) -> BOOL; + pub fn K32EnumProcesses( + lpidProcess: *mut DWORD, cb: DWORD, lpcbNeeded: LPDWORD, + ) -> BOOL; + pub fn K32GetDeviceDriverBaseNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) -> DWORD; + pub fn K32GetDeviceDriverBaseNameW( + ImageBase: LPVOID, lpFilename: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetDeviceDriverFileNameA(ImageBase: LPVOID, lpFilename: LPSTR, nSize: DWORD) -> DWORD; + pub fn K32GetDeviceDriverFileNameW( + ImageBase: LPVOID, lpFilename: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetMappedFileNameA( + hProcess: HANDLE, lpv: LPVOID, lpFilename: LPSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetMappedFileNameW( + hProcess: HANDLE, lpv: LPVOID, lpFilename: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetModuleBaseNameA( + hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetModuleBaseNameW( + hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetModuleFileNameExA( + hProcess: HANDLE, hModule: HMODULE, lpFilename: LPSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetModuleFileNameExW( + hProcess: HANDLE, hModule: HMODULE, lpFilename: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetModuleInformation( + hProcess: HANDLE, hModule: HMODULE, lpmodinfo: LPMODULEINFO, cb: DWORD, + ) -> BOOL; + pub fn K32GetPerformanceInfo( + pPerformanceInformation: PPERFORMANCE_INFORMATION, cb: DWORD, + ) -> BOOL; + pub fn K32GetProcessImageFileNameA( + hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetProcessImageFileNameW( + hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD, + ) -> DWORD; + pub fn K32GetProcessMemoryInfo( + Process: HANDLE, ppsmemCounters: PPROCESS_MEMORY_COUNTERS, cb: DWORD, + ) -> BOOL; + pub fn K32GetWsChanges( + hProcess: HANDLE, lpWatchInfo: PPSAPI_WS_WATCH_INFORMATION, cb: DWORD, + ) -> BOOL; + pub fn K32GetWsChangesEx( + hProcess: HANDLE, lpWatchInfoEx: PPSAPI_WS_WATCH_INFORMATION_EX, cb: PDWORD, + ) -> BOOL; + pub fn K32InitializeProcessForWsWatch(hProcess: HANDLE) -> BOOL; + pub fn K32QueryWorkingSet(hProcess: HANDLE, pv: PVOID, cb: DWORD) -> BOOL; + pub fn K32QueryWorkingSetEx(hProcess: HANDLE, pv: PVOID, cb: DWORD) -> BOOL; + pub fn LCIDToLocaleName(Locale: LCID, lpName: LPWSTR, cchName: c_int, dwFlags: DWORD) -> c_int; + pub fn LCMapStringA( + Locale: LCID, dwMapFlags: DWORD, lpSrcStr: LPCSTR, cchSrc: c_int, lpDestStr: LPSTR, + cchDest: c_int, + ) -> c_int; + pub fn LCMapStringEx( + lpLocaleName: LPCWSTR, dwMapFlags: DWORD, lpSrcStr: LPCWSTR, cchSrc: c_int, + lpDestStr: LPWSTR, cchDest: c_int, lpVersionInformation: LPNLSVERSIONINFO, + lpReserved: LPVOID, sortHandle: LPARAM, + ) -> c_int; + pub fn LCMapStringW( + Locale: LCID, dwMapFlags: DWORD, lpSrcStr: LPCWSTR, cchSrc: c_int, lpDestStr: LPWSTR, + cchDest: c_int, + ) -> c_int; + pub fn LeaveCriticalSection(lpCriticalSection: LPCRITICAL_SECTION); + pub fn LeaveCriticalSectionWhenCallbackReturns( + pci: PTP_CALLBACK_INSTANCE, pcs: PCRITICAL_SECTION, + ); + // pub fn LoadAppInitDlls(); + pub fn LoadLibraryA(lpFileName: LPCSTR) -> HMODULE; + pub fn LoadLibraryExA(lpLibFileName: LPCSTR, hFile: HANDLE, dwFlags: DWORD) -> HMODULE; + pub fn LoadLibraryExW(lpLibFileName: LPCWSTR, hFile: HANDLE, dwFlags: DWORD) -> HMODULE; + pub fn LoadLibraryW(lpFileName: LPCWSTR) -> HMODULE; + pub fn LoadModule(lpModuleName: LPCSTR, lpParameterBlock: LPVOID) -> DWORD; + pub fn LoadPackagedLibrary(lpwLibFileName: LPCWSTR, Reserved: DWORD) -> HMODULE; + pub fn LoadResource(hModule: HMODULE, hResInfo: HRSRC) -> HGLOBAL; + // pub fn LoadStringBaseExW(); + // pub fn LoadStringBaseW(); + pub fn LocalAlloc(uFlags: UINT, uBytes: SIZE_T) -> HLOCAL; + pub fn LocalCompact(uMinFree: UINT) -> SIZE_T; + pub fn LocalFileTimeToFileTime( + lpLocalFileTime: *const FILETIME, lpFileTime: LPFILETIME, + ) -> BOOL; + pub fn LocalFlags(hMem: HLOCAL) -> UINT; + pub fn LocalFree(hMem: HLOCAL) -> HLOCAL; + pub fn LocalHandle(pMem: LPCVOID) -> HLOCAL; + pub fn LocalLock(hMem: HLOCAL) -> LPVOID; + pub fn LocalReAlloc(hMem: HLOCAL, uBytes: SIZE_T, uFlags: UINT) -> HLOCAL; + pub fn LocalShrink(hMem: HLOCAL, cbNewSize: UINT) -> SIZE_T; + pub fn LocalSize(hMem: HLOCAL) -> SIZE_T; + pub fn LocalUnlock(hMem: HLOCAL) -> BOOL; + pub fn LocaleNameToLCID(lpName: LPCWSTR, dwFlags: DWORD) -> LCID; + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn LocateXStateFeature(Context: PCONTEXT, FeatureId: DWORD, Length: PDWORD) -> PVOID; + pub fn LockFile( + hFile: HANDLE, dwFileOffsetLow: DWORD, dwFileOffsetHigh: DWORD, + nNumberOfBytesToLockLow: DWORD, nNumberOfBytesToLockHigh: DWORD, + ) -> BOOL; + pub fn LockFileEx( + hFile: HANDLE, dwFlags: DWORD, dwReserved: DWORD, nNumberOfBytesToLockLow: DWORD, + nNumberOfBytesToLockHigh: DWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn LockResource(hResData: HGLOBAL) -> LPVOID; + pub fn MapUserPhysicalPages( + VirtualAddress: PVOID, NumberOfPages: ULONG_PTR, PageArray: PULONG_PTR, + ) -> BOOL; + pub fn MapUserPhysicalPagesScatter( + VirtualAddresses: *mut PVOID, NumberOfPages: ULONG_PTR, PageArray: PULONG_PTR, + ) -> BOOL; + pub fn MapViewOfFile( + hFileMappingObject: HANDLE, dwDesiredAccess: DWORD, dwFileOffsetHigh: DWORD, + dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: SIZE_T, + ) -> LPVOID; + pub fn MapViewOfFileEx( + hFileMappingObject: HANDLE, dwDesiredAccess: DWORD, dwFileOffsetHigh: DWORD, + dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: SIZE_T, lpBaseAddress: LPVOID, + ) -> LPVOID; + pub fn MapViewOfFileExNuma( + hFileMappingObject: HANDLE, dwDesiredAccess: DWORD, dwFileOffsetHigh: DWORD, + dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: SIZE_T, lpBaseAddress: LPVOID, + nndPreferred: DWORD, + ) -> LPVOID; + pub fn MapViewOfFileFromApp( + hFileMappingObject: HANDLE, DesiredAccess: ULONG, FileOffset: ULONG64, + NumberOfBytesToMap: SIZE_T, + ) -> PVOID; + pub fn Module32First(hSnapshot: HANDLE, lpme: LPMODULEENTRY32) -> BOOL; + pub fn Module32FirstW(hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL; + pub fn Module32Next(hSnapshot: HANDLE, lpme: LPMODULEENTRY32) -> BOOL; + pub fn Module32NextW(hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL; + pub fn MoveFileA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR) -> BOOL; + pub fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, dwFlags: DWORD) -> BOOL; + pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD) -> BOOL; + pub fn MoveFileTransactedA( + lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, dwFlags: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn MoveFileTransactedW( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, dwFlags: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn MoveFileW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR) -> BOOL; + pub fn MoveFileWithProgressA( + lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, dwFlags: DWORD, + ) -> BOOL; + pub fn MoveFileWithProgressW( + lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, lpProgressRoutine: LPPROGRESS_ROUTINE, + lpData: LPVOID, dwFlags: DWORD, + ) -> BOOL; + pub fn MulDiv(nNumber: c_int, nNumerator: c_int, nDenominator: c_int) -> c_int; + pub fn MultiByteToWideChar( + CodePage: UINT, dwFlags: DWORD, lpMultiByteStr: LPCSTR, cbMultiByte: c_int, + lpWideCharStr: LPWSTR, cchWideChar: c_int, + ) -> c_int; + pub fn NeedCurrentDirectoryForExePathA(ExeName: LPCSTR) -> BOOL; + pub fn NeedCurrentDirectoryForExePathW(ExeName: LPCWSTR) -> BOOL; + pub fn NormalizeString( + NormForm: NORM_FORM, lpSrcString: LPCWSTR, cwSrcLength: c_int, lpDstString: LPWSTR, + cwDstLength: c_int, + ) -> c_int; + // pub fn NotifyMountMgr(); + pub fn NotifyUILanguageChange( + dwFlags: DWORD, pcwstrNewLanguage: PCWSTR, pcwstrPreviousLanguage: PCWSTR, + dwReserved: DWORD, pdwStatusRtrn: PDWORD, + ) -> BOOL; + // pub fn OOBEComplete(); + pub fn OpenEventA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCSTR) -> HANDLE; + pub fn OpenEventW(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR) -> HANDLE; + pub fn OpenFile(lpFileName: LPCSTR, lpReOpenBuff: LPOFSTRUCT, uStyle: UINT) -> HFILE; + pub fn OpenFileById( + hVolumeHint: HANDLE, lpFileId: LPFILE_ID_DESCRIPTOR, dwDesiredAccess: DWORD, + dwShareMode: DWORD, lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + dwFlagsAndAttributes: DWORD, + ) -> HANDLE; + pub fn OpenFileMappingA( + dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCSTR, + ) -> HANDLE; + pub fn OpenFileMappingW( + dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR, + ) -> HANDLE; + pub fn OpenJobObjectA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCSTR) -> HANDLE; + pub fn OpenJobObjectW(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR) -> HANDLE; + pub fn OpenMutexA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCSTR) -> HANDLE; + pub fn OpenMutexW(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR) -> HANDLE; + // pub fn OpenPackageInfoByFullName(); + pub fn OpenPrivateNamespaceA(lpBoundaryDescriptor: LPVOID, lpAliasPrefix: LPCSTR) -> HANDLE; + pub fn OpenPrivateNamespaceW(lpBoundaryDescriptor: LPVOID, lpAliasPrefix: LPCWSTR) -> HANDLE; + pub fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE; + pub fn OpenSemaphoreA(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCSTR) -> HANDLE; + pub fn OpenSemaphoreW(dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR) -> HANDLE; + // pub fn OpenState(); + // pub fn OpenStateExplicit(); + pub fn OpenThread(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwThreadId: DWORD) -> HANDLE; + pub fn OpenWaitableTimerA( + dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpTimerName: LPCSTR, + ) -> HANDLE; + pub fn OpenWaitableTimerW( + dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpTimerName: LPCWSTR, + ) -> HANDLE; + pub fn OutputDebugStringA(lpOutputString: LPCSTR); + pub fn OutputDebugStringW(lpOutputString: LPCWSTR); + // pub fn PackageFamilyNameFromFullName(); + // pub fn PackageFamilyNameFromId(); + // pub fn PackageFullNameFromId(); + // pub fn PackageIdFromFullName(); + // pub fn PackageNameAndPublisherIdFromFamilyName(); + // pub fn ParseApplicationUserModelId(); + pub fn PeekConsoleInputA( + hConsoleInput: HANDLE, lpBuffer: PINPUT_RECORD, nLength: DWORD, + lpNumberOfEventsRead: LPDWORD, + ) -> BOOL; + pub fn PeekConsoleInputW( + hConsoleInput: HANDLE, lpBuffer: PINPUT_RECORD, nLength: DWORD, + lpNumberOfEventsRead: LPDWORD, + ) -> BOOL; + pub fn PeekNamedPipe( + hNamedPipe: HANDLE, lpBuffer: LPVOID, nBufferSize: DWORD, lpBytesRead: LPDWORD, + lpTotalBytesAvail: LPDWORD, lpBytesLeftThisMessage: LPDWORD, + ) -> BOOL; + pub fn PostQueuedCompletionStatus( + CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, + lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn PowerClearRequest(PowerRequest: HANDLE, RequestType: POWER_REQUEST_TYPE) -> BOOL; + pub fn PowerCreateRequest(Context: PREASON_CONTEXT) -> HANDLE; + pub fn PowerSetRequest(PowerRequest: HANDLE, RequestType: POWER_REQUEST_TYPE) -> BOOL; + pub fn PrefetchVirtualMemory( + hProcess: HANDLE, NumberOfEntries: ULONG_PTR, VirtualAddresses: PWIN32_MEMORY_RANGE_ENTRY, + Flags: ULONG, + ) -> BOOL; + pub fn PrepareTape(hDevice: HANDLE, dwOperation: DWORD, bImmediate: BOOL) -> DWORD; + pub fn Process32First(hSnapshot: HANDLE, lppe: LPPROCESSENTRY32) -> BOOL; + pub fn Process32FirstW(hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL; + pub fn Process32Next(hSnapshot: HANDLE, lppe: LPPROCESSENTRY32) -> BOOL; + pub fn Process32NextW(hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL; + pub fn ProcessIdToSessionId(dwProcessId: DWORD, pSessionId: *mut DWORD) -> BOOL; + pub fn PssCaptureSnapshot( + ProcessHandle: HANDLE, CaptureFlags: PSS_CAPTURE_FLAGS, ThreadContextFlags: DWORD, + SnapshotHandle: *mut HPSS, + ) -> DWORD; + pub fn PssDuplicateSnapshot( + SourceProcessHandle: HANDLE, SnapshotHandle: HPSS, TargetProcessHandle: HANDLE, + TargetSnapshotHandle: *mut HPSS, Flags: PSS_DUPLICATE_FLAGS, + ) -> DWORD; + pub fn PssFreeSnapshot(ProcessHandle: HANDLE, SnapshotHandle: HPSS) -> DWORD; + pub fn PssQuerySnapshot( + SnapshotHandle: HPSS, InformationClass: PSS_QUERY_INFORMATION_CLASS, Buffer: *mut c_void, + BufferLength: DWORD, + ) -> DWORD; + pub fn PssWalkMarkerCreate( + Allocator: *const PSS_ALLOCATOR, WalkMarkerHandle: *mut HPSSWALK, + ) -> DWORD; + pub fn PssWalkMarkerFree(WalkMarkerHandle: HPSSWALK) -> DWORD; + pub fn PssWalkMarkerGetPosition(WalkMarkerHandle: HPSSWALK, Position: *mut ULONG_PTR) -> DWORD; + // pub fn PssWalkMarkerRewind(); + // pub fn PssWalkMarkerSeek(); + pub fn PssWalkMarkerSeekToBeginning(WalkMarkerHandle: HPSS) -> DWORD; + pub fn PssWalkMarkerSetPosition(WalkMarkerHandle: HPSSWALK, Position: ULONG_PTR) -> DWORD; + // pub fn PssWalkMarkerTell(); + pub fn PssWalkSnapshot( + SnapshotHandle: HPSS, InformationClass: PSS_WALK_INFORMATION_CLASS, + WalkMarkerHandle: HPSSWALK, Buffer: *mut c_void, BufferLength: DWORD, + ) -> DWORD; + pub fn PulseEvent(hEvent: HANDLE) -> BOOL; + pub fn PurgeComm(hFile: HANDLE, dwFlags: DWORD) -> BOOL; + pub fn QueryActCtxSettingsW( + dwFlags: DWORD, hActCtx: HANDLE, settingsNameSpace: PCWSTR, settingName: PCWSTR, + pvBuffer: PWSTR, dwBuffer: SIZE_T, pdwWrittenOrRequired: *mut SIZE_T, + ) -> BOOL; + pub fn QueryActCtxW( + dwFlags: DWORD, hActCtx: HANDLE, pvSubInstance: PVOID, ulInfoClass: ULONG, pvBuffer: PVOID, + cbBuffer: SIZE_T, pcbWrittenOrRequired: *mut SIZE_T, + ) -> BOOL; + pub fn QueryDepthSList(ListHead: PSLIST_HEADER) -> USHORT; + pub fn QueryDosDeviceA(lpDeviceName: LPCSTR, lpTargetPath: LPSTR, ucchMax: DWORD) -> DWORD; + pub fn QueryDosDeviceW(lpDeviceName: LPCWSTR, lpTargetPath: LPWSTR, ucchMax: DWORD) -> DWORD; + pub fn QueryFullProcessImageNameA( + hProcess: HANDLE, dwFlags: DWORD, lpExeName: LPSTR, lpdwSize: PDWORD, + ) -> BOOL; + pub fn QueryFullProcessImageNameW( + hProcess: HANDLE, dwFlags: DWORD, lpExeName: LPWSTR, lpdwSize: PDWORD, + ) -> BOOL; + pub fn QueryIdleProcessorCycleTime( + BufferLength: PULONG, ProcessorIdleCycleTime: PULONG64, + ) -> BOOL; + pub fn QueryIdleProcessorCycleTimeEx( + Group: USHORT, BufferLength: PULONG, ProcessorIdleCycleTime: PULONG64, + ) -> BOOL; + pub fn QueryInformationJobObject( + hJob: HANDLE, JobObjectInformationClass: JOBOBJECTINFOCLASS, + lpJobObjectInformation: LPVOID, cbJobObjectInformationLength: DWORD, + lpReturnLength: LPDWORD, + ) -> BOOL; + pub fn QueryMemoryResourceNotification( + ResourceNotificationHandle: HANDLE, ResourceState: PBOOL, + ) -> BOOL; + pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER) -> BOOL; + pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL; + pub fn QueryProcessAffinityUpdateMode(hProcess: HANDLE, lpdwFlags: LPDWORD) -> BOOL; + pub fn QueryProcessCycleTime(ProcessHandle: HANDLE, CycleTime: PULONG64) -> BOOL; + pub fn QueryProtectedPolicy(PolicyGuid: LPCGUID, PolicyValue: PULONG_PTR) -> BOOL; + pub fn QueryThreadCycleTime(ThreadHandle: HANDLE, CycleTime: PULONG64) -> BOOL; + pub fn QueryThreadProfiling(ThreadHandle: HANDLE, Enabled: PBOOLEAN) -> DWORD; + pub fn QueryThreadpoolStackInformation( + ptpp: PTP_POOL, ptpsi: PTP_POOL_STACK_INFORMATION, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn QueryUmsThreadInformation( + UmsThread: PUMS_CONTEXT, UmsThreadInfoClass: UMS_THREAD_INFO_CLASS, + UmsThreadInformation: PVOID, UmsThreadInformationLength: ULONG, ReturnLength: PULONG, + ) -> BOOL; + pub fn QueryUnbiasedInterruptTime(UnbiasedTime: PULONGLONG) -> BOOL; + pub fn QueueUserAPC(pfnAPC: PAPCFUNC, hThread: HANDLE, dwData: ULONG_PTR) -> DWORD; + pub fn QueueUserWorkItem( + Function: LPTHREAD_START_ROUTINE, Context: PVOID, Flags: ULONG, + ) -> BOOL; + pub fn RaiseException( + dwExceptionCode: DWORD, dwExceptionFlags: DWORD, nNumberOfArguments: DWORD, + lpArguments: *const ULONG_PTR, + ); + pub fn RaiseFailFastException( + pExceptionRecord: PEXCEPTION_RECORD, pContextRecord: PCONTEXT, dwFlags: DWORD, + ); + pub fn ReOpenFile( + hOriginalFile: HANDLE, dwDesiredAccess: DWORD, dwShareMode: DWORD, dwFlags: DWORD, + ) -> HANDLE; + pub fn ReadConsoleA( + hConsoleInput: HANDLE, lpBuffer: LPVOID, nNumberOfCharsToRead: DWORD, + lpNumberOfCharsRead: LPDWORD, pInputControl: PCONSOLE_READCONSOLE_CONTROL, + ) -> BOOL; + pub fn ReadConsoleInputA( + hConsoleInput: HANDLE, lpBuffer: PINPUT_RECORD, nLength: DWORD, + lpNumberOfEventsRead: LPDWORD, + ) -> BOOL; + pub fn ReadConsoleInputW( + hConsoleInput: HANDLE, lpBuffer: PINPUT_RECORD, nLength: DWORD, + lpNumberOfEventsRead: LPDWORD, + ) -> BOOL; + pub fn ReadConsoleOutputA( + hConsoleOutput: HANDLE, lpBuffer: PCHAR_INFO, dwBufferSize: COORD, dwBufferCoord: COORD, + lpReadRegion: PSMALL_RECT, + ) -> BOOL; + pub fn ReadConsoleOutputAttribute( + hConsoleOutput: HANDLE, lpAttribute: LPWORD, nLength: DWORD, dwReadCoord: COORD, + lpNumberOfAttrsRead: LPDWORD, + ) -> BOOL; + pub fn ReadConsoleOutputCharacterA( + hConsoleOutput: HANDLE, lpCharacter: LPSTR, nLength: DWORD, dwReadCoord: COORD, + lpNumberOfCharsRead: LPDWORD, + ) -> BOOL; + pub fn ReadConsoleOutputCharacterW( + hConsoleOutput: HANDLE, lpCharacter: LPWSTR, nLength: DWORD, dwReadCoord: COORD, + lpNumberOfCharsRead: LPDWORD, + ) -> BOOL; + pub fn ReadConsoleOutputW( + hConsoleOutput: HANDLE, lpBuffer: PCHAR_INFO, dwBufferSize: COORD, dwBufferCoord: COORD, + lpReadRegion: PSMALL_RECT, + ) -> BOOL; + pub fn ReadConsoleW( + hConsoleInput: HANDLE, lpBuffer: LPVOID, nNumberOfCharsToRead: DWORD, + lpNumberOfCharsRead: LPDWORD, pInputControl: PCONSOLE_READCONSOLE_CONTROL, + ) -> BOOL; + pub fn ReadDirectoryChangesW( + hDirectory: HANDLE, lpBuffer: LPVOID, nBufferLength: DWORD, bWatchSubtree: BOOL, + dwNotifyFilter: DWORD, lpBytesReturned: LPDWORD, lpOverlapped: LPOVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL; + pub fn ReadFile( + hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, + lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn ReadFileEx( + hFile: HANDLE, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpOverlapped: LPOVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL; + pub fn ReadFileScatter( + hFile: HANDLE, aSegmentArray: *mut FILE_SEGMENT_ELEMENT, nNumberOfBytesToRead: DWORD, + lpReserved: LPDWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn ReadProcessMemory( + hProcess: HANDLE, lpBaseAddress: LPCVOID, lpBuffer: LPVOID, nSize: SIZE_T, + lpNumberOfBytesRead: *mut SIZE_T, + ) -> BOOL; + pub fn ReadThreadProfilingData( + PerformanceDataHandle: HANDLE, Flags: DWORD, PerformanceData: PPERFORMANCE_DATA, + ) -> DWORD; + pub fn RegisterApplicationRecoveryCallback( + pRecoveyCallback: APPLICATION_RECOVERY_CALLBACK, pvParameter: PVOID, dwPingInterval: DWORD, + dwFlags: DWORD, + ) -> HRESULT; + pub fn RegisterApplicationRestart(pwzCommandline: PCWSTR, dwFlags: DWORD) -> HRESULT; + pub fn RegisterBadMemoryNotification(Callback: PBAD_MEMORY_CALLBACK_ROUTINE) -> PVOID; + // pub fn RegisterWaitForInputIdle(); + pub fn RegisterWaitForSingleObject( + phNewWaitObject: PHANDLE, hObject: HANDLE, Callback: WAITORTIMERCALLBACK, Context: PVOID, + dwMilliseconds: ULONG, dwFlags: ULONG, + ) -> BOOL; + pub fn RegisterWaitForSingleObjectEx( + hObject: HANDLE, Callback: WAITORTIMERCALLBACK, Context: PVOID, dwMilliseconds: ULONG, + dwFlags: ULONG, + ) -> HANDLE; + // pub fn RegisterWaitUntilOOBECompleted(); + pub fn ReleaseActCtx(hActCtx: HANDLE); + pub fn ReleaseMutex(hMutex: HANDLE) -> BOOL; + pub fn ReleaseMutexWhenCallbackReturns(pci: PTP_CALLBACK_INSTANCE, mutex: HANDLE); + pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK); + pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK); + pub fn ReleaseSemaphore( + hSemaphore: HANDLE, lReleaseCount: LONG, lpPreviousCount: LPLONG, + ) -> BOOL; + pub fn ReleaseSemaphoreWhenCallbackReturns( + pci: PTP_CALLBACK_INSTANCE, sem: HANDLE, crel: DWORD, + ); + pub fn RemoveDirectoryA(lpPathName: LPCSTR) -> BOOL; + pub fn RemoveDirectoryTransactedA(lpPathName: LPCSTR, hTransaction: HANDLE) -> BOOL; + pub fn RemoveDirectoryTransactedW(lpPathName: LPCWSTR, hTransaction: HANDLE) -> BOOL; + pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn RemoveDllDirectory(Cookie: DLL_DIRECTORY_COOKIE) -> BOOL; + // pub fn RemoveLocalAlternateComputerNameA(); + // pub fn RemoveLocalAlternateComputerNameW(); + pub fn RemoveSecureMemoryCacheCallback(pfnCallBack: PSECURE_MEMORY_CACHE_CALLBACK) -> BOOL; + pub fn RemoveVectoredContinueHandler(Handle: PVOID) -> ULONG; + pub fn RemoveVectoredExceptionHandler(Handle: PVOID) -> ULONG; + pub fn ReplaceFileA( + lpReplacedFileName: LPCSTR, lpReplacementFileName: LPCSTR, lpBackupFileName: LPCSTR, + dwReplaceFlags: DWORD, lpExclude: LPVOID, lpReserved: LPVOID, + ); + pub fn ReplaceFileW( + lpReplacedFileName: LPCWSTR, lpReplacementFileName: LPCWSTR, lpBackupFileName: LPCWSTR, + dwReplaceFlags: DWORD, lpExclude: LPVOID, lpReserved: LPVOID, + ); + pub fn ReplacePartitionUnit( + TargetPartition: PWSTR, SparePartition: PWSTR, Flags: ULONG, + ) -> BOOL; + pub fn RequestDeviceWakeup(hDevice: HANDLE) -> BOOL; + pub fn RequestWakeupLatency(latency: LATENCY_TIME) -> BOOL; + pub fn ResetEvent(hEvent: HANDLE) -> BOOL; + pub fn ResetWriteWatch(lpBaseAddress: LPVOID, dwRegionSize: SIZE_T) -> UINT; + // pub fn ResolveDelayLoadedAPI(); + // pub fn ResolveDelayLoadsFromDll(); + pub fn ResolveLocaleName( + lpNameToResolve: LPCWSTR, lpLocaleName: LPWSTR, cchLocaleName: c_int, + ) -> c_int; + pub fn RestoreLastError(dwErrCode: DWORD); + pub fn ResumeThread(hThread: HANDLE) -> DWORD; + #[cfg(target_arch = "arm")] + pub fn RtlAddFunctionTable( + FunctionTable: PRUNTIME_FUNCTION, EntryCount: DWORD, BaseAddress: DWORD, + ) -> BOOLEAN; + #[cfg(target_arch = "x86_64")] + pub fn RtlAddFunctionTable( + FunctionTable: PRUNTIME_FUNCTION, EntryCount: DWORD, BaseAddress: DWORD64, + ) -> BOOLEAN; + pub fn RtlCaptureContext(ContextRecord: PCONTEXT); + pub fn RtlCaptureStackBackTrace( + FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: *mut PVOID, BackTraceHash: PDWORD, + ) -> WORD; + // #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlCompareMemory(Source1: *const VOID, Source2: *const VOID, Length: SIZE_T) -> SIZE_T; + // #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlCopyMemory(Destination: PVOID, Source: *const VOID, Length: SIZE_T); + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlDeleteFunctionTable(FunctionTable: PRUNTIME_FUNCTION) -> BOOLEAN; + // pub fn RtlFillMemory(); + #[cfg(target_arch = "arm")] + pub fn RtlInstallFunctionTableCallback( + TableIdentifier: DWORD, BaseAddress: DWORD, Length: DWORD, + Callback: PGET_RUNTIME_FUNCTION_CALLBACK, Context: PVOID, OutOfProcessCallbackDll: PCWSTR, + ) -> BOOLEAN; + #[cfg(target_arch = "x86_64")] + pub fn RtlInstallFunctionTableCallback( + TableIdentifier: DWORD64, BaseAddress: DWORD64, Length: DWORD, + Callback: PGET_RUNTIME_FUNCTION_CALLBACK, Context: PVOID, OutOfProcessCallbackDll: PCWSTR, + ) -> BOOLEAN; + #[cfg(target_arch = "arm")] + pub fn RtlLookupFunctionEntry( + ControlPc: ULONG_PTR, ImageBase: PDWORD, HistoryTable: PUNWIND_HISTORY_TABLE, + ) -> PRUNTIME_FUNCTION; + #[cfg(target_arch = "x86_64")] + pub fn RtlLookupFunctionEntry( + ControlPc: DWORD64, ImageBase: PDWORD64, HistoryTable: PUNWIND_HISTORY_TABLE, + ) -> PRUNTIME_FUNCTION; + // pub fn RtlMoveMemory(); + // #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlPcToFileHeader(PcValue: PVOID, BaseOfImage: *mut PVOID) -> PVOID; + // #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + // pub fn RtlRaiseException(); + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlRestoreContext(ContextRecord: PCONTEXT, ExceptionRecord: *mut EXCEPTION_RECORD); + pub fn RtlUnwind( + TargetFrame: PVOID, TargetIp: PVOID, ExceptionRecord: PEXCEPTION_RECORD, ReturnValue: PVOID, + ); + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn RtlUnwindEx( + TargetFrame: PVOID, TargetIp: PVOID, ExceptionRecord: PEXCEPTION_RECORD, ReturnValue: PVOID, + ContextRecord: PCONTEXT, HistoryTable: PUNWIND_HISTORY_TABLE, + ); + #[cfg(target_arch = "arm")] + pub fn RtlVirtualUnwind( + HandlerType: DWORD, ImageBase: DWORD, ControlPc: DWORD, FunctionEntry: PRUNTIME_FUNCTION, + ContextRecord: PCONTEXT, HandlerData: *mut PVOID, EstablisherFrame: PDWORD, + ContextPointers: PKNONVOLATILE_CONTEXT_POINTERS, + ) -> PEXCEPTION_ROUTINE; + #[cfg(target_arch = "x86_64")] + pub fn RtlVirtualUnwind( + HandlerType: DWORD, ImageBase: DWORD64, ControlPc: DWORD64, + FunctionEntry: PRUNTIME_FUNCTION, ContextRecord: PCONTEXT, HandlerData: *mut PVOID, + EstablisherFrame: PDWORD64, ContextPointers: PKNONVOLATILE_CONTEXT_POINTERS, + ) -> PEXCEPTION_ROUTINE; + // pub fn RtlZeroMemory(); + pub fn ScrollConsoleScreenBufferA( + hConsoleOutput: HANDLE, lpScrollRectangle: *const SMALL_RECT, + lpClipRectangle: *const SMALL_RECT, dwDestinationOrigin: COORD, lpFill: *const CHAR_INFO, + ) -> BOOL; + pub fn ScrollConsoleScreenBufferW( + hConsoleOutput: HANDLE, lpScrollRectangle: *const SMALL_RECT, + lpClipRectangle: *const SMALL_RECT, dwDestinationOrigin: COORD, lpFill: *const CHAR_INFO, + ) -> BOOL; + pub fn SearchPathA( + lpPath: LPCSTR, lpFileName: LPCSTR, lpExtension: LPCSTR, nBufferLength: DWORD, + lpBuffer: LPSTR, lpFilePart: *mut LPSTR, + ) -> DWORD; + pub fn SearchPathW( + lpPath: LPCWSTR, lpFileName: LPCWSTR, lpExtension: LPCWSTR, nBufferLength: DWORD, + lpBuffer: LPWSTR, lpFilePart: *mut LPWSTR, + ) -> DWORD; + pub fn SetCachedSigningLevel( + SourceFiles: PHANDLE, SourceFileCount: ULONG, Flags: ULONG, TargetFile: HANDLE, + ) -> BOOL; + pub fn SetCalendarInfoA( + Locale: LCID, Calendar: CALID, CalType: CALTYPE, lpCalData: LPCSTR, + ) -> BOOL; + pub fn SetCalendarInfoW( + Locale: LCID, Calendar: CALID, CalType: CALTYPE, lpCalData: LPCWSTR, + ) -> BOOL; + pub fn SetCommBreak(hFile: HANDLE) -> BOOL; + pub fn SetCommConfig(hCommDev: HANDLE, lpCC: LPCOMMCONFIG, dwSize: DWORD) -> BOOL; + pub fn SetCommMask(hFile: HANDLE, dwEvtMask: DWORD) -> BOOL; + pub fn SetCommState(hFile: HANDLE, lpDCB: LPDCB) -> BOOL; + pub fn SetCommTimeouts(hFile: HANDLE, lpCommTimeouts: LPCOMMTIMEOUTS) -> BOOL; + pub fn SetComputerNameA(lpComputerName: LPCSTR) -> BOOL; + pub fn SetComputerNameEx2W( + NameType: COMPUTER_NAME_FORMAT, Flags: DWORD, lpBuffer: LPCWSTR, + ) -> BOOL; + pub fn SetComputerNameExA(NameType: COMPUTER_NAME_FORMAT, lpBuffer: LPCSTR) -> BOOL; + pub fn SetComputerNameExW(NameType: COMPUTER_NAME_FORMAT, lpBuffer: LPCWSTR) -> BOOL; + pub fn SetComputerNameW(lpComputerName: LPCWSTR) -> BOOL; + pub fn SetConsoleActiveScreenBuffer(hConsoleOutput: HANDLE) -> BOOL; + pub fn SetConsoleCP(wCodePageID: UINT) -> BOOL; + pub fn SetConsoleCtrlHandler(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL; + // pub fn SetConsoleCursor(); + pub fn SetConsoleCursorInfo( + hConsoleOutput: HANDLE, lpConsoleCursorInfo: *const CONSOLE_CURSOR_INFO, + ) -> BOOL; + pub fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) -> BOOL; + pub fn SetConsoleDisplayMode( + hConsoleOutput: HANDLE, dwFlags: DWORD, lpNewScreenBufferDimensions: PCOORD, + ) -> BOOL; + pub fn SetConsoleHistoryInfo(lpConsoleHistoryInfo: PCONSOLE_HISTORY_INFO) -> BOOL; + pub fn SetConsoleMode(hConsoleHandle: HANDLE, dwMode: DWORD) -> BOOL; + pub fn SetConsoleOutputCP(wCodePageID: UINT) -> BOOL; + pub fn SetConsoleScreenBufferInfoEx( + hConsoleOutput: HANDLE, lpConsoleScreenBufferInfoEx: PCONSOLE_SCREEN_BUFFER_INFOEX, + ) -> BOOL; + pub fn SetConsoleScreenBufferSize(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL; + pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) -> BOOL; + pub fn SetConsoleTitleA(lpConsoleTitle: LPCSTR) -> BOOL; + pub fn SetConsoleTitleW(lpConsoleTitle: LPCWSTR) -> BOOL; + pub fn SetConsoleWindowInfo( + hConsoleOutput: HANDLE, bAbsolute: BOOL, lpConsoleWindow: *const SMALL_RECT, + ) -> BOOL; + pub fn SetCriticalSectionSpinCount( + lpCriticalSection: LPCRITICAL_SECTION, dwSpinCount: DWORD, + ) -> DWORD; + pub fn SetCurrentConsoleFontEx( + hConsoleOutput: HANDLE, bMaximumWindow: BOOL, lpConsoleCurrentFontEx: PCONSOLE_FONT_INFOEX, + ) -> BOOL; + pub fn SetCurrentDirectoryA(lpPathName: LPCSTR) -> BOOL; + pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn SetDefaultCommConfigA(lpszName: LPCSTR, lpCC: LPCOMMCONFIG, dwSize: DWORD) -> BOOL; + pub fn SetDefaultCommConfigW(lpszName: LPCWSTR, lpCC: LPCOMMCONFIG, dwSize: DWORD) -> BOOL; + pub fn SetDefaultDllDirectories(DirectoryFlags: DWORD) -> BOOL; + pub fn SetDllDirectoryA(lpPathName: LPCSTR) -> BOOL; + pub fn SetDllDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn SetDynamicTimeZoneInformation( + lpTimeZoneInformation: *const DYNAMIC_TIME_ZONE_INFORMATION, + ) -> BOOL; + pub fn SetEndOfFile(hFile: HANDLE) -> BOOL; + pub fn SetEnvironmentStringsA(NewEnvironment: LPCH) -> BOOL; + pub fn SetEnvironmentStringsW(NewEnvironment: LPWCH) -> BOOL; + pub fn SetEnvironmentVariableA(lpName: LPCSTR, lpValue: LPCSTR) -> BOOL; + pub fn SetEnvironmentVariableW(lpName: LPCWSTR, lpValue: LPCWSTR) -> BOOL; + pub fn SetErrorMode(uMode: UINT) -> UINT; + pub fn SetEvent(hEvent: HANDLE) -> BOOL; + pub fn SetEventWhenCallbackReturns(pci: PTP_CALLBACK_INSTANCE, evt: HANDLE); + pub fn SetFileApisToANSI(); + pub fn SetFileApisToOEM(); + pub fn SetFileAttributesA(lpFileName: LPCSTR, dwFileAttributes: DWORD) -> BOOL; + pub fn SetFileAttributesTransactedA( + lpFileName: LPCSTR, dwFileAttributes: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn SetFileAttributesTransactedW( + lpFileName: LPCWSTR, dwFileAttributes: DWORD, hTransaction: HANDLE, + ) -> BOOL; + pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; + pub fn SetFileBandwidthReservation( + hFile: HANDLE, nPeriodMilliseconds: DWORD, nBytesPerPeriod: DWORD, bDiscardable: BOOL, + lpTransferSize: LPDWORD, lpNumOutstandingRequests: LPDWORD, + ) -> BOOL; + pub fn SetFileCompletionNotificationModes(FileHandle: HANDLE, Flags: UCHAR) -> BOOL; + pub fn SetFileInformationByHandle( + hFile: HANDLE, FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, lpFileInformation: LPVOID, + dwBufferSize: DWORD, + ) -> BOOL; + pub fn SetFileIoOverlappedRange( + FileHandle: HANDLE, OverlappedRangeStart: PUCHAR, Length: ULONG, + ) -> BOOL; + pub fn SetFilePointer( + hFile: HANDLE, lDistanceToMove: LONG, lpDistanceToMoveHigh: PLONG, dwMoveMethod: DWORD, + ) -> DWORD; + pub fn SetFilePointerEx( + hFile: HANDLE, liDistanceToMove: LARGE_INTEGER, lpNewFilePointer: PLARGE_INTEGER, + dwMoveMethod: DWORD, + ) -> BOOL; + pub fn SetFileShortNameA(hFile: HANDLE, lpShortName: LPCSTR) -> BOOL; + pub fn SetFileShortNameW(hFile: HANDLE, lpShortName: LPCWSTR) -> BOOL; + pub fn SetFileTime( + hFile: HANDLE, lpCreationTime: *const FILETIME, lpLastAccessTime: *const FILETIME, + lpLastWriteTime: *const FILETIME, + ) -> BOOL; + pub fn SetFileValidData(hFile: HANDLE, ValidDataLength: LONGLONG) -> BOOL; + pub fn SetFirmwareEnvironmentVariableA( + lpName: LPCSTR, lpGuid: LPCSTR, pValue: PVOID, nSize: DWORD, + ) -> BOOL; + pub fn SetFirmwareEnvironmentVariableExA( + lpName: LPCSTR, lpGuid: LPCSTR, pValue: PVOID, nSize: DWORD, dwAttributes: DWORD, + ) -> BOOL; + pub fn SetFirmwareEnvironmentVariableExW( + lpName: LPCWSTR, lpGuid: LPCWSTR, pValue: PVOID, nSize: DWORD, dwAttributes: DWORD, + ) -> BOOL; + pub fn SetFirmwareEnvironmentVariableW( + lpName: LPCWSTR, lpGuid: LPCWSTR, pValue: PVOID, nSize: DWORD, + ) -> BOOL; + pub fn SetHandleCount(uNumber: UINT) -> UINT; + pub fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL; + pub fn SetInformationJobObject( + hJob: HANDLE, JobObjectInformationClass: JOBOBJECTINFOCLASS, + lpJobObjectInformation: LPVOID, cbJobObjectInformationLength: DWORD, + ) -> BOOL; + pub fn SetLastError(dwErrCode: DWORD); + // pub fn SetLocalPrimaryComputerNameA(); + // pub fn SetLocalPrimaryComputerNameW(); + pub fn SetLocalTime(lpSystemTime: *const SYSTEMTIME) -> BOOL; + pub fn SetLocaleInfoA(Locale: LCID, LCType: LCTYPE, lpLCData: LPCSTR) -> BOOL; + pub fn SetLocaleInfoW(Locale: LCID, LCType: LCTYPE, lpLCData: LPCWSTR) -> BOOL; + pub fn SetMailslotInfo(hMailslot: HANDLE, lReadTimeout: DWORD) -> BOOL; + pub fn SetMessageWaitingIndicator(hMsgIndicator: HANDLE, ulMsgCount: ULONG) -> BOOL; + pub fn SetNamedPipeAttribute( + Pipe: HANDLE, AttributeType: PIPE_ATTRIBUTE_TYPE, AttributeName: PSTR, + AttributeValue: PVOID, AttributeValueLength: SIZE_T, + ) -> BOOL; + pub fn SetNamedPipeHandleState( + hNamedPipe: HANDLE, lpMode: LPDWORD, lpMaxCollectionCount: LPDWORD, + lpCollectDataTimeout: LPDWORD, + ) -> BOOL; + pub fn SetPriorityClass(hProcess: HANDLE, dwPriorityClass: DWORD) -> BOOL; + pub fn SetProcessAffinityMask(hProcess: HANDLE, dwProcessAffinityMask: DWORD) -> BOOL; + pub fn SetProcessAffinityUpdateMode(hProcess: HANDLE, dwFlags: DWORD) -> BOOL; + pub fn SetProcessDEPPolicy(dwFlags: DWORD) -> BOOL; + pub fn SetProcessInformation( + hProcess: HANDLE, ProcessInformationClass: PROCESS_INFORMATION_CLASS, + ProcessInformation: LPVOID, ProcessInformationSize: DWORD, + ) -> BOOL; + pub fn SetProcessMitigationPolicy( + MitigationPolicy: PROCESS_MITIGATION_POLICY, lpBuffer: PVOID, dwLength: SIZE_T, + ) -> BOOL; + pub fn SetProcessPreferredUILanguages( + dwFlags: DWORD, pwszLanguagesBuffer: PCZZWSTR, pulNumLanguages: PULONG, + ) -> BOOL; + pub fn SetProcessPriorityBoost(hProcess: HANDLE, bDisablePriorityBoost: BOOL) -> BOOL; + pub fn SetProcessShutdownParameters(dwLevel: DWORD, dwFlags: DWORD) -> BOOL; + pub fn SetProcessWorkingSetSize( + hProcess: HANDLE, dwMinimumWorkingSetSize: SIZE_T, dwMaximumWorkingSetSize: SIZE_T, + ) -> BOOL; + pub fn SetProcessWorkingSetSizeEx( + hProcess: HANDLE, dwMinimumWorkingSetSize: SIZE_T, dwMaximumWorkingSetSize: SIZE_T, + Flags: DWORD, + ) -> BOOL; + pub fn SetProtectedPolicy( + PolicyGuid: LPCGUID, PolicyValue: ULONG_PTR, OldPolicyValue: PULONG_PTR, + ) -> BOOL; + pub fn SetSearchPathMode(Flags: DWORD) -> BOOL; + pub fn SetStdHandle(nStdHandle: DWORD, hHandle: HANDLE) -> BOOL; + pub fn SetStdHandleEx(nStdHandle: DWORD, hHandle: HANDLE, phPrevValue: PHANDLE) -> BOOL; + pub fn SetSystemFileCacheSize( + MinimumFileCacheSize: SIZE_T, MaximumFileCacheSize: SIZE_T, Flags: DWORD, + ) -> BOOL; + pub fn SetSystemPowerState(fSuspend: BOOL, fForce: BOOL) -> BOOL; + pub fn SetSystemTime(lpSystemTime: *const SYSTEMTIME) -> BOOL; + pub fn SetSystemTimeAdjustment(dwTimeAdjustment: DWORD, bTimeAdjustmentDisabled: BOOL) -> BOOL; + pub fn SetTapeParameters( + hDevice: HANDLE, dwOperation: DWORD, lpTapeInformation: LPVOID, + ) -> DWORD; + pub fn SetTapePosition( + hDevice: HANDLE, dwPositionMethod: DWORD, dwPartition: DWORD, + dwOffsetLow: DWORD, dwOffsetHigh: DWORD, bImmediate: BOOL + ) -> DWORD; + pub fn SetThreadAffinityMask(hThread: HANDLE, dwThreadAffinityMask: DWORD_PTR) -> DWORD_PTR; + pub fn SetThreadContext(hThread: HANDLE, lpContext: *const CONTEXT) -> BOOL; + pub fn SetThreadErrorMode(dwNewMode: DWORD, lpOldMode: LPDWORD) -> BOOL; + pub fn SetThreadExecutionState(esFlags: EXECUTION_STATE) -> EXECUTION_STATE; + pub fn SetThreadGroupAffinity( + hThread: HANDLE, GroupAffinity: *const GROUP_AFFINITY, + PreviousGroupAffinity: PGROUP_AFFINITY, + ) -> BOOL; + pub fn SetThreadIdealProcessor(hThread: HANDLE, dwIdealProcessor: DWORD) -> DWORD; + pub fn SetThreadIdealProcessorEx( + hThread: HANDLE, lpIdealProcessor: PPROCESSOR_NUMBER, + lpPreviousIdealProcessor: PPROCESSOR_NUMBER, + ) -> BOOL; + pub fn SetThreadInformation( + hThread: HANDLE, ThreadInformationClass: THREAD_INFORMATION_CLASS, + ThreadInformation: LPVOID, ThreadInformationSize: DWORD, + ); + pub fn SetThreadLocale(Locale: LCID) -> BOOL; + pub fn SetThreadPreferredUILanguages( + dwFlags: DWORD, pwszLanguagesBuffer: PCZZWSTR, pulNumLanguages: PULONG, + ) -> BOOL; + pub fn SetThreadPriority(hThread: HANDLE, nPriority: c_int) -> BOOL; + pub fn SetThreadPriorityBoost(hThread: HANDLE, bDisablePriorityBoost: BOOL) -> BOOL; + pub fn SetThreadStackGuarantee(StackSizeInBytes: PULONG) -> BOOL; + pub fn SetThreadUILanguage(LangId: LANGID) -> LANGID; + pub fn SetThreadpoolStackInformation( + ptpp: PTP_POOL, ptpsi: PTP_POOL_STACK_INFORMATION, + ) -> BOOL; + pub fn SetThreadpoolThreadMaximum(ptpp: PTP_POOL, cthrdMost: DWORD); + pub fn SetThreadpoolThreadMinimum(ptpp: PTP_POOL, cthrdMic: DWORD) -> BOOL; + pub fn SetThreadpoolTimer( + pti: PTP_TIMER, pftDueTime: PFILETIME, msPeriod: DWORD, msWindowLength: DWORD, + ); + pub fn SetThreadpoolTimerEx( + pti: PTP_TIMER, pftDueTime: PFILETIME, msPeriod: DWORD, msWindowLength: DWORD, + ) -> BOOL; + pub fn SetThreadpoolWait(pwa: PTP_WAIT, h: HANDLE, pftTimeout: PFILETIME); + pub fn SetThreadpoolWaitEx( + pwa: PTP_WAIT, h: HANDLE, pftTimeout: PFILETIME, Reserved: PVOID, + ) -> BOOL; + pub fn SetTimeZoneInformation(lpTimeZoneInformation: *const TIME_ZONE_INFORMATION) -> BOOL; + pub fn SetTimerQueueTimer( + TimerQueue: HANDLE, Callback: WAITORTIMERCALLBACK, Parameter: PVOID, DueTime: DWORD, + Period: DWORD, PreferIo: BOOL, + ) -> HANDLE; + #[cfg(target_arch = "x86_64")] + pub fn SetUmsThreadInformation( + UmsThread: PUMS_CONTEXT, UmsThreadInfoClass: UMS_THREAD_INFO_CLASS, + UmsThreadInformation: PVOID, UmsThreadInformationLength: ULONG, + ) -> BOOL; + pub fn SetUnhandledExceptionFilter( + lpTopLevelExceptionFilter: LPTOP_LEVEL_EXCEPTION_FILTER, + ) -> LPTOP_LEVEL_EXCEPTION_FILTER; + pub fn SetUserGeoID(GeoId: GEOID) -> BOOL; + pub fn SetVolumeLabelA(lpRootPathName: LPCSTR, lpVolumeName: LPCSTR) -> BOOL; + pub fn SetVolumeLabelW(lpRootPathName: LPCWSTR, lpVolumeName: LPCWSTR) -> BOOL; + pub fn SetVolumeMountPointA(lpszVolumeMountPoint: LPCSTR, lpszVolumeName: LPCSTR) -> BOOL; + pub fn SetVolumeMountPointW(lpszVolumeMountPoint: LPCWSTR, lpszVolumeName: LPCWSTR) -> BOOL; + pub fn SetWaitableTimer( + hTimer: HANDLE, lpDueTime: *const LARGE_INTEGER, lPeriod: LONG, + pfnCompletionRoutine: PTIMERAPCROUTINE, lpArgToCompletionRoutine: LPVOID, fResume: BOOL, + ) -> BOOL; + pub fn SetWaitableTimerEx( + hTimer: HANDLE, lpDueTime: *const LARGE_INTEGER, lPeriod: LONG, + pfnCompletionRoutine: PTIMERAPCROUTINE, lpArgToCompletionRoutine: LPVOID, + WakeContext: PREASON_CONTEXT, TolerableDelay: ULONG, + ) -> BOOL; + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + pub fn SetXStateFeaturesMask(Context: PCONTEXT, FeatureMask: DWORD64) -> BOOL; + pub fn SetupComm(hFile: HANDLE, dwInQueue: DWORD, dwOutQueue: DWORD) -> BOOL; + pub fn SignalObjectAndWait( + hObjectToSignal: HANDLE, hObjectToWaitOn: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL, + ) -> DWORD; + pub fn SizeofResource(hModule: HMODULE, hResInfo: HRSRC) -> DWORD; + pub fn Sleep(dwMilliseconds: DWORD); + pub fn SleepConditionVariableCS( + ConditionVariable: PCONDITION_VARIABLE, CriticalSection: PCRITICAL_SECTION, + dwMilliseconds: DWORD, + ) -> BOOL; + pub fn SleepConditionVariableSRW( + ConditionVariable: PCONDITION_VARIABLE, SRWLock: PSRWLOCK, dwMilliseconds: DWORD, + Flags: ULONG, + ) -> BOOL; + pub fn SleepEx(dwMilliseconds: DWORD, bAlertable: BOOL) -> DWORD; + pub fn StartThreadpoolIo(pio: PTP_IO); + pub fn SubmitThreadpoolWork(pwk: PTP_WORK); + pub fn SuspendThread(hThread: HANDLE) -> DWORD; + pub fn SwitchToFiber(lpFiber: LPVOID); + pub fn SwitchToThread() -> BOOL; + pub fn SystemTimeToFileTime(lpSystemTime: *const SYSTEMTIME, lpFileTime: LPFILETIME) -> BOOL; + pub fn SystemTimeToTzSpecificLocalTime( + lpTimeZoneInformation: *const TIME_ZONE_INFORMATION, lpUniversalTime: *const SYSTEMTIME, + lpLocalTime: LPSYSTEMTIME, + ) -> BOOL; + pub fn SystemTimeToTzSpecificLocalTimeEx( + lpTimeZoneInformation: *const DYNAMIC_TIME_ZONE_INFORMATION, + lpUniversalTime: *const SYSTEMTIME, lpLocalTime: LPSYSTEMTIME, + ) -> BOOL; + pub fn TerminateJobObject(hJob: HANDLE, uExitCode: UINT) -> BOOL; + pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL; + pub fn TerminateThread(hThread: HANDLE, dwExitCode: DWORD) -> BOOL; + pub fn Thread32First(hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL; + pub fn Thread32Next(hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL; + pub fn TlsAlloc() -> DWORD; + pub fn TlsFree(dwTlsIndex: DWORD) -> BOOL; + pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; + pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsValue: LPVOID) -> BOOL; + pub fn Toolhelp32ReadProcessMemory(th32ProcessID: DWORD, lpBaseAddress: LPCVOID, + lpBuffer: LPVOID, cbRead: SIZE_T, lpNumberOfBytesRead: *mut SIZE_T + ) -> BOOL; + pub fn TransactNamedPipe( + hNamedPipe: HANDLE, lpInBuffer: LPVOID, nInBufferSize: DWORD, lpOutBuffer: LPVOID, + nOutBufferSize: DWORD, lpBytesRead: LPDWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn TransmitCommChar(hFile: HANDLE, cChar: c_char) -> BOOL; + pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN; + pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN; + pub fn TryEnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION) -> BOOL; + pub fn TrySubmitThreadpoolCallback( + pfns: PTP_SIMPLE_CALLBACK, pv: PVOID, pcbe: PTP_CALLBACK_ENVIRON, + ) -> BOOL; + pub fn TzSpecificLocalTimeToSystemTime( + lpTimeZoneInformation: *const TIME_ZONE_INFORMATION, lpLocalTime: *const SYSTEMTIME, + lpUniversalTime: LPSYSTEMTIME, + ) -> BOOL; + pub fn TzSpecificLocalTimeToSystemTimeEx( + lpTimeZoneInformation: *const DYNAMIC_TIME_ZONE_INFORMATION, + lpLocalTime: *const SYSTEMTIME, lpUniversalTime: LPSYSTEMTIME, + ) -> BOOL; + #[cfg(target_arch = "x86_64")] + pub fn UmsThreadYield(SchedulerParam: PVOID) -> BOOL; + pub fn UnhandledExceptionFilter(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG; + pub fn UnlockFile( + hFile: HANDLE, dwFileOffsetLow: DWORD, dwFileOffsetHigh: DWORD, + nNumberOfBytesToUnlockLow: DWORD, nNumberOfBytesToUnlockHigh: DWORD, + ) -> BOOL; + pub fn UnlockFileEx( + hFile: HANDLE, dwReserved: DWORD, nNumberOfBytesToUnlockLow: DWORD, + nNumberOfBytesToUnlockHigh: DWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL; + pub fn UnregisterApplicationRecoveryCallback() -> HRESULT; + pub fn UnregisterApplicationRestart() -> HRESULT; + pub fn UnregisterBadMemoryNotification(RegistrationHandle: PVOID) -> BOOL; + pub fn UnregisterWait(WaitHandle: HANDLE) -> BOOL; + pub fn UnregisterWaitEx(WaitHandle: HANDLE, CompletionEvent: HANDLE) -> BOOL; + // pub fn UnregisterWaitUntilOOBECompleted(); + pub fn UpdateProcThreadAttribute( + lpAttributeList: LPPROC_THREAD_ATTRIBUTE_LIST, dwFlags: DWORD, Attribute: DWORD_PTR, + lpValue: PVOID, cbSize: SIZE_T, lpPreviousValue: PVOID, lpReturnSize: PSIZE_T, + ) -> BOOL; + pub fn UpdateResourceA( + hUpdate: HANDLE, lpType: LPCSTR, lpName: LPCSTR, wLanguage: WORD, lpData: LPVOID, cb: DWORD, + ) -> BOOL; + pub fn UpdateResourceW( + hUpdate: HANDLE, lpType: LPCWSTR, lpName: LPCWSTR, wLanguage: WORD, lpData: LPVOID, + cb: DWORD, + ) -> BOOL; + pub fn VerLanguageNameA(wLang: DWORD, szLang: LPSTR, cchLang: DWORD) -> DWORD; + pub fn VerLanguageNameW(wLang: DWORD, szLang: LPWSTR, cchLang: DWORD) -> DWORD; + pub fn VerSetConditionMask( + ConditionMask: ULONGLONG, TypeMask: DWORD, Condition: BYTE, + ) -> ULONGLONG; + pub fn VerifyScripts( + dwFlags: DWORD, lpLocaleScripts: LPCWSTR, cchLocaleScripts: c_int, lpTestScripts: LPCWSTR, + cchTestScripts: c_int, + ) -> BOOL; + pub fn VerifyVersionInfoA( + lpVersionInformation: LPOSVERSIONINFOEXA, dwTypeMask: DWORD, dwlConditionMask: DWORDLONG, + ) -> BOOL; + pub fn VerifyVersionInfoW( + lpVersionInformation: LPOSVERSIONINFOEXW, dwTypeMask: DWORD, dwlConditionMask: DWORDLONG, + ) -> BOOL; + pub fn VirtualAlloc( + lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD, + ) -> LPVOID; + pub fn VirtualAllocEx( + hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, + flProtect: DWORD, + ) -> LPVOID; + pub fn VirtualAllocExNuma( + hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, + flProtect: DWORD, nndPreferred: DWORD, + ) -> LPVOID; + pub fn VirtualFree(lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) -> BOOL; + pub fn VirtualFreeEx( + hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD, + ) -> BOOL; + pub fn VirtualLock(lpAddress: LPVOID, dwSize: SIZE_T) -> BOOL; + pub fn VirtualProtect( + lpAddress: LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: PDWORD, + ) -> BOOL; + pub fn VirtualProtectEx( + hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, + lpflOldProtect: DWORD, + ) -> BOOL; + pub fn VirtualQuery( + lpAddress: LPCVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T, + ) -> SIZE_T; + pub fn VirtualQueryEx( + hProcess: HANDLE, lpAddress: LPCVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T, + ) -> SIZE_T; + pub fn VirtualUnlock(lpAddress: LPVOID, dwSize: SIZE_T) -> BOOL; + pub fn WTSGetActiveConsoleSessionId() -> DWORD; + pub fn WaitCommEvent(hFile: HANDLE, lpEvtMask: LPDWORD, lpOverlapped: LPOVERLAPPED) -> BOOL; + pub fn WaitForDebugEvent(lpDebugEvent: LPDEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL; + pub fn WaitForMultipleObjects( + nCount: DWORD, lpHandles: *const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD, + ) -> DWORD; + pub fn WaitForMultipleObjectsEx( + nCount: DWORD, lpHandles: *const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD, + bAlertable: BOOL, + ) -> DWORD; + pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; + pub fn WaitForSingleObjectEx( + hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL, + ) -> DWORD; + pub fn WaitForThreadpoolIoCallbacks(pio: PTP_IO, fCancelPendingCallbacks: BOOL); + pub fn WaitForThreadpoolTimerCallbacks(pti: PTP_TIMER, fCancelPendingCallbacks: BOOL); + pub fn WaitForThreadpoolWaitCallbacks(pwa: PTP_WAIT, fCancelPendingCallbacks: BOOL); + pub fn WaitForThreadpoolWorkCallbacks(pwk: PTP_WORK, fCancelPendingCallbacks: BOOL); + pub fn WaitNamedPipeA(lpNamedPipeName: LPCSTR, nTimeOut: DWORD) -> BOOL; + pub fn WaitNamedPipeW(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL; + pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE); + pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE); + pub fn WerGetFlags(hProcess: HANDLE, pdwFlags: PDWORD) -> HRESULT; + pub fn WerRegisterFile( + pwzFile: PCWSTR, regFileType: WER_REGISTER_FILE_TYPE, dwFlags: DWORD, + ) -> HRESULT; + pub fn WerRegisterMemoryBlock(pvAddress: PVOID, dwSize: DWORD) -> HRESULT; + pub fn WerRegisterRuntimeExceptionModule( + pwszOutOfProcessCallbackDll: PCWSTR, pContext: PVOID, + ) -> HRESULT; + pub fn WerSetFlags(dwFlags: DWORD) -> HRESULT; + pub fn WerUnregisterFile(pwzFilePath: PCWSTR) -> HRESULT; + pub fn WerUnregisterMemoryBlock(pvAddress: PVOID) -> HRESULT; + pub fn WerUnregisterRuntimeExceptionModule( + pwszOutOfProcessCallbackDll: PCWSTR, pContext: PVOID, + ) -> HRESULT; + // pub fn WerpInitiateRemoteRecovery(); + pub fn WideCharToMultiByte( + CodePage: UINT, dwFlags: DWORD, lpWideCharStr: LPCWSTR, cchWideChar: c_int, + lpMultiByteStr: LPSTR, cbMultiByte: c_int, lpDefaultChar: LPCSTR, lpUsedDefaultChar: LPBOOL, + ) -> c_int; + pub fn WinExec(lpCmdLine: LPCSTR, uCmdShow: UINT) -> UINT; + pub fn Wow64DisableWow64FsRedirection(OldValue: *mut PVOID) -> BOOL; + pub fn Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: BOOLEAN) -> BOOLEAN; + pub fn Wow64GetThreadContext(hThread: HANDLE, lpContext: PWOW64_CONTEXT) -> BOOL; + pub fn Wow64GetThreadSelectorEntry( + hThread: HANDLE, dwSelector: DWORD, lpSelectorEntry: PWOW64_LDT_ENTRY, + ) -> BOOL; + pub fn Wow64RevertWow64FsRedirection(OlValue: PVOID) -> BOOL; + pub fn Wow64SetThreadContext(hThread: HANDLE, lpContext: *const WOW64_CONTEXT) -> BOOL; + pub fn Wow64SuspendThread(hThread: HANDLE) -> DWORD; + pub fn WriteConsoleA( + hConsoleOutput: HANDLE, lpBuffer: *const VOID, nNumberOfCharsToWrite: DWORD, + lpNumberOfCharsWritten: LPDWORD, lpReserved: LPVOID, + ) -> BOOL; + pub fn WriteConsoleInputA( + hConsoleInput: HANDLE, lpBuffer: *const INPUT_RECORD, nLength: DWORD, + lpNumberOfEventsWritten: LPDWORD, + ) -> BOOL; + pub fn WriteConsoleInputW( + hConsoleInput: HANDLE, lpBuffer: *const INPUT_RECORD, nLength: DWORD, + lpNumberOfEventsWritten: LPDWORD, + ) -> BOOL; + pub fn WriteConsoleOutputA( + hConsoleOutput: HANDLE, lpBuffer: *const CHAR_INFO, dwBufferSize: COORD, + dwBufferCoord: COORD, lpWriteRegion: PSMALL_RECT, + ) -> BOOL; + pub fn WriteConsoleOutputAttribute( + hConsoleOutput: HANDLE, lpAttribute: *const WORD, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfAttrsWritten: LPDWORD, + ) -> BOOL; + pub fn WriteConsoleOutputCharacterA( + hConsoleOutput: HANDLE, lpCharacter: LPCSTR, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfCharsWritten: LPDWORD, + ) -> BOOL; + pub fn WriteConsoleOutputCharacterW( + hConsoleOutput: HANDLE, lpCharacter: LPCWSTR, nLength: DWORD, dwWriteCoord: COORD, + lpNumberOfCharsWritten: LPDWORD, + ) -> BOOL; + pub fn WriteConsoleOutputW( + hConsoleOutput: HANDLE, lpBuffer: *const CHAR_INFO, dwBufferSize: COORD, + dwBufferCoord: COORD, lpWriteRegion: PSMALL_RECT, + ) -> BOOL; + pub fn WriteConsoleW( + hConsoleOutput: HANDLE, lpBuffer: *const VOID, nNumberOfCharsToWrite: DWORD, + lpNumberOfCharsWritten: LPDWORD, lpReserved: LPVOID, + ) -> BOOL; + pub fn WriteFile( + hFile: HANDLE, lpBuffer: LPCVOID, nNumberOfBytesToWrite: DWORD, + lpNumberOfBytesWritten: LPDWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn WriteFileEx( + hFile: HANDLE, lpBuffer: LPCVOID, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL; + pub fn WriteFileGather( + hFile: HANDLE, aSegmentArray: *mut FILE_SEGMENT_ELEMENT, nNumberOfBytesToWrite: DWORD, + lpReserved: LPDWORD, lpOverlapped: LPOVERLAPPED, + ) -> BOOL; + pub fn WritePrivateProfileSectionA( + lpAppName: LPCSTR, lpString: LPCSTR, lpFileName: LPCSTR, + ) -> BOOL; + pub fn WritePrivateProfileSectionW( + lpAppName: LPCWSTR, lpString: LPCWSTR, lpFileName: LPCWSTR, + ) -> BOOL; + pub fn WritePrivateProfileStringA( + lpAppName: LPCSTR, lpKeyName: LPCSTR, lpString: LPCSTR, lpFileName: LPCSTR, + ) -> BOOL; + pub fn WritePrivateProfileStringW( + lpAppName: LPCWSTR, lpKeyName: LPCWSTR, lpString: LPCWSTR, lpFileName: LPCWSTR, + ) -> BOOL; + pub fn WritePrivateProfileStructA( + lpszSection: LPCSTR, lpszKey: LPCSTR, lpStruct: LPVOID, uSizeStruct: UINT, szFile: LPCSTR, + ) -> BOOL; + pub fn WritePrivateProfileStructW( + lpszSection: LPCWSTR, lpszKey: LPCWSTR, lpStruct: LPVOID, uSizeStruct: UINT, + szFile: LPCWSTR, + ) -> BOOL; + pub fn WriteProcessMemory( + hProcess: HANDLE, lpBaseAddress: LPVOID, lpBuffer: LPCVOID, nSize: SIZE_T, + lpNumberOfBytesWritten: *mut SIZE_T, + ) -> BOOL; + pub fn WriteProfileSectionA(lpAppName: LPCSTR, lpString: LPCSTR) -> BOOL; + pub fn WriteProfileSectionW(lpAppName: LPCWSTR, lpString: LPCWSTR) -> BOOL; + pub fn WriteProfileStringA(lpAppName: LPCSTR, lpKeyName: LPCSTR, lpString: LPCSTR) -> BOOL; + pub fn WriteProfileStringW(lpAppName: LPCWSTR, lpKeyName: LPCWSTR, lpString: LPCWSTR) -> BOOL; + pub fn WriteTapemark( + hDevice: HANDLE, dwTapemarkType: DWORD, dwTapemarkCount: DWORD, bImmediate: BOOL, + ) -> DWORD; + pub fn ZombifyActCtx(hActCtx: HANDLE) -> BOOL; + pub fn _hread(hFile: HFILE, lpBuffer: LPVOID, lBytes: c_long) -> c_long; + pub fn _hwrite(hFile: HFILE, lpBuffer: LPCCH, lBytes: c_long) -> c_long; + pub fn _lclose(hFile: HFILE) -> HFILE; + pub fn _lcreat(lpPathName: LPCSTR, iAttrubute: c_int) -> HFILE; + pub fn _llseek(hFile: HFILE, lOffset: LONG, iOrigin: c_int) -> LONG; + pub fn _lopen(lpPathName: LPCSTR, iReadWrite: c_int) -> HFILE; + pub fn _lread(hFile: HFILE, lpBuffer: LPVOID, uBytes: UINT) -> UINT; + pub fn _lwrite(hFile: HFILE, lpBuffer: LPCCH, uBytes: UINT) -> UINT; + pub fn lstrcat(lpString1: LPSTR, lpString2: LPCSTR) -> LPSTR; + pub fn lstrcatA(lpString1: LPSTR, lpString2: LPCSTR) -> LPSTR; + pub fn lstrcatW(lpString1: LPWSTR, lpString2: LPCWSTR) -> LPSTR; + pub fn lstrcmp(lpString1: LPCSTR, lpString2: LPCSTR) -> c_int; + pub fn lstrcmpA(lpString1: LPCSTR, lpString2: LPCSTR) -> c_int; + pub fn lstrcmpW(lpString1: LPCWSTR, lpString2: LPCWSTR) -> c_int; + pub fn lstrcmpi(lpString1: LPCSTR, lpString2: LPCSTR) -> c_int; + pub fn lstrcmpiA(lpString1: LPCSTR, lpString2: LPCSTR) -> c_int; + pub fn lstrcmpiW(lpString1: LPCWSTR, lpString2: LPCWSTR) -> c_int; + pub fn lstrcpy(lpString1: LPSTR, lpString2: LPCSTR) -> LPSTR; + pub fn lstrcpyA(lpString1: LPSTR, lpString2: LPCSTR) -> LPSTR; + pub fn lstrcpyW(lpString1: LPWSTR, lpString2: LPCWSTR) -> LPSTR; + pub fn lstrcpyn(lpString1: LPSTR, lpString2: LPCSTR, iMaxLength: c_int) -> LPSTR; + pub fn lstrcpynA(lpString1: LPSTR, lpString2: LPCSTR, iMaxLength: c_int) -> LPSTR; + pub fn lstrcpynW(lpString1: LPWSTR, lpString2: LPCWSTR, iMaxLength: c_int) -> LPSTR; + pub fn lstrlen(lpString: LPCSTR) -> c_int; + pub fn lstrlenA(lpString: LPCSTR) -> c_int; + pub fn lstrlenW(lpString: LPCWSTR) -> c_int; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_lstrcmpW(String1: PCUWSTR, String2: PCUWSTR) -> c_int; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_lstrcmpiW(String1: PCUWSTR, String2: PCUWSTR) -> c_int; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_lstrlenW(String: LPCUWSTR) -> c_int; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_wcschr(String: PCUWSTR, Character: WCHAR) -> PUWSTR; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_wcscpy(Destination: PUWSTR, Source: PCUWSTR) -> PUWSTR; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_wcsicmp(String1: PCUWSTR, String2: PCUWSTR) -> c_int; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_wcslen(String: PCUWSTR) -> size_t; + #[cfg(any(target_arch = "arm", target_arch = "x86_64"))] + pub fn uaw_wcsrchr(String: PCUWSTR, Character: WCHAR) -> PUWSTR; +} diff -Nru cargo-0.33.0/vendor/lazy_static/.cargo-checksum.json cargo-0.35.0/vendor/lazy_static/.cargo-checksum.json --- cargo-0.33.0/vendor/lazy_static/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/lazy_static/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"} \ No newline at end of file +{"files":{},"package":"bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/lazy_static/Cargo.toml cargo-0.35.0/vendor/lazy_static/Cargo.toml --- cargo-0.33.0/vendor/lazy_static/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/lazy_static/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "lazy_static" -version = "1.2.0" +version = "1.3.0" authors = ["Marvin Löbel "] exclude = ["/.travis.yml", "/appveyor.yml"] description = "A macro for declaring lazily evaluated statics in Rust." @@ -23,13 +23,10 @@ license = "MIT/Apache-2.0" repository = "https://github.com/rust-lang-nursery/lazy-static.rs" [dependencies.spin] -version = "0.4.10" -features = ["once"] +version = "0.5.0" optional = true -default-features = false [features] -nightly = [] spin_no_std = ["spin"] [badges.appveyor] repository = "rust-lang-nursery/lazy-static.rs" diff -Nru cargo-0.33.0/vendor/lazy_static/README.md cargo-0.35.0/vendor/lazy_static/README.md --- cargo-0.33.0/vendor/lazy_static/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/lazy_static/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -8,7 +8,7 @@ This includes anything requiring heap allocations, like vectors or hash maps, as well as anything that requires non-const function calls to be computed. -[![Travis-CI Status](https://travis-ci.org/rust-lang-nursery/lazy-static.rs.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/lazy-static.rs) +[![Travis-CI Status](https://travis-ci.com/rust-lang-nursery/lazy-static.rs.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/lazy-static.rs) [![Latest version](https://img.shields.io/crates/v/lazy_static.svg)](https://crates.io/crates/lazy_static) [![Documentation](https://docs.rs/lazy_static/badge.svg)](https://docs.rs/lazy_static) [![License](https://img.shields.io/crates/l/lazy_static.svg)](https://github.com/rust-lang-nursery/lazy-static.rs#license) @@ -31,7 +31,7 @@ ```toml [dependencies] -lazy_static = "1.2.0" +lazy_static = "1.3.0" ``` ...and see the [docs](https://docs.rs/lazy_static) for how to use it. diff -Nru cargo-0.33.0/vendor/lazy_static/src/lib.rs cargo-0.35.0/vendor/lazy_static/src/lib.rs --- cargo-0.33.0/vendor/lazy_static/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/lazy_static/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -92,15 +92,14 @@ This crate provides two cargo features: -- `nightly`: This uses unstable language features only available on the nightly release channel for a more optimal implementation. In practice this currently means avoiding a heap allocation per static. This feature might get deprecated at a later point once all relevant optimizations are usable from stable. -- `spin_no_std` (implies `nightly`): This allows using this crate in a no-std environment, by depending on the standalone `spin` crate. +- `spin_no_std`: This allows using this crate in a no-std environment, by depending on the standalone `spin` crate. Both features depend on unstable language features, which means no guarantees can be made about them in regard to SemVer stability. */ -#![doc(html_root_url = "https://docs.rs/lazy_static/1.2.0")] +#![doc(html_root_url = "https://docs.rs/lazy_static/1.3.0")] #![no_std] #[cfg(not(feature = "spin_no_std"))] @@ -196,7 +195,7 @@ /// extern crate lazy_static; /// /// lazy_static! { -/// static ref BUFFER: Vec = (0..65537).collect(); +/// static ref BUFFER: Vec = (0..255).collect(); /// } /// /// fn main() { diff -Nru cargo-0.33.0/vendor/libc/build.rs cargo-0.35.0/vendor/libc/build.rs --- cargo-0.33.0/vendor/libc/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,12 +3,42 @@ use std::str; fn main() { - /* - * If `core::ffi::c_void` exists, libc can just re-export it. Otherwise, it - * must define an incompatible type to retain backwards-compatibility. - */ - if rustc_minor_version().expect("Failed to get rustc version") >= 30 { - println!("cargo:rustc-cfg=core_cvoid"); + let rustc_minor_ver = + rustc_minor_version().expect("Failed to get rustc version"); + let rustc_dep_of_std = + std::env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); + let align_cargo_feature = std::env::var("CARGO_FEATURE_ALIGN").is_ok(); + + // Rust >= 1.15 supports private module use: + if rustc_minor_ver >= 15 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_priv_mod_use"); + } + + // Rust >= 1.19 supports unions: + if rustc_minor_ver >= 19 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_union"); + } + + // Rust >= 1.24 supports const mem::size_of: + if rustc_minor_ver >= 24 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_const_size_of"); + } + + // Rust >= 1.25 supports repr(align): + if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature { + println!("cargo:rustc-cfg=libc_align"); + } + + // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it. + // Otherwise, it defines an incompatible type to retaining + // backwards-compatibility. + if rustc_minor_ver >= 30 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_core_cvoid"); + } + + // Rust >= 1.33 supports repr(packed(N)) + if rustc_minor_ver >= 33 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_packedN"); } } diff -Nru cargo-0.33.0/vendor/libc/.cargo-checksum.json cargo-0.35.0/vendor/libc/.cargo-checksum.json --- cargo-0.33.0/vendor/libc/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"} \ No newline at end of file +{"files":{},"package":"c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/libc/Cargo.toml cargo-0.35.0/vendor/libc/Cargo.toml --- cargo-0.33.0/vendor/libc/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "libc" -version = "0.2.48" +version = "0.2.54" authors = ["The Rust Project Developers"] build = "build.rs" exclude = ["/ci/*", "/.travis.yml", "/appveyor.yml"] @@ -31,6 +31,7 @@ [features] align = [] default = ["use_std"] +extra_traits = [] rustc-dep-of-std = ["align", "rustc-std-workspace-core"] use_std = [] [badges.appveyor] diff -Nru cargo-0.33.0/vendor/libc/CONTRIBUTING.md cargo-0.35.0/vendor/libc/CONTRIBUTING.md --- cargo-0.33.0/vendor/libc/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/CONTRIBUTING.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,66 @@ +# Contributing to `libc` + +Welcome! If you are reading this document, it means you are interested in contributing +to the `libc` crate. + +## Adding an API + +Want to use an API which currently isn't bound in `libc`? It's quite easy to add +one! + +The internal structure of this crate is designed to minimize the number of +`#[cfg]` attributes in order to easily be able to add new items which apply +to all platforms in the future. As a result, the crate is organized +hierarchically based on platform. Each module has a number of `#[cfg]`'d +children, but only one is ever actually compiled. Each module then reexports all +the contents of its children. + +This means that for each platform that libc supports, the path from a +leaf module to the root will contain all bindings for the platform in question. +Consequently, this indicates where an API should be added! Adding an API at a +particular level in the hierarchy means that it is supported on all the child +platforms of that level. For example, when adding a Unix API it should be added +to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to +`src/unix/notbsd/linux/mod.rs`. + +If you're not 100% sure at what level of the hierarchy an API should be added +at, fear not! This crate has CI support which tests any binding against all +platforms supported, so you'll see failures if an API is added at the wrong +level or has different signatures across platforms. + +With that in mind, the steps for adding a new API are: + +1. Determine where in the module hierarchy your API should be added. +2. Add the API. +3. Send a PR to this repo. +4. Wait for CI to pass, fixing errors. +5. Wait for a merge! + +### Test before you commit + +We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc): + +1. [`libc-test`](https://github.com/alexcrichton/ctest) + - `cd libc-test && cargo test` + - Use the `skip_*()` functions in `build.rs` if you really need a workaround. +2. Style checker + - `rustc ci/style.rs && ./style src` + +### Releasing your change to crates.io + +Now that you've done the amazing job of landing your new API or your new +platform in this crate, the next step is to get that sweet, sweet usage from +crates.io! The only next step is to bump the version of libc and then publish +it. If you'd like to get a release out ASAP you can follow these steps: + +1. Update the version number in `Cargo.toml`, you'll just be bumping the patch + version number. +2. Run `cargo update` to regenerate the lockfile to encode your version bump in + the lock file. You may pull in some other updated dependencies, that's ok. +3. Send a PR to this repository. It should [look like this][example], but it'd + also be nice to fill out the description with a small rationale for the + release (any rationale is ok though!) +4. Once merged the release will be tagged and published by one of the libc crate + maintainers. + +[example]: https://github.com/rust-lang/libc/pull/583 diff -Nru cargo-0.33.0/vendor/libc/README.md cargo-0.35.0/vendor/libc/README.md --- cargo-0.33.0/vendor/libc/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,173 +1,103 @@ -libc +[![Travis-CI Status]][Travis-CI] [![Appveyor Status]][Appveyor] [![Cirrus-CI Status]][Cirrus-CI] [![Latest Version]][crates.io] [![Documentation]][docs.rs] ![License] + +libc - Raw FFI bindings to platforms' system libraries ==== -Raw FFI bindings to platform libraries like `libc`. +`libc` provides all of the definitions necessary to easily interoperate with C +code (or "C-like" code) on each of the platforms that Rust supports. This +includes type definitions (e.g. `c_int`), constants (e.g. `EINVAL`) as well as +function headers (e.g. `malloc`). + +This crate exports all underlying platform types, functions, and constants under +the crate root, so all items are accessible as `libc::foo`. The types and values +of all the exported APIs match the platform that libc is compiled for. -[![Build Status](https://travis-ci.org/rust-lang/libc.svg?branch=master)](https://travis-ci.org/rust-lang/libc) -[![Build status](https://ci.appveyor.com/api/projects/status/github/rust-lang/libc?svg=true)](https://ci.appveyor.com/project/rust-lang-libs/libc) -[![Build Status](https://api.cirrus-ci.com/github/rust-lang/libc.svg)](https://cirrus-ci.com/github/rust-lang/libc) -[![Latest version](https://img.shields.io/crates/v/libc.svg)](https://crates.io/crates/libc) -[![Documentation](https://docs.rs/libc/badge.svg)](https://docs.rs/libc) -![License](https://img.shields.io/crates/l/libc.svg) +More detailed information about the design of this library can be found in its +[associated RFC][rfc]. + +[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md ## Usage -First, add the following to your `Cargo.toml`: +Add the following to your `Cargo.toml`: ```toml [dependencies] libc = "0.2" ``` -Next, add this to your crate root: +## Features -```rust -extern crate libc; -``` +* `use_std`: by default `libc` links to the standard library. Disable this + feature remove this dependency and be able to use `libc` in `#![no_std]` + crates. -Currently libc by default links to the standard library, but if you would -instead like to use libc in a `#![no_std]` situation or crate you can request -this via: +* `extra_traits`: all `struct`s implemented in `libc` are `Copy` and `Clone`. + This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`. -```toml -[dependencies] -libc = { version = "0.2", default-features = false } -``` +## Rust version support -By default libc uses private fields in structs in order to enforce a certain -memory alignment on them. These structs can be hard to instantiate outside of -libc. To make libc use `#[repr(align(x))]`, instead of the private fields, -activate the *align* feature. This requires Rust 1.25 or newer: +The minimum supported Rust toolchain version is **Rust 1.13.0** . APIs requiring +newer Rust features are only available on newer Rust toolchains: -```toml -[dependencies] -libc = { version = "0.2", features = ["align"] } -``` +| Feature | Version | +|----------------------|---------| +| `union` | 1.19.0 | +| `const mem::size_of` | 1.24.0 | +| `repr(align)` | 1.25.0 | +| `extra_traits` | 1.25.0 | +| `core::ffi::c_void` | 1.30.0 | +| `repr(packed(N))` | 1.33.0 | -## What is libc? +## Platform support -The primary purpose of this crate is to provide all of the definitions necessary -to easily interoperate with C code (or "C-like" code) on each of the platforms -that Rust supports. This includes type definitions (e.g. `c_int`), constants -(e.g. `EINVAL`) as well as function headers (e.g. `malloc`). - -This crate does not strive to have any form of compatibility across platforms, -but rather it is simply a straight binding to the system libraries on the -platform in question. +[Platform-specific documentation (master branch)][docs.master]. -## Public API +See +[`ci/build.sh`](https://github.com/rust-lang/libc/blob/master/libc-test/build.rs) +for the platforms on which `libc` is guaranteed to build for each Rust +toolchain. The test-matrix at [Travis-CI], [Appveyor], and [Cirrus-CI] show the +platforms in which `libc` tests are run. -This crate exports all underlying platform types, functions, and constants under -the crate root, so all items are accessible as `libc::foo`. The types and values -of all the exported APIs match the platform that libc is compiled for. +

-More detailed information about the design of this library can be found in its -[associated RFC][rfc]. +## License -[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md +This project is licensed under either of + +* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + ([LICENSE-APACHE](LICENSE-APACHE)) + +* [MIT License](http://opensource.org/licenses/MIT) + ([LICENSE-MIT](LICENSE-MIT)) + +at your option. + +## Contributing + +We welcome all people who want to contribute. Please see the [contributing +instructions] for more information. + +[contributing instructions]: CONTRIBUTING.md + +Contributions in any form (issues, pull requests, etc.) to this project +must adhere to Rust's [Code of Conduct]. -## Adding an API +[Code of Conduct]: https://www.rust-lang.org/en-US/conduct.html -Want to use an API which currently isn't bound in `libc`? It's quite easy to add -one! +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `libc` by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. -The internal structure of this crate is designed to minimize the number of -`#[cfg]` attributes in order to easily be able to add new items which apply -to all platforms in the future. As a result, the crate is organized -hierarchically based on platform. Each module has a number of `#[cfg]`'d -children, but only one is ever actually compiled. Each module then reexports all -the contents of its children. - -This means that for each platform that libc supports, the path from a -leaf module to the root will contain all bindings for the platform in question. -Consequently, this indicates where an API should be added! Adding an API at a -particular level in the hierarchy means that it is supported on all the child -platforms of that level. For example, when adding a Unix API it should be added -to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to -`src/unix/notbsd/linux/mod.rs`. - -If you're not 100% sure at what level of the hierarchy an API should be added -at, fear not! This crate has CI support which tests any binding against all -platforms supported, so you'll see failures if an API is added at the wrong -level or has different signatures across platforms. - -With that in mind, the steps for adding a new API are: - -1. Determine where in the module hierarchy your API should be added. -2. Add the API. -3. Send a PR to this repo. -4. Wait for CI to pass, fixing errors. -5. Wait for a merge! - -### Test before you commit - -We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc): - -1. [`libc-test`](https://github.com/alexcrichton/ctest) - - `cd libc-test && cargo test` - - Use the `skip_*()` functions in `build.rs` if you really need a workaround. -2. Style checker - - `rustc ci/style.rs && ./style src` - -### Releasing your change to crates.io - -Now that you've done the amazing job of landing your new API or your new -platform in this crate, the next step is to get that sweet, sweet usage from -crates.io! The only next step is to bump the version of libc and then publish -it. If you'd like to get a release out ASAP you can follow these steps: - -1. Update the version number in `Cargo.toml`, you'll just be bumping the patch - version number. -2. Run `cargo update` to regenerate the lockfile to encode your version bump in - the lock file. You may pull in some other updated dependencies, that's ok. -3. Send a PR to this repository. It should [look like this][example], but it'd - also be nice to fill out the description with a small rationale for the - release (any rationale is ok though!) -4. Once merged the release will be tagged and published by one of the libc crate - maintainers. - -[example]: https://github.com/rust-lang/libc/pull/583 - -## Platforms and Documentation - -The following platforms are currently tested and have documentation available: - -Tested: - * [`i686-pc-windows-msvc`](https://rust-lang.github.io/libc/i686-pc-windows-msvc/libc/) - * [`x86_64-pc-windows-msvc`](https://rust-lang.github.io/libc/x86_64-pc-windows-msvc/libc/) - (Windows) - * [`i686-pc-windows-gnu`](https://rust-lang.github.io/libc/i686-pc-windows-gnu/libc/) - * [`x86_64-pc-windows-gnu`](https://rust-lang.github.io/libc/x86_64-pc-windows-gnu/libc/) - * [`i686-apple-darwin`](https://rust-lang.github.io/libc/i686-apple-darwin/libc/) - * [`x86_64-apple-darwin`](https://rust-lang.github.io/libc/x86_64-apple-darwin/libc/) - (OSX) - * `i386-apple-ios` - * `x86_64-apple-ios` - * [`i686-unknown-linux-gnu`](https://rust-lang.github.io/libc/i686-unknown-linux-gnu/libc/) - * [`x86_64-unknown-linux-gnu`](https://rust-lang.github.io/libc/x86_64-unknown-linux-gnu/libc/) - (Linux) - * [`x86_64-unknown-linux-musl`](https://rust-lang.github.io/libc/x86_64-unknown-linux-musl/libc/) - (Linux MUSL) - * [`aarch64-unknown-linux-gnu`](https://rust-lang.github.io/libc/aarch64-unknown-linux-gnu/libc/) - (Linux) - * `aarch64-unknown-linux-musl` - (Linux MUSL) - * [`sparc64-unknown-linux-gnu`](https://rust-lang.github.io/libc/sparc64-unknown-linux-gnu/libc/) - (Linux) - * [`mips-unknown-linux-gnu`](https://rust-lang.github.io/libc/mips-unknown-linux-gnu/libc/) - * [`arm-unknown-linux-gnueabihf`](https://rust-lang.github.io/libc/arm-unknown-linux-gnueabihf/libc/) - * [`arm-linux-androideabi`](https://rust-lang.github.io/libc/arm-linux-androideabi/libc/) - (Android) - * [`x86_64-unknown-freebsd`](https://rust-lang.github.io/libc/x86_64-unknown-freebsd/libc/) - * [`x86_64-unknown-openbsd`](https://rust-lang.github.io/libc/x86_64-unknown-openbsd/libc/) - * [`x86_64-rumprun-netbsd`](https://rust-lang.github.io/libc/x86_64-unknown-netbsd/libc/) - -The following may be supported, but are not guaranteed to always work: - - * `i686-unknown-freebsd` - * [`x86_64-unknown-bitrig`](https://rust-lang.github.io/libc/x86_64-unknown-bitrig/libc/) - * [`x86_64-unknown-dragonfly`](https://rust-lang.github.io/libc/x86_64-unknown-dragonfly/libc/) - * `i686-unknown-haiku` - * `x86_64-unknown-haiku` - * [`x86_64-unknown-netbsd`](https://rust-lang.github.io/libc/x86_64-unknown-netbsd/libc/) - * [`x86_64-sun-solaris`](https://rust-lang.github.io/libc/x86_64-sun-solaris/libc/) +[Travis-CI]: https://travis-ci.com/rust-lang/libc +[Travis-CI Status]: https://travis-ci.com/rust-lang/libc.svg?branch=master +[Appveyor]: https://ci.appveyor.com/project/rust-lang-libs/libc +[Appveyor Status]: https://ci.appveyor.com/api/projects/status/github/rust-lang/libc?svg=true +[Cirrus-CI]: https://cirrus-ci.com/github/rust-lang/libc +[Cirrus-CI Status]: https://api.cirrus-ci.com/github/rust-lang/libc.svg +[crates.io]: https://crates.io/crates/libc +[Latest Version]: https://img.shields.io/crates/v/libc.svg +[Documentation]: https://docs.rs/libc/badge.svg +[docs.rs]: https://docs.rs/libc +[License]: https://img.shields.io/crates/l/libc.svg +[docs.master]: https://rust-lang.github.io/libc/#platform-specific-documentation diff -Nru cargo-0.33.0/vendor/libc/rustfmt.toml cargo-0.35.0/vendor/libc/rustfmt.toml --- cargo-0.33.0/vendor/libc/rustfmt.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/rustfmt.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,3 @@ +max_width = 79 +comment_width = 79 +error_on_line_overflow = true \ No newline at end of file diff -Nru cargo-0.33.0/vendor/libc/src/cloudabi/mod.rs cargo-0.35.0/vendor/libc/src/cloudabi/mod.rs --- cargo-0.33.0/vendor/libc/src/cloudabi/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/cloudabi/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::Option; - pub type int8_t = i8; pub type int16_t = i16; pub type int32_t = i32; @@ -122,8 +120,18 @@ pub const SOCK_DGRAM: ::c_int = 128; pub const SOCK_STREAM: ::c_int = 130; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos_t {} // TODO: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { *self } +} extern { pub fn isalnum(c: c_int) -> c_int; @@ -271,7 +279,7 @@ ) -> ::c_int; pub fn pthread_key_create( key: *mut pthread_key_t, - dtor: Option, + dtor: ::Option, ) -> ::c_int; pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; pub fn pthread_setspecific( @@ -306,13 +314,15 @@ } cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] diff -Nru cargo-0.33.0/vendor/libc/src/dox.rs cargo-0.35.0/vendor/libc/src/dox.rs --- cargo-0.33.0/vendor/libc/src/dox.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/dox.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -pub use self::imp::*; - -#[cfg(not(cross_platform_docs))] -mod imp { - pub use core::clone::Clone; - pub use core::marker::Copy; - pub use core::mem; - pub use core::option::Option; -} - -#[cfg(cross_platform_docs)] -mod imp { - pub enum Option { - Some(T), - None, - } - impl Copy for Option {} - impl Clone for Option { - fn clone(&self) -> Option { - loop {} - } - } - - impl Copy for *mut T {} - impl Clone for *mut T { - fn clone(&self) -> *mut T { - loop {} - } - } - - impl Copy for *const T {} - impl Clone for *const T { - fn clone(&self) -> *const T { - loop {} - } - } - - pub trait Clone { - fn clone(&self) -> Self; - } - - #[lang = "copy"] - pub trait Copy {} - - #[lang = "freeze"] - pub trait Freeze {} - - #[lang = "sync"] - pub trait Sync {} - impl Sync for T {} - - #[lang = "sized"] - pub trait Sized {} - - #[lang = "receiver"] - pub trait Receiver {} - impl Receiver for &T {} - impl Receiver for &mut T {} - - macro_rules! each_int { - ($mac:ident) => { - $mac!(u8); - $mac!(u16); - $mac!(u32); - $mac!(u64); - $mac!(usize); - each_signed_int!($mac); - }; - } - - macro_rules! each_signed_int { - ($mac:ident) => { - $mac!(i8); - $mac!(i16); - $mac!(i32); - $mac!(i64); - $mac!(isize); - }; - } - - #[lang = "div"] - pub trait Div { - type Output; - fn div(self, rhs: RHS) -> Self::Output; - } - - #[lang = "shl"] - pub trait Shl { - type Output; - fn shl(self, rhs: RHS) -> Self::Output; - } - - #[lang = "mul"] - pub trait Mul { - type Output; - fn mul(self, rhs: RHS) -> Self::Output; - } - - #[lang = "sub"] - pub trait Sub { - type Output; - fn sub(self, rhs: RHS) -> Self::Output; - } - - #[lang = "bitand"] - pub trait BitAnd { - type Output; - fn bitand(self, rhs: RHS) -> Self::Output; - } - - #[lang = "bitand_assign"] - pub trait BitAndAssign { - fn bitand_assign(&mut self, rhs: RHS); - } - - #[lang = "bitor"] - pub trait BitOr { - type Output; - fn bitor(self, rhs: RHS) -> Self::Output; - } - - #[lang = "bitor_assign"] - pub trait BitOrAssign { - fn bitor_assign(&mut self, rhs: RHS); - } - - #[lang = "bitxor"] - pub trait BitXor { - type Output; - fn bitxor(self, rhs: RHS) -> Self::Output; - } - - #[lang = "bitxor_assign"] - pub trait BitXorAssign { - fn bitxor_assign(&mut self, rhs: RHS); - } - - #[lang = "neg"] - pub trait Neg { - type Output; - fn neg(self) -> Self::Output; - } - - #[lang = "not"] - pub trait Not { - type Output; - fn not(self) -> Self::Output; - } - - #[lang = "add"] - pub trait Add { - type Output; - fn add(self, r: RHS) -> Self::Output; - } - - macro_rules! impl_traits { - ($($i:ident)*) => ($( - impl Div<$i> for $i { - type Output = $i; - fn div(self, rhs: $i) -> $i { self / rhs } - } - impl Shl<$i> for $i { - type Output = $i; - fn shl(self, rhs: $i) -> $i { self << rhs } - } - impl Mul for $i { - type Output = $i; - fn mul(self, rhs: $i) -> $i { self * rhs } - } - - impl Sub for $i { - type Output = $i; - fn sub(self, rhs: $i) -> $i { self - rhs } - } - impl BitAnd for $i { - type Output = $i; - fn bitand(self, rhs: $i) -> $i { self & rhs } - } - impl BitAndAssign for $i { - fn bitand_assign(&mut self, rhs: $i) { *self &= rhs; } - } - impl BitOr for $i { - type Output = $i; - fn bitor(self, rhs: $i) -> $i { self | rhs } - } - impl BitOrAssign for $i { - fn bitor_assign(&mut self, rhs: $i) { *self |= rhs; } - } - impl BitXor for $i { - type Output = $i; - fn bitxor(self, rhs: $i) -> $i { self ^ rhs } - } - impl BitXorAssign for $i { - fn bitxor_assign(&mut self, rhs: $i) { *self ^= rhs; } - } - impl Neg for $i { - type Output = $i; - fn neg(self) -> $i { -self } - } - impl Not for $i { - type Output = $i; - fn not(self) -> $i { !self } - } - impl Add<$i> for $i { - type Output = $i; - fn add(self, other: $i) -> $i { self + other } - } - impl Copy for $i {} - impl Clone for $i { - fn clone(&self) -> $i { loop {} } - } - )*) - } - each_int!(impl_traits); - - pub mod mem { - pub fn size_of_val(_: &T) -> usize { - 4 - } - pub const fn size_of() -> usize { - 4 - } - } -} diff -Nru cargo-0.33.0/vendor/libc/src/fuchsia/align.rs cargo-0.35.0/vendor/libc/src/fuchsia/align.rs --- cargo-0.33.0/vendor/libc/src/fuchsia/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/fuchsia/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,142 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr( + any( + target_pointer_width = "32", + target_arch = "x86_64" + ), + repr(align(4)))] + #[cfg_attr( + not(any( + target_pointer_width = "32", + target_arch = "x86_64" + )), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + #[cfg_attr(target_arch = "x86", + repr(align(4)))] + #[cfg_attr(not(target_arch = "x86"), + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/fuchsia/mod.rs cargo-0.35.0/vendor/libc/src/fuchsia/mod.rs --- cargo-0.33.0/vendor/libc/src/fuchsia/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/fuchsia/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,8 +3,6 @@ //! More functions and definitions can be found in the more specific modules //! according to the platform in question. -use dox::{mem, Option}; - // PUB_TYPE pub type int8_t = i8; @@ -100,10 +98,30 @@ // FIXME: why are these uninhabited types? that seems... wrong? // Presumably these should be `()` or an `extern type` (when that stabilizes). +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum locale_t {} +impl ::Copy for locale_t {} +impl ::Clone for locale_t { + fn clone(&self) -> locale_t { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos64_t {} // TODO: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { *self } +} // PUB_STRUCT @@ -182,9 +200,6 @@ pub ru_nivcsw: c_long, #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] __pad14: u32, - - #[cfg(any(target_env = "musl", target_os = "emscripten"))] - __reserved: [c_long; 16], } pub struct in_addr { @@ -292,7 +307,7 @@ pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, pub sa_flags: ::c_int, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct termios { @@ -314,23 +329,6 @@ pub l_pid: ::pid_t, } - pub struct sysinfo { - pub uptime: ::c_ulong, - pub loads: [::c_ulong; 3], - pub totalram: ::c_ulong, - pub freeram: ::c_ulong, - pub sharedram: ::c_ulong, - pub bufferram: ::c_ulong, - pub totalswap: ::c_ulong, - pub freeswap: ::c_ulong, - pub procs: ::c_ushort, - pub pad: ::c_ushort, - pub totalhigh: ::c_ulong, - pub freehigh: ::c_ulong, - pub mem_unit: ::c_uint, - pub __reserved: [::c_char; 256], - } - pub struct ucred { pub pid: ::pid_t, pub uid: ::uid_t, @@ -357,17 +355,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108] - } - - pub struct sockaddr_storage { - pub ss_family: sa_family_t, - __ss_align: ::size_t, - __ss_pad2: [u8; 128 - 2 * 8], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -437,15 +424,6 @@ pub u64: ::uint64_t, } - pub struct utsname { - pub sysname: [::c_char; 65], - pub nodename: [::c_char; 65], - pub release: [::c_char; 65], - pub version: [::c_char; 65], - pub machine: [::c_char; 65], - pub domainname: [::c_char; 65] - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -482,22 +460,6 @@ pub __pad: [::c_char; 56 - 3 * 8 /* 8 == sizeof(long) */], } - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - pub struct rlimit64 { pub rlim_cur: rlim64_t, pub rlim_max: rlim64_t, @@ -526,122 +488,6 @@ pub ifa_data: *mut ::c_void } - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "arm", - target_arch = "x86_64")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "arm", - target_arch = "x86_64")))), - repr(align(8)))] - pub struct pthread_mutex_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "arm", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "arm", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "arm", - target_arch = "x86_64")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "arm", - target_arch = "x86_64")))), - repr(align(8)))] - pub struct pthread_rwlock_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "arm", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "arm", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "32", - target_arch = "x86_64", - all(target_arch = "aarch64", target_env = "musl"))), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(any(target_pointer_width = "32", - target_arch = "x86_64", - all(target_arch = "aarch64", target_env = "musl")))), - repr(align(8)))] - pub struct pthread_mutexattr_t { - #[cfg(all(not(features = "align"), - any(target_arch = "x86_64", - all(target_arch = "aarch64", target_env = "musl"))))] - __align: [::c_int; 0], - #[cfg(all(not(features = "align"), - not(any(target_arch = "x86_64", - all(target_arch = "aarch64", target_env = "musl")))))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - - #[cfg_attr(all(feature = "align", - any(target_env = "musl", target_pointer_width = "32")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - target_pointer_width = "64"), - repr(align(8)))] - pub struct pthread_rwlockattr_t { - #[cfg(all(not(feature = "align"), target_env = "musl"))] - __align: [::c_int; 0], - #[cfg(all(not(feature = "align"), not(target_env = "musl")))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T], - } - - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "64"), - repr(align(8)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - target_arch = "x86"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - not(target_arch = "x86")), - repr(align(8)))] - pub struct pthread_cond_t { - #[cfg(all(not(feature = "align"), target_env = "musl"))] - __align: [*const ::c_void; 0], - #[cfg(not(any(feature = "align", target_env = "musl")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - pub struct passwd { pub pw_name: *mut ::c_char, pub pw_passwd: *mut ::c_char, @@ -1075,6 +921,302 @@ } } +s_no_extra_traits! { + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_align: ::size_t, + __ss_pad2: [u8; 128 - 2 * 8], + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent64 {} + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + } +} + // PUB_CONST pub const INT_MIN: c_int = -2147483648; @@ -1701,7 +1843,7 @@ pub const WCONTINUED: ::c_int = 0x00000008; pub const WNOWAIT: ::c_int = 0x01000000; -// Options set using PTRACE_SETOPTIONS. +// ::Options set using PTRACE_SETOPTIONS. pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001; pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002; pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004; @@ -2920,20 +3062,20 @@ f! { pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] &= !(1 << (fd % size)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] |= 1 << (fd % size); return } @@ -2987,21 +3129,23 @@ } pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] |= 1 << offset; () } pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] &= !(1 << offset); () } pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); 0 != (cpuset.bits[idx] & (1 << offset)) } @@ -3042,8 +3186,18 @@ #[link(name = "fdio")] extern {} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos_t {} // TODO: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { *self } +} extern { pub fn isalnum(c: c_int) -> c_int; @@ -3371,7 +3525,7 @@ pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; pub fn sched_yield() -> ::c_int; pub fn pthread_key_create(key: *mut pthread_key_t, - dtor: Option) + dtor: ::Option) -> ::c_int; pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; @@ -3876,7 +4030,7 @@ pub fn glob(pattern: *const c_char, flags: ::c_int, - errfunc: Option ::c_int>, pglob: *mut ::glob_t) -> ::c_int; pub fn globfree(pglob: *mut ::glob_t); @@ -4014,7 +4168,7 @@ offset: *mut off_t, count: ::size_t) -> ::ssize_t; pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -4049,9 +4203,9 @@ result: *mut *mut passwd) -> ::c_int; pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; pub fn getgrouplist(user: *const ::c_char, group: ::gid_t, @@ -4068,7 +4222,7 @@ f: extern fn(*mut ::c_void) -> *mut ::c_void, value: *mut ::c_void) -> ::c_int; pub fn dl_iterate_phdr( - callback: Option { + s! { + pub struct pthread_mutexattr_t { + #[cfg(target_arch = "x86_64")] + __align: [::c_int; 0], + #[cfg(not(target_arch = "x86_64"))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + #[cfg(not(target_env = "musl"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/fuchsia/x86_64.rs cargo-0.35.0/vendor/libc/src/fuchsia/x86_64.rs --- cargo-0.33.0/vendor/libc/src/fuchsia/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/fuchsia/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -51,15 +51,6 @@ __private: [u64; 32], } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 512], - } - pub struct ipc_perm { pub __ipc_perm_key: ::key_t, pub uid: ::uid_t, @@ -73,6 +64,59 @@ } } +s_no_extra_traits! { + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // FIXME: .field("__private", &self.__private) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + // Syscall table pub const SYS_read: ::c_long = 0; diff -Nru cargo-0.33.0/vendor/libc/src/hermit/aarch64.rs cargo-0.35.0/vendor/libc/src/hermit/aarch64.rs --- cargo-0.33.0/vendor/libc/src/hermit/aarch64.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/hermit/aarch64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2 @@ +pub type c_char = u8; +pub type wchar_t = u32; diff -Nru cargo-0.33.0/vendor/libc/src/hermit/mod.rs cargo-0.35.0/vendor/libc/src/hermit/mod.rs --- cargo-0.33.0/vendor/libc/src/hermit/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/hermit/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,83 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// libc port for HermitCore (https://hermitcore.org) +// +// Ported by Colin Fink +// and Stefan Lankes + +pub type int8_t = i8; +pub type int16_t = i16; +pub type int32_t = i32; +pub type int64_t = i64; +pub type uint8_t = u8; +pub type uint16_t = u16; +pub type uint32_t = u32; +pub type uint64_t = u64; + +pub type c_schar = i8; +pub type c_uchar = u8; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_float = f32; +pub type c_double = f64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; + +pub type size_t = usize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type ssize_t = isize; + +pub type c_long = i64; +pub type c_ulong = u64; + +pub type wint_t = u32; +pub type wctype_t = i64; + +pub type regoff_t = size_t; +pub type off_t = c_long; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; + } else { + // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help + // enable more optimization opportunities around it recognizing things + // like malloc/free. + #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] + pub enum c_void { + // Two dummy variants so the #[repr] attribute can be used. + #[doc(hidden)] + __variant1, + #[doc(hidden)] + __variant2, + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/hermit/x86_64.rs cargo-0.35.0/vendor/libc/src/hermit/x86_64.rs --- cargo-0.33.0/vendor/libc/src/hermit/x86_64.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/hermit/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2 @@ +pub type c_char = i8; +pub type wchar_t = i32; diff -Nru cargo-0.33.0/vendor/libc/src/lib.rs cargo-0.35.0/vendor/libc/src/lib.rs --- cargo-0.33.0/vendor/libc/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,172 +7,85 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - -//! Crate docs - -#![allow(bad_style, overflowing_literals, improper_ctypes)] -#![crate_type = "rlib"] +//! libc - Raw FFI bindings to platforms' system libraries +//! +//! [Documentation for other platforms][pd]. +//! +//! [pd]: https://rust-lang.github.io/libc/#platform-specific-documentation #![crate_name = "libc"] -#![cfg_attr(cross_platform_docs, feature(no_core, lang_items, const_fn))] -#![cfg_attr(cross_platform_docs, no_core)] -#![doc( - html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico" -)] -#![cfg_attr( - all(target_os = "linux", target_arch = "x86_64"), - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-linux-gnu" - ) -)] -#![cfg_attr( - all(target_os = "linux", target_arch = "x86"), - doc( - html_root_url = "https://rust-lang.github.io/libc/i686-unknown-linux-gnu" - ) -)] -#![cfg_attr( - all(target_os = "linux", target_arch = "arm"), - doc( - html_root_url = "https://rust-lang.github.io/libc/arm-unknown-linux-gnueabihf" - ) -)] -#![cfg_attr( - all(target_os = "linux", target_arch = "mips"), - doc( - html_root_url = "https://rust-lang.github.io/libc/mips-unknown-linux-gnu" - ) -)] -#![cfg_attr( - all(target_os = "linux", target_arch = "aarch64"), - doc( - html_root_url = "https://rust-lang.github.io/libc/aarch64-unknown-linux-gnu" - ) -)] -#![cfg_attr( - all(target_os = "linux", target_env = "musl"), - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-linux-musl" - ) -)] -#![cfg_attr( - all(target_os = "macos", target_arch = "x86_64"), - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-apple-darwin" - ) -)] -#![cfg_attr( - all(target_os = "macos", target_arch = "x86"), - doc(html_root_url = "https://rust-lang.github.io/libc/i686-apple-darwin") -)] -#![cfg_attr( - all(windows, target_arch = "x86_64", target_env = "gnu"), - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-pc-windows-gnu" - ) -)] -#![cfg_attr( - all(windows, target_arch = "x86", target_env = "gnu"), - doc( - html_root_url = "https://rust-lang.github.io/libc/i686-pc-windows-gnu" - ) -)] -#![cfg_attr( - all(windows, target_arch = "x86_64", target_env = "msvc"), - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-pc-windows-msvc" - ) -)] -#![cfg_attr( - all(windows, target_arch = "x86", target_env = "msvc"), - doc( - html_root_url = "https://rust-lang.github.io/libc/i686-pc-windows-msvc" - ) -)] -#![cfg_attr( - target_os = "android", - doc( - html_root_url = "https://rust-lang.github.io/libc/arm-linux-androideabi" - ) -)] -#![cfg_attr( - target_os = "freebsd", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-freebsd" - ) -)] -#![cfg_attr( - target_os = "openbsd", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-openbsd" - ) -)] -#![cfg_attr( - target_os = "bitrig", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-bitrig" - ) -)] -#![cfg_attr( - target_os = "netbsd", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-netbsd" - ) -)] -#![cfg_attr( - target_os = "dragonfly", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-unknown-dragonfly" - ) -)] -#![cfg_attr( - target_os = "solaris", - doc( - html_root_url = "https://rust-lang.github.io/libc/x86_64-sun-solaris" - ) -)] -#![cfg_attr( - all(target_os = "emscripten", target_arch = "asmjs"), - doc( - html_root_url = "https://rust-lang.github.io/libc/asmjs-unknown-emscripten" - ) -)] -#![cfg_attr( - all(target_os = "emscripten", target_arch = "wasm32"), - doc( - html_root_url = "https://rust-lang.github.io/libc/wasm32-unknown-emscripten" - ) -)] +#![crate_type = "rlib"] +#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))] +#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)] +// Attributes needed when building as part of the standard library #![cfg_attr( - all(target_os = "linux", target_arch = "sparc64"), - doc( - html_root_url = "https://rust-lang.github.io/libc/sparc64-unknown-linux-gnu" - ) + feature = "rustc-dep-of-std", + feature(cfg_target_vendor, link_cfg, no_core) )] -// Attributes needed when building as part of the standard library -#![cfg_attr(feature = "rustc-dep-of-std", feature(cfg_target_vendor))] -#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, repr_packed))] -#![cfg_attr(feature = "rustc-dep-of-std", feature(no_core))] +// Enable extra lints: +#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))] +#![deny(missing_copy_implementations, safe_packed_borrows)] +#![no_std] #![cfg_attr(feature = "rustc-dep-of-std", no_core)] -#![cfg_attr(feature = "rustc-dep-of-std", allow(warnings))] -#![cfg_attr(not(any(feature = "use_std", feature = "rustc-dep-of-std")), no_std)] - -#[cfg(all(not(cross_platform_docs), feature = "use_std"))] -extern crate std as core; - -#[cfg(feature = "rustc-dep-of-std")] -extern crate rustc_std_workspace_core as core; -#[cfg(feature = "rustc-dep-of-std")] -#[allow(unused_imports)] -use core::iter; -#[cfg(feature = "rustc-dep-of-std")] -#[allow(unused_imports)] -use core::option; #[macro_use] mod macros; -mod dox; +cfg_if! { + if #[cfg(feature = "rustc-dep-of-std")] { + extern crate rustc_std_workspace_core as core; + #[allow(unused_imports)] + use core::iter; + #[allow(unused_imports)] + use core::option; + } +} + +cfg_if! { + if #[cfg(libc_priv_mod_use)] { + #[cfg(libc_core_cvoid)] + #[allow(unused_imports)] + use core::ffi; + #[allow(unused_imports)] + use core::fmt; + #[allow(unused_imports)] + use core::hash; + #[allow(unused_imports)] + use core::num; + #[allow(unused_imports)] + use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + use core::marker::Copy; + #[doc(hidden)] + #[allow(unused_imports)] + use core::option::Option; + } else { + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::fmt; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::hash; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::num; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::marker::Copy; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::option::Option; + } +} cfg_if! { if #[cfg(windows)] { @@ -193,10 +106,16 @@ } else if #[cfg(unix)] { mod unix; pub use unix::*; - } else if #[cfg(target_env = "sgx")] { + } else if #[cfg(target_os = "hermit")] { + mod hermit; + pub use hermit::*; + } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] { mod sgx; pub use sgx::*; - } else { + } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] { + mod wasi; + pub use wasi::*; + } else { // non-supported targets: empty... } } diff -Nru cargo-0.33.0/vendor/libc/src/macros.rs cargo-0.35.0/vendor/libc/src/macros.rs --- cargo-0.33.0/vendor/libc/src/macros.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/macros.rs 2019-05-15 11:26:24.000000000 +0000 @@ -6,46 +6,116 @@ /// /// This allows you to conveniently provide a long list #[cfg]'d blocks of code /// without having to rewrite each clause multiple times. +#[allow(unused_macros)] macro_rules! cfg_if { + // match if/else chains with a final `else` ($( if #[cfg($($meta:meta),*)] { $($it:item)* } ) else * else { $($it2:item)* }) => { - __cfg_if_items! { + cfg_if! { + @__items () ; $( ( ($($meta),*) ($($it)*) ), )* ( () ($($it2)*) ), } - } -} + }; -macro_rules! __cfg_if_items { - (($($not:meta,)*) ; ) => {}; - (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { - __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } - __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } - } -} + // match if/else chains lacking a final `else` + ( + if #[cfg($($i_met:meta),*)] { $($i_it:item)* } + $( + else if #[cfg($($e_met:meta),*)] { $($e_it:item)* } + )* + ) => { + cfg_if! { + @__items + () ; + ( ($($i_met),*) ($($i_it)*) ), + $( ( ($($e_met),*) ($($e_it)*) ), )* + ( () () ), + } + }; -macro_rules! __cfg_if_apply { - ($m:meta, $($it:item)*) => { + // Internal and recursive macro to emit all the items + // + // Collects all the negated cfgs in a list at the beginning and after the + // semicolon is all the remaining items + (@__items ($($not:meta,)*) ; ) => {}; + (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), + $($rest:tt)*) => { + // Emit all items within one block, applying an approprate #[cfg]. The + // #[cfg] will require all `$m` matchers specified and must also negate + // all previous matchers. + cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* } + + // Recurse to emit all other items in `$rest`, and when we do so add all + // our `$m` matchers to the list of `$not` matchers as future emissions + // will have to negate everything we just matched as well. + cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to Apply a cfg attribute to a list of items + (@__apply $m:meta, $($it:item)*) => { $(#[$m] $it)* - } + }; } +#[allow(unused_macros)] macro_rules! s { ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s!(it: $(#[$attr])* pub $t $i { $($field)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead"); + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( __item! { #[repr(C)] + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] $(#[$attr])* - pub $t $i { $($field)* } + pub struct $i { $($field)* } } - impl ::dox::Copy for $i {} - impl ::dox::Clone for $i { + impl ::Copy for $i {} + impl ::Clone for $i { fn clone(&self) -> $i { *self } } - )*) + ); +} + +#[allow(unused_macros)] +macro_rules! s_no_extra_traits { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + cfg_if! { + if #[cfg(libc_union)] { + __item! { + #[repr(C)] + $(#[$attr])* + pub union $i { $($field)* } + } + + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + } + } + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + $(#[$attr])* + pub struct $i { $($field)* } + } + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + ); } #[allow(unused_macros)] @@ -54,19 +124,13 @@ $($body:stmt);* })*) => ($( #[inline] - #[cfg(not(cross_platform_docs))] pub unsafe extern fn $i($($arg: $argty),*) -> $ret { $($body);* } - - #[cfg(cross_platform_docs)] - #[allow(dead_code)] - pub unsafe extern fn $i($($arg: $argty),*) -> $ret { - loop {} - } )*) } +#[allow(unused_macros)] macro_rules! __item { ($i:item) => { $i @@ -75,13 +139,15 @@ #[allow(unused_macros)] macro_rules! align_const { - ($($(#[$attr:meta])* pub const $name:ident : $t1:ty = $t2:ident { $($field:tt)* };)*) => ($( - #[cfg(feature = "align")] + ($($(#[$attr:meta])* + pub const $name:ident : $t1:ty + = $t2:ident { $($field:tt)* };)*) => ($( + #[cfg(libc_align)] $(#[$attr])* pub const $name : $t1 = $t2 { $($field)* }; - #[cfg(not(feature = "align"))] + #[cfg(not(libc_align))] $(#[$attr])* pub const $name : $t1 = $t2 { $($field)* diff -Nru cargo-0.33.0/vendor/libc/src/redox/align.rs cargo-0.35.0/vendor/libc/src/redox/align.rs --- cargo-0.33.0/vendor/libc/src/redox/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/redox/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,6 @@ +s! { + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/redox/mod.rs cargo-0.35.0/vendor/libc/src/redox/mod.rs --- cargo-0.33.0/vendor/libc/src/redox/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/redox/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -219,8 +219,18 @@ pub const SIGPWR: ::c_int = 30; pub const SIGSYS: ::c_int = 31; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos_t {} // TODO: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { *self } +} // intentionally not public, only used for fd_set cfg_if! { @@ -376,13 +386,15 @@ mod net; cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] @@ -392,3 +404,13 @@ } } } + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/redox/net.rs cargo-0.35.0/vendor/libc/src/redox/net.rs --- cargo-0.33.0/vendor/libc/src/redox/net.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/redox/net.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,20 +9,13 @@ pub s_addr: in_addr_t, } - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct in6_addr { - pub s6_addr: [u8; 16], - #[cfg(not(feature = "align"))] - __align: [u32; 0], - } - pub struct ip_mreq { pub imr_multiaddr: in_addr, pub imr_interface: in_addr, } pub struct ipv6_mreq { - pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_multiaddr: ::in6_addr, pub ipv6mr_interface: ::c_uint, } diff -Nru cargo-0.33.0/vendor/libc/src/redox/no_align.rs cargo-0.35.0/vendor/libc/src/redox/no_align.rs --- cargo-0.33.0/vendor/libc/src/redox/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/redox/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,6 @@ +s! { + pub struct in6_addr { + pub s6_addr: [u8; 16], + __align: [u32; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/sgx.rs cargo-0.35.0/vendor/libc/src/sgx.rs --- cargo-0.33.0/vendor/libc/src/sgx.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/sgx.rs 2019-05-15 11:26:24.000000000 +0000 @@ -36,13 +36,15 @@ pub const INT_MAX: c_int = 2147483647; cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] diff -Nru cargo-0.33.0/vendor/libc/src/switch.rs cargo-0.35.0/vendor/libc/src/switch.rs --- cargo-0.33.0/vendor/libc/src/switch.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/switch.rs 2019-05-15 11:26:24.000000000 +0000 @@ -38,13 +38,15 @@ pub const INT_MAX: c_int = 2147483647; cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] diff -Nru cargo-0.33.0/vendor/libc/src/unix/align.rs cargo-0.35.0/vendor/libc/src/unix/align.rs --- cargo-0.33.0/vendor/libc/src/unix/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,6 @@ +s! { + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/apple/b32.rs cargo-0.35.0/vendor/libc/src/unix/bsd/apple/b32.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/apple/b32.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/apple/b32.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,11 +5,6 @@ pub type boolean_t = ::c_int; s! { - pub struct pthread_attr_t { - __sig: c_long, - __opaque: [::c_char; 36] - } - pub struct if_data { pub ifi_type: ::c_uchar, pub ifi_typelen: ::c_uchar, @@ -50,6 +45,42 @@ } } +s_no_extra_traits!{ + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 36] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + pub const __PTHREAD_MUTEX_SIZE__: usize = 40; pub const __PTHREAD_COND_SIZE__: usize = 24; pub const __PTHREAD_CONDATTR_SIZE__: usize = 4; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/apple/b64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/apple/b64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/apple/b64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/apple/b64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,11 +5,6 @@ pub type boolean_t = ::c_uint; s! { - pub struct pthread_attr_t { - __sig: c_long, - __opaque: [::c_char; 56] - } - pub struct timeval32 { pub tv_sec: i32, pub tv_usec: i32, @@ -55,6 +50,42 @@ } } +s_no_extra_traits!{ + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 56] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + pub const __PTHREAD_MUTEX_SIZE__: usize = 56; pub const __PTHREAD_COND_SIZE__: usize = 40; pub const __PTHREAD_CONDATTR_SIZE__: usize = 8; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/apple/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/apple/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/apple/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/apple/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,6 @@ //! Apple (ios/darwin)-specific definitions //! //! This covers *-apple-* triples currently -use dox::mem; - pub type c_char = i8; pub type clock_t = c_ulong; pub type time_t = c_long; @@ -33,10 +31,21 @@ pub type posix_spawn_file_actions_t = *mut ::c_void; pub type key_t = ::c_int; pub type shmatt_t = ::c_ushort; +pub type vm_size_t = ::uintptr_t; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} s! { + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct aiocb { pub aio_fildes: ::c_int, pub aio_offset: ::off_t, @@ -47,17 +56,6 @@ pub aio_lio_opcode: ::c_int } - pub struct utmpx { - pub ut_user: [::c_char; _UTX_USERSIZE], - pub ut_id: [::c_char; _UTX_IDSIZE], - pub ut_line: [::c_char; _UTX_LINESIZE], - pub ut_pid: ::pid_t, - pub ut_type: ::c_short, - pub ut_tv: ::timeval, - pub ut_host: [::c_char; _UTX_HOSTSIZE], - ut_pad: [::uint32_t; 16], - } - pub struct glob_t { pub gl_pathc: ::size_t, __unused1: ::c_int, @@ -74,14 +72,6 @@ __unused8: *mut ::c_void, } - pub struct sockaddr_storage { - pub ss_len: u8, - pub ss_family: ::sa_family_t, - __ss_pad1: [u8; 6], - __ss_align: i64, - __ss_pad2: [u8; 112], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -123,40 +113,16 @@ pub st_qspare: [::int64_t; 2], } - pub struct dirent { - pub d_ino: u64, - pub d_seekoff: u64, - pub d_reclen: u16, - pub d_namlen: u16, - pub d_type: u8, - pub d_name: [::c_char; 1024], - } - - pub struct pthread_mutex_t { - __sig: ::c_long, - __opaque: [u8; __PTHREAD_MUTEX_SIZE__], - } - pub struct pthread_mutexattr_t { __sig: ::c_long, __opaque: [u8; 8], } - pub struct pthread_cond_t { - __sig: ::c_long, - __opaque: [u8; __PTHREAD_COND_SIZE__], - } - pub struct pthread_condattr_t { __sig: ::c_long, __opaque: [u8; __PTHREAD_CONDATTR_SIZE__], } - pub struct pthread_rwlock_t { - __sig: ::c_long, - __opaque: [u8; __PTHREAD_RWLOCK_SIZE__], - } - pub struct pthread_rwlockattr_t { __sig: ::c_long, __opaque: [u8; __PTHREAD_RWLOCKATTR_SIZE__], @@ -174,6 +140,7 @@ } pub struct sigaction { + // FIXME: this field is actually a union pub sa_sigaction: ::sighandler_t, pub sa_mask: sigset_t, pub sa_flags: ::c_int, @@ -227,35 +194,6 @@ pub sin_zero: [::c_char; 8], } - pub struct statfs { - pub f_bsize: ::uint32_t, - pub f_iosize: ::int32_t, - pub f_blocks: ::uint64_t, - pub f_bfree: ::uint64_t, - pub f_bavail: ::uint64_t, - pub f_files: ::uint64_t, - pub f_ffree: ::uint64_t, - pub f_fsid: ::fsid_t, - pub f_owner: ::uid_t, - pub f_type: ::uint32_t, - pub f_flags: ::uint32_t, - pub f_fssubtype: ::uint32_t, - pub f_fstypename: [::c_char; 16], - pub f_mntonname: [::c_char; 1024], - pub f_mntfromname: [::c_char; 1024], - pub f_reserved: [::uint32_t; 8], - } - - #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))] - pub struct kevent { - pub ident: ::uintptr_t, - pub filter: ::int16_t, - pub flags: ::uint16_t, - pub fflags: ::uint32_t, - pub data: ::intptr_t, - pub udata: *mut ::c_void, - } - pub struct kevent64_s { pub ident: ::uint64_t, pub filter: ::int16_t, @@ -400,20 +338,6 @@ pub ptinfo: proc_taskinfo, } - pub struct proc_threadinfo { - pub pth_user_time: u64, - pub pth_system_time: u64, - pub pth_cpu_usage: i32, - pub pth_policy: i32, - pub pth_run_state: i32, - pub pth_flags: i32, - pub pth_sleep_time: i32, - pub pth_curpri: i32, - pub pth_priority: i32, - pub pth_maxpriority: i32, - pub pth_name: [::c_char; MAXTHREADNAMESIZE], - } - pub struct xsw_usage { pub xsu_total: u64, pub xsu_avail: u64, @@ -544,7 +468,33 @@ pub sem_flg: ::c_short, } - #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))] + // sys/shm.h + + pub struct arphdr { + pub ar_hrd: u16, + pub ar_pro: u16, + pub ar_hln: u8, + pub ar_pln: u8, + pub ar_op: u16, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } +} + +s_no_extra_traits!{ + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::int16_t, + pub flags: ::uint16_t, + pub fflags: ::uint32_t, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] pub struct semid_ds { // Note the manpage shows different types than the system header. pub sem_perm: ipc_perm, @@ -557,15 +507,7 @@ pub sem_pad3: [::int32_t; 4], } - pub union semun { - pub val: ::c_int, - pub buf: *mut semid_ds, - pub array: *mut ::c_ushort, - } - - // sys/shm.h - - #[cfg_attr(feature = "rustc-dep-of-std", repr(packed(4)))] + #[cfg_attr(libc_packedN, repr(packed(4)))] pub struct shmid_ds { pub shm_perm: ipc_perm, pub shm_segsz: ::size_t, @@ -577,15 +519,630 @@ pub shm_ctime: ::time_t, // FIXME: 64-bit wrong align => wrong offset // FIXME: 64-bit wrong align => wrong offset: pub shm_internal: *mut ::c_void, + } + pub struct proc_threadinfo { + pub pth_user_time: u64, + pub pth_system_time: u64, + pub pth_cpu_usage: i32, + pub pth_policy: i32, + pub pth_run_state: i32, + pub pth_flags: i32, + pub pth_sleep_time: i32, + pub pth_curpri: i32, + pub pth_priority: i32, + pub pth_maxpriority: i32, + pub pth_name: [::c_char; MAXTHREADNAMESIZE], } - pub struct arphdr { - pub ar_hrd: u16, - pub ar_pro: u16, - pub ar_hln: u8, - pub ar_pln: u8, - pub ar_op: u16, + pub struct statfs { + pub f_bsize: ::uint32_t, + pub f_iosize: ::int32_t, + pub f_blocks: ::uint64_t, + pub f_bfree: ::uint64_t, + pub f_bavail: ::uint64_t, + pub f_files: ::uint64_t, + pub f_ffree: ::uint64_t, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, + pub f_type: ::uint32_t, + pub f_flags: ::uint32_t, + pub f_fssubtype: ::uint32_t, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + pub f_reserved: [::uint32_t; 8], + } + + pub struct dirent { + pub d_ino: u64, + pub d_seekoff: u64, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 1024], + } + + pub struct pthread_rwlock_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_RWLOCK_SIZE__], + } + + pub struct pthread_mutex_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_MUTEX_SIZE__], + } + + pub struct pthread_cond_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_COND_SIZE__], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } + + pub struct utmpx { + pub ut_user: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_host: [::c_char; _UTX_HOSTSIZE], + ut_pad: [::uint32_t; 16], + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub union semun { + pub val: ::c_int, + pub buf: *mut semid_ds, + pub array: *mut ::c_ushort, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for semun { + fn eq(&self, other: &semun) -> bool { + unsafe { self.val == other.val } + } + } + impl Eq for semun {} + impl ::fmt::Debug for semun { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("semun") + .field("val", unsafe { &self.val }) + .finish() + } + } + impl ::hash::Hash for semun { + fn hash(&self, state: &mut H) { + unsafe { self.val.hash(state) }; + } + } + } + } + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for kevent { + fn eq(&self, other: &kevent) -> bool { + self.ident == other.ident + && self.filter == other.filter + && self.flags == other.flags + && self.fflags == other.fflags + && self.data == other.data + && self.udata == other.udata + } + } + impl Eq for kevent {} + impl ::fmt::Debug for kevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + f.debug_struct("kevent") + .field("ident", &ident) + .field("filter", &filter) + .field("flags", &flags) + .field("fflags", &fflags) + .field("data", &data) + .field("udata", &udata) + .finish() + } + } + impl ::hash::Hash for kevent { + fn hash(&self, state: &mut H) { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + ident.hash(state); + filter.hash(state); + flags.hash(state); + fflags.hash(state); + data.hash(state); + udata.hash(state); + } + } + + impl PartialEq for semid_ds { + fn eq(&self, other: &semid_ds) -> bool { + let sem_perm = self.sem_perm; + let sem_pad3 = self.sem_pad3; + let other_sem_perm = other.sem_perm; + let other_sem_pad3 = other.sem_pad3; + sem_perm == other_sem_perm + && self.sem_base == other.sem_base + && self.sem_nsems == other.sem_nsems + && self.sem_otime == other.sem_otime + && self.sem_pad1 == other.sem_pad1 + && self.sem_ctime == other.sem_ctime + && self.sem_pad2 == other.sem_pad2 + && sem_pad3 == other_sem_pad3 + } + } + impl Eq for semid_ds {} + impl ::fmt::Debug for semid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + f.debug_struct("semid_ds") + .field("sem_perm", &sem_perm) + .field("sem_base", &sem_base) + .field("sem_nsems", &sem_nsems) + .field("sem_otime", &sem_otime) + .field("sem_pad1", &sem_pad1) + .field("sem_ctime", &sem_ctime) + .field("sem_pad2", &sem_pad2) + .field("sem_pad3", &sem_pad3) + .finish() + } + } + impl ::hash::Hash for semid_ds { + fn hash(&self, state: &mut H) { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + sem_perm.hash(state); + sem_base.hash(state); + sem_nsems.hash(state); + sem_otime.hash(state); + sem_pad1.hash(state); + sem_ctime.hash(state); + sem_pad2.hash(state); + sem_pad3.hash(state); + } + } + + impl PartialEq for shmid_ds { + fn eq(&self, other: &shmid_ds) -> bool { + let shm_perm = self.shm_perm; + let other_shm_perm = other.shm_perm; + shm_perm == other_shm_perm + && self.shm_segsz == other.shm_segsz + && self.shm_lpid == other.shm_lpid + && self.shm_cpid == other.shm_cpid + && self.shm_nattch == other.shm_nattch + && self.shm_atime == other.shm_atime + && self.shm_dtime == other.shm_dtime + && self.shm_ctime == other.shm_ctime + && self.shm_internal == other.shm_internal + } + } + impl Eq for shmid_ds {} + impl ::fmt::Debug for shmid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + f.debug_struct("shmid_ds") + .field("shm_perm", &shm_perm) + .field("shm_segsz", &shm_segsz) + .field("shm_lpid", &shm_lpid) + .field("shm_cpid", &shm_cpid) + .field("shm_nattch", &shm_nattch) + .field("shm_atime", &shm_atime) + .field("shm_dtime", &shm_dtime) + .field("shm_ctime", &shm_ctime) + .field("shm_internal", &shm_internal) + .finish() + } + } + impl ::hash::Hash for shmid_ds { + fn hash(&self, state: &mut H) { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + shm_perm.hash(state); + shm_segsz.hash(state); + shm_lpid.hash(state); + shm_cpid.hash(state); + shm_nattch.hash(state); + shm_atime.hash(state); + shm_dtime.hash(state); + shm_ctime.hash(state); + shm_internal.hash(state); + } + } + + impl PartialEq for proc_threadinfo { + fn eq(&self, other: &proc_threadinfo) -> bool { + self.pth_user_time == other.pth_user_time + && self.pth_system_time == other.pth_system_time + && self.pth_cpu_usage == other.pth_cpu_usage + && self.pth_policy == other.pth_policy + && self.pth_run_state == other.pth_run_state + && self.pth_flags == other.pth_flags + && self.pth_sleep_time == other.pth_sleep_time + && self.pth_curpri == other.pth_curpri + && self.pth_priority == other.pth_priority + && self.pth_maxpriority == other.pth_maxpriority + && self.pth_name + .iter() + .zip(other.pth_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for proc_threadinfo {} + impl ::fmt::Debug for proc_threadinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("proc_threadinfo") + .field("pth_user_time", &self.pth_user_time) + .field("pth_system_time", &self.pth_system_time) + .field("pth_cpu_usage", &self.pth_cpu_usage) + .field("pth_policy", &self.pth_policy) + .field("pth_run_state", &self.pth_run_state) + .field("pth_flags", &self.pth_flags) + .field("pth_sleep_time", &self.pth_sleep_time) + .field("pth_curpri", &self.pth_curpri) + .field("pth_priority", &self.pth_priority) + .field("pth_maxpriority", &self.pth_maxpriority) + // FIXME: .field("pth_name", &self.pth_name) + .finish() + } + } + impl ::hash::Hash for proc_threadinfo { + fn hash(&self, state: &mut H) { + self.pth_user_time.hash(state); + self.pth_system_time.hash(state); + self.pth_cpu_usage.hash(state); + self.pth_policy.hash(state); + self.pth_run_state.hash(state); + self.pth_flags.hash(state); + self.pth_sleep_time.hash(state); + self.pth_curpri.hash(state); + self.pth_priority.hash(state); + self.pth_maxpriority.hash(state); + self.pth_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_flags == other.f_flags + && self.f_fssubtype == other.f_fssubtype + && self.f_fstypename == other.f_fstypename + && self.f_type == other.f_type + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_reserved == other.f_reserved + } + } + + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_flags", &self.f_flags) + .field("f_fssubtype", &self.f_fssubtype) + .field("f_fstypename", &self.f_fstypename) + .field("f_type", &self.f_type) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .field("f_reserved", &self.f_reserved) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_flags.hash(state); + self.f_fssubtype.hash(state); + self.f_fstypename.hash(state); + self.f_type.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_reserved.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_seekoff == other.d_seekoff + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_seekoff", &self.d_seekoff) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_seekoff.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self.ut_pid == other.ut_pid + && self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_pad == other.ut_pad + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + // FIXME: .field("ut_user", &self.ut_user) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + .field("ut_pid", &self.ut_pid) + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_pad", &self.ut_pad) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_user.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_pid.hash(state); + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_host.hash(state); + self.ut_pad.hash(state); + } + } } } @@ -1862,12 +2419,14 @@ pub const NOTE_EXIT: ::uint32_t = 0x80000000; pub const NOTE_FORK: ::uint32_t = 0x40000000; pub const NOTE_EXEC: ::uint32_t = 0x20000000; +#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")] pub const NOTE_REAP: ::uint32_t = 0x10000000; pub const NOTE_SIGNAL: ::uint32_t = 0x08000000; pub const NOTE_EXITSTATUS: ::uint32_t = 0x04000000; pub const NOTE_EXIT_DETAIL: ::uint32_t = 0x02000000; pub const NOTE_PDATAMASK: ::uint32_t = 0x000fffff; pub const NOTE_PCTRLMASK: ::uint32_t = 0xfff00000; +#[deprecated(since="0.2.49", note="Deprecated since MacOSX 10.9")] pub const NOTE_EXIT_REPARENTED: ::uint32_t = 0x00080000; pub const NOTE_EXIT_DETAIL_MASK: ::uint32_t = 0x00070000; pub const NOTE_EXIT_DECRYPTFAIL: ::uint32_t = 0x00010000; @@ -2073,7 +2632,9 @@ pub const KERN_KDGETENTROPY: ::c_int = 16; pub const KERN_KDWRITETR: ::c_int = 17; pub const KERN_KDWRITEMAP: ::c_int = 18; +#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")] pub const KERN_KDENABLE_BG_TRACE: ::c_int = 19; +#[deprecated(since = "0.2.49", note ="Removed in MacOSX 10.12")] pub const KERN_KDDISABLE_BG_TRACE: ::c_int = 20; pub const KERN_KDREADCURTHRMAP: ::c_int = 21; pub const KERN_KDSET_TYPEFILTER: ::c_int = 22; @@ -2384,9 +2945,18 @@ pub const SF_APPEND: ::c_uint = 0x00040000; pub const UF_HIDDEN: ::c_uint = 0x00008000; -fn __DARWIN_ALIGN32(p: usize) -> usize { - const __DARWIN_ALIGNBYTES32: usize = mem::size_of::() - 1; - p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 +cfg_if! { + if #[cfg(libc_const_size_of)] { + fn __DARWIN_ALIGN32(p: usize) -> usize { + const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } else { + fn __DARWIN_ALIGN32(p: usize) -> usize { + let __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } } f! { @@ -2396,11 +2966,10 @@ return ::CMSG_FIRSTHDR(mhdr); }; let cmsg_len = (*cmsg).cmsg_len as usize; - let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize) - + __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()); + let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize); let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; - if next > max { + if next + __DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) > max { 0 as *mut ::cmsghdr } else { next as *mut ::cmsghdr @@ -2409,17 +2978,17 @@ pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { (cmsg as *mut ::c_uchar) - .offset(__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) as isize) + .offset(__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) as isize) } pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { - (__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + __DARWIN_ALIGN32(length as usize)) as ::c_uint } pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { - __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>() + length as usize) + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + length as usize) as ::c_uint } @@ -2445,6 +3014,16 @@ } extern { + #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.5")] + #[link_name = "daemon$1050"] + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")] + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + #[deprecated(since="0.2.49", note="Deprecated in MacOSX 10.10")] + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; @@ -2589,6 +3168,7 @@ name: *mut ::c_char, termp: *mut termios, winp: *mut ::winsize) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; pub fn duplocale(base: ::locale_t) -> ::locale_t; pub fn freelocale(loc: ::locale_t) -> ::c_int; pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,3 +1,4 @@ +pub type c_char = i8; pub type clock_t = u64; pub type ino_t = u64; pub type lwpid_t = i32; @@ -15,34 +16,22 @@ pub type fsblkcnt_t = u64; pub type fsfilcnt_t = u64; +pub type mqd_t = ::c_int; pub type sem_t = *mut sem; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum sem {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { *self } +} s! { - pub struct exit_status { pub e_termination: u16, pub e_exit: u16 } - pub struct utmpx { - pub ut_name: [::c_char; 32], - pub ut_id: [::c_char; 4], - - pub ut_line: [::c_char; 32], - pub ut_host: [::c_char; 256], - - pub ut_unused: [u8; 16], - pub ut_session: u16, - pub ut_type: u16, - pub ut_pid: ::pid_t, - ut_exit: exit_status, - ut_ss: ::sockaddr_storage, - pub ut_tv: ::timeval, - pub ut_unused2: [u8; 16], - } - pub struct aiocb { pub aio_fildes: ::c_int, pub aio_offset: ::off_t, @@ -55,15 +44,6 @@ _aio_err: ::c_int } - pub struct dirent { - pub d_fileno: ::ino_t, - pub d_namlen: u16, - pub d_type: u8, - __unused1: u8, - __unused2: u32, - pub d_name: [::c_char; 256], - } - pub struct uuid { pub time_low: u32, pub time_mid: u16, @@ -115,27 +95,6 @@ pub f_uid_uuid: ::uuid_t, } - pub struct statfs { - pub f_bsize: ::c_long, - pub f_iosize: ::c_long, - pub f_blocks: ::c_long, - pub f_bfree: ::c_long, - pub f_bavail: ::c_long, - pub f_files: ::c_long, - pub f_ffree: ::c_long, - pub f_fsid: ::fsid_t, - pub f_owner: ::uid_t, - pub f_type: ::int32_t, - pub f_flags: ::int32_t, - pub f_syncwrites: ::c_long, - pub f_asyncwrites: ::c_long, - pub f_fstypename: [::c_char; 16], - pub f_mntonname: [::c_char; 90], - pub f_syncreads: ::c_long, - pub f_asyncreads: ::c_long, - pub f_mntfromname: [::c_char; 90], - } - pub struct stat { pub st_ino: ::ino_t, pub st_nlink: ::nlink_t, @@ -218,6 +177,230 @@ } } +s_no_extra_traits! { + pub struct utmpx { + pub ut_name: [::c_char; 32], + pub ut_id: [::c_char; 4], + + pub ut_line: [::c_char; 32], + pub ut_host: [::c_char; 256], + + pub ut_unused: [u8; 16], + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: ::pid_t, + ut_exit: exit_status, + ut_ss: ::sockaddr_storage, + pub ut_tv: ::timeval, + pub ut_unused2: [u8; 16], + } + + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_namlen: u16, + pub d_type: u8, + __unused1: u8, + __unused2: u32, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_bsize: ::c_long, + pub f_iosize: ::c_long, + pub f_blocks: ::c_long, + pub f_bfree: ::c_long, + pub f_bavail: ::c_long, + pub f_files: ::c_long, + pub f_ffree: ::c_long, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, + pub f_type: ::int32_t, + pub f_flags: ::int32_t, + pub f_syncwrites: ::c_long, + pub f_asyncwrites: ::c_long, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 90], + pub f_syncreads: ::c_long, + pub f_asyncreads: ::c_long, + pub f_mntfromname: [::c_char; 90], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_name == other.ut_name + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_unused == other.ut_unused + && self.ut_session == other.ut_session + && self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_exit == other.ut_exit + && self.ut_ss == other.ut_ss + && self.ut_tv == other.ut_tv + && self.ut_unused2 == other.ut_unused2 + } + } + impl Eq for utmpx {} + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_name", &self.ut_name) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_unused", &self.ut_unused) + .field("ut_session", &self.ut_session) + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_exit", &self.ut_exit) + .field("ut_ss", &self.ut_ss) + .field("ut_tv", &self.ut_tv) + .field("ut_unused2", &self.ut_unused2) + .finish() + } + } + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_name.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.ut_unused.hash(state); + self.ut_session.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_exit.hash(state); + self.ut_ss.hash(state); + self.ut_tv.hash(state); + self.ut_unused2.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + // Ignore __unused1 + // Ignore __unused2 + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // Ignore __unused1 + // Ignore __unused2 + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + // Ignore __unused1 + // Ignore __unused2 + self.d_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_type", &self.f_type) + .field("f_flags", &self.f_flags) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + // FIXME: .field("f_mntonname", &self.f_mntonname) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_mntfromname.hash(state); + } + } + } +} + pub const RAND_MAX: ::c_int = 0x7fff_ffff; pub const PTHREAD_STACK_MIN: ::size_t = 16384; pub const SIGSTKSZ: ::size_t = 40960; @@ -795,29 +978,32 @@ f! { pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { (cmsg as *mut ::c_uchar) - .offset(_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) as isize) + .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) } pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { - _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + length as usize + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + length as usize) + as ::c_uint } pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) -> *mut ::cmsghdr { - let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len) - + _CMSG_ALIGN(mem::size_of::<::cmsghdr>()); + let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize) + + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; if next <= max { - (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)) as *mut ::cmsghdr + (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr } else { 0 as *mut ::cmsghdr } } pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { - _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + _CMSG_ALIGN(length as usize) + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + + _CMSG_ALIGN(length as usize)) as ::c_uint } } diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,4 @@ -use dox::mem; - +pub type c_char = u8; pub type c_long = i64; pub type c_ulong = u64; pub type time_t = i64; @@ -32,6 +31,14 @@ } // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + pub const MAP_32BIT: ::c_int = 0x00080000; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,47 @@ +pub type c_char = u8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type time_t = i64; +pub type suseconds_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_atime_pad: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_mtime_pad: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ctime_pad: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: ::uint32_t, + pub st_lspare: ::int32_t, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + pub st_birthtime_pad: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} +pub const MAP_32BIT: ::c_int = 0x00080000; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - pub type fflags_t = u32; pub type clock_t = i32; pub type ino_t = u32; @@ -17,21 +15,11 @@ pub type msglen_t = ::c_ulong; pub type msgqnum_t = ::c_ulong; +pub type mqd_t = *mut ::c_void; pub type posix_spawnattr_t = *mut ::c_void; pub type posix_spawn_file_actions_t = *mut ::c_void; s! { - pub struct utmpx { - pub ut_type: ::c_short, - pub ut_tv: ::timeval, - pub ut_id: [::c_char; 8], - pub ut_pid: ::pid_t, - pub ut_user: [::c_char; 32], - pub ut_line: [::c_char; 16], - pub ut_host: [::c_char; 128], - pub __ut_spare: [::c_char; 64], - } - pub struct aiocb { pub aio_fildes: ::c_int, pub aio_offset: ::off_t, @@ -48,14 +36,6 @@ pub aio_sigevent: sigevent } - pub struct dirent { - pub d_fileno: u32, - pub d_reclen: u16, - pub d_type: u8, - pub d_namlen: u8, - pub d_name: [::c_char; 256], - } - pub struct jail { pub version: u32, pub path: *mut ::c_char, @@ -101,31 +81,6 @@ pub f_namemax: ::c_ulong, } - pub struct statfs { - pub f_version: ::uint32_t, - pub f_type: ::uint32_t, - pub f_flags: ::uint64_t, - pub f_bsize: ::uint64_t, - pub f_iosize: ::uint64_t, - pub f_blocks: ::uint64_t, - pub f_bfree: ::uint64_t, - pub f_bavail: ::int64_t, - pub f_files: ::uint64_t, - pub f_ffree: ::int64_t, - pub f_syncwrites: ::uint64_t, - pub f_asyncwrites: ::uint64_t, - pub f_syncreads: ::uint64_t, - pub f_asyncreads: ::uint64_t, - f_spare: [::uint64_t; 10], - pub f_namemax: ::uint32_t, - pub f_owner: ::uid_t, - pub f_fsid: ::fsid_t, - f_charspare: [::c_char; 80], - pub f_fstypename: [::c_char; 16], - pub f_mntfromname: [::c_char; 88], - pub f_mntonname: [::c_char; 88], - } - // internal structure has changed over time pub struct _sem { data: [u32; 4], @@ -174,6 +129,63 @@ __cr_unused1: *mut ::c_void, } + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::ssize_t, + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_id: [::c_char; 8], + pub ut_pid: ::pid_t, + pub ut_user: [::c_char; 32], + pub ut_line: [::c_char; 16], + pub ut_host: [::c_char; 128], + pub __ut_spare: [::c_char; 64], + } + + pub struct dirent { + pub d_fileno: u32, + pub d_reclen: u16, + pub d_type: u8, + pub d_namlen: u8, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + pub f_version: ::uint32_t, + pub f_type: ::uint32_t, + pub f_flags: ::uint64_t, + pub f_bsize: ::uint64_t, + pub f_iosize: ::uint64_t, + pub f_blocks: ::uint64_t, + pub f_bfree: ::uint64_t, + pub f_bavail: ::int64_t, + pub f_files: ::uint64_t, + pub f_ffree: ::int64_t, + pub f_syncwrites: ::uint64_t, + pub f_asyncwrites: ::uint64_t, + pub f_syncreads: ::uint64_t, + pub f_asyncreads: ::uint64_t, + f_spare: [::uint64_t; 10], + pub f_namemax: ::uint32_t, + pub f_owner: ::uid_t, + pub f_fsid: ::fsid_t, + f_charspare: [::c_char; 80], + pub f_fstypename: [::c_char; 16], + pub f_mntfromname: [::c_char; 88], + pub f_mntonname: [::c_char; 88], + } + pub struct sockaddr_dl { pub sdl_len: ::c_uchar, pub sdl_family: ::c_uchar, @@ -184,11 +196,227 @@ pub sdl_slen: ::c_uchar, pub sdl_data: [::c_char; 46], } +} - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_size: ::size_t, - pub ss_flags: ::c_int, +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self.ut_id == other.ut_id + && self.ut_pid == other.ut_pid + && self.ut_user == other.ut_user + && self.ut_line == other.ut_line + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self + .__ut_spare + .iter() + .zip(other.__ut_spare.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for utmpx {} + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + .field("ut_id", &self.ut_id) + .field("ut_pid", &self.ut_pid) + .field("ut_user", &self.ut_user) + .field("ut_line", &self.ut_line) + // FIXME: .field("ut_host", &self.ut_host) + // FIXME: .field("__ut_spare", &self.__ut_spare) + .finish() + } + } + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_id.hash(state); + self.ut_pid.hash(state); + self.ut_user.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.__ut_spare.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_version == other.f_version + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self.f_spare == other.f_spare + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_fsid == other.f_fsid + && self + .f_charspare + .iter() + .zip(other.f_charspare.iter()) + .all(|(a,b)| a == b) + && self.f_fstypename == other.f_fstypename + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_spare", &self.f_spare) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_fsid", &self.f_fsid) + // FIXME: .field("f_charspare", &self.f_charspare) + .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + // FIXME: .field("f_mntonname", &self.f_mntonname) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_version.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_spare.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_fsid.hash(state); + self.f_charspare.hash(state); + self.f_fstypename.hash(state); + self.f_mntfromname.hash(state); + self.f_mntonname.hash(state); + } + } + + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_len == other.sdl_len + && self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_len", &self.sdl_len) + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + // FIXME: .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_len.hash(state); + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } } } @@ -824,8 +1052,16 @@ pub const TCP_PCAP_IN: ::c_int = 4096; pub const IP_BINDANY: ::c_int = 24; +pub const IP_BINDMULTI: ::c_int = 25; +pub const IP_RSS_LISTEN_BUCKET: ::c_int = 26; +pub const IP_ORIGDSTADDR : ::c_int = 27; +pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR; + pub const IP_RECVTOS: ::c_int = 68; +pub const IPV6_ORIGDSTADDR: ::c_int = 72; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; + pub const PF_SLOW: ::c_int = AF_SLOW; pub const PF_SCLUSTER: ::c_int = AF_SCLUSTER; pub const PF_ARP: ::c_int = AF_ARP; @@ -977,11 +1213,11 @@ f! { pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { (cmsg as *mut ::c_uchar) - .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) } pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { - _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length } pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) @@ -991,7 +1227,7 @@ return ::CMSG_FIRSTHDR(mhdr); }; let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) - + _ALIGN(mem::size_of::<::cmsghdr>()); + + _ALIGN(::mem::size_of::<::cmsghdr>()); let max = (*mhdr).msg_control as usize + (*mhdr).msg_controllen as usize; if next > max { @@ -1003,7 +1239,7 @@ } pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { - (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) as ::c_uint } @@ -1097,6 +1333,7 @@ pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::ssize_t; + pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int; pub fn freelocale(loc: ::locale_t) -> ::c_int; pub fn waitid(idtype: idtype_t, id: ::id_t, infop: *mut ::siginfo_t, @@ -1199,6 +1436,11 @@ pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; pub fn __xuname(nmln: ::c_int, buf: *mut ::c_void) -> ::c_int; + + pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t, + flags: ::c_int) -> ::ssize_t; + pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::size_t, + flags: ::c_int, timeout: *const ::timespec) -> ::ssize_t; } #[link(name = "util")] @@ -1219,6 +1461,12 @@ } else if #[cfg(target_arch = "aarch64")] { mod aarch64; pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(target_arch = "powerpc64")] { + mod powerpc64; + pub use self::powerpc64::*; } else { // Unknown target_arch } diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,44 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type time_t = i64; +pub type suseconds_t = i64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: ::fflags_t, + pub st_gen: ::uint32_t, + pub st_lspare: ::int32_t, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + } +} + +// should be pub(crate), but that requires Rust 1.18.0 +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const MAP_32BIT: ::c_int = 0x00080000; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,4 @@ -use dox::mem; - +pub type c_char = i8; pub type c_long = i64; pub type c_ulong = u64; pub type time_t = i64; @@ -32,6 +31,13 @@ } // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} pub const MAP_32BIT: ::c_int = 0x00080000; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,4 @@ -use dox::mem; - +pub type c_char = i8; pub type c_long = i32; pub type c_ulong = u32; pub type time_t = i32; @@ -33,5 +32,12 @@ } // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/freebsdlike/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,7 @@ -pub type c_char = i8; pub type dev_t = u32; pub type mode_t = u16; pub type pthread_attr_t = *mut ::c_void; pub type rlim_t = i64; -pub type mqd_t = *mut ::c_void; pub type pthread_mutex_t = *mut ::c_void; pub type pthread_mutexattr_t = *mut ::c_void; pub type pthread_cond_t = *mut ::c_void; @@ -15,10 +13,25 @@ pub type speed_t = ::c_uint; pub type nl_item = ::c_int; pub type id_t = i64; +pub type vm_size_t = ::uintptr_t; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct glob_t { pub gl_pathc: ::size_t, pub gl_matchc: ::size_t, @@ -42,14 +55,6 @@ pub udata: *mut ::c_void, } - pub struct sockaddr_storage { - pub ss_len: u8, - pub ss_family: ::sa_family_t, - __ss_pad1: [u8; 6], - __ss_align: i64, - __ss_pad2: [u8; 112], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -183,6 +188,55 @@ } } +s_no_extra_traits! { + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + } +} + pub const AIO_LISTIO_MAX: ::c_int = 16; pub const AIO_CANCELED: ::c_int = 1; pub const AIO_NOTCANCELED: ::c_int = 2; @@ -1034,6 +1088,14 @@ } extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn accept4(s: ::c_int, addr: *mut ::sockaddr, addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int; pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; @@ -1237,6 +1299,7 @@ name: *mut ::c_char, termp: *mut termios, winp: *mut ::winsize) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; } cfg_if! { diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::{mem, Option}; - pub type wchar_t = i32; pub type off_t = i64; pub type useconds_t = u32; @@ -25,12 +23,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_len: u8, - pub sun_family: sa_family_t, - pub sun_path: [c_char; 104] - } - pub struct passwd { pub pw_name: *mut ::c_char, pub pw_passwd: *mut ::c_char, @@ -85,6 +77,39 @@ pub tm_zone: *mut ::c_char, } + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct fsid_t { + __fsid_val: [::int32_t; 2], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } +} + +s_no_extra_traits!{ + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [c_char; 104] + } + pub struct utsname { #[cfg(not(target_os = "dragonfly"))] pub sysname: [::c_char; 256], @@ -108,29 +133,94 @@ pub machine: [::c_char; 32], } - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::c_int, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::socklen_t, - pub msg_flags: ::c_int, - } +} - pub struct cmsghdr { - pub cmsg_len: ::socklen_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len + && self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } - pub struct fsid_t { - __fsid_val: [::int32_t; 2], - } + impl Eq for sockaddr_un {} - pub struct if_nameindex { - pub if_index: ::c_uint, - pub if_name: *mut ::c_char, + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_len.hash(state); + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } } } @@ -343,7 +433,7 @@ f! { pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { - if (*mhdr).msg_controllen as usize >= mem::size_of::<::cmsghdr>() { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::<::cmsghdr>() { (*mhdr).msg_control as *mut ::cmsghdr } else { 0 as *mut ::cmsghdr @@ -351,20 +441,20 @@ } pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; (*set).fds_bits[fd / bits] |= 1 << (fd % bits); return @@ -435,7 +525,7 @@ #[cfg_attr(target_os = "freebsd", link_name = "glob@FBSD_1.0")] pub fn glob(pattern: *const ::c_char, flags: ::c_int, - errfunc: Option ::c_int>, pglob: *mut ::glob_t) -> ::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__globfree30")] @@ -504,7 +594,7 @@ pub fn sync(); #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -533,7 +623,6 @@ pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; pub fn sem_unlink(name: *const ::c_char) -> ::c_int; - pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam_r50")] #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwnam_r")] pub fn getpwnam_r(name: *const ::c_char, @@ -553,9 +642,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "popen$UNIX2003")] diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - pub type time_t = i64; pub type mode_t = u32; pub type nlink_t = ::uint32_t; @@ -13,8 +11,18 @@ pub type id_t = ::uint32_t; pub type sem_t = *mut sem; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum sem {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { *self } +} s! { pub struct sigaction { @@ -29,14 +37,6 @@ pub ss_flags: ::c_int, } - pub struct sockaddr_in { - pub sin_len: u8, - pub sin_family: ::sa_family_t, - pub sin_port: ::in_port_t, - pub sin_addr: ::in_addr, - pub sin_zero: [::int8_t; 8], - } - pub struct in6_pktinfo { pub ipi6_addr: ::in6_addr, pub ipi6_ifindex: ::c_uint, @@ -595,58 +595,15 @@ pub const TIMER_ABSTIME: ::c_int = 1; -fn _ALIGN(p: usize) -> usize { - (p + _ALIGNBYTES) & !_ALIGNBYTES -} - -f! { - pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { - (cmsg as *mut ::c_uchar) - .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize) - } - - pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { - _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length - } - - pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) - -> *mut ::cmsghdr - { - if cmsg.is_null() { - return ::CMSG_FIRSTHDR(mhdr); - }; - let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) - + _ALIGN(mem::size_of::<::cmsghdr>()); - let max = (*mhdr).msg_control as usize - + (*mhdr).msg_controllen as usize; - if next > max { - 0 as *mut ::cmsghdr - } else { - (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) - as *mut ::cmsghdr - } - } - - pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { - (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) - as ::c_uint - } - - pub fn WSTOPSIG(status: ::c_int) -> ::c_int { - status >> 8 - } - - pub fn WIFSIGNALED(status: ::c_int) -> bool { - (status & 0o177) != 0o177 && (status & 0o177) != 0 - } - - pub fn WIFSTOPPED(status: ::c_int) -> bool { - (status & 0o177) == 0o177 - } -} - #[link(name = "util")] extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__clock_getres50")] @@ -686,6 +643,7 @@ name: *mut ::c_char, termp: *mut termios, winp: *mut ::winsize) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - use PT_FIRSTMACH; pub type c_long = i64; @@ -8,8 +6,15 @@ pub type __cpu_simple_lock_nv_t = ::c_uchar; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0; pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - use PT_FIRSTMACH; pub type c_long = i32; @@ -8,8 +6,15 @@ pub type __cpu_simple_lock_nv_t = ::c_int; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - pub type clock_t = ::c_uint; pub type suseconds_t = ::c_int; pub type dev_t = u64; @@ -9,6 +7,7 @@ pub type idtype_t = ::c_int; pub type mqd_t = ::c_int; type __pthread_spin_t = __cpu_simple_lock_nv_t; +pub type vm_size_t = ::uintptr_t; s! { pub struct aiocb { @@ -24,14 +23,6 @@ _retval: ::ssize_t } - pub struct dirent { - pub d_fileno: ::ino_t, - pub d_reclen: u16, - pub d_namlen: u16, - pub d_type: u8, - pub d_name: [::c_char; 512], - } - pub struct glob_t { pub gl_pathc: ::size_t, pub gl_matchc: ::size_t, @@ -91,41 +82,7 @@ pub st_spare: [::uint32_t; 2], } - pub struct statvfs { - pub f_flag: ::c_ulong, - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_iosize: ::c_ulong, - - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_bresvd: ::fsblkcnt_t, - - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_favail: ::fsfilcnt_t, - pub f_fresvd: ::fsfilcnt_t, - - pub f_syncreads: ::uint64_t, - pub f_syncwrites: ::uint64_t, - - pub f_asyncreads: ::uint64_t, - pub f_asyncwrites: ::uint64_t, - - pub f_fsidx: ::fsid_t, - pub f_fsid: ::c_ulong, - pub f_namemax: ::c_ulong, - pub f_owner: ::uid_t, - - pub f_spare: [::uint32_t; 4], - - pub f_fstypename: [::c_char; 32], - pub f_mntonname: [::c_char; 1024], - pub f_mntfromname: [::c_char; 1024], - } - - pub struct addrinfo { + pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, pub ai_socktype: ::c_int, @@ -136,14 +93,6 @@ pub ai_next: *mut ::addrinfo, } - pub struct sockaddr_storage { - pub ss_len: u8, - pub ss_family: ::sa_family_t, - __ss_pad1: [u8; 6], - __ss_pad2: i64, - __ss_pad3: [u8; 112], - } - pub struct siginfo_t { pub si_signo: ::c_int, pub si_code: ::c_int, @@ -319,6 +268,13 @@ pub sdl_data: [::c_char; 12], } + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } +} + +s_no_extra_traits! { pub struct in_pktinfo { pub ipi_addr: ::in_addr, pub ipi_ifindex: ::c_uint, @@ -332,6 +288,377 @@ pub ar_pln: u8, pub ar_op: u16, } + + #[repr(packed)] + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::int8_t; 8], + } + + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 512], + } + + pub struct statvfs { + pub f_flag: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_iosize: ::c_ulong, + + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_bresvd: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fresvd: ::fsfilcnt_t, + + pub f_syncreads: ::uint64_t, + pub f_syncwrites: ::uint64_t, + + pub f_asyncreads: ::uint64_t, + pub f_asyncwrites: ::uint64_t, + + pub f_fsidx: ::fsid_t, + pub f_fsid: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_owner: ::uid_t, + + pub f_spare: [::uint32_t; 4], + + pub f_fstypename: [::c_char; 32], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for in_pktinfo { + fn eq(&self, other: &in_pktinfo) -> bool { + self.ipi_addr == other.ipi_addr + && self.ipi_ifindex == other.ipi_ifindex + } + } + impl Eq for in_pktinfo {} + impl ::fmt::Debug for in_pktinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("in_pktinfo") + .field("ipi_addr", &self.ipi_addr) + .field("ipi_ifindex", &self.ipi_ifindex) + .finish() + } + } + impl ::hash::Hash for in_pktinfo { + fn hash(&self, state: &mut H) { + self.ipi_addr.hash(state); + self.ipi_ifindex.hash(state); + } + } + + impl PartialEq for arphdr { + fn eq(&self, other: &arphdr) -> bool { + self.ar_hrd == other.ar_hrd + && self.ar_pro == other.ar_pro + && self.ar_hln == other.ar_hln + && self.ar_pln == other.ar_pln + && self.ar_op == other.ar_op + } + } + impl Eq for arphdr {} + impl ::fmt::Debug for arphdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + f.debug_struct("arphdr") + .field("ar_hrd", &ar_hrd) + .field("ar_pro", &ar_pro) + .field("ar_hln", &self.ar_hln) + .field("ar_pln", &self.ar_pln) + .field("ar_op", &ar_op) + .finish() + } + } + impl ::hash::Hash for arphdr { + fn hash(&self, state: &mut H) { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + ar_hrd.hash(state); + ar_pro.hash(state); + self.ar_hln.hash(state); + self.ar_pln.hash(state); + ar_op.hash(state); + } + } + + impl PartialEq for in_addr { + fn eq(&self, other: &in_addr) -> bool { + self.s_addr == other.s_addr + } + } + impl Eq for in_addr {} + impl ::fmt::Debug for in_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let s_addr = self.s_addr; + f.debug_struct("in_addr") + .field("s_addr", &s_addr) + .finish() + } + } + impl ::hash::Hash for in_addr { + fn hash(&self, state: &mut H) { + let s_addr = self.s_addr; + s_addr.hash(state); + } + } + + impl PartialEq for ip_mreq { + fn eq(&self, other: &ip_mreq) -> bool { + self.imr_multiaddr == other.imr_multiaddr + && self.imr_interface == other.imr_interface + } + } + impl Eq for ip_mreq {} + impl ::fmt::Debug for ip_mreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ip_mreq") + .field("imr_multiaddr", &self.imr_multiaddr) + .field("imr_interface", &self.imr_interface) + .finish() + } + } + impl ::hash::Hash for ip_mreq { + fn hash(&self, state: &mut H) { + self.imr_multiaddr.hash(state); + self.imr_interface.hash(state); + } + } + + impl PartialEq for sockaddr_in { + fn eq(&self, other: &sockaddr_in) -> bool { + self.sin_len == other.sin_len + && self.sin_family == other.sin_family + && self.sin_port == other.sin_port + && self.sin_addr == other.sin_addr + && self.sin_zero == other.sin_zero + } + } + impl Eq for sockaddr_in {} + impl ::fmt::Debug for sockaddr_in { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_in") + .field("sin_len", &self.sin_len) + .field("sin_family", &self.sin_family) + .field("sin_port", &self.sin_port) + .field("sin_addr", &self.sin_addr) + .field("sin_zero", &self.sin_zero) + .finish() + } + } + impl ::hash::Hash for sockaddr_in { + fn hash(&self, state: &mut H) { + self.sin_len.hash(state); + self.sin_family.hash(state); + self.sin_port.hash(state); + self.sin_addr.hash(state); + self.sin_zero.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for statvfs { + fn eq(&self, other: &statvfs) -> bool { + self.f_flag == other.f_flag + && self.f_bsize == other.f_bsize + && self.f_frsize == other.f_frsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_bresvd == other.f_bresvd + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_fresvd == other.f_fresvd + && self.f_syncreads == other.f_syncreads + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fsidx == other.f_fsidx + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_spare == other.f_spare + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statvfs {} + impl ::fmt::Debug for statvfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statvfs") + .field("f_flag", &self.f_flag) + .field("f_bsize", &self.f_bsize) + .field("f_frsize", &self.f_frsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_bresvd", &self.f_bresvd) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_fresvd", &self.f_fresvd) + .field("f_syncreads", &self.f_syncreads) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_fsidx", &self.f_fsidx) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_spare", &self.f_spare) + .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statvfs { + fn hash(&self, state: &mut H) { + self.f_flag.hash(state); + self.f_bsize.hash(state); + self.f_frsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_bresvd.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_fresvd.hash(state); + self.f_syncreads.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_fsidx.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_spare.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + } } pub const AT_FDCWD: ::c_int = -100; @@ -708,21 +1035,32 @@ pub const ST_NOSUID: ::c_ulong = 8; -pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { - ptm_magic: 0x33330003, - ptm_errorcheck: 0, - #[cfg(any(target_arch = "sparc", target_arch = "sparc64", - target_arch = "x86", target_arch = "x86_64"))] - ptm_pad1: [0; 3], - ptm_unused: 0, - #[cfg(any(target_arch = "sparc", target_arch = "sparc64", - target_arch = "x86", target_arch = "x86_64"))] - ptm_pad2: [0; 3], - ptm_waiters: 0 as *mut _, - ptm_owner: 0, - ptm_recursed: 0, - ptm_spare2: 0 as *mut _, -}; +cfg_if! { + if #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_pad1: [0; 3], + ptm_unused: 0, + ptm_pad2: [0; 3], + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } else { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_unused: 0, + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } +} pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { ptc_magic: 0x55550005, @@ -1018,10 +1356,58 @@ pub const SF_LOG: ::c_ulong = 0x00400000; pub const SF_SNAPINVAL: ::c_ulong = 0x00800000; -// dirfd() is a macro on netbsd to access -// the first field of the struct where dirp points to: -// http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36 +fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +} + f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + pub fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } + + // dirfd() is a macro on netbsd to access + // the first field of the struct where dirp points to: + // http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36 pub fn dirfd(dirp: *mut ::DIR) -> ::c_int { *(dirp as *const ::c_int) } @@ -1036,7 +1422,7 @@ } else { 0 }; - mem::size_of::() + mem::size_of::<::gid_t>() * ngrps + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps } } @@ -1199,6 +1585,11 @@ pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int; pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, + flags: ::c_int) -> ::c_int; + pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, + flags: ::c_int, timeout: *mut ::timespec) -> ::c_int; } #[link(name = "util")] diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - use PT_FIRSTMACH; pub type c_long = i32; @@ -8,8 +6,15 @@ pub type __cpu_simple_lock_nv_t = ::c_int; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_double>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - use PT_FIRSTMACH; pub type c_long = i64; @@ -8,8 +6,15 @@ pub type __cpu_simple_lock_nv_t = ::c_uchar; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,10 +1,15 @@ -use dox::mem; - pub type c_long = i32; pub type c_ulong = u32; pub type c_char = i8; pub type __cpu_simple_lock_nv_t = ::c_uchar; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/bitrig/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,21 @@ pub type c_char = i8; s! { + pub struct glob_t { + pub gl_pathc: ::c_int, + pub gl_matchc: ::c_int, + pub gl_offs: ::c_int, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + } + pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -83,6 +98,7 @@ pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast +pub const PTHREAD_STACK_MIN : ::size_t = 2048; pub const SIGSTKSZ : ::size_t = 40960; pub const PT_FIRSTMACH: ::c_int = 32; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -17,29 +17,21 @@ pub type caddr_t = *mut ::c_char; s! { - pub struct dirent { - pub d_fileno: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: u16, - pub d_type: u8, - pub d_namlen: u8, - __d_padding: [u8; 4], - pub d_name: [::c_char; 256], + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, } - pub struct glob_t { - pub gl_pathc: ::c_int, - pub gl_matchc: ::c_int, - pub gl_offs: ::c_int, - pub gl_flags: ::c_int, - pub gl_pathv: *mut *mut ::c_char, - __unused1: *mut ::c_void, - __unused2: *mut ::c_void, - __unused3: *mut ::c_void, - __unused4: *mut ::c_void, - __unused5: *mut ::c_void, - __unused6: *mut ::c_void, - __unused7: *mut ::c_void, + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::int8_t; 8], } pub struct kevent { @@ -99,25 +91,6 @@ pub ai_next: *mut ::addrinfo, } - pub struct sockaddr_storage { - pub ss_len: u8, - pub ss_family: ::sa_family_t, - __ss_pad1: [u8; 6], - __ss_pad2: i64, - __ss_pad3: [u8; 240], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_code: ::c_int, - pub si_errno: ::c_int, - pub si_addr: *mut ::c_char, - #[cfg(target_pointer_width = "32")] - __pad: [u8; 112], - #[cfg(target_pointer_width = "64")] - __pad: [u8; 108], - } - pub struct Dl_info { pub dli_fname: *const ::c_char, pub dli_fbase: *mut ::c_void, @@ -125,19 +98,6 @@ pub dli_saddr: *mut ::c_void, } - pub struct lastlog { - ll_time: ::time_t, - ll_line: [::c_char; UT_LINESIZE], - ll_host: [::c_char; UT_HOSTSIZE], - } - - pub struct utmp { - pub ut_line: [::c_char; UT_LINESIZE], - pub ut_name: [::c_char; UT_NAMESIZE], - pub ut_host: [::c_char; UT_HOSTSIZE], - pub ut_time: ::time_t, - } - pub struct if_data { pub ifi_type: ::c_uchar, pub ifi_addrlen: ::c_uchar, @@ -204,6 +164,230 @@ } } +s_no_extra_traits! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_namlen: u8, + __d_padding: [u8; 4], + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 240], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_addr: *mut ::c_char, + #[cfg(target_pointer_width = "32")] + __pad: [u8; 112], + #[cfg(target_pointer_width = "64")] + __pad: [u8; 108], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_name: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_time: ::time_t, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_code == other.si_code + && self.si_errno == other.si_errno + && self.si_addr == other.si_addr + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + .field("si_addr", &self.si_addr) + .finish() + } + } + + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); + self.si_addr.hash(state); + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + // FIXME: .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_time == other.ut_time + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self + .ut_name + .iter() + .zip(other.ut_name.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + // FIXME: .field("ut_line", &self.ut_line) + // FIXME: .field("ut_name", &self.ut_name) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_time", &self.ut_time) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_line.hash(state); + self.ut_name.hash(state); + self.ut_host.hash(state); + self.ut_time.hash(state); + } + } + } +} + pub const UT_NAMESIZE: usize = 32; pub const UT_LINESIZE: usize = 8; pub const UT_HOSTSIZE: usize = 256; @@ -215,8 +399,6 @@ pub const MS_SYNC : ::c_int = 0x0002; pub const MS_INVALIDATE : ::c_int = 0x0004; -pub const PTHREAD_STACK_MIN : ::size_t = 2048; - pub const POLLNORM: ::c_short = ::POLLRDNORM; pub const ENOATTR : ::c_int = 83; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,14 @@ -use dox::mem; - pub type c_long = i64; pub type c_ulong = u64; pub type c_char = u8; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,19 @@ s! { + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + } + pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -26,42 +41,6 @@ pub int_n_sign_posn: ::c_char, } - pub struct statfs { - pub f_flags: ::uint32_t, - pub f_bsize: ::uint32_t, - pub f_iosize: ::uint32_t, - pub f_blocks: ::uint64_t, - pub f_bfree: ::uint64_t, - pub f_bavail: ::int64_t, - pub f_files: ::uint64_t, - pub f_ffree: ::uint64_t, - pub f_favail: ::int64_t, - pub f_syncwrites: ::uint64_t, - pub f_syncreads: ::uint64_t, - pub f_asyncwrites: ::uint64_t, - pub f_asyncreads: ::uint64_t, - pub f_fsid: ::fsid_t, - pub f_namemax: ::uint32_t, - pub f_owner: ::uid_t, - pub f_ctime: ::uint64_t, - pub f_fstypename: [::c_char; 16], - pub f_mntonname: [::c_char; 90], - pub f_mntfromname: [::c_char; 90], - pub f_mntfromspec: [::c_char; 90], - pub mount_info: mount_info, - } - - pub union mount_info { - pub ufs_args: ufs_args, - pub mfs_args: mfs_args, - pub nfs_args: nfs_args, - pub iso_args: iso_args, - pub msdosfs_args: msdosfs_args, - pub ntfs_args: ntfs_args, - pub tmpfs_args: tmpfs_args, - align: [::c_char; 160], - } - pub struct ufs_args { pub fspec: *mut ::c_char, pub export_info: export_args, @@ -165,6 +144,184 @@ } } +s_no_extra_traits! { + pub union mount_info { + pub ufs_args: ufs_args, + pub mfs_args: mfs_args, + pub nfs_args: nfs_args, + pub iso_args: iso_args, + pub msdosfs_args: msdosfs_args, + pub ntfs_args: ntfs_args, + pub tmpfs_args: tmpfs_args, + align: [::c_char; 160], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for mount_info { + fn eq(&self, other: &mount_info) -> bool { + unsafe { + self.align + .iter() + .zip(other.align.iter()) + .all(|(a,b)| a == b) + } + } + } + + impl Eq for mount_info { } + + impl ::fmt::Debug for mount_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mount_info") + // FIXME: .field("align", &self.align) + .finish() + } + } + + impl ::hash::Hash for mount_info { + fn hash(&self, state: &mut H) { + unsafe { self.align.hash(state) }; + } + } + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + // This type uses the union mount_info: + pub struct statfs { + pub f_flags: ::uint32_t, + pub f_bsize: ::uint32_t, + pub f_iosize: ::uint32_t, + pub f_blocks: ::uint64_t, + pub f_bfree: ::uint64_t, + pub f_bavail: ::int64_t, + pub f_files: ::uint64_t, + pub f_ffree: ::uint64_t, + pub f_favail: ::int64_t, + pub f_syncwrites: ::uint64_t, + pub f_syncreads: ::uint64_t, + pub f_asyncwrites: ::uint64_t, + pub f_asyncreads: ::uint64_t, + pub f_fsid: ::fsid_t, + pub f_namemax: ::uint32_t, + pub f_owner: ::uid_t, + pub f_ctime: ::uint64_t, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 90], + pub f_mntfromname: [::c_char; 90], + pub f_mntfromspec: [::c_char; 90], + pub mount_info: mount_info, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_syncwrites == other.f_syncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_ctime == other.f_ctime + && self.f_fstypename + .iter() + .zip(other.f_fstypename.iter()) + .all(|(a,b)| a == b) + && self.f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromspec + .iter() + .zip(other.f_mntfromspec.iter()) + .all(|(a,b)| a == b) + && self.mount_info == other.mount_info + } + } + + impl Eq for statfs { } + + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_flags", &self.f_flags) + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_ctime", &self.f_ctime) + // FIXME: .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + // FIXME: .field("f_mntfromspec", &self.f_mntfromspec) + .field("mount_info", &self.mount_info) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_syncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_ctime.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_mntfromspec.hash(state); + self.mount_info.hash(state); + } + } + } + } + } +} + //https://github.com/openbsd/src/blob/master/sys/sys/mount.h pub const ISOFSMNT_NORRIP: ::c_int = 0x1; // disable Rock Ridge Ext pub const ISOFSMNT_GENS: ::c_int = 0x2; // enable generation numbers @@ -246,10 +403,61 @@ pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast +pub const PTHREAD_STACK_MIN : ::size_t = 4096; pub const SIGSTKSZ : ::size_t = 28672; pub const PT_FIRSTMACH: ::c_int = 32; +fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + pub fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } +} + extern { pub fn accept4(s: ::c_int, addr: *mut ::sockaddr, addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int; @@ -260,14 +468,20 @@ pub fn strtonum(nptr: *const ::c_char, minval: ::c_longlong, maxval: ::c_longlong, errstr: *mut *const ::c_char) -> ::c_longlong; - - pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; - pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; - pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; } cfg_if! { + if #[cfg(libc_union)] { + extern { + // these functions use statfs which uses the union mount_info: + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + } + } +} + +cfg_if! { if #[cfg(target_arch = "x86")] { mod x86; pub use self::x86::*; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - use PT_FIRSTMACH; pub type c_long = i64; @@ -7,8 +5,15 @@ pub type c_char = i8; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; diff -Nru cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs --- cargo-0.33.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,9 +1,14 @@ -use dox::mem; - pub type c_long = i32; pub type c_ulong = u32; pub type c_char = i8; // should be pub(crate), but that requires Rust 1.18.0 -#[doc(hidden)] -pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1; +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/haiku/mod.rs cargo-0.35.0/vendor/libc/src/unix/haiku/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/haiku/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/haiku/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::{mem, Option}; - pub type rlim_t = ::uintptr_t; pub type sa_family_t = u8; pub type pthread_key_t = ::c_int; @@ -31,9 +29,23 @@ pub type id_t = i32; pub type idtype_t = ::c_uint; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct sockaddr { pub sa_len: u8, pub sa_family: sa_family_t, @@ -57,20 +69,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_len: u8, - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 126] - } - - pub struct sockaddr_storage { - pub ss_len: u8, - pub ss_family: sa_family_t, - __ss_pad1: [u8; 6], - __ss_pad2: u64, - __ss_pad3: [u8; 112], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -199,15 +197,6 @@ pub st_blocks: blkcnt_t, } - pub struct dirent { - pub d_dev: dev_t, - pub d_pdev: dev_t, - pub d_ino: ino_t, - pub d_pino: i64, - pub d_reclen: ::c_ushort, - pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX - } - pub struct glob_t { pub gl_pathc: ::size_t, __unused1: ::size_t, @@ -319,6 +308,139 @@ } } +s_no_extra_traits! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 126] + } + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: u64, + __ss_pad3: [u8; 112], + } + pub struct dirent { + pub d_dev: dev_t, + pub d_pdev: dev_t, + pub d_ino: ino_t, + pub d_pino: i64, + pub d_reclen: ::c_ushort, + pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_len == other.sun_len + && self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_len", &self.sun_len) + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_len.hash(state); + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_dev == other.d_dev + && self.d_pdev == other.d_pdev + && self.d_ino == other.d_ino + && self.d_pino == other.d_pino + && self.d_reclen == other.d_reclen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_dev", &self.d_dev) + .field("d_pdev", &self.d_pdev) + .field("d_ino", &self.d_ino) + .field("d_pino", &self.d_pino) + .field("d_reclen", &self.d_reclen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_dev.hash(state); + self.d_pdev.hash(state); + self.d_ino.hash(state); + self.d_pino.hash(state); + self.d_reclen.hash(state); + self.d_name.hash(state); + } + } + } +} + // intentionally not public, only used for fd_set cfg_if! { if #[cfg(target_pointer_width = "32")] { @@ -1028,20 +1150,20 @@ f! { pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] &= !(1 << (fd % size)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] |= 1 << (fd % size); return } @@ -1096,6 +1218,12 @@ #[link(name = "bsd")] extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + pub fn clock_gettime(clk_id: ::c_int, tp: *mut ::timespec) -> ::c_int; pub fn clock_settime(clk_id: ::c_int, tp: *const ::timespec) -> ::c_int; pub fn pthread_create(thread: *mut ::pthread_t, @@ -1132,7 +1260,7 @@ pub fn glob(pattern: *const ::c_char, flags: ::c_int, - errfunc: Option ::c_int>, pglob: *mut ::glob_t) -> ::c_int; pub fn globfree(pglob: *mut ::glob_t); @@ -1178,7 +1306,7 @@ pub fn execvpe(file: *const ::c_char, argv: *const *const ::c_char, environment: *const *const ::c_char) -> ::c_int; #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -1224,9 +1352,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "popen$UNIX2003")] diff -Nru cargo-0.33.0/vendor/libc/src/unix/hermit/mod.rs cargo-0.35.0/vendor/libc/src/unix/hermit/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/hermit/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/hermit/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -19,8 +19,6 @@ pub type c_long = i64; pub type c_ulong = u64; -pub type uid_t = u16; -pub type gid_t = u16; pub type speed_t = ::c_uint; pub type mode_t = u32; pub type dev_t = i16; @@ -49,7 +47,336 @@ pub type pthread_rwlock_t = usize; pub type pthread_rwlockattr_t = usize; +s_no_extra_traits! { + pub struct dirent { + pub d_ino: ::c_long, + pub d_off: off_t, + pub d_reclen: u16, + pub d_name: [::c_char; 256], + } + + // Dummy + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108], + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_len: u8, + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8], + } + + pub struct fd_set { + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct sockaddr_storage { + pub s2_len: u8, + pub ss_family: sa_family_t, + pub s2_data1: [::c_char; 2], + pub s2_data2: [u32; 3], + pub s2_data3: [u32; 3], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_atime: time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_spare4: [::c_long; 2], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr { + fn eq(&self, other: &sockaddr) -> bool { + self.sa_len == other.sa_len + && self.sa_family == other.sa_family + && self + .sa_data + .iter() + .zip(other.sa_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr {} + impl ::fmt::Debug for sockaddr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr") + .field("sa_len", &self.sa_len) + .field("sa_family", &self.sa_family) + // FIXME: .field("sa_data", &self.sa_data) + .finish() + } + } + impl ::hash::Hash for sockaddr { + fn hash(&self, state: &mut H) { + self.sa_len.hash(state); + self.sa_family.hash(state); + self.sa_data.hash(state); + } + } + + impl PartialEq for sockaddr_in { + fn eq(&self, other: &sockaddr_in) -> bool { + self.sin_len == other.sin_len + && self.sin_family == other.sin_family + && self.sin_port == other.sin_port + && self.sin_addr == other.sin_addr + && self + .sin_zero + .iter() + .zip(other.sin_zero.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_in {} + impl ::fmt::Debug for sockaddr_in { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_in") + .field("sin_len", &self.sin_len) + .field("sin_family", &self.sin_family) + .field("sin_port", &self.sin_port) + .field("sin_addr", &self.sin_addr) + // FIXME: .field("sin_zero", &self.sin_zero) + .finish() + } + } + impl ::hash::Hash for sockaddr_in { + fn hash(&self, state: &mut H) { + self.sin_len.hash(state); + self.sin_family.hash(state); + self.sin_port.hash(state); + self.sin_addr.hash(state); + self.sin_zero.hash(state); + } + } + + impl PartialEq for fd_set { + fn eq(&self, other: &fd_set) -> bool { + self.fds_bits + .iter() + .zip(other.fds_bits.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for fd_set {} + impl ::fmt::Debug for fd_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fd_set") + // FIXME: .field("fds_bits", &self.fds_bits) + .finish() + } + } + impl ::hash::Hash for fd_set { + fn hash(&self, state: &mut H) { + self.fds_bits.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.s2_len == other.s2_len + && self.ss_family == other.ss_family + && self.s2_data1 + .iter() + .zip(other.s2_data1.iter()) + .all(|(a,b)| a == b) + && self.s2_data2 + .iter() + .zip(other.s2_data2.iter()) + .all(|(a,b)| a == b) + && self.s2_data3 + .iter() + .zip(other.s2_data3.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("s2_len", &self.s2_len) + .field("ss_family", &self.ss_family) + // FIXME: .field("s2_data1", &self.s2_data1) + // FIXME: .field("s2_data2", &self.s2_data2) + // FIXME: .field("s2_data3", &self.s2_data3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.s2_len.hash(state); + self.ss_family.hash(state); + self.s2_data1.hash(state); + self.s2_data2.hash(state); + self.s2_data3.hash(state); + } + } + + impl PartialEq for stat { + fn eq(&self, other: &stat) -> bool { + self.st_dev == other.st_dev + && self.st_ino == other.st_ino + && self.st_mode == other.st_mode + && self.st_nlink == other.st_nlink + && self.st_uid == other.st_uid + && self.st_gid == other.st_gid + && self.st_rdev == other.st_rdev + && self.st_size == other.st_size + && self.st_atime == other.st_atime + && self.st_atime_nsec == other.st_atime_nsec + && self.st_mtime == other.st_mtime + && self.st_mtime_nsec == other.st_mtime_nsec + && self.st_ctime == other.st_ctime + && self.st_ctime_nsec == other.st_ctime_nsec + && self.st_blksize == other.st_blksize + && self.st_blocks == other.st_blocks + && self + .st_spare4 + .iter() + .zip(other.st_spare4.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for stat {} + impl ::fmt::Debug for stat { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("stat") + .field("st_dev", &self.st_dev) + .field("st_ino", &self.st_ino) + .field("st_mode", &self.st_mode) + .field("st_nlink", &self.st_nlink) + .field("st_uid", &self.st_uid) + .field("st_gid", &self.st_gid) + .field("st_rdev", &self.st_rdev) + .field("st_size", &self.st_size) + .field("st_atime", &self.st_atime) + .field("st_atime_nsec", &self.st_atime_nsec) + .field("st_mtime", &self.st_mtime) + .field("st_mtime_nsec", &self.st_mtime_nsec) + .field("st_ctime", &self.st_ctime) + .field("st_ctime_nsec", &self.st_ctime_nsec) + .field("st_blksize", &self.st_blksize) + .field("st_blocks", &self.st_blocks) + // FIXME: .field("st_spare4", &self.st_spare4) + .finish() + } + } + impl ::hash::Hash for stat { + fn hash(&self, state: &mut H) { + self.st_dev.hash(state); + self.st_ino.hash(state); + self.st_mode.hash(state); + self.st_nlink.hash(state); + self.st_uid.hash(state); + self.st_gid.hash(state); + self.st_rdev.hash(state); + self.st_size.hash(state); + self.st_atime.hash(state); + self.st_atime_nsec.hash(state); + self.st_mtime.hash(state); + self.st_mtime_nsec.hash(state); + self.st_ctime.hash(state); + self.st_ctime_nsec.hash(state); + self.st_blksize.hash(state); + self.st_blocks.hash(state); + self.st_spare4.hash(state); + } + } + } +} + s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -61,19 +388,8 @@ pub ai_next: *mut addrinfo, } - pub struct dirent { - pub d_ino: ::c_long, - pub d_off: off_t, - pub d_reclen: u16, - pub d_name: [::c_char; 256], - } - pub struct Dl_info {} - pub struct fd_set { - fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -132,20 +448,6 @@ pub sa_handler: usize, } - pub struct sockaddr { - pub sa_len: u8, - pub sa_family: sa_family_t, - pub sa_data: [::c_char; 14], - } - - pub struct sockaddr_in { - pub sin_len: u8, - pub sin_family: sa_family_t, - pub sin_port: ::in_port_t, - pub sin_addr: ::in_addr, - pub sin_zero: [::c_char; 8], - } - pub struct sockaddr_in6 { pub sin6_len: u8, pub sin6_family: sa_family_t, @@ -155,40 +457,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_storage { - pub s2_len: u8, - pub ss_family: sa_family_t, - pub s2_data1: [::c_char; 2], - pub s2_data2: [u32; 3], - pub s2_data3: [u32; 3], - } - - // Dummy - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108], - } - - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: dev_t, - pub st_size: off_t, - pub st_atime: time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: blksize_t, - pub st_blocks: blkcnt_t, - pub st_spare4: [::c_long; 2], - } - pub struct statvfs {} pub struct tm { @@ -696,6 +964,12 @@ } extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; pub fn atof(s: *const ::c_char) -> ::c_double; pub fn labs(i: ::c_long) -> ::c_long; diff -Nru cargo-0.33.0/vendor/libc/src/unix/mod.rs cargo-0.35.0/vendor/libc/src/unix/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,8 +3,6 @@ //! More functions and definitions can be found in the more specific modules //! according to the platform in question. -use dox::Option; - pub type int8_t = i8; pub type int16_t = i16; pub type int32_t = i32; @@ -41,8 +39,18 @@ pub type sighandler_t = ::size_t; pub type cc_t = ::c_uchar; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum locale_t {} +impl ::Copy for locale_t {} +impl ::Clone for locale_t { + fn clone(&self) -> locale_t { *self } +} s! { pub struct group { @@ -127,23 +135,6 @@ __reserved: [c_long; 16], } - #[cfg_attr(target_os = "netbsd", repr(packed))] - pub struct in_addr { - pub s_addr: in_addr_t, - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct in6_addr { - pub s6_addr: [u8; 16], - #[cfg(not(feature = "align"))] - __align: [u32; 0], - } - - pub struct ip_mreq { - pub imr_multiaddr: in_addr, - pub imr_interface: in_addr, - } - pub struct ipv6_mreq { pub ipv6mr_multiaddr: in6_addr, #[cfg(target_os = "android")] @@ -310,9 +301,7 @@ pub const ATF_USETRAILERS: ::c_int = 0x10; cfg_if! { - if #[cfg(cross_platform_docs)] { - // on dox builds don't pull in anything - } else if #[cfg(target_os = "l4re")] { + if #[cfg(target_os = "l4re")] { // required libraries for L4Re are linked externally, ATM } else if #[cfg(feature = "use_std")] { // cargo build, don't pull in anything extra as the libstd dep @@ -356,6 +345,10 @@ // to "pthread" needs to be added. #[link(name = "pthread")] extern {} + } else if #[cfg(target_env = "illumos")] { + #[link(name = "c")] + #[link(name = "m")] + extern {} } else { #[link(name = "c")] #[link(name = "m")] @@ -365,8 +358,18 @@ } } +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos_t {} // TODO: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { *self } +} extern { pub fn isalnum(c: c_int) -> c_int; @@ -516,13 +519,16 @@ pub fn putchar_unlocked(c: ::c_int) -> ::c_int; #[cfg_attr(target_os = "netbsd", link_name = "__socket30")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")] pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "connect$UNIX2003")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_connect")] pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "listen$UNIX2003")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_listen")] pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "accept$UNIX2003")] @@ -541,10 +547,12 @@ option_len: socklen_t) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "socketpair$UNIX2003")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_socketpair")] pub fn socketpair(domain: ::c_int, type_: ::c_int, protocol: ::c_int, socket_vector: *mut ::c_int) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "sendto$UNIX2003")] + #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendto")] pub fn sendto(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int, addr: *const sockaddr, addrlen: socklen_t) -> ::ssize_t; @@ -604,8 +612,13 @@ pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; #[cfg_attr(target_os = "macos", link_name = "readdir_r$INODE64")] #[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")] - #[cfg_attr(target_os = "solaris", link_name = "__posix_readdir_r")] #[cfg_attr(target_os = "freebsd", link_name = "readdir_r@FBSD_1.0")] + /// The 64-bit libc on Solaris and illumos only has readdir_r. If a + /// 32-bit Solaris or illumos target is ever created, it should use + /// __posix_readdir_r. See libc(3LIB) on Solaris or illumos: + /// https://illumos.org/man/3lib/libc + /// https://docs.oracle.com/cd/E36784_01/html/E36873/libc-3lib.html + /// https://www.unix.com/man-page/opensolaris/3LIB/libc/ pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), @@ -845,7 +858,7 @@ #[cfg_attr(target_os = "netbsd", link_name = "__libc_thr_yield")] pub fn sched_yield() -> ::c_int; pub fn pthread_key_create(key: *mut pthread_key_t, - dtor: Option) + dtor: ::Option) -> ::c_int; pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; @@ -913,6 +926,7 @@ pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + #[cfg_attr(target_os = "illumos", link_name = "__xnet_getsockopt")] pub fn getsockopt(sockfd: ::c_int, level: ::c_int, optname: ::c_int, @@ -1011,16 +1025,11 @@ locale: *const ::c_char) -> *mut ::c_char; pub fn localeconv() -> *mut lconv; - pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "sem_wait$UNIX2003")] pub fn sem_wait(sem: *mut sem_t) -> ::c_int; pub fn sem_trywait(sem: *mut sem_t) -> ::c_int; pub fn sem_post(sem: *mut sem_t) -> ::c_int; - pub fn sem_init(sem: *mut sem_t, - pshared: ::c_int, - value: ::c_uint) - -> ::c_int; pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; @@ -1077,10 +1086,8 @@ pub fn tcdrain(fd: ::c_int) -> ::c_int; pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t; pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t; - pub fn cfmakeraw(termios: *mut ::termios); pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; - pub fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int; pub fn tcsetattr(fd: ::c_int, optional_actions: ::c_int, @@ -1114,6 +1121,16 @@ } cfg_if! { + if #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] { + extern { + pub fn cfmakeraw(termios: *mut ::termios); + pub fn cfsetspeed(termios: *mut ::termios, + speed: ::speed_t) -> ::c_int; + } + } +} + +cfg_if! { if #[cfg(target_env = "uclibc")] { mod uclibc; pub use self::uclibc::*; @@ -1134,9 +1151,10 @@ target_os = "bitrig"))] { mod bsd; pub use self::bsd::*; - } else if #[cfg(target_os = "solaris")] { - mod solaris; - pub use self::solaris::*; + } else if #[cfg(any(target_os = "solaris", + target_os = "illumos"))] { + mod solarish; + pub use self::solarish::*; } else if #[cfg(target_os = "haiku")] { mod haiku; pub use self::haiku::*; @@ -1149,13 +1167,15 @@ } cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] @@ -1165,3 +1185,13 @@ } } } + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/newlib/align.rs cargo-0.35.0/vendor/libc/src/unix/newlib/align.rs --- cargo-0.33.0/vendor/libc/src/unix/newlib/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/newlib/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,61 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_mutex_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_rwlock_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(8))] + pub struct pthread_cond_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/newlib/mod.rs cargo-0.35.0/vendor/libc/src/unix/newlib/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/newlib/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/newlib/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - pub type blkcnt_t = i32; pub type blksize_t = i32; pub type clock_t = i32; @@ -238,103 +236,10 @@ __size: [u64; 7] } - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_mutex_t { // Unverified - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_rwlock_t { // Unverified - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))), - repr(align(8)))] - pub struct pthread_mutexattr_t { // Unverified - #[cfg(all(not(feature = "align"), - any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")))] - __align: [::c_int; 0], - #[cfg(all(not(feature = "align"), - not(any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - pub struct pthread_rwlockattr_t { // Unverified __lockkind: ::c_int, __pshared: ::c_int, } - - #[cfg_attr(feature = "align", repr(align(8)))] - pub struct pthread_cond_t { // Unverified - #[cfg(not(feature = "align"))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { // Unverified - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - } // unverified constants @@ -586,10 +491,6 @@ pub const IFF_ALTPHYS: ::c_int = IFF_LINK2; // use alternate physical connection pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast -pub const IPPROTO_IP: ::c_int = 0; -pub const IPPROTO_UDP: ::c_int = 17; -pub const IPPROTO_TCP: ::c_int = 6; - pub const TCP_NODELAY: ::c_int = 8193; pub const TCP_MAXSEG: ::c_int = 8194; @@ -627,20 +528,20 @@ f! { pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; let fd = fd as usize; (*set).fds_bits[fd / bits] |= 1 << (fd % bits); return @@ -654,6 +555,12 @@ } extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; pub fn atof(s: *const ::c_char) -> ::c_double; pub fn labs(i: ::c_long) -> ::c_long; @@ -674,7 +581,7 @@ envp: *const *const ::c_char) -> ::c_int; #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -720,9 +627,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; #[cfg_attr(all(target_os = "macos", target_arch = "x86"), link_name = "popen$UNIX2003")] @@ -744,3 +651,14 @@ pub use target_arch_not_implemented; } } + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff -Nru cargo-0.33.0/vendor/libc/src/unix/newlib/no_align.rs cargo-0.35.0/vendor/libc/src/unix/newlib/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/newlib/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/newlib/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,51 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { // Unverified + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { // Unverified + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { // Unverified + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/no_align.rs cargo-0.35.0/vendor/libc/src/unix/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,6 @@ +s! { + pub struct in6_addr { + pub s6_addr: [u8; 16], + __align: [u32; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/android/b32/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/android/b32/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/android/b32/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/android/b32/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,7 +14,7 @@ pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, pub sa_flags: ::c_ulong, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct rlimit64 { diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/android/b64/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/android/b64/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/android/b64/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/android/b64/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -16,7 +16,7 @@ pub sa_flags: ::c_uint, pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct rlimit64 { @@ -34,25 +34,6 @@ __reserved: [::c_char; 16], } - pub struct pthread_mutex_t { - value: ::c_int, - __reserved: [::c_char; 36], - } - - pub struct pthread_cond_t { - value: ::c_int, - __reserved: [::c_char; 44], - } - - pub struct pthread_rwlock_t { - numLocks: ::c_int, - writerThreadId: ::c_int, - pendingReaders: ::c_int, - pendingWriters: ::c_int, - attr: i32, - __reserved: [::c_char; 36], - } - pub struct passwd { pub pw_name: *mut ::c_char, pub pw_passwd: *mut ::c_char, @@ -126,6 +107,130 @@ } } +s_no_extra_traits!{ + pub struct pthread_mutex_t { + value: ::c_int, + __reserved: [::c_char; 36], + } + + pub struct pthread_cond_t { + value: ::c_int, + __reserved: [::c_char; 44], + } + + pub struct pthread_rwlock_t { + numLocks: ::c_int, + writerThreadId: ::c_int, + pendingReaders: ::c_int, + pendingWriters: ::c_int, + attr: i32, + __reserved: [::c_char; 36], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.numLocks == other.numLocks + && self.writerThreadId == other.writerThreadId + && self.pendingReaders == other.pendingReaders + && self.pendingWriters == other.pendingWriters + && self.attr == other.attr + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("numLocks", &self.numLocks) + .field("writerThreadId", &self.writerThreadId) + .field("pendingReaders", &self.pendingReaders) + .field("pendingWriters", &self.pendingWriters) + .field("attr", &self.attr) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.numLocks.hash(state); + self.writerThreadId.hash(state); + self.pendingReaders.hash(state); + self.pendingWriters.hash(state); + self.attr.hash(state); + self.__reserved.hash(state); + } + } + } +} + pub const RTLD_GLOBAL: ::c_int = 0x00100; pub const RTLD_NOW: ::c_int = 2; pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/android/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/android/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/android/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/android/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,5 @@ //! Android-specific definitions for linux-like values -use dox::{mem, Option}; - pub type clock_t = ::c_long; pub type time_t = ::c_long; pub type suseconds_t = ::c_long; @@ -25,36 +23,12 @@ pub type loff_t = ::c_longlong; s! { - pub struct dirent { - pub d_ino: u64, - pub d_off: i64, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: u64, - pub d_off: i64, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - pub struct stack_t { pub ss_sp: *mut ::c_void, pub ss_flags: ::c_int, pub ss_size: ::size_t } - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_errno: ::c_int, - pub si_code: ::c_int, - pub _pad: [::c_int; 29], - _align: [usize; 0], - } - pub struct __fsid_t { __val: [::c_int; 2], } @@ -116,33 +90,11 @@ __reserved: [::c_int; 3], } - pub struct lastlog { - ll_time: ::time_t, - ll_line: [::c_char; UT_LINESIZE], - ll_host: [::c_char; UT_HOSTSIZE], - } - pub struct exit_status { pub e_termination: ::c_short, pub e_exit: ::c_short, } - pub struct utmp { - pub ut_type: ::c_short, - pub ut_pid: ::pid_t, - pub ut_line: [::c_char; UT_LINESIZE], - pub ut_id: [::c_char; 4], - - pub ut_user: [::c_char; UT_NAMESIZE], - pub ut_host: [::c_char; UT_HOSTSIZE], - pub ut_exit: exit_status, - pub ut_session: ::c_long, - pub ut_tv: ::timeval, - - pub ut_addr_v6: [::int32_t; 4], - unused: [::c_char; 20], - } - pub struct statvfs { pub f_bsize: ::c_ulong, pub f_frsize: ::c_ulong, @@ -238,6 +190,361 @@ pub ipi6_addr: ::in6_addr, pub ipi6_ifindex: ::c_int, } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: ::uint32_t, + pub cookie: ::uint32_t, + pub len: ::uint32_t + } +} + +s_no_extra_traits!{ + pub struct dirent { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_exit: exit_status, + pub ut_session: ::c_long, + pub ut_tv: ::timeval, + pub ut_addr_v6: [::int32_t; 4], + unused: [::c_char; 20], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct af_alg_iv { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_errno == other.si_errno + && self.si_code == other.si_code + // Ignore _pad + // Ignore _align + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_errno", &self.si_errno) + .field("si_code", &self.si_code) + // Ignore _pad + // Ignore _align + .finish() + } + } + + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_errno.hash(state); + self.si_code.hash(state); + // Ignore _pad + // Ignore _align + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self + .ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.unused == other.unused + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("unused", &self.unused) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.unused.hash(state); + } + } + + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + impl Eq for af_alg_iv {} + + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("iv", &self.as_slice()) + .finish() + } + } + + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + } } pub const O_TRUNC: ::c_int = 512; @@ -1052,6 +1359,15 @@ pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; pub const SO_ORIGINAL_DST: ::c_int = 80; +pub const IP_ORIGDSTADDR : ::c_int = 20; +pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR; +pub const IPV6_ORIGDSTADDR : ::c_int = 74; +pub const IPV6_RECVORIGDSTADDR : ::c_int = IPV6_ORIGDSTADDR; +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; pub const IUTF8: ::tcflag_t = 0x00004000; pub const CMSPAR: ::tcflag_t = 0o10000000000; pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; @@ -1476,7 +1792,68 @@ // Similarity to Linux it's not used but defined for compatibility. pub const ENOATTR: ::c_int = ::ENODATA; +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; + +pub const ALG_OP_DECRYPT: ::c_int = 0; +pub const ALG_OP_ENCRYPT: ::c_int = 1; + +// uapi/linux/inotify.h +pub const IN_ACCESS: ::uint32_t = 0x0000_0001; +pub const IN_MODIFY: ::uint32_t = 0x0000_0002; +pub const IN_ATTRIB: ::uint32_t = 0x0000_0004; +pub const IN_CLOSE_WRITE: ::uint32_t = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: ::uint32_t = 0x0000_0010; +pub const IN_CLOSE: ::uint32_t = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE); +pub const IN_OPEN: ::uint32_t = 0x0000_0020; +pub const IN_MOVED_FROM: ::uint32_t = 0x0000_0040; +pub const IN_MOVED_TO: ::uint32_t = 0x0000_0080; +pub const IN_MOVE: ::uint32_t = (IN_MOVED_FROM | IN_MOVED_TO); +pub const IN_CREATE: ::uint32_t = 0x0000_0100; +pub const IN_DELETE: ::uint32_t = 0x0000_0200; +pub const IN_DELETE_SELF: ::uint32_t = 0x0000_0400; +pub const IN_MOVE_SELF: ::uint32_t = 0x0000_0800; +pub const IN_UNMOUNT: ::uint32_t = 0x0000_2000; +pub const IN_Q_OVERFLOW: ::uint32_t = 0x0000_4000; +pub const IN_IGNORED: ::uint32_t = 0x0000_8000; +pub const IN_ONLYDIR: ::uint32_t = 0x0100_0000; +pub const IN_DONT_FOLLOW: ::uint32_t = 0x0200_0000; +// pub const IN_EXCL_UNLINK: ::uint32_t = 0x0400_0000; + +// pub const IN_MASK_CREATE: ::uint32_t = 0x1000_0000; +// pub const IN_MASK_ADD: ::uint32_t = 0x2000_0000; +pub const IN_ISDIR: ::uint32_t = 0x4000_0000; +pub const IN_ONESHOT: ::uint32_t = 0x8000_0000; + +pub const IN_ALL_EVENTS: ::uint32_t = ( + IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | + IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | + IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | + IN_MOVE_SELF +); + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { for slot in cpuset.__bits.iter_mut() { *slot = 0; @@ -1484,21 +1861,21 @@ } pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]); + let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); cpuset.__bits[idx] |= 1 << offset; () } pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]); + let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); cpuset.__bits[idx] &= !(1 << offset); () } pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { - let size_in___bits = 8 * mem::size_of_val(&cpuset.__bits[0]); + let size_in___bits = 8 * ::mem::size_of_val(&cpuset.__bits[0]); let (idx, offset) = (cpu / size_in___bits, cpu % size_in___bits); 0 != (cpuset.__bits[idx] & (1 << offset)) } @@ -1654,7 +2031,7 @@ pub fn setfsuid(uid: ::uid_t) -> ::c_int; pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -1700,9 +2077,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; pub fn getgrouplist(user: *const ::c_char, group: ::gid_t, @@ -1722,6 +2099,16 @@ f: extern fn(*mut ::c_void) -> *mut ::c_void, value: *mut ::c_void) -> ::c_int; pub fn __errno() -> *mut ::c_int; + pub fn inotify_rm_watch(fd: ::c_int, wd: ::uint32_t) -> ::c_int; + pub fn sendmmsg(sockfd: ::c_int, msgvec: *const ::mmsghdr, vlen: ::c_uint, + flags: ::c_int) -> ::c_int; + pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, + flags: ::c_int, timeout: *const ::timespec) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, + path: *const ::c_char, + mask: ::uint32_t) -> ::c_int; } cfg_if! { diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,66 @@ +macro_rules! expand_align { + () => { + s! { + #[repr(align(4))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(4))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[repr(align(4))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1802 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type useconds_t = u32; +pub type dev_t = u32; +pub type socklen_t = u32; +pub type pthread_t = c_ulong; +pub type mode_t = u32; +pub type ino64_t = u32; +pub type off64_t = i32; +pub type blkcnt64_t = i32; +pub type rlim64_t = u64; +pub type shmatt_t = ::c_ulong; +pub type mqd_t = ::c_int; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = i32; + +pub type clock_t = c_long; +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u32; +pub type off_t = i32; +pub type blkcnt_t = i32; + +pub type blksize_t = c_long; +pub type fsblkcnt_t = u32; +pub type fsfilcnt_t = u32; +pub type rlim_t = ::c_ulonglong; +pub type c_long = i32; +pub type c_ulong = u32; +pub type nlink_t = u32; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // TODO: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { *self } +} + +s! { + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct dqblk { + pub dqb_bhardlimit: ::uint64_t, + pub dqb_bsoftlimit: ::uint64_t, + pub dqb_curspace: ::uint64_t, + pub dqb_ihardlimit: ::uint64_t, + pub dqb_isoftlimit: ::uint64_t, + pub dqb_curinodes: ::uint64_t, + pub dqb_btime: ::uint64_t, + pub dqb_itime: ::uint64_t, + pub dqb_valid: ::uint32_t, + } + + pub struct signalfd_siginfo { + pub ssi_signo: ::uint32_t, + pub ssi_errno: ::int32_t, + pub ssi_code: ::int32_t, + pub ssi_pid: ::uint32_t, + pub ssi_uid: ::uint32_t, + pub ssi_fd: ::int32_t, + pub ssi_tid: ::uint32_t, + pub ssi_band: ::uint32_t, + pub ssi_overrun: ::uint32_t, + pub ssi_trapno: ::uint32_t, + pub ssi_status: ::int32_t, + pub ssi_int: ::int32_t, + pub ssi_ptr: ::uint64_t, + pub ssi_utime: ::uint64_t, + pub ssi_stime: ::uint64_t, + pub ssi_addr: ::uint64_t, + pub ssi_addr_lsb: ::uint16_t, + _pad2: ::uint16_t, + pub ssi_syscall: ::int32_t, + pub ssi_call_addr: ::uint64_t, + pub ssi_arch: ::uint32_t, + _pad: [::uint8_t; 28], + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + pad: [::c_long; 4] + } + + pub struct cpu_set_t { + bits: [u32; 32], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + __dummy4: [::c_char; 24], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct ipc_perm { + pub __ipc_perm_key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct pthread_attr_t { + __size: [u32; 11] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 4], + } + pub struct stat { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_int, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_int, + pub msg_rtime: ::time_t, + __unused2: ::c_int, + pub msg_ctime: ::time_t, + __unused3: ::c_int, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u32, + pub f_bfree: u32, + pub f_bavail: u32, + pub f_files: u32, + pub f_ffree: u32, + pub f_favail: u32, + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent64 {} + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + } +} + +pub const ABDAY_1: ::nl_item = 0x20000; +pub const ABDAY_2: ::nl_item = 0x20001; +pub const ABDAY_3: ::nl_item = 0x20002; +pub const ABDAY_4: ::nl_item = 0x20003; +pub const ABDAY_5: ::nl_item = 0x20004; +pub const ABDAY_6: ::nl_item = 0x20005; +pub const ABDAY_7: ::nl_item = 0x20006; + +pub const DAY_1: ::nl_item = 0x20007; +pub const DAY_2: ::nl_item = 0x20008; +pub const DAY_3: ::nl_item = 0x20009; +pub const DAY_4: ::nl_item = 0x2000A; +pub const DAY_5: ::nl_item = 0x2000B; +pub const DAY_6: ::nl_item = 0x2000C; +pub const DAY_7: ::nl_item = 0x2000D; + +pub const ABMON_1: ::nl_item = 0x2000E; +pub const ABMON_2: ::nl_item = 0x2000F; +pub const ABMON_3: ::nl_item = 0x20010; +pub const ABMON_4: ::nl_item = 0x20011; +pub const ABMON_5: ::nl_item = 0x20012; +pub const ABMON_6: ::nl_item = 0x20013; +pub const ABMON_7: ::nl_item = 0x20014; +pub const ABMON_8: ::nl_item = 0x20015; +pub const ABMON_9: ::nl_item = 0x20016; +pub const ABMON_10: ::nl_item = 0x20017; +pub const ABMON_11: ::nl_item = 0x20018; +pub const ABMON_12: ::nl_item = 0x20019; + +pub const MON_1: ::nl_item = 0x2001A; +pub const MON_2: ::nl_item = 0x2001B; +pub const MON_3: ::nl_item = 0x2001C; +pub const MON_4: ::nl_item = 0x2001D; +pub const MON_5: ::nl_item = 0x2001E; +pub const MON_6: ::nl_item = 0x2001F; +pub const MON_7: ::nl_item = 0x20020; +pub const MON_8: ::nl_item = 0x20021; +pub const MON_9: ::nl_item = 0x20022; +pub const MON_10: ::nl_item = 0x20023; +pub const MON_11: ::nl_item = 0x20024; +pub const MON_12: ::nl_item = 0x20025; + +pub const AM_STR: ::nl_item = 0x20026; +pub const PM_STR: ::nl_item = 0x20027; + +pub const D_T_FMT: ::nl_item = 0x20028; +pub const D_FMT: ::nl_item = 0x20029; +pub const T_FMT: ::nl_item = 0x2002A; +pub const T_FMT_AMPM: ::nl_item = 0x2002B; + +pub const ERA: ::nl_item = 0x2002C; +pub const ERA_D_FMT: ::nl_item = 0x2002E; +pub const ALT_DIGITS: ::nl_item = 0x2002F; +pub const ERA_D_T_FMT: ::nl_item = 0x20030; +pub const ERA_T_FMT: ::nl_item = 0x20031; + +pub const CODESET: ::nl_item = 14; + +pub const CRNCYSTR: ::nl_item = 0x4000F; + +pub const RUSAGE_THREAD: ::c_int = 1; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const RADIXCHAR: ::nl_item = 0x10000; +pub const THOUSEP: ::nl_item = 0x10001; + +pub const YESEXPR: ::nl_item = 0x50000; +pub const NOEXPR: ::nl_item = 0x50001; +pub const YESSTR: ::nl_item = 0x50002; +pub const NOSTR: ::nl_item = 0x50003; + +pub const FILENAME_MAX: ::c_uint = 4096; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _SC_ARG_MAX: ::c_int = 0; +pub const _SC_CHILD_MAX: ::c_int = 1; +pub const _SC_CLK_TCK: ::c_int = 2; +pub const _SC_NGROUPS_MAX: ::c_int = 3; +pub const _SC_OPEN_MAX: ::c_int = 4; +pub const _SC_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; + +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; + +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +pub const TCP_MD5SIG: ::c_int = 14; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} + +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +#[doc(hidden)] +pub const AF_MAX: ::c_int = 42; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; +#[doc(hidden)] +pub const PF_MAX: ::c_int = AF_MAX; + +// System V IPC +pub const IPC_PRIVATE: ::key_t = 0; + +pub const IPC_CREAT: ::c_int = 0o1000; +pub const IPC_EXCL: ::c_int = 0o2000; +pub const IPC_NOWAIT: ::c_int = 0o4000; + +pub const IPC_RMID: ::c_int = 0; +pub const IPC_SET: ::c_int = 1; +pub const IPC_STAT: ::c_int = 2; +pub const IPC_INFO: ::c_int = 3; +pub const MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; +pub const MSG_COPY: ::c_int = 0o40000; + +pub const SHM_R: ::c_int = 0o400; +pub const SHM_W: ::c_int = 0o200; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; +pub const SHM_EXEC: ::c_int = 0o100000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +pub const SHM_HUGETLB: ::c_int = 0o4000; +pub const SHM_NORESERVE: ::c_int = 0o10000; + +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; + +pub const QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +pub const EAI_SYSTEM: ::c_int = -11; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +pub const PR_GET_TIMING: ::c_int = 13; +pub const PR_SET_TIMING: ::c_int = 14; +pub const PR_TIMING_STATISTICAL: ::c_int = 0; +pub const PR_TIMING_TIMESTAMP: ::c_int = 1; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +pub const PR_SET_MM_MAP: ::c_int = 14; +pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; + +pub const PR_SET_PTRACER: ::c_int = 0x59616d61; + +pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; +pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; +pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; +pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +// On Linux, libc doesn't define this constant, libattr does instead. +// We still define it for Linux as it's defined by libc on other platforms, +// and it's mentioned in the man pages for getxattr and setxattr. +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_EXEC: ::c_int = 0o10000000; +pub const O_SEARCH: ::c_int = 0o10000000; +pub const O_ACCMODE: ::c_int = 0o10000003; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POSIX_MADV_DONTNEED: ::c_int = 0; + +pub const RLIM_INFINITY: ::rlim_t = !0; +pub const RLIMIT_RTTIME: ::c_int = 15; +pub const RLIMIT_NLIMITS: ::c_int = 16; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; + +pub const SIGUNUSED: ::c_int = ::SIGSYS; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +pub const CPU_SETSIZE: ::c_int = 128; + +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +pub const PTRACE_POKEUSER: ::c_int = 6; +pub const PTRACE_CONT: ::c_int = 7; +pub const PTRACE_KILL: ::c_int = 8; +pub const PTRACE_SINGLESTEP: ::c_int = 9; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_SYSCALL: ::c_int = 24; +pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; +pub const PTRACE_GETREGSET: ::c_int = 0x4204; +pub const PTRACE_SETREGSET: ::c_int = 0x4205; +pub const PTRACE_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; + +pub const EPOLLWAKEUP: ::c_int = 0x20000000; + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; + +pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TIOCINQ: ::c_int = ::FIONREAD; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +// TODO(#247) Temporarily musl-specific (available since musl 0.9.12 / Linux +// kernel 3.10). See also notbsd/mod.rs +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; +pub const CLOCK_TAI: ::clockid_t = 11; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const CBAUD: ::tcflag_t = 0o0010017; +pub const TAB1: ::c_int = 0x00000800; +pub const TAB2: ::c_int = 0x00001000; +pub const TAB3: ::c_int = 0x00001800; +pub const CR1: ::c_int = 0x00000200; +pub const CR2: ::c_int = 0x00000400; +pub const CR3: ::c_int = 0x00000600; +pub const FF1: ::c_int = 0x00008000; +pub const BS1: ::c_int = 0x00002000; +pub const VT1: ::c_int = 0x00004000; +pub const VWERASE: usize = 14; +pub const VREPRINT: usize = 12; +pub const VSUSP: usize = 10; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VDISCARD: usize = 13; +pub const VTIME: usize = 5; +pub const IXON: ::tcflag_t = 0x00000400; +pub const IXOFF: ::tcflag_t = 0x00001000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x00000030; +pub const CS6: ::tcflag_t = 0x00000010; +pub const CS7: ::tcflag_t = 0x00000020; +pub const CS8: ::tcflag_t = 0x00000030; +pub const CSTOPB: ::tcflag_t = 0x00000040; +pub const CREAD: ::tcflag_t = 0x00000080; +pub const PARENB: ::tcflag_t = 0x00000100; +pub const PARODD: ::tcflag_t = 0x00000200; +pub const HUPCL: ::tcflag_t = 0x00000400; +pub const CLOCAL: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00000800; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const ECHOPRT: ::tcflag_t = 0x00000400; +pub const ECHOCTL: ::tcflag_t = 0x00000200; +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const PENDIN: ::tcflag_t = 0x00004000; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const VSWTC: usize = 7; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; + +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 28; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const FIOCLEX: ::c_int = 0x5451; +pub const FIONBIO: ::c_int = 0x5421; + +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_AS: ::c_int = 9; +pub const RLIMIT_NPROC: ::c_int = 6; +pub const RLIMIT_MEMLOCK: ::c_int = 8; + +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; + +pub const SOCK_NONBLOCK: ::c_int = 2048; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOL_SOCKET: ::c_int = 1; + +pub const EDEADLK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOSYS: ::c_int = 38; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +pub const EBADMSG: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ENOTCONN: ::c_int = 107; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const ECONNREFUSED: ::c_int = 111; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_LINGER: ::c_int = 13; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGBUS: ::c_int = 7; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_SETMASK: ::c_int = 2; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const TCGETS: ::c_int = 0x5401; +pub const TCSETS: ::c_int = 0x5402; +pub const TCSETSW: ::c_int = 0x5403; +pub const TCSETSF: ::c_int = 0x5404; +pub const TCGETA: ::c_int = 0x5405; +pub const TCSETA: ::c_int = 0x5406; +pub const TCSETAW: ::c_int = 0x5407; +pub const TCSETAF: ::c_int = 0x5408; +pub const TCSBRK: ::c_int = 0x5409; +pub const TCXONC: ::c_int = 0x540A; +pub const TCFLSH: ::c_int = 0x540B; +pub const TIOCGSOFTCAR: ::c_int = 0x5419; +pub const TIOCSSOFTCAR: ::c_int = 0x541A; +pub const TIOCLINUX: ::c_int = 0x541C; +pub const TIOCGSERIAL: ::c_int = 0x541E; +pub const TIOCEXCL: ::c_int = 0x540C; +pub const TIOCNXCL: ::c_int = 0x540D; +pub const TIOCSCTTY: ::c_int = 0x540E; +pub const TIOCGPGRP: ::c_int = 0x540F; +pub const TIOCSPGRP: ::c_int = 0x5410; +pub const TIOCOUTQ: ::c_int = 0x5411; +pub const TIOCSTI: ::c_int = 0x5412; +pub const TIOCGWINSZ: ::c_int = 0x5413; +pub const TIOCSWINSZ: ::c_int = 0x5414; +pub const TIOCMGET: ::c_int = 0x5415; +pub const TIOCMBIS: ::c_int = 0x5416; +pub const TIOCMBIC: ::c_int = 0x5417; +pub const TIOCMSET: ::c_int = 0x5418; +pub const FIONREAD: ::c_int = 0x541B; +pub const TIOCCONS: ::c_int = 0x541D; + +pub const SYS_gettid: ::c_long = 224; // Valid for arm (32-bit) and x86 (32-bit) + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; +pub const O_TMPFILE: ::c_int = 0x400000; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset); + () + } + + pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/kripken/emscripten/blob/ + // master/system/include/libc/sys/sysmacros.h + let mut major = 0; + major |= (dev & 0x00000fff) >> 8; + major |= (dev & 0xfffff000) >> 31 >> 1; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/kripken/emscripten/blob/ + // master/system/include/libc/sys/sysmacros.h + let mut minor = 0; + minor |= (dev & 0x000000ff) >> 0; + minor |= (dev & 0xffffff00) >> 12; + minor as ::c_uint + } + + pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + let major = major as ::dev_t; + let minor = minor as ::dev_t; + let mut dev = 0; + dev |= (major & 0x00000fff) << 8; + dev |= (major & 0xfffff000) << 31 << 1; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } +} + +extern { + pub fn abs(i: ::c_int) -> ::c_int; + pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, + mode: mode_t) -> ::c_int; + + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) + -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn fopen64(filename: *const c_char, + mode: *const c_char) -> *mut ::FILE; + pub fn freopen64(filename: *const c_char, mode: *const c_char, + file: *mut ::FILE) -> *mut ::FILE; + pub fn tmpfile64() -> *mut ::FILE; + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; + pub fn fseeko64(stream: *mut ::FILE, + offset: ::off64_t, + whence: ::c_int) -> ::c_int; + pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, + len: ::off_t) -> ::c_int; + pub fn pwritev(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t) -> ::ssize_t; + pub fn preadv(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t) -> ::ssize_t; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; + pub fn mkostemps(template: *mut ::c_char, + suffixlen: ::c_int, + flags: ::c_int) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn getnameinfo(sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + sevlen: ::socklen_t, + flags: ::c_int) -> ::c_int; + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + + // Not available now on Android + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, + mode: ::mode_t) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn mremap(addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ...) -> *mut ::c_void; + + pub fn glob(pattern: *const c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t) -> ::c_int; + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) + -> ::c_int; + + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) + -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, + flags: ::c_int, addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, + flags: ::c_int) -> ::c_int; + pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, + flags: ::c_int, timeout: *mut ::timespec) -> ::c_int; + pub fn sync(); + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; + pub fn pthread_create(native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/no_align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,63 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/emscripten.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/emscripten.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1681 +0,0 @@ -use dox::{mem, Option}; - -pub type c_char = i8; -pub type wchar_t = i32; -pub type useconds_t = u32; -pub type dev_t = u32; -pub type socklen_t = u32; -pub type pthread_t = c_ulong; -pub type mode_t = u32; -pub type ino64_t = u32; -pub type off64_t = i32; -pub type blkcnt64_t = i32; -pub type rlim64_t = u64; -pub type shmatt_t = ::c_ulong; -pub type mqd_t = ::c_int; -pub type msgqnum_t = ::c_ulong; -pub type msglen_t = ::c_ulong; -pub type nfds_t = ::c_ulong; -pub type nl_item = ::c_int; -pub type idtype_t = ::c_uint; -pub type loff_t = i32; - -pub type clock_t = c_long; -pub type time_t = c_long; -pub type suseconds_t = c_long; -pub type ino_t = u32; -pub type off_t = i32; -pub type blkcnt_t = i32; - -pub type blksize_t = c_long; -pub type fsblkcnt_t = u32; -pub type fsfilcnt_t = u32; -pub type rlim_t = ::c_ulonglong; -pub type c_long = i32; -pub type c_ulong = u32; -pub type nlink_t = u32; - -pub enum fpos64_t {} // TODO: fill this out with a struct - -s! { - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct rlimit64 { - pub rlim_cur: rlim64_t, - pub rlim_max: rlim64_t, - } - - pub struct glob_t { - pub gl_pathc: ::size_t, - pub gl_pathv: *mut *mut c_char, - pub gl_offs: ::size_t, - pub gl_flags: ::c_int, - - __unused1: *mut ::c_void, - __unused2: *mut ::c_void, - __unused3: *mut ::c_void, - __unused4: *mut ::c_void, - __unused5: *mut ::c_void, - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_mutex_t { - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_rwlock_t { - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_mutexattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_rwlockattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T], - } - - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct pthread_cond_t { - #[cfg(not(feature = "align"))] - __align: [*const ::c_void; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - - pub struct passwd { - pub pw_name: *mut ::c_char, - pub pw_passwd: *mut ::c_char, - pub pw_uid: ::uid_t, - pub pw_gid: ::gid_t, - pub pw_gecos: *mut ::c_char, - pub pw_dir: *mut ::c_char, - pub pw_shell: *mut ::c_char, - } - - pub struct spwd { - pub sp_namp: *mut ::c_char, - pub sp_pwdp: *mut ::c_char, - pub sp_lstchg: ::c_long, - pub sp_min: ::c_long, - pub sp_max: ::c_long, - pub sp_warn: ::c_long, - pub sp_inact: ::c_long, - pub sp_expire: ::c_long, - pub sp_flag: ::c_ulong, - } - - pub struct statvfs { - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_favail: ::fsfilcnt_t, - pub f_fsid: ::c_ulong, - __f_unused: ::c_int, - pub f_flag: ::c_ulong, - pub f_namemax: ::c_ulong, - __f_spare: [::c_int; 6], - } - - pub struct dqblk { - pub dqb_bhardlimit: ::uint64_t, - pub dqb_bsoftlimit: ::uint64_t, - pub dqb_curspace: ::uint64_t, - pub dqb_ihardlimit: ::uint64_t, - pub dqb_isoftlimit: ::uint64_t, - pub dqb_curinodes: ::uint64_t, - pub dqb_btime: ::uint64_t, - pub dqb_itime: ::uint64_t, - pub dqb_valid: ::uint32_t, - } - - pub struct signalfd_siginfo { - pub ssi_signo: ::uint32_t, - pub ssi_errno: ::int32_t, - pub ssi_code: ::int32_t, - pub ssi_pid: ::uint32_t, - pub ssi_uid: ::uint32_t, - pub ssi_fd: ::int32_t, - pub ssi_tid: ::uint32_t, - pub ssi_band: ::uint32_t, - pub ssi_overrun: ::uint32_t, - pub ssi_trapno: ::uint32_t, - pub ssi_status: ::int32_t, - pub ssi_int: ::int32_t, - pub ssi_ptr: ::uint64_t, - pub ssi_utime: ::uint64_t, - pub ssi_stime: ::uint64_t, - pub ssi_addr: ::uint64_t, - pub ssi_addr_lsb: ::uint16_t, - _pad2: ::uint16_t, - pub ssi_syscall: ::int32_t, - pub ssi_call_addr: ::uint64_t, - pub ssi_arch: ::uint32_t, - _pad: [::uint8_t; 28], - } - - pub struct fsid_t { - __val: [::c_int; 2], - } - - pub struct mq_attr { - pub mq_flags: ::c_long, - pub mq_maxmsg: ::c_long, - pub mq_msgsize: ::c_long, - pub mq_curmsgs: ::c_long, - pad: [::c_long; 4] - } - - pub struct cpu_set_t { - bits: [u32; 32], - } - - pub struct if_nameindex { - pub if_index: ::c_uint, - pub if_name: *mut ::c_char, - } - - // System V IPC - pub struct msginfo { - pub msgpool: ::c_int, - pub msgmap: ::c_int, - pub msgmax: ::c_int, - pub msgmnb: ::c_int, - pub msgmni: ::c_int, - pub msgssz: ::c_int, - pub msgtql: ::c_int, - pub msgseg: ::c_ushort, - } - - pub struct mmsghdr { - pub msg_hdr: ::msghdr, - pub msg_len: ::c_uint, - } - - pub struct sembuf { - pub sem_num: ::c_ushort, - pub sem_op: ::c_short, - pub sem_flg: ::c_short, - } - - pub struct aiocb { - pub aio_fildes: ::c_int, - pub aio_lio_opcode: ::c_int, - pub aio_reqprio: ::c_int, - pub aio_buf: *mut ::c_void, - pub aio_nbytes: ::size_t, - pub aio_sigevent: ::sigevent, - __td: *mut ::c_void, - __lock: [::c_int; 2], - __err: ::c_int, - __ret: ::ssize_t, - pub aio_offset: off_t, - __next: *mut ::c_void, - __prev: *mut ::c_void, - __dummy4: [::c_char; 24], - } - - pub struct sigaction { - pub sa_sigaction: ::sighandler_t, - pub sa_mask: ::sigset_t, - pub sa_flags: ::c_int, - pub sa_restorer: ::dox::Option, - } - - pub struct ipc_perm { - pub __ipc_perm_key: ::key_t, - pub uid: ::uid_t, - pub gid: ::gid_t, - pub cuid: ::uid_t, - pub cgid: ::gid_t, - pub mode: ::mode_t, - pub __seq: ::c_int, - __unused1: ::c_long, - __unused2: ::c_long - } - - pub struct termios { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_line: ::cc_t, - pub c_cc: [::cc_t; ::NCCS], - pub __c_ispeed: ::speed_t, - pub __c_ospeed: ::speed_t, - } - - pub struct flock { - pub l_type: ::c_short, - pub l_whence: ::c_short, - pub l_start: ::off_t, - pub l_len: ::off_t, - pub l_pid: ::pid_t, - } - - pub struct sysinfo { - pub uptime: ::c_ulong, - pub loads: [::c_ulong; 3], - pub totalram: ::c_ulong, - pub freeram: ::c_ulong, - pub sharedram: ::c_ulong, - pub bufferram: ::c_ulong, - pub totalswap: ::c_ulong, - pub freeswap: ::c_ulong, - pub procs: ::c_ushort, - pub pad: ::c_ushort, - pub totalhigh: ::c_ulong, - pub freehigh: ::c_ulong, - pub mem_unit: ::c_uint, - pub __reserved: [::c_char; 256], - } - - pub struct pthread_attr_t { - __size: [u32; 11] - } - - pub struct sigset_t { - __val: [::c_ulong; 32], - } - - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::c_int, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::socklen_t, - pub msg_flags: ::c_int, - } - - pub struct cmsghdr { - pub cmsg_len: ::socklen_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } - - pub struct sem_t { - __val: [::c_int; 4], - } - pub struct stat { - pub st_dev: ::dev_t, - __st_dev_padding: ::c_int, - __st_ino_truncated: ::c_long, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - __st_rdev_padding: ::c_int, - pub st_size: ::off_t, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_ino: ::ino_t, - } - - pub struct stat64 { - pub st_dev: ::dev_t, - __st_dev_padding: ::c_int, - __st_ino_truncated: ::c_long, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - __st_rdev_padding: ::c_int, - pub st_size: ::off_t, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_ino: ::ino_t, - } - - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_flags: ::c_int, - pub ss_size: ::size_t - } - - pub struct shmid_ds { - pub shm_perm: ::ipc_perm, - pub shm_segsz: ::size_t, - pub shm_atime: ::time_t, - __unused1: ::c_int, - pub shm_dtime: ::time_t, - __unused2: ::c_int, - pub shm_ctime: ::time_t, - __unused3: ::c_int, - pub shm_cpid: ::pid_t, - pub shm_lpid: ::pid_t, - pub shm_nattch: ::c_ulong, - __pad1: ::c_ulong, - __pad2: ::c_ulong, - } - - pub struct msqid_ds { - pub msg_perm: ::ipc_perm, - pub msg_stime: ::time_t, - __unused1: ::c_int, - pub msg_rtime: ::time_t, - __unused2: ::c_int, - pub msg_ctime: ::time_t, - __unused3: ::c_int, - __msg_cbytes: ::c_ulong, - pub msg_qnum: ::msgqnum_t, - pub msg_qbytes: ::msglen_t, - pub msg_lspid: ::pid_t, - pub msg_lrpid: ::pid_t, - __pad1: ::c_ulong, - __pad2: ::c_ulong, - } - - pub struct statfs { - pub f_type: ::c_ulong, - pub f_bsize: ::c_ulong, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_fsid: ::fsid_t, - pub f_namelen: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_flags: ::c_ulong, - pub f_spare: [::c_ulong; 4], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_errno: ::c_int, - pub si_code: ::c_int, - pub _pad: [::c_int; 29], - _align: [usize; 0], - } - - pub struct statfs64 { - pub f_type: ::c_ulong, - pub f_bsize: ::c_ulong, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_fsid: ::fsid_t, - pub f_namelen: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_flags: ::c_ulong, - pub f_spare: [::c_ulong; 4], - } - - pub struct statvfs64 { - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_blocks: u32, - pub f_bfree: u32, - pub f_bavail: u32, - pub f_files: u32, - pub f_ffree: u32, - pub f_favail: u32, - pub f_fsid: ::c_ulong, - __f_unused: ::c_int, - pub f_flag: ::c_ulong, - pub f_namemax: ::c_ulong, - __f_spare: [::c_int; 6], - } - - pub struct arpd_request { - pub req: ::c_ushort, - pub ip: u32, - pub dev: ::c_ulong, - pub stamp: ::c_ulong, - pub updated: ::c_ulong, - pub ha: [::c_uchar; ::MAX_ADDR_LEN], - } -} - -pub const ABDAY_1: ::nl_item = 0x20000; -pub const ABDAY_2: ::nl_item = 0x20001; -pub const ABDAY_3: ::nl_item = 0x20002; -pub const ABDAY_4: ::nl_item = 0x20003; -pub const ABDAY_5: ::nl_item = 0x20004; -pub const ABDAY_6: ::nl_item = 0x20005; -pub const ABDAY_7: ::nl_item = 0x20006; - -pub const DAY_1: ::nl_item = 0x20007; -pub const DAY_2: ::nl_item = 0x20008; -pub const DAY_3: ::nl_item = 0x20009; -pub const DAY_4: ::nl_item = 0x2000A; -pub const DAY_5: ::nl_item = 0x2000B; -pub const DAY_6: ::nl_item = 0x2000C; -pub const DAY_7: ::nl_item = 0x2000D; - -pub const ABMON_1: ::nl_item = 0x2000E; -pub const ABMON_2: ::nl_item = 0x2000F; -pub const ABMON_3: ::nl_item = 0x20010; -pub const ABMON_4: ::nl_item = 0x20011; -pub const ABMON_5: ::nl_item = 0x20012; -pub const ABMON_6: ::nl_item = 0x20013; -pub const ABMON_7: ::nl_item = 0x20014; -pub const ABMON_8: ::nl_item = 0x20015; -pub const ABMON_9: ::nl_item = 0x20016; -pub const ABMON_10: ::nl_item = 0x20017; -pub const ABMON_11: ::nl_item = 0x20018; -pub const ABMON_12: ::nl_item = 0x20019; - -pub const MON_1: ::nl_item = 0x2001A; -pub const MON_2: ::nl_item = 0x2001B; -pub const MON_3: ::nl_item = 0x2001C; -pub const MON_4: ::nl_item = 0x2001D; -pub const MON_5: ::nl_item = 0x2001E; -pub const MON_6: ::nl_item = 0x2001F; -pub const MON_7: ::nl_item = 0x20020; -pub const MON_8: ::nl_item = 0x20021; -pub const MON_9: ::nl_item = 0x20022; -pub const MON_10: ::nl_item = 0x20023; -pub const MON_11: ::nl_item = 0x20024; -pub const MON_12: ::nl_item = 0x20025; - -pub const AM_STR: ::nl_item = 0x20026; -pub const PM_STR: ::nl_item = 0x20027; - -pub const D_T_FMT: ::nl_item = 0x20028; -pub const D_FMT: ::nl_item = 0x20029; -pub const T_FMT: ::nl_item = 0x2002A; -pub const T_FMT_AMPM: ::nl_item = 0x2002B; - -pub const ERA: ::nl_item = 0x2002C; -pub const ERA_D_FMT: ::nl_item = 0x2002E; -pub const ALT_DIGITS: ::nl_item = 0x2002F; -pub const ERA_D_T_FMT: ::nl_item = 0x20030; -pub const ERA_T_FMT: ::nl_item = 0x20031; - -pub const CODESET: ::nl_item = 14; - -pub const CRNCYSTR: ::nl_item = 0x4000F; - -pub const RUSAGE_THREAD: ::c_int = 1; -pub const RUSAGE_CHILDREN: ::c_int = -1; - -pub const RADIXCHAR: ::nl_item = 0x10000; -pub const THOUSEP: ::nl_item = 0x10001; - -pub const YESEXPR: ::nl_item = 0x50000; -pub const NOEXPR: ::nl_item = 0x50001; -pub const YESSTR: ::nl_item = 0x50002; -pub const NOSTR: ::nl_item = 0x50003; - -pub const FILENAME_MAX: ::c_uint = 4096; -pub const L_tmpnam: ::c_uint = 20; -pub const _PC_LINK_MAX: ::c_int = 0; -pub const _PC_MAX_CANON: ::c_int = 1; -pub const _PC_MAX_INPUT: ::c_int = 2; -pub const _PC_NAME_MAX: ::c_int = 3; -pub const _PC_PATH_MAX: ::c_int = 4; -pub const _PC_PIPE_BUF: ::c_int = 5; -pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; -pub const _PC_NO_TRUNC: ::c_int = 7; -pub const _PC_VDISABLE: ::c_int = 8; -pub const _PC_SYNC_IO: ::c_int = 9; -pub const _PC_ASYNC_IO: ::c_int = 10; -pub const _PC_PRIO_IO: ::c_int = 11; -pub const _PC_SOCK_MAXBUF: ::c_int = 12; -pub const _PC_FILESIZEBITS: ::c_int = 13; -pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; -pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; -pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; -pub const _PC_REC_XFER_ALIGN: ::c_int = 17; -pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; -pub const _PC_SYMLINK_MAX: ::c_int = 19; -pub const _PC_2_SYMLINKS: ::c_int = 20; - -pub const _SC_ARG_MAX: ::c_int = 0; -pub const _SC_CHILD_MAX: ::c_int = 1; -pub const _SC_CLK_TCK: ::c_int = 2; -pub const _SC_NGROUPS_MAX: ::c_int = 3; -pub const _SC_OPEN_MAX: ::c_int = 4; -pub const _SC_STREAM_MAX: ::c_int = 5; -pub const _SC_TZNAME_MAX: ::c_int = 6; -pub const _SC_JOB_CONTROL: ::c_int = 7; -pub const _SC_SAVED_IDS: ::c_int = 8; -pub const _SC_REALTIME_SIGNALS: ::c_int = 9; -pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; -pub const _SC_TIMERS: ::c_int = 11; -pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; -pub const _SC_PRIORITIZED_IO: ::c_int = 13; -pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; -pub const _SC_FSYNC: ::c_int = 15; -pub const _SC_MAPPED_FILES: ::c_int = 16; -pub const _SC_MEMLOCK: ::c_int = 17; -pub const _SC_MEMLOCK_RANGE: ::c_int = 18; -pub const _SC_MEMORY_PROTECTION: ::c_int = 19; -pub const _SC_MESSAGE_PASSING: ::c_int = 20; -pub const _SC_SEMAPHORES: ::c_int = 21; -pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; -pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; -pub const _SC_AIO_MAX: ::c_int = 24; -pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; -pub const _SC_DELAYTIMER_MAX: ::c_int = 26; -pub const _SC_MQ_OPEN_MAX: ::c_int = 27; -pub const _SC_MQ_PRIO_MAX: ::c_int = 28; -pub const _SC_VERSION: ::c_int = 29; -pub const _SC_PAGESIZE: ::c_int = 30; -pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; -pub const _SC_RTSIG_MAX: ::c_int = 31; -pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; -pub const _SC_SEM_VALUE_MAX: ::c_int = 33; -pub const _SC_SIGQUEUE_MAX: ::c_int = 34; -pub const _SC_TIMER_MAX: ::c_int = 35; -pub const _SC_BC_BASE_MAX: ::c_int = 36; -pub const _SC_BC_DIM_MAX: ::c_int = 37; -pub const _SC_BC_SCALE_MAX: ::c_int = 38; -pub const _SC_BC_STRING_MAX: ::c_int = 39; -pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; -pub const _SC_EXPR_NEST_MAX: ::c_int = 42; -pub const _SC_LINE_MAX: ::c_int = 43; -pub const _SC_RE_DUP_MAX: ::c_int = 44; -pub const _SC_2_VERSION: ::c_int = 46; -pub const _SC_2_C_BIND: ::c_int = 47; -pub const _SC_2_C_DEV: ::c_int = 48; -pub const _SC_2_FORT_DEV: ::c_int = 49; -pub const _SC_2_FORT_RUN: ::c_int = 50; -pub const _SC_2_SW_DEV: ::c_int = 51; -pub const _SC_2_LOCALEDEF: ::c_int = 52; -pub const _SC_UIO_MAXIOV: ::c_int = 60; -pub const _SC_IOV_MAX: ::c_int = 60; -pub const _SC_THREADS: ::c_int = 67; -pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; -pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; -pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; -pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; -pub const _SC_TTY_NAME_MAX: ::c_int = 72; -pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; -pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; -pub const _SC_THREAD_STACK_MIN: ::c_int = 75; -pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; -pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; -pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; -pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; -pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; -pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; -pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; -pub const _SC_NPROCESSORS_CONF: ::c_int = 83; -pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; -pub const _SC_PHYS_PAGES: ::c_int = 85; -pub const _SC_AVPHYS_PAGES: ::c_int = 86; -pub const _SC_ATEXIT_MAX: ::c_int = 87; -pub const _SC_PASS_MAX: ::c_int = 88; -pub const _SC_XOPEN_VERSION: ::c_int = 89; -pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; -pub const _SC_XOPEN_UNIX: ::c_int = 91; -pub const _SC_XOPEN_CRYPT: ::c_int = 92; -pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; -pub const _SC_XOPEN_SHM: ::c_int = 94; -pub const _SC_2_CHAR_TERM: ::c_int = 95; -pub const _SC_2_UPE: ::c_int = 97; -pub const _SC_XOPEN_XPG2: ::c_int = 98; -pub const _SC_XOPEN_XPG3: ::c_int = 99; -pub const _SC_XOPEN_XPG4: ::c_int = 100; -pub const _SC_NZERO: ::c_int = 109; -pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; -pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; -pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; -pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; -pub const _SC_XOPEN_LEGACY: ::c_int = 129; -pub const _SC_XOPEN_REALTIME: ::c_int = 130; -pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; -pub const _SC_ADVISORY_INFO: ::c_int = 132; -pub const _SC_BARRIERS: ::c_int = 133; -pub const _SC_CLOCK_SELECTION: ::c_int = 137; -pub const _SC_CPUTIME: ::c_int = 138; -pub const _SC_THREAD_CPUTIME: ::c_int = 139; -pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; -pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; -pub const _SC_SPIN_LOCKS: ::c_int = 154; -pub const _SC_REGEXP: ::c_int = 155; -pub const _SC_SHELL: ::c_int = 157; -pub const _SC_SPAWN: ::c_int = 159; -pub const _SC_SPORADIC_SERVER: ::c_int = 160; -pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; -pub const _SC_TIMEOUTS: ::c_int = 164; -pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; -pub const _SC_2_PBS: ::c_int = 168; -pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; -pub const _SC_2_PBS_LOCATE: ::c_int = 170; -pub const _SC_2_PBS_MESSAGE: ::c_int = 171; -pub const _SC_2_PBS_TRACK: ::c_int = 172; -pub const _SC_SYMLOOP_MAX: ::c_int = 173; -pub const _SC_STREAMS: ::c_int = 174; -pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; -pub const _SC_V6_ILP32_OFF32: ::c_int = 176; -pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; -pub const _SC_V6_LP64_OFF64: ::c_int = 178; -pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; -pub const _SC_HOST_NAME_MAX: ::c_int = 180; -pub const _SC_TRACE: ::c_int = 181; -pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; -pub const _SC_TRACE_INHERIT: ::c_int = 183; -pub const _SC_TRACE_LOG: ::c_int = 184; -pub const _SC_IPV6: ::c_int = 235; -pub const _SC_RAW_SOCKETS: ::c_int = 236; -pub const _SC_V7_ILP32_OFF32: ::c_int = 237; -pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; -pub const _SC_V7_LP64_OFF64: ::c_int = 239; -pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; -pub const _SC_SS_REPL_MAX: ::c_int = 241; -pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; -pub const _SC_TRACE_NAME_MAX: ::c_int = 243; -pub const _SC_TRACE_SYS_MAX: ::c_int = 244; -pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; -pub const _SC_XOPEN_STREAMS: ::c_int = 246; -pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; -pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; - -pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; -pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; - -pub const GLOB_ERR: ::c_int = 1 << 0; -pub const GLOB_MARK: ::c_int = 1 << 1; -pub const GLOB_NOSORT: ::c_int = 1 << 2; -pub const GLOB_DOOFFS: ::c_int = 1 << 3; -pub const GLOB_NOCHECK: ::c_int = 1 << 4; -pub const GLOB_APPEND: ::c_int = 1 << 5; -pub const GLOB_NOESCAPE: ::c_int = 1 << 6; - -pub const GLOB_NOSPACE: ::c_int = 1; -pub const GLOB_ABORTED: ::c_int = 2; -pub const GLOB_NOMATCH: ::c_int = 3; - -pub const POSIX_MADV_NORMAL: ::c_int = 0; -pub const POSIX_MADV_RANDOM: ::c_int = 1; -pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; -pub const POSIX_MADV_WILLNEED: ::c_int = 3; - -pub const S_IEXEC: mode_t = 64; -pub const S_IWRITE: mode_t = 128; -pub const S_IREAD: mode_t = 256; - -pub const F_LOCK: ::c_int = 1; -pub const F_TEST: ::c_int = 3; -pub const F_TLOCK: ::c_int = 2; -pub const F_ULOCK: ::c_int = 0; - -pub const ST_RDONLY: ::c_ulong = 1; -pub const ST_NOSUID: ::c_ulong = 2; -pub const ST_NODEV: ::c_ulong = 4; -pub const ST_NOEXEC: ::c_ulong = 8; -pub const ST_SYNCHRONOUS: ::c_ulong = 16; -pub const ST_MANDLOCK: ::c_ulong = 64; -pub const ST_WRITE: ::c_ulong = 128; -pub const ST_APPEND: ::c_ulong = 256; -pub const ST_IMMUTABLE: ::c_ulong = 512; -pub const ST_NOATIME: ::c_ulong = 1024; -pub const ST_NODIRATIME: ::c_ulong = 2048; - -pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; -pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; -pub const RTLD_NODELETE: ::c_int = 0x1000; -pub const RTLD_NOW: ::c_int = 0x2; - -pub const TCP_MD5SIG: ::c_int = 14; - -align_const! { - pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { - size: [0; __SIZEOF_PTHREAD_MUTEX_T], - }; - pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { - size: [0; __SIZEOF_PTHREAD_COND_T], - }; - pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { - size: [0; __SIZEOF_PTHREAD_RWLOCK_T], - }; -} - -pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; -pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; -pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; -pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; -pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; -pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; -pub const __SIZEOF_PTHREAD_COND_T: usize = 48; - -pub const SCHED_OTHER: ::c_int = 0; -pub const SCHED_FIFO: ::c_int = 1; -pub const SCHED_RR: ::c_int = 2; -pub const SCHED_BATCH: ::c_int = 3; -pub const SCHED_IDLE: ::c_int = 5; - -pub const AF_IB: ::c_int = 27; -pub const AF_MPLS: ::c_int = 28; -pub const AF_NFC: ::c_int = 39; -pub const AF_VSOCK: ::c_int = 40; -#[doc(hidden)] -pub const AF_MAX: ::c_int = 42; -pub const PF_IB: ::c_int = AF_IB; -pub const PF_MPLS: ::c_int = AF_MPLS; -pub const PF_NFC: ::c_int = AF_NFC; -pub const PF_VSOCK: ::c_int = AF_VSOCK; -#[doc(hidden)] -pub const PF_MAX: ::c_int = AF_MAX; - -// System V IPC -pub const IPC_PRIVATE: ::key_t = 0; - -pub const IPC_CREAT: ::c_int = 0o1000; -pub const IPC_EXCL: ::c_int = 0o2000; -pub const IPC_NOWAIT: ::c_int = 0o4000; - -pub const IPC_RMID: ::c_int = 0; -pub const IPC_SET: ::c_int = 1; -pub const IPC_STAT: ::c_int = 2; -pub const IPC_INFO: ::c_int = 3; -pub const MSG_STAT: ::c_int = 11; -pub const MSG_INFO: ::c_int = 12; - -pub const MSG_NOERROR: ::c_int = 0o10000; -pub const MSG_EXCEPT: ::c_int = 0o20000; -pub const MSG_COPY: ::c_int = 0o40000; - -pub const SHM_R: ::c_int = 0o400; -pub const SHM_W: ::c_int = 0o200; - -pub const SHM_RDONLY: ::c_int = 0o10000; -pub const SHM_RND: ::c_int = 0o20000; -pub const SHM_REMAP: ::c_int = 0o40000; -pub const SHM_EXEC: ::c_int = 0o100000; - -pub const SHM_LOCK: ::c_int = 11; -pub const SHM_UNLOCK: ::c_int = 12; - -pub const SHM_HUGETLB: ::c_int = 0o4000; -pub const SHM_NORESERVE: ::c_int = 0o10000; - -pub const EPOLLRDHUP: ::c_int = 0x2000; -pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; -pub const EPOLLONESHOT: ::c_int = 0x40000000; - -pub const QFMT_VFS_OLD: ::c_int = 1; -pub const QFMT_VFS_V0: ::c_int = 2; - -pub const EFD_SEMAPHORE: ::c_int = 0x1; - -pub const LOG_NFACILITIES: ::c_int = 24; - -pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; - -pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; -pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; -pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; -pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; -pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; -pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; -pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; - -pub const AI_PASSIVE: ::c_int = 0x0001; -pub const AI_CANONNAME: ::c_int = 0x0002; -pub const AI_NUMERICHOST: ::c_int = 0x0004; -pub const AI_V4MAPPED: ::c_int = 0x0008; -pub const AI_ALL: ::c_int = 0x0010; -pub const AI_ADDRCONFIG: ::c_int = 0x0020; - -pub const AI_NUMERICSERV: ::c_int = 0x0400; - -pub const EAI_BADFLAGS: ::c_int = -1; -pub const EAI_NONAME: ::c_int = -2; -pub const EAI_AGAIN: ::c_int = -3; -pub const EAI_FAIL: ::c_int = -4; -pub const EAI_FAMILY: ::c_int = -6; -pub const EAI_SOCKTYPE: ::c_int = -7; -pub const EAI_SERVICE: ::c_int = -8; -pub const EAI_MEMORY: ::c_int = -10; -pub const EAI_OVERFLOW: ::c_int = -12; - -pub const NI_NUMERICHOST: ::c_int = 1; -pub const NI_NUMERICSERV: ::c_int = 2; -pub const NI_NOFQDN: ::c_int = 4; -pub const NI_NAMEREQD: ::c_int = 8; -pub const NI_DGRAM: ::c_int = 16; - -pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; -pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; -pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; - -pub const EAI_SYSTEM: ::c_int = -11; - -pub const AIO_CANCELED: ::c_int = 0; -pub const AIO_NOTCANCELED: ::c_int = 1; -pub const AIO_ALLDONE: ::c_int = 2; -pub const LIO_READ: ::c_int = 0; -pub const LIO_WRITE: ::c_int = 1; -pub const LIO_NOP: ::c_int = 2; -pub const LIO_WAIT: ::c_int = 0; -pub const LIO_NOWAIT: ::c_int = 1; - -pub const MREMAP_MAYMOVE: ::c_int = 1; -pub const MREMAP_FIXED: ::c_int = 2; - -pub const PR_SET_PDEATHSIG: ::c_int = 1; -pub const PR_GET_PDEATHSIG: ::c_int = 2; - -pub const PR_GET_DUMPABLE: ::c_int = 3; -pub const PR_SET_DUMPABLE: ::c_int = 4; - -pub const PR_GET_UNALIGN: ::c_int = 5; -pub const PR_SET_UNALIGN: ::c_int = 6; -pub const PR_UNALIGN_NOPRINT: ::c_int = 1; -pub const PR_UNALIGN_SIGBUS: ::c_int = 2; - -pub const PR_GET_KEEPCAPS: ::c_int = 7; -pub const PR_SET_KEEPCAPS: ::c_int = 8; - -pub const PR_GET_FPEMU: ::c_int = 9; -pub const PR_SET_FPEMU: ::c_int = 10; -pub const PR_FPEMU_NOPRINT: ::c_int = 1; -pub const PR_FPEMU_SIGFPE: ::c_int = 2; - -pub const PR_GET_FPEXC: ::c_int = 11; -pub const PR_SET_FPEXC: ::c_int = 12; -pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; -pub const PR_FP_EXC_DIV: ::c_int = 0x010000; -pub const PR_FP_EXC_OVF: ::c_int = 0x020000; -pub const PR_FP_EXC_UND: ::c_int = 0x040000; -pub const PR_FP_EXC_RES: ::c_int = 0x080000; -pub const PR_FP_EXC_INV: ::c_int = 0x100000; -pub const PR_FP_EXC_DISABLED: ::c_int = 0; -pub const PR_FP_EXC_NONRECOV: ::c_int = 1; -pub const PR_FP_EXC_ASYNC: ::c_int = 2; -pub const PR_FP_EXC_PRECISE: ::c_int = 3; - -pub const PR_GET_TIMING: ::c_int = 13; -pub const PR_SET_TIMING: ::c_int = 14; -pub const PR_TIMING_STATISTICAL: ::c_int = 0; -pub const PR_TIMING_TIMESTAMP: ::c_int = 1; - -pub const PR_SET_NAME: ::c_int = 15; -pub const PR_GET_NAME: ::c_int = 16; - -pub const PR_GET_ENDIAN: ::c_int = 19; -pub const PR_SET_ENDIAN: ::c_int = 20; -pub const PR_ENDIAN_BIG: ::c_int = 0; -pub const PR_ENDIAN_LITTLE: ::c_int = 1; -pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; - -pub const PR_GET_SECCOMP: ::c_int = 21; -pub const PR_SET_SECCOMP: ::c_int = 22; - -pub const PR_CAPBSET_READ: ::c_int = 23; -pub const PR_CAPBSET_DROP: ::c_int = 24; - -pub const PR_GET_TSC: ::c_int = 25; -pub const PR_SET_TSC: ::c_int = 26; -pub const PR_TSC_ENABLE: ::c_int = 1; -pub const PR_TSC_SIGSEGV: ::c_int = 2; - -pub const PR_GET_SECUREBITS: ::c_int = 27; -pub const PR_SET_SECUREBITS: ::c_int = 28; - -pub const PR_SET_TIMERSLACK: ::c_int = 29; -pub const PR_GET_TIMERSLACK: ::c_int = 30; - -pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; -pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; - -pub const PR_MCE_KILL: ::c_int = 33; -pub const PR_MCE_KILL_CLEAR: ::c_int = 0; -pub const PR_MCE_KILL_SET: ::c_int = 1; - -pub const PR_MCE_KILL_LATE: ::c_int = 0; -pub const PR_MCE_KILL_EARLY: ::c_int = 1; -pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; - -pub const PR_MCE_KILL_GET: ::c_int = 34; - -pub const PR_SET_MM: ::c_int = 35; -pub const PR_SET_MM_START_CODE: ::c_int = 1; -pub const PR_SET_MM_END_CODE: ::c_int = 2; -pub const PR_SET_MM_START_DATA: ::c_int = 3; -pub const PR_SET_MM_END_DATA: ::c_int = 4; -pub const PR_SET_MM_START_STACK: ::c_int = 5; -pub const PR_SET_MM_START_BRK: ::c_int = 6; -pub const PR_SET_MM_BRK: ::c_int = 7; -pub const PR_SET_MM_ARG_START: ::c_int = 8; -pub const PR_SET_MM_ARG_END: ::c_int = 9; -pub const PR_SET_MM_ENV_START: ::c_int = 10; -pub const PR_SET_MM_ENV_END: ::c_int = 11; -pub const PR_SET_MM_AUXV: ::c_int = 12; -pub const PR_SET_MM_EXE_FILE: ::c_int = 13; -pub const PR_SET_MM_MAP: ::c_int = 14; -pub const PR_SET_MM_MAP_SIZE: ::c_int = 15; - -pub const PR_SET_PTRACER: ::c_int = 0x59616d61; - -pub const PR_SET_CHILD_SUBREAPER: ::c_int = 36; -pub const PR_GET_CHILD_SUBREAPER: ::c_int = 37; - -pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; -pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; - -pub const PR_GET_TID_ADDRESS: ::c_int = 40; - -pub const PR_SET_THP_DISABLE: ::c_int = 41; -pub const PR_GET_THP_DISABLE: ::c_int = 42; - -pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; -pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; - -pub const PR_SET_FP_MODE: ::c_int = 45; -pub const PR_GET_FP_MODE: ::c_int = 46; -pub const PR_FP_MODE_FR: ::c_int = 1 << 0; -pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; - -pub const PR_CAP_AMBIENT: ::c_int = 47; -pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; -pub const PR_CAP_AMBIENT_RAISE: ::c_int = 2; -pub const PR_CAP_AMBIENT_LOWER: ::c_int = 3; -pub const PR_CAP_AMBIENT_CLEAR_ALL: ::c_int = 4; - -pub const ITIMER_REAL: ::c_int = 0; -pub const ITIMER_VIRTUAL: ::c_int = 1; -pub const ITIMER_PROF: ::c_int = 2; - -pub const XATTR_CREATE: ::c_int = 0x1; -pub const XATTR_REPLACE: ::c_int = 0x2; - -pub const _POSIX_VDISABLE: ::cc_t = 0; - -pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; -pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; -pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; -pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; -pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; -pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; - -// On Linux, libc doesn't define this constant, libattr does instead. -// We still define it for Linux as it's defined by libc on other platforms, -// and it's mentioned in the man pages for getxattr and setxattr. -pub const SFD_CLOEXEC: ::c_int = 0x080000; - -pub const NCCS: usize = 32; - -pub const O_TRUNC: ::c_int = 512; -pub const O_NOATIME: ::c_int = 0o1000000; -pub const O_CLOEXEC: ::c_int = 0x80000; - -pub const EBFONT: ::c_int = 59; -pub const ENOSTR: ::c_int = 60; -pub const ENODATA: ::c_int = 61; -pub const ETIME: ::c_int = 62; -pub const ENOSR: ::c_int = 63; -pub const ENONET: ::c_int = 64; -pub const ENOPKG: ::c_int = 65; -pub const EREMOTE: ::c_int = 66; -pub const ENOLINK: ::c_int = 67; -pub const EADV: ::c_int = 68; -pub const ESRMNT: ::c_int = 69; -pub const ECOMM: ::c_int = 70; -pub const EPROTO: ::c_int = 71; -pub const EDOTDOT: ::c_int = 73; - -pub const SA_NODEFER: ::c_int = 0x40000000; -pub const SA_RESETHAND: ::c_int = 0x80000000; -pub const SA_RESTART: ::c_int = 0x10000000; -pub const SA_NOCLDSTOP: ::c_int = 0x00000001; - -pub const EPOLL_CLOEXEC: ::c_int = 0x80000; - -pub const EFD_CLOEXEC: ::c_int = 0x80000; - -pub const BUFSIZ: ::c_uint = 1024; -pub const TMP_MAX: ::c_uint = 10000; -pub const FOPEN_MAX: ::c_uint = 1000; -pub const O_PATH: ::c_int = 0o10000000; -pub const O_EXEC: ::c_int = 0o10000000; -pub const O_SEARCH: ::c_int = 0o10000000; -pub const O_ACCMODE: ::c_int = 0o10000003; -pub const O_NDELAY: ::c_int = O_NONBLOCK; -pub const NI_MAXHOST: ::socklen_t = 255; -pub const PTHREAD_STACK_MIN: ::size_t = 2048; -pub const POSIX_FADV_DONTNEED: ::c_int = 4; -pub const POSIX_FADV_NOREUSE: ::c_int = 5; - -pub const POSIX_MADV_DONTNEED: ::c_int = 0; - -pub const RLIM_INFINITY: ::rlim_t = !0; -pub const RLIMIT_RTTIME: ::c_int = 15; -pub const RLIMIT_NLIMITS: ::c_int = 16; - -pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; - -pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; -pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; -pub const TCP_THIN_DUPACK: ::c_int = 17; -pub const TCP_USER_TIMEOUT: ::c_int = 18; -pub const TCP_REPAIR: ::c_int = 19; -pub const TCP_REPAIR_QUEUE: ::c_int = 20; -pub const TCP_QUEUE_SEQ: ::c_int = 21; -pub const TCP_REPAIR_OPTIONS: ::c_int = 22; -pub const TCP_FASTOPEN: ::c_int = 23; -pub const TCP_TIMESTAMP: ::c_int = 24; - -pub const SIGUNUSED: ::c_int = ::SIGSYS; - -pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; - -pub const CPU_SETSIZE: ::c_int = 128; - -pub const QFMT_VFS_V1: ::c_int = 4; - -pub const PTRACE_TRACEME: ::c_int = 0; -pub const PTRACE_PEEKTEXT: ::c_int = 1; -pub const PTRACE_PEEKDATA: ::c_int = 2; -pub const PTRACE_PEEKUSER: ::c_int = 3; -pub const PTRACE_POKETEXT: ::c_int = 4; -pub const PTRACE_POKEDATA: ::c_int = 5; -pub const PTRACE_POKEUSER: ::c_int = 6; -pub const PTRACE_CONT: ::c_int = 7; -pub const PTRACE_KILL: ::c_int = 8; -pub const PTRACE_SINGLESTEP: ::c_int = 9; -pub const PTRACE_ATTACH: ::c_int = 16; -pub const PTRACE_DETACH: ::c_int = 17; -pub const PTRACE_SYSCALL: ::c_int = 24; -pub const PTRACE_SETOPTIONS: ::c_int = 0x4200; -pub const PTRACE_GETEVENTMSG: ::c_int = 0x4201; -pub const PTRACE_GETSIGINFO: ::c_int = 0x4202; -pub const PTRACE_SETSIGINFO: ::c_int = 0x4203; -pub const PTRACE_GETREGSET: ::c_int = 0x4204; -pub const PTRACE_SETREGSET: ::c_int = 0x4205; -pub const PTRACE_SEIZE: ::c_int = 0x4206; -pub const PTRACE_INTERRUPT: ::c_int = 0x4207; -pub const PTRACE_LISTEN: ::c_int = 0x4208; -pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; - -pub const EPOLLWAKEUP: ::c_int = 0x20000000; - -pub const PTRACE_GETFPREGS: ::c_uint = 14; -pub const PTRACE_SETFPREGS: ::c_uint = 15; -pub const PTRACE_GETFPXREGS: ::c_uint = 18; -pub const PTRACE_SETFPXREGS: ::c_uint = 19; -pub const PTRACE_GETREGS: ::c_uint = 12; -pub const PTRACE_SETREGS: ::c_uint = 13; - -pub const EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; - -pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; - -pub const TCSANOW: ::c_int = 0; -pub const TCSADRAIN: ::c_int = 1; -pub const TCSAFLUSH: ::c_int = 2; - -pub const TIOCINQ: ::c_int = ::FIONREAD; - -pub const RTLD_GLOBAL: ::c_int = 0x100; -pub const RTLD_NOLOAD: ::c_int = 0x4; - -// TODO(#247) Temporarily musl-specific (available since musl 0.9.12 / Linux -// kernel 3.10). See also notbsd/mod.rs -pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; -pub const CLOCK_TAI: ::clockid_t = 11; - -pub const MCL_CURRENT: ::c_int = 0x0001; -pub const MCL_FUTURE: ::c_int = 0x0002; - -pub const SIGSTKSZ: ::size_t = 8192; -pub const MINSIGSTKSZ: ::size_t = 2048; -pub const CBAUD: ::tcflag_t = 0o0010017; -pub const TAB1: ::c_int = 0x00000800; -pub const TAB2: ::c_int = 0x00001000; -pub const TAB3: ::c_int = 0x00001800; -pub const CR1: ::c_int = 0x00000200; -pub const CR2: ::c_int = 0x00000400; -pub const CR3: ::c_int = 0x00000600; -pub const FF1: ::c_int = 0x00008000; -pub const BS1: ::c_int = 0x00002000; -pub const VT1: ::c_int = 0x00004000; -pub const VWERASE: usize = 14; -pub const VREPRINT: usize = 12; -pub const VSUSP: usize = 10; -pub const VSTART: usize = 8; -pub const VSTOP: usize = 9; -pub const VDISCARD: usize = 13; -pub const VTIME: usize = 5; -pub const IXON: ::tcflag_t = 0x00000400; -pub const IXOFF: ::tcflag_t = 0x00001000; -pub const ONLCR: ::tcflag_t = 0x4; -pub const CSIZE: ::tcflag_t = 0x00000030; -pub const CS6: ::tcflag_t = 0x00000010; -pub const CS7: ::tcflag_t = 0x00000020; -pub const CS8: ::tcflag_t = 0x00000030; -pub const CSTOPB: ::tcflag_t = 0x00000040; -pub const CREAD: ::tcflag_t = 0x00000080; -pub const PARENB: ::tcflag_t = 0x00000100; -pub const PARODD: ::tcflag_t = 0x00000200; -pub const HUPCL: ::tcflag_t = 0x00000400; -pub const CLOCAL: ::tcflag_t = 0x00000800; -pub const ECHOKE: ::tcflag_t = 0x00000800; -pub const ECHOE: ::tcflag_t = 0x00000010; -pub const ECHOK: ::tcflag_t = 0x00000020; -pub const ECHONL: ::tcflag_t = 0x00000040; -pub const ECHOPRT: ::tcflag_t = 0x00000400; -pub const ECHOCTL: ::tcflag_t = 0x00000200; -pub const ISIG: ::tcflag_t = 0x00000001; -pub const ICANON: ::tcflag_t = 0x00000002; -pub const PENDIN: ::tcflag_t = 0x00004000; -pub const NOFLSH: ::tcflag_t = 0x00000080; -pub const CBAUDEX: ::tcflag_t = 0o010000; -pub const VSWTC: usize = 7; -pub const OLCUC: ::tcflag_t = 0o000002; -pub const NLDLY: ::tcflag_t = 0o000400; -pub const CRDLY: ::tcflag_t = 0o003000; -pub const TABDLY: ::tcflag_t = 0o014000; -pub const BSDLY: ::tcflag_t = 0o020000; -pub const FFDLY: ::tcflag_t = 0o100000; -pub const VTDLY: ::tcflag_t = 0o040000; -pub const XTABS: ::tcflag_t = 0o014000; - -pub const B0: ::speed_t = 0o000000; -pub const B50: ::speed_t = 0o000001; -pub const B75: ::speed_t = 0o000002; -pub const B110: ::speed_t = 0o000003; -pub const B134: ::speed_t = 0o000004; -pub const B150: ::speed_t = 0o000005; -pub const B200: ::speed_t = 0o000006; -pub const B300: ::speed_t = 0o000007; -pub const B600: ::speed_t = 0o000010; -pub const B1200: ::speed_t = 0o000011; -pub const B1800: ::speed_t = 0o000012; -pub const B2400: ::speed_t = 0o000013; -pub const B4800: ::speed_t = 0o000014; -pub const B9600: ::speed_t = 0o000015; -pub const B19200: ::speed_t = 0o000016; -pub const B38400: ::speed_t = 0o000017; -pub const B57600: ::speed_t = 0o010001; -pub const B115200: ::speed_t = 0o010002; -pub const B230400: ::speed_t = 0o010003; -pub const B460800: ::speed_t = 0o010004; -pub const B500000: ::speed_t = 0o010005; -pub const B576000: ::speed_t = 0o010006; -pub const B921600: ::speed_t = 0o010007; -pub const B1000000: ::speed_t = 0o010010; -pub const B1152000: ::speed_t = 0o010011; -pub const B1500000: ::speed_t = 0o010012; -pub const B2000000: ::speed_t = 0o010013; -pub const B2500000: ::speed_t = 0o010014; -pub const B3000000: ::speed_t = 0o010015; -pub const B3500000: ::speed_t = 0o010016; -pub const B4000000: ::speed_t = 0o010017; - -pub const SO_BINDTODEVICE: ::c_int = 25; -pub const SO_TIMESTAMP: ::c_int = 29; -pub const SO_MARK: ::c_int = 36; -pub const SO_RXQ_OVFL: ::c_int = 40; -pub const SO_PEEK_OFF: ::c_int = 42; -pub const SO_BUSY_POLL: ::c_int = 46; - -pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; -pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 28; - -pub const O_DIRECT: ::c_int = 0x4000; -pub const O_DIRECTORY: ::c_int = 0x10000; -pub const O_NOFOLLOW: ::c_int = 0x20000; -pub const O_ASYNC: ::c_int = 0x2000; - -pub const FIOCLEX: ::c_int = 0x5451; -pub const FIONBIO: ::c_int = 0x5421; - -pub const RLIMIT_RSS: ::c_int = 5; -pub const RLIMIT_NOFILE: ::c_int = 7; -pub const RLIMIT_AS: ::c_int = 9; -pub const RLIMIT_NPROC: ::c_int = 6; -pub const RLIMIT_MEMLOCK: ::c_int = 8; - -pub const O_APPEND: ::c_int = 1024; -pub const O_CREAT: ::c_int = 64; -pub const O_EXCL: ::c_int = 128; -pub const O_NOCTTY: ::c_int = 256; -pub const O_NONBLOCK: ::c_int = 2048; -pub const O_SYNC: ::c_int = 1052672; -pub const O_RSYNC: ::c_int = 1052672; -pub const O_DSYNC: ::c_int = 4096; - -pub const SOCK_NONBLOCK: ::c_int = 2048; - -pub const MAP_ANON: ::c_int = 0x0020; -pub const MAP_GROWSDOWN: ::c_int = 0x0100; -pub const MAP_DENYWRITE: ::c_int = 0x0800; -pub const MAP_EXECUTABLE: ::c_int = 0x01000; -pub const MAP_LOCKED: ::c_int = 0x02000; -pub const MAP_NORESERVE: ::c_int = 0x04000; -pub const MAP_POPULATE: ::c_int = 0x08000; -pub const MAP_NONBLOCK: ::c_int = 0x010000; -pub const MAP_STACK: ::c_int = 0x020000; - -pub const SOCK_STREAM: ::c_int = 1; -pub const SOCK_DGRAM: ::c_int = 2; -pub const SOCK_SEQPACKET: ::c_int = 5; - -pub const SOL_SOCKET: ::c_int = 1; - -pub const EDEADLK: ::c_int = 35; -pub const ENAMETOOLONG: ::c_int = 36; -pub const ENOLCK: ::c_int = 37; -pub const ENOSYS: ::c_int = 38; -pub const ENOTEMPTY: ::c_int = 39; -pub const ELOOP: ::c_int = 40; -pub const ENOMSG: ::c_int = 42; -pub const EIDRM: ::c_int = 43; -pub const ECHRNG: ::c_int = 44; -pub const EL2NSYNC: ::c_int = 45; -pub const EL3HLT: ::c_int = 46; -pub const EL3RST: ::c_int = 47; -pub const ELNRNG: ::c_int = 48; -pub const EUNATCH: ::c_int = 49; -pub const ENOCSI: ::c_int = 50; -pub const EL2HLT: ::c_int = 51; -pub const EBADE: ::c_int = 52; -pub const EBADR: ::c_int = 53; -pub const EXFULL: ::c_int = 54; -pub const ENOANO: ::c_int = 55; -pub const EBADRQC: ::c_int = 56; -pub const EBADSLT: ::c_int = 57; -pub const EDEADLOCK: ::c_int = EDEADLK; -pub const EMULTIHOP: ::c_int = 72; -pub const EBADMSG: ::c_int = 74; -pub const EOVERFLOW: ::c_int = 75; -pub const ENOTUNIQ: ::c_int = 76; -pub const EBADFD: ::c_int = 77; -pub const EREMCHG: ::c_int = 78; -pub const ELIBACC: ::c_int = 79; -pub const ELIBBAD: ::c_int = 80; -pub const ELIBSCN: ::c_int = 81; -pub const ELIBMAX: ::c_int = 82; -pub const ELIBEXEC: ::c_int = 83; -pub const EILSEQ: ::c_int = 84; -pub const ERESTART: ::c_int = 85; -pub const ESTRPIPE: ::c_int = 86; -pub const EUSERS: ::c_int = 87; -pub const ENOTSOCK: ::c_int = 88; -pub const EDESTADDRREQ: ::c_int = 89; -pub const EMSGSIZE: ::c_int = 90; -pub const EPROTOTYPE: ::c_int = 91; -pub const ENOPROTOOPT: ::c_int = 92; -pub const EPROTONOSUPPORT: ::c_int = 93; -pub const ESOCKTNOSUPPORT: ::c_int = 94; -pub const EOPNOTSUPP: ::c_int = 95; -pub const ENOTSUP: ::c_int = EOPNOTSUPP; -pub const EPFNOSUPPORT: ::c_int = 96; -pub const EAFNOSUPPORT: ::c_int = 97; -pub const EADDRINUSE: ::c_int = 98; -pub const EADDRNOTAVAIL: ::c_int = 99; -pub const ENETDOWN: ::c_int = 100; -pub const ENETUNREACH: ::c_int = 101; -pub const ENETRESET: ::c_int = 102; -pub const ECONNABORTED: ::c_int = 103; -pub const ECONNRESET: ::c_int = 104; -pub const ENOBUFS: ::c_int = 105; -pub const EISCONN: ::c_int = 106; -pub const ENOTCONN: ::c_int = 107; -pub const ESHUTDOWN: ::c_int = 108; -pub const ETOOMANYREFS: ::c_int = 109; -pub const ETIMEDOUT: ::c_int = 110; -pub const ECONNREFUSED: ::c_int = 111; -pub const EHOSTDOWN: ::c_int = 112; -pub const EHOSTUNREACH: ::c_int = 113; -pub const EALREADY: ::c_int = 114; -pub const EINPROGRESS: ::c_int = 115; -pub const ESTALE: ::c_int = 116; -pub const EUCLEAN: ::c_int = 117; -pub const ENOTNAM: ::c_int = 118; -pub const ENAVAIL: ::c_int = 119; -pub const EISNAM: ::c_int = 120; -pub const EREMOTEIO: ::c_int = 121; -pub const EDQUOT: ::c_int = 122; -pub const ENOMEDIUM: ::c_int = 123; -pub const EMEDIUMTYPE: ::c_int = 124; -pub const ECANCELED: ::c_int = 125; -pub const ENOKEY: ::c_int = 126; -pub const EKEYEXPIRED: ::c_int = 127; -pub const EKEYREVOKED: ::c_int = 128; -pub const EKEYREJECTED: ::c_int = 129; -pub const EOWNERDEAD: ::c_int = 130; -pub const ENOTRECOVERABLE: ::c_int = 131; -pub const ERFKILL: ::c_int = 132; -pub const EHWPOISON: ::c_int = 133; - -pub const SO_REUSEADDR: ::c_int = 2; -pub const SO_TYPE: ::c_int = 3; -pub const SO_ERROR: ::c_int = 4; -pub const SO_DONTROUTE: ::c_int = 5; -pub const SO_BROADCAST: ::c_int = 6; -pub const SO_SNDBUF: ::c_int = 7; -pub const SO_RCVBUF: ::c_int = 8; -pub const SO_KEEPALIVE: ::c_int = 9; -pub const SO_OOBINLINE: ::c_int = 10; -pub const SO_LINGER: ::c_int = 13; -pub const SO_REUSEPORT: ::c_int = 15; -pub const SO_RCVLOWAT: ::c_int = 18; -pub const SO_SNDLOWAT: ::c_int = 19; -pub const SO_RCVTIMEO: ::c_int = 20; -pub const SO_SNDTIMEO: ::c_int = 21; -pub const SO_ACCEPTCONN: ::c_int = 30; - -pub const SA_ONSTACK: ::c_int = 0x08000000; -pub const SA_SIGINFO: ::c_int = 0x00000004; -pub const SA_NOCLDWAIT: ::c_int = 0x00000002; - -pub const SIGCHLD: ::c_int = 17; -pub const SIGBUS: ::c_int = 7; -pub const SIGTTIN: ::c_int = 21; -pub const SIGTTOU: ::c_int = 22; -pub const SIGXCPU: ::c_int = 24; -pub const SIGXFSZ: ::c_int = 25; -pub const SIGVTALRM: ::c_int = 26; -pub const SIGPROF: ::c_int = 27; -pub const SIGWINCH: ::c_int = 28; -pub const SIGUSR1: ::c_int = 10; -pub const SIGUSR2: ::c_int = 12; -pub const SIGCONT: ::c_int = 18; -pub const SIGSTOP: ::c_int = 19; -pub const SIGTSTP: ::c_int = 20; -pub const SIGURG: ::c_int = 23; -pub const SIGIO: ::c_int = 29; -pub const SIGSYS: ::c_int = 31; -pub const SIGSTKFLT: ::c_int = 16; -pub const SIGPOLL: ::c_int = 29; -pub const SIGPWR: ::c_int = 30; -pub const SIG_SETMASK: ::c_int = 2; -pub const SIG_BLOCK: ::c_int = 0x000000; -pub const SIG_UNBLOCK: ::c_int = 0x01; - -pub const EXTPROC: ::tcflag_t = 0x00010000; - -pub const MAP_HUGETLB: ::c_int = 0x040000; - -pub const F_GETLK: ::c_int = 12; -pub const F_GETOWN: ::c_int = 9; -pub const F_SETLK: ::c_int = 13; -pub const F_SETLKW: ::c_int = 14; -pub const F_SETOWN: ::c_int = 8; - -pub const VEOF: usize = 4; -pub const VEOL: usize = 11; -pub const VEOL2: usize = 16; -pub const VMIN: usize = 6; -pub const IEXTEN: ::tcflag_t = 0x00008000; -pub const TOSTOP: ::tcflag_t = 0x00000100; -pub const FLUSHO: ::tcflag_t = 0x00001000; - -pub const TCGETS: ::c_int = 0x5401; -pub const TCSETS: ::c_int = 0x5402; -pub const TCSETSW: ::c_int = 0x5403; -pub const TCSETSF: ::c_int = 0x5404; -pub const TCGETA: ::c_int = 0x5405; -pub const TCSETA: ::c_int = 0x5406; -pub const TCSETAW: ::c_int = 0x5407; -pub const TCSETAF: ::c_int = 0x5408; -pub const TCSBRK: ::c_int = 0x5409; -pub const TCXONC: ::c_int = 0x540A; -pub const TCFLSH: ::c_int = 0x540B; -pub const TIOCGSOFTCAR: ::c_int = 0x5419; -pub const TIOCSSOFTCAR: ::c_int = 0x541A; -pub const TIOCLINUX: ::c_int = 0x541C; -pub const TIOCGSERIAL: ::c_int = 0x541E; -pub const TIOCEXCL: ::c_int = 0x540C; -pub const TIOCNXCL: ::c_int = 0x540D; -pub const TIOCSCTTY: ::c_int = 0x540E; -pub const TIOCGPGRP: ::c_int = 0x540F; -pub const TIOCSPGRP: ::c_int = 0x5410; -pub const TIOCOUTQ: ::c_int = 0x5411; -pub const TIOCSTI: ::c_int = 0x5412; -pub const TIOCGWINSZ: ::c_int = 0x5413; -pub const TIOCSWINSZ: ::c_int = 0x5414; -pub const TIOCMGET: ::c_int = 0x5415; -pub const TIOCMBIS: ::c_int = 0x5416; -pub const TIOCMBIC: ::c_int = 0x5417; -pub const TIOCMSET: ::c_int = 0x5418; -pub const FIONREAD: ::c_int = 0x541B; -pub const TIOCCONS: ::c_int = 0x541D; - -pub const SYS_gettid: ::c_long = 224; // Valid for arm (32-bit) and x86 (32-bit) - -pub const POLLWRNORM: ::c_short = 0x100; -pub const POLLWRBAND: ::c_short = 0x200; - -pub const TIOCM_LE: ::c_int = 0x001; -pub const TIOCM_DTR: ::c_int = 0x002; -pub const TIOCM_RTS: ::c_int = 0x004; -pub const TIOCM_ST: ::c_int = 0x008; -pub const TIOCM_SR: ::c_int = 0x010; -pub const TIOCM_CTS: ::c_int = 0x020; -pub const TIOCM_CAR: ::c_int = 0x040; -pub const TIOCM_RNG: ::c_int = 0x080; -pub const TIOCM_DSR: ::c_int = 0x100; -pub const TIOCM_CD: ::c_int = TIOCM_CAR; -pub const TIOCM_RI: ::c_int = TIOCM_RNG; -pub const O_TMPFILE: ::c_int = 0x400000; - -pub const MAX_ADDR_LEN: usize = 7; -pub const ARPD_UPDATE: ::c_ushort = 0x01; -pub const ARPD_LOOKUP: ::c_ushort = 0x02; -pub const ARPD_FLUSH: ::c_ushort = 0x03; -pub const ATF_MAGIC: ::c_int = 0x80; - -f! { - pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { - for slot in cpuset.bits.iter_mut() { - *slot = 0; - } - } - - pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] |= 1 << offset; - () - } - - pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] &= !(1 << offset); - () - } - - pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - 0 != (cpuset.bits[idx] & (1 << offset)) - } - - pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { - set1.bits == set2.bits - } - - pub fn major(dev: ::dev_t) -> ::c_uint { - // see - // https://github.com/kripken/emscripten/blob/ - // master/system/include/libc/sys/sysmacros.h - let mut major = 0; - major |= (dev & 0x00000fff) >> 8; - major |= (dev & 0xfffff000) >> 31 >> 1; - major as ::c_uint - } - - pub fn minor(dev: ::dev_t) -> ::c_uint { - // see - // https://github.com/kripken/emscripten/blob/ - // master/system/include/libc/sys/sysmacros.h - let mut minor = 0; - minor |= (dev & 0x000000ff) >> 0; - minor |= (dev & 0xffffff00) >> 12; - minor as ::c_uint - } - - pub fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { - let major = major as ::dev_t; - let minor = minor as ::dev_t; - let mut dev = 0; - dev |= (major & 0x00000fff) << 8; - dev |= (major & 0xfffff000) << 31 << 1; - dev |= (minor & 0x000000ff) << 0; - dev |= (minor & 0xffffff00) << 12; - dev - } -} - -extern { - pub fn abs(i: ::c_int) -> ::c_int; - pub fn atof(s: *const ::c_char) -> ::c_double; - pub fn labs(i: ::c_long) -> ::c_long; - pub fn rand() -> ::c_int; - pub fn srand(seed: ::c_uint); - - pub fn setpwent(); - pub fn endpwent(); - pub fn getpwent() -> *mut passwd; - - pub fn shm_open(name: *const c_char, oflag: ::c_int, - mode: mode_t) -> ::c_int; - - pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) - -> ::c_int; - pub fn __errno_location() -> *mut ::c_int; - - pub fn fopen64(filename: *const c_char, - mode: *const c_char) -> *mut ::FILE; - pub fn freopen64(filename: *const c_char, mode: *const c_char, - file: *mut ::FILE) -> *mut ::FILE; - pub fn tmpfile64() -> *mut ::FILE; - pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; - pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int; - pub fn fseeko64(stream: *mut ::FILE, - offset: ::off64_t, - whence: ::c_int) -> ::c_int; - pub fn ftello64(stream: *mut ::FILE) -> ::off64_t; - pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, - len: ::off_t) -> ::c_int; - pub fn pwritev(fd: ::c_int, - iov: *const ::iovec, - iovcnt: ::c_int, - offset: ::off_t) -> ::ssize_t; - pub fn preadv(fd: ::c_int, - iov: *const ::iovec, - iovcnt: ::c_int, - offset: ::off_t) -> ::ssize_t; - pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; - pub fn mkostemp(template: *mut ::c_char, flags: ::c_int) -> ::c_int; - pub fn mkostemps(template: *mut ::c_char, - suffixlen: ::c_int, - flags: ::c_int) -> ::c_int; - pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; - pub fn getnameinfo(sa: *const ::sockaddr, - salen: ::socklen_t, - host: *mut ::c_char, - hostlen: ::socklen_t, - serv: *mut ::c_char, - sevlen: ::socklen_t, - flags: ::c_int) -> ::c_int; - pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; - - // Not available now on Android - pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, - mode: ::mode_t) -> ::c_int; - pub fn if_nameindex() -> *mut if_nameindex; - pub fn if_freenameindex(ptr: *mut if_nameindex); - - pub fn mremap(addr: *mut ::c_void, - len: ::size_t, - new_len: ::size_t, - flags: ::c_int, - ...) -> *mut ::c_void; - - pub fn glob(pattern: *const c_char, - flags: ::c_int, - errfunc: Option ::c_int>, - pglob: *mut ::glob_t) -> ::c_int; - pub fn globfree(pglob: *mut ::glob_t); - - pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) - -> ::c_int; - - pub fn shm_unlink(name: *const ::c_char) -> ::c_int; - - pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); - - pub fn telldir(dirp: *mut ::DIR) -> ::c_long; - pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) - -> ::c_int; - - pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; - - pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, - flags: ::c_int, addr: *mut ::sockaddr, - addrlen: *mut ::socklen_t) -> ::ssize_t; - pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; - pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; - - pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; - pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; - pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut mmsghdr, vlen: ::c_uint, - flags: ::c_int) -> ::c_int; - pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut mmsghdr, vlen: ::c_uint, - flags: ::c_int, timeout: *mut ::timespec) -> ::c_int; - pub fn sync(); - pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; - pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int; - pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int; - pub fn pthread_create(native: *mut ::pthread_t, - attr: *const ::pthread_attr_t, - f: extern fn(*mut ::c_void) -> *mut ::c_void, - value: *mut ::c_void) -> ::c_int; -} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,100 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64", + all(target_arch = "aarch64", + target_env = "musl")), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64", + all(target_arch = "aarch64", + target_env = "musl"))), + repr(align(8)))] + pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr(any(target_env = "musl", target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(not(target_env = "musl"), + target_pointer_width = "64"), + repr(align(8)))] + pub struct pthread_rwlockattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(all(target_env = "musl", + target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(target_env = "musl", + target_pointer_width = "64"), + repr(align(8)))] + #[cfg_attr(all(not(target_env = "musl"), + target_arch = "x86"), + repr(align(4)))] + #[cfg_attr(all(not(target_env = "musl"), + not(target_arch = "x86")), + repr(align(8)))] + pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mips32.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mips32.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mips32.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mips32.rs 2019-05-15 11:26:24.000000000 +0000 @@ -133,7 +133,7 @@ pub sa_flags: ::c_int, pub sa_sigaction: ::sighandler_t, pub sa_mask: sigset_t, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, _resv: [::c_int; 1], } diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mips64.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mips64.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mips64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mips64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -131,7 +131,7 @@ pub sa_flags: ::c_int, pub sa_sigaction: ::sighandler_t, pub sa_mask: sigset_t, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct stack_t { diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -20,20 +20,6 @@ __unused5: *mut ::c_void, } - // FIXME this is actually a union - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { - #[cfg(target_pointer_width = "32")] - __size: [::c_char; 16], - #[cfg(target_pointer_width = "64")] - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } - pub struct termios2 { pub c_iflag: ::tcflag_t, pub c_oflag: ::tcflag_t, @@ -927,7 +913,7 @@ sz: ::c_int) -> ::c_int; pub fn glob64(pattern: *const ::c_char, flags: ::c_int, - errfunc: ::dox::Option ::c_int>, pglob: *mut glob64_t) -> ::c_int; @@ -962,3 +948,13 @@ // Unknown target_arch } } + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/no_align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mips/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mips/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,5 @@ //! Linux-specific definitions for linux-like values -use dox::{mem, Option}; - pub type useconds_t = u32; pub type dev_t = u64; pub type socklen_t = u32; @@ -38,25 +36,14 @@ pub type Elf32_Section = u16; pub type Elf64_Section = u16; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos64_t {} // TODO: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { *self } +} s! { - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - pub struct rlimit64 { pub rlim_cur: rlim64_t, pub rlim_max: rlim64_t, @@ -75,150 +62,6 @@ __unused5: *mut ::c_void, } - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")))), - repr(align(8)))] - pub struct pthread_mutex_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")))), - repr(align(8)))] - pub struct pthread_rwlock_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64", - all(target_arch = "aarch64", target_env = "musl"))), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64", - all(target_arch = "aarch64", target_env = "musl")))), - repr(align(8)))] - pub struct pthread_mutexattr_t { - #[cfg(all(not(features = "align"), - any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64", - all(target_arch = "aarch64", target_env = "musl"))))] - __align: [::c_int; 0], - #[cfg(all(not(features = "align"), - not(any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64", - all(target_arch = "aarch64", target_env = "musl")))))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - - #[cfg_attr(all(feature = "align", - any(target_env = "musl", target_pointer_width = "32")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - target_pointer_width = "64"), - repr(align(8)))] - pub struct pthread_rwlockattr_t { - #[cfg(all(not(feature = "align"), target_env = "musl"))] - __align: [::c_int; 0], - #[cfg(all(not(feature = "align"), not(target_env = "musl")))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T], - } - - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "64"), - repr(align(8)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - target_arch = "x86"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - not(target_arch = "x86")), - repr(align(8)))] - pub struct pthread_cond_t { - #[cfg(all(not(feature = "align"), target_env = "musl"))] - __align: [*const ::c_void; 0], - #[cfg(not(any(feature = "align", target_env = "musl")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - pub struct passwd { pub pw_name: *mut ::c_char, pub pw_passwd: *mut ::c_char, @@ -346,11 +189,6 @@ pub msgseg: ::c_ushort, } - pub struct mmsghdr { - pub msg_hdr: ::msghdr, - pub msg_len: ::c_uint, - } - pub struct sembuf { pub sem_num: ::c_ushort, pub sem_op: ::c_short, @@ -655,6 +493,265 @@ pub updated: ::c_ulong, pub ha: [::c_uchar; ::MAX_ADDR_LEN], } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: ::uint32_t, + pub cookie: ::uint32_t, + pub len: ::uint32_t + } +} + +s_no_extra_traits!{ + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct af_alg_iv { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + impl Eq for af_alg_iv {} + + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("iv", &self.as_slice()) + .finish() + } + } + + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } + } + } } pub const ABDAY_1: ::nl_item = 0x20000; @@ -1315,6 +1412,15 @@ pub const ENOATTR: ::c_int = ::ENODATA; pub const SO_ORIGINAL_DST: ::c_int = 80; +pub const IP_ORIGDSTADDR : ::c_int = 20; +pub const IP_RECVORIGDSTADDR : ::c_int = IP_ORIGDSTADDR; +pub const IPV6_ORIGDSTADDR : ::c_int = 74; +pub const IPV6_RECVORIGDSTADDR : ::c_int = IPV6_ORIGDSTADDR; +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; pub const IUTF8: ::tcflag_t = 0x00004000; pub const CMSPAR: ::tcflag_t = 0o10000000000; @@ -1696,7 +1802,73 @@ pub const SOF_TIMESTAMPING_SYS_HARDWARE: ::c_uint = 1 << 5; pub const SOF_TIMESTAMPING_RAW_HARDWARE: ::c_uint = 1 << 6; +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; + +pub const ALG_OP_DECRYPT: ::c_int = 0; +pub const ALG_OP_ENCRYPT: ::c_int = 1; + +// uapi/linux/inotify.h +pub const IN_ACCESS: ::uint32_t = 0x0000_0001; +pub const IN_MODIFY: ::uint32_t = 0x0000_0002; +pub const IN_ATTRIB: ::uint32_t = 0x0000_0004; +pub const IN_CLOSE_WRITE: ::uint32_t = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: ::uint32_t = 0x0000_0010; +pub const IN_CLOSE: ::uint32_t = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE); +pub const IN_OPEN: ::uint32_t = 0x0000_0020; +pub const IN_MOVED_FROM: ::uint32_t = 0x0000_0040; +pub const IN_MOVED_TO: ::uint32_t = 0x0000_0080; +pub const IN_MOVE: ::uint32_t = (IN_MOVED_FROM | IN_MOVED_TO); +pub const IN_CREATE: ::uint32_t = 0x0000_0100; +pub const IN_DELETE: ::uint32_t = 0x0000_0200; +pub const IN_DELETE_SELF: ::uint32_t = 0x0000_0400; +pub const IN_MOVE_SELF: ::uint32_t = 0x0000_0800; +pub const IN_UNMOUNT: ::uint32_t = 0x0000_2000; +pub const IN_Q_OVERFLOW: ::uint32_t = 0x0000_4000; +pub const IN_IGNORED: ::uint32_t = 0x0000_8000; +pub const IN_ONLYDIR: ::uint32_t = 0x0100_0000; +pub const IN_DONT_FOLLOW: ::uint32_t = 0x0200_0000; +// pub const IN_EXCL_UNLINK: ::uint32_t = 0x0400_0000; + +// pub const IN_MASK_CREATE: ::uint32_t = 0x1000_0000; +// pub const IN_MASK_ADD: ::uint32_t = 0x2000_0000; +pub const IN_ISDIR: ::uint32_t = 0x4000_0000; +pub const IN_ONESHOT: ::uint32_t = 0x8000_0000; + +pub const IN_ALL_EVENTS: ::uint32_t = ( + IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | + IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | + IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | + IN_MOVE_SELF +); + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + f! { + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max || + next as usize + super::CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { for slot in cpuset.bits.iter_mut() { *slot = 0; @@ -1704,21 +1876,23 @@ } pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] |= 1 << offset; () } pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] &= !(1 << offset); () } pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); 0 != (cpuset.bits[idx] & (1 << offset)) } @@ -1979,7 +2153,7 @@ pub fn glob(pattern: *const c_char, flags: ::c_int, - errfunc: Option ::c_int>, pglob: *mut ::glob_t) -> ::c_int; pub fn globfree(pglob: *mut ::glob_t); @@ -2008,9 +2182,9 @@ pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; pub fn vhangup() -> ::c_int; - pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut mmsghdr, vlen: ::c_uint, + pub fn sendmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, flags: ::c_int) -> ::c_int; - pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut mmsghdr, vlen: ::c_uint, + pub fn recvmmsg(sockfd: ::c_int, msgvec: *mut ::mmsghdr, vlen: ::c_uint, flags: ::c_int, timeout: *mut ::timespec) -> ::c_int; pub fn sync(); pub fn syscall(num: ::c_long, ...) -> ::c_long; @@ -2104,7 +2278,7 @@ count: ::size_t) -> ::ssize_t; pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -2152,9 +2326,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn getgrgid(gid: ::gid_t) -> *mut ::group; pub fn getgrouplist(user: *const ::c_char, group: ::gid_t, @@ -2173,7 +2347,7 @@ f: extern fn(*mut ::c_void) -> *mut ::c_void, value: *mut ::c_void) -> ::c_int; pub fn dl_iterate_phdr( - callback: Option ::size_t; + pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, + path: *const ::c_char, + mask: ::uint32_t) -> ::c_int; } cfg_if! { @@ -2277,3 +2457,14 @@ pub use self::other::*; } } + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/b32/x86.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/b32/x86.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/b32/x86.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/b32/x86.rs 2019-05-15 11:26:24.000000000 +0000 @@ -116,15 +116,6 @@ __private: [u32; 22] } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 112], - } - pub struct siginfo_t { pub si_signo: ::c_int, pub si_errno: ::c_int, @@ -176,6 +167,62 @@ } } +s_no_extra_traits!{ + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + pub const SIGSTKSZ: ::size_t = 8192; pub const MINSIGSTKSZ: ::size_t = 2048; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/b64/x86_64.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/b64/x86_64.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/b64/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/b64/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -51,15 +51,6 @@ __private: [u64; 32], } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 512], - } - pub struct ipc_perm { pub __ipc_perm_key: ::key_t, pub uid: ::uid_t, @@ -73,6 +64,62 @@ } } +s_no_extra_traits!{ + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + // Syscall table pub const SYS_read: ::c_long = 0; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/musl/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/musl/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -37,7 +37,7 @@ pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, pub sa_flags: ::c_int, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct statvfs { @@ -78,7 +78,9 @@ pub l_len: ::off_t, pub l_pid: ::pid_t, } +} +s_no_extra_traits!{ pub struct sysinfo { pub uptime: ::c_ulong, pub loads: [::c_ulong; 3], @@ -97,6 +99,75 @@ } } +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sysinfo {} + + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + } +} + pub const SFD_CLOEXEC: ::c_int = 0x080000; pub const NCCS: usize = 32; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/no_align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,80 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64", + all(target_arch = "aarch64", + target_env = "musl")))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64", + all(target_arch = "aarch64", + target_env = "musl"))))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + #[cfg(target_env = "musl")] + __align: [::c_int; 0], + #[cfg(not(target_env = "musl"))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + #[cfg(target_env = "musl")] + __align: [*const ::c_void; 0], + #[cfg(not(target_env = "musl"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/b32/x86.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/b32/x86.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/b32/x86.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/b32/x86.rs 2019-05-15 11:26:24.000000000 +0000 @@ -31,22 +31,6 @@ pub st_space: [::c_long; 20], } - pub struct user_fpxregs_struct { - pub cwd: ::c_ushort, - pub swd: ::c_ushort, - pub twd: ::c_ushort, - pub fop: ::c_ushort, - pub fip: ::c_long, - pub fcs: ::c_long, - pub foo: ::c_long, - pub fos: ::c_long, - pub mxcsr: ::c_long, - __reserved: ::c_long, - pub st_space: [::c_long; 32], - pub xmm_space: [::c_long; 32], - padding: [::c_long; 56], - } - pub struct user_regs_struct { pub ebx: ::c_long, pub ecx: ::c_long, @@ -92,15 +76,6 @@ pub cr2: ::c_ulong, } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 112], - } - pub struct ipc_perm { pub __key: ::key_t, pub uid: ::uid_t, @@ -213,6 +188,132 @@ } } +s_no_extra_traits!{ + pub struct user_fpxregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub twd: ::c_ushort, + pub fop: ::c_ushort, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub mxcsr: ::c_long, + __reserved: ::c_long, + pub st_space: [::c_long; 32], + pub xmm_space: [::c_long; 32], + padding: [::c_long; 56], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpxregs_struct { + fn eq(&self, other: &user_fpxregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.twd == other.twd + && self.fop == other.fop + && self.fip == other.fip + && self.fcs == other.fcs + && self.foo == other.foo + && self.fos == other.fos + && self.mxcsr == other.mxcsr + // Ignore __reserved field + && self.st_space == other.st_space + && self.xmm_space == other.xmm_space + // Ignore padding field + } + } + + impl Eq for user_fpxregs_struct {} + + impl ::fmt::Debug for user_fpxregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpxregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("twd", &self.twd) + .field("fop", &self.fop) + .field("fip", &self.fip) + .field("fcs", &self.fcs) + .field("foo", &self.foo) + .field("fos", &self.fos) + .field("mxcsr", &self.mxcsr) + // Ignore __reserved field + .field("st_space", &self.st_space) + .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpxregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.twd.hash(state); + self.fop.hash(state); + self.fip.hash(state); + self.fcs.hash(state); + self.foo.hash(state); + self.fos.hash(state); + self.mxcsr.hash(state); + // Ignore __reserved field + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + // Ignore __private field + } + } + } +} + pub const O_DIRECT: ::c_int = 0x4000; pub const O_DIRECTORY: ::c_int = 0x10000; pub const O_NOFOLLOW: ::c_int = 0x20000; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/b64/x86_64.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/b64/x86_64.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/b64/x86_64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/b64/x86_64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -112,20 +112,6 @@ __private: [u64; 12], } - pub struct user_fpregs_struct { - pub cwd: ::c_ushort, - pub swd: ::c_ushort, - pub ftw: ::c_ushort, - pub fop: ::c_ushort, - pub rip: ::c_ulonglong, - pub rdp: ::c_ulonglong, - pub mxcsr: ::c_uint, - pub mxcr_mask: ::c_uint, - pub st_space: [::c_uint; 32], - pub xmm_space: [::c_uint; 64], - padding: [::c_uint; 24], - } - pub struct user_regs_struct { pub r15: ::c_ulonglong, pub r14: ::c_ulonglong, @@ -184,15 +170,6 @@ __private: [u64; 8], } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 512], - } - pub struct ipc_perm { pub __key: ::key_t, pub uid: ::uid_t, @@ -232,6 +209,126 @@ } } +s_no_extra_traits! { + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulonglong, + pub rdp: ::c_ulonglong, + pub mxcsr: ::c_uint, + pub mxcr_mask: ::c_uint, + pub st_space: [::c_uint; 32], + pub xmm_space: [::c_uint; 64], + padding: [::c_uint; 24], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpregs_struct { + fn eq(&self, other: &user_fpregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.ftw == other.ftw + && self.fop == other.fop + && self.rip == other.rip + && self.rdp == other.rdp + && self.mxcsr == other.mxcsr + && self.mxcr_mask == other.mxcr_mask + && self.st_space == other.st_space + && self + .xmm_space + .iter() + .zip(other.xmm_space.iter()) + .all(|(a,b)| a == b) + // Ignore padding field + } + } + + impl Eq for user_fpregs_struct {} + + impl ::fmt::Debug for user_fpregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpregs_struct") + .field("cwd", &self.cwd) + .field("ftw", &self.ftw) + .field("fop", &self.fop) + .field("rip", &self.rip) + .field("rdp", &self.rdp) + .field("mxcsr", &self.mxcsr) + .field("mxcr_mask", &self.mxcr_mask) + .field("st_space", &self.st_space) + // FIXME: .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.ftw.hash(state); + self.fop.hash(state); + self.rip.hash(state); + self.rdp.hash(state); + self.mxcsr.hash(state); + self.mxcr_mask.hash(state); + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .finish() + } + } + + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + // Ignore __private field + } + } + } +} + pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -29,49 +29,13 @@ pub tv_usec: ::int32_t, } - pub struct utmpx { - pub ut_type: ::c_short, - pub ut_pid: ::pid_t, - pub ut_line: [::c_char; __UT_LINESIZE], - pub ut_id: [::c_char; 4], - - pub ut_user: [::c_char; __UT_NAMESIZE], - pub ut_host: [::c_char; __UT_HOSTSIZE], - pub ut_exit: __exit_status, - - #[cfg(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64"))))] - pub ut_session: ::c_long, - #[cfg(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64"))))] - pub ut_tv: ::timeval, - - #[cfg(not(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64")))))] - pub ut_session: ::int32_t, - #[cfg(not(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64")))))] - pub ut_tv: __timeval, - - pub ut_addr_v6: [::int32_t; 4], - __glibc_reserved: [::c_char; 20], - } - pub struct sigaction { pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, #[cfg(target_arch = "sparc64")] __reserved0: ::c_int, pub sa_flags: ::c_int, - pub sa_restorer: ::dox::Option, + pub sa_restorer: ::Option, } pub struct stack_t { @@ -84,6 +48,12 @@ pub si_signo: ::c_int, pub si_errno: ::c_int, pub si_code: ::c_int, + #[deprecated( + since="0.2.54", + note="Please leave a comment on \ + https://github.com/rust-lang/libc/pull/1316 if you're using \ + this field" + )] pub _pad: [::c_int; 29], #[cfg(target_arch = "x86_64")] _align: [u64; 0], @@ -157,20 +127,6 @@ pub l_pid: ::pid_t, } - // FIXME this is actually a union - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { - #[cfg(target_pointer_width = "32")] - __size: [::c_char; 16], - #[cfg(target_pointer_width = "64")] - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } - pub struct mallinfo { pub arena: ::c_int, pub ordblks: ::c_int, @@ -244,6 +200,117 @@ } } +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + #[repr(C)] + struct siginfo_sigfault { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + si_addr: *mut ::c_void + } + (*(self as *const siginfo_t as *const siginfo_sigfault)).si_addr + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[cfg(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: ::int32_t, + #[cfg(not(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, + + pub ut_addr_v6: [::int32_t; 4], + __glibc_reserved: [::c_char; 20], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__glibc_reserved == other.__glibc_reserved + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__glibc_reserved", &self.__glibc_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__glibc_reserved.hash(state); + } + } + } +} + pub const __UT_LINESIZE: usize = 32; pub const __UT_NAMESIZE: usize = 32; pub const __UT_HOSTSIZE: usize = 256; @@ -273,7 +340,6 @@ pub const SOL_RDS: ::c_int = 276; pub const SOL_IUCV: ::c_int = 277; pub const SOL_CAIF: ::c_int = 278; -pub const SOL_ALG: ::c_int = 279; pub const SOL_NFC: ::c_int = 280; pub const SOL_XDP: ::c_int = 283; @@ -623,8 +689,7 @@ // linux/netfilter/nf_tables.h cfg_if!{ - if #[cfg(any(target_arch = "arm", target_arch = "powerpc", - target_arch = "powerpc64", target_arch = "aarch64"))] { + if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] { pub const NFT_TABLE_MAXNAMELEN: ::c_int = 32; pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 32; pub const NFT_SET_MAXNAMELEN: ::c_int = 32; @@ -879,7 +944,7 @@ sz: ::c_int) -> ::c_int; pub fn glob64(pattern: *const ::c_char, flags: ::c_int, - errfunc: ::dox::Option ::c_int>, pglob: *mut glob64_t) -> ::c_int; @@ -939,3 +1004,13 @@ // Unknown target_arch } } + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/no_align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/other/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/other/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1364 @@ +use ::pthread_mutex_t; + +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type ino_t = u64; +pub type nlink_t = u64; +pub type off_t = i64; +pub type rlim_t = u64; +pub type suseconds_t = i64; +pub type time_t = i64; +pub type wchar_t = i32; +pub type greg_t = u64; +pub type clock_t = i64; +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type __fsword_t = ::c_long; +pub type __priority_which_t = ::c_uint; +pub type __u64 = u64; + +s! { + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __next_prio: *mut aiocb, + __abs_prio: ::c_int, + __policy: ::c_int, + __error_code: ::c_int, + __return_value: ::ssize_t, + pub aio_offset: off_t, + #[cfg(target_pointer_width = "32")] + __unused1: [::c_char; 4], + __glibc_reserved: [::c_char; 32] + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + __glibc_reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + pub sa_mask: sigset_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct sigset_t { + __size: [::c_ulong; 16], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + f_spare: [::c_uint; 4], + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct termios2 { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; 19], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct __psw_t { + pub mask: u64, + pub addr: u64, + } + + pub struct fpregset_t { + pub fpc: u32, + __pad: u32, + pub fprs: [fpreg_t; 16], + } + + pub struct mcontext_t { + pub psw: __psw_t, + pub gregs: [u64; 16], + pub aregs: [u32; 16], + pub fpregs: fpregset_t, + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +s_no_extra_traits!{ + // FIXME: This is actually a union. + pub struct fpreg_t { + pub d: ::c_double, + // f: ::c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + + impl Eq for fpreg_t {} + + impl ::fmt::Debug for fpreg_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg_t") + .field("d", &self.d) + .finish() + } + } + + impl ::hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = unsafe { ::mem::transmute(self.d) }; + d.hash(state); + } + } + } +} + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_LARGEFILE: ::c_int = 0; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const EBFONT: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const EDOTDOT: ::c_int = 73; + +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const POSIX_FADV_DONTNEED: ::c_int = 6; +pub const POSIX_FADV_NOREUSE: ::c_int = 7; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +align_const! { + pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = + pthread_mutex_t { + size: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +pub const EDEADLK: ::c_int = 35; +pub const ENOSYS: ::c_int = 38; +pub const ENOTCONN: ::c_int = 107; +pub const ETIMEDOUT: ::c_int = 110; +pub const FIOCLEX: ::c_ulong = 0x5451; +pub const FIONBIO: ::c_ulong = 0x5421; +pub const MAP_ANON: ::c_int = 0x20; +pub const O_ACCMODE: ::c_int = 3; +pub const O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NONBLOCK: ::c_int = 2048; +pub const PTHREAD_STACK_MIN: ::size_t = 16384; +pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 3; +pub const RLIM_INFINITY: ::rlim_t = 0xffffffffffffffff; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 4; +pub const SIGBUS: ::c_int = 7; +pub const SIGSTKSZ: ::size_t = 0x2000; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIG_SETMASK: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOL_SOCKET: ::c_int = 1; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_ERROR: ::c_int = 4; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; + +pub const RLIMIT_RSS: ::c_int = 5; +pub const RLIMIT_NOFILE: ::c_int = 7; +pub const RLIMIT_AS: ::c_int = 9; +pub const RLIMIT_NPROC: ::c_int = 6; +pub const RLIMIT_MEMLOCK: ::c_int = 8; +pub const RLIMIT_RTTIME: ::c_int = 15; +pub const RLIMIT_NLIMITS: ::c_int = 16; + +pub const O_NOCTTY: ::c_int = 256; +pub const O_SYNC: ::c_int = 1052672; +pub const O_RSYNC: ::c_int = 1052672; +pub const O_DSYNC: ::c_int = 4096; +pub const O_FSYNC: ::c_int = 0x101000; +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_PAPER_MASK: ::c_int = (1 << LC_PAPER); +pub const LC_NAME_MASK: ::c_int = (1 << LC_NAME); +pub const LC_ADDRESS_MASK: ::c_int = (1 << LC_ADDRESS); +pub const LC_TELEPHONE_MASK: ::c_int = (1 << LC_TELEPHONE); +pub const LC_MEASUREMENT_MASK: ::c_int = (1 << LC_MEASUREMENT); +pub const LC_IDENTIFICATION_MASK: ::c_int = (1 << LC_IDENTIFICATION); +pub const LC_ALL_MASK: ::c_int = ::LC_CTYPE_MASK + | ::LC_NUMERIC_MASK + | ::LC_TIME_MASK + | ::LC_COLLATE_MASK + | ::LC_MONETARY_MASK + | ::LC_MESSAGES_MASK + | LC_PAPER_MASK + | LC_NAME_MASK + | LC_ADDRESS_MASK + | LC_TELEPHONE_MASK + | LC_MEASUREMENT_MASK + | LC_IDENTIFICATION_MASK; + +pub const MAP_ANONYMOUS: ::c_int = 0x0020; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_DENYWRITE: ::c_int = 0x0800; +pub const MAP_EXECUTABLE: ::c_int = 0x01000; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_POPULATE: ::c_int = 0x08000; +pub const MAP_NONBLOCK: ::c_int = 0x010000; +pub const MAP_STACK: ::c_int = 0x020000; + +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +pub const ENOTEMPTY: ::c_int = 39; +pub const ELOOP: ::c_int = 40; +pub const ENOMSG: ::c_int = 42; +pub const EIDRM: ::c_int = 43; +pub const ECHRNG: ::c_int = 44; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELNRNG: ::c_int = 48; +pub const EUNATCH: ::c_int = 49; +pub const ENOCSI: ::c_int = 50; +pub const EL2HLT: ::c_int = 51; +pub const EBADE: ::c_int = 52; +pub const EBADR: ::c_int = 53; +pub const EXFULL: ::c_int = 54; +pub const ENOANO: ::c_int = 55; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const EMULTIHOP: ::c_int = 72; +pub const EOVERFLOW: ::c_int = 75; +pub const ENOTUNIQ: ::c_int = 76; +pub const EBADFD: ::c_int = 77; +pub const EBADMSG: ::c_int = 74; +pub const EREMCHG: ::c_int = 78; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBSCN: ::c_int = 81; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; +pub const EUSERS: ::c_int = 87; +pub const ENOTSOCK: ::c_int = 88; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EMSGSIZE: ::c_int = 90; +pub const EPROTOTYPE: ::c_int = 91; +pub const ENOPROTOOPT: ::c_int = 92; +pub const EPROTONOSUPPORT: ::c_int = 93; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const EOPNOTSUPP: ::c_int = 95; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EALREADY: ::c_int = 114; +pub const EINPROGRESS: ::c_int = 115; +pub const ESTALE: ::c_int = 116; +pub const EUCLEAN: ::c_int = 117; +pub const ENOTNAM: ::c_int = 118; +pub const ENAVAIL: ::c_int = 119; +pub const EISNAM: ::c_int = 120; +pub const EREMOTEIO: ::c_int = 121; +pub const EDQUOT: ::c_int = 122; +pub const ENOMEDIUM: ::c_int = 123; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const ECANCELED: ::c_int = 125; +pub const ENOKEY: ::c_int = 126; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREVOKED: ::c_int = 128; +pub const EKEYREJECTED: ::c_int = 129; +pub const EOWNERDEAD: ::c_int = 130; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const EHWPOISON: ::c_int = 133; +pub const ERFKILL: ::c_int = 132; + +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SO_TYPE: ::c_int = 3; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; + +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; + +pub const SIGCHLD: ::c_int = 17; +pub const SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGCONT: ::c_int = 18; +pub const SIGSTOP: ::c_int = 19; +pub const SIGTSTP: ::c_int = 20; +pub const SIGURG: ::c_int = 23; +pub const SIGIO: ::c_int = 29; +pub const SIGSYS: ::c_int = 31; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGUNUSED: ::c_int = 31; +pub const SIGTTIN: ::c_int = 21; +pub const SIGTTOU: ::c_int = 22; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGWINCH: ::c_int = 28; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPWR: ::c_int = 30; +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const BUFSIZ: ::c_uint = 8192; +pub const TMP_MAX: ::c_uint = 238328; +pub const FOPEN_MAX: ::c_uint = 16; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; +pub const _SC_PII: ::c_int = 53; +pub const _SC_PII_XTI: ::c_int = 54; +pub const _SC_PII_SOCKET: ::c_int = 55; +pub const _SC_PII_INTERNET: ::c_int = 56; +pub const _SC_PII_OSI: ::c_int = 57; +pub const _SC_POLL: ::c_int = 58; +pub const _SC_SELECT: ::c_int = 59; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; +pub const _SC_PII_OSI_COTS: ::c_int = 63; +pub const _SC_PII_OSI_CLTS: ::c_int = 64; +pub const _SC_PII_OSI_M: ::c_int = 65; +pub const _SC_T_IOV_MAX: ::c_int = 66; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const _SC_CHAR_BIT: ::c_int = 101; +pub const _SC_CHAR_MAX: ::c_int = 102; +pub const _SC_CHAR_MIN: ::c_int = 103; +pub const _SC_INT_MAX: ::c_int = 104; +pub const _SC_INT_MIN: ::c_int = 105; +pub const _SC_LONG_BIT: ::c_int = 106; +pub const _SC_WORD_BIT: ::c_int = 107; +pub const _SC_MB_LEN_MAX: ::c_int = 108; +pub const _SC_SSIZE_MAX: ::c_int = 110; +pub const _SC_SCHAR_MAX: ::c_int = 111; +pub const _SC_SCHAR_MIN: ::c_int = 112; +pub const _SC_SHRT_MAX: ::c_int = 113; +pub const _SC_SHRT_MIN: ::c_int = 114; +pub const _SC_UCHAR_MAX: ::c_int = 115; +pub const _SC_UINT_MAX: ::c_int = 116; +pub const _SC_ULONG_MAX: ::c_int = 117; +pub const _SC_USHRT_MAX: ::c_int = 118; +pub const _SC_NL_ARGMAX: ::c_int = 119; +pub const _SC_NL_LANGMAX: ::c_int = 120; +pub const _SC_NL_MSGMAX: ::c_int = 121; +pub const _SC_NL_NMAX: ::c_int = 122; +pub const _SC_NL_SETMAX: ::c_int = 123; +pub const _SC_NL_TEXTMAX: ::c_int = 124; +pub const _SC_BASE: ::c_int = 134; +pub const _SC_C_LANG_SUPPORT: ::c_int = 135; +pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; +pub const _SC_DEVICE_IO: ::c_int = 140; +pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; +pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; +pub const _SC_FD_MGMT: ::c_int = 143; +pub const _SC_FIFO: ::c_int = 144; +pub const _SC_PIPE: ::c_int = 145; +pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; +pub const _SC_FILE_LOCKING: ::c_int = 147; +pub const _SC_FILE_SYSTEM: ::c_int = 148; +pub const _SC_MULTI_PROCESS: ::c_int = 150; +pub const _SC_SINGLE_PROCESS: ::c_int = 151; +pub const _SC_NETWORKING: ::c_int = 152; +pub const _SC_REGEX_VERSION: ::c_int = 156; +pub const _SC_SIGNALS: ::c_int = 158; +pub const _SC_SYSTEM_DATABASE: ::c_int = 162; +pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; +pub const _SC_USER_GROUPS: ::c_int = 166; +pub const _SC_USER_GROUPS_R: ::c_int = 167; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; +pub const ST_RELATIME: ::c_ulong = 4096; +pub const NI_MAXHOST: ::socklen_t = 1025; + +pub const ADFS_SUPER_MAGIC: ::c_int = 0x0000adf5; +pub const AFFS_SUPER_MAGIC: ::c_int = 0x0000adff; +pub const CODA_SUPER_MAGIC: ::c_int = 0x73757245; +pub const CRAMFS_MAGIC: ::c_int = 0x28cd3d45; +pub const EFS_SUPER_MAGIC: ::c_int = 0x00414a53; +pub const EXT2_SUPER_MAGIC: ::c_int = 0x0000ef53; +pub const EXT3_SUPER_MAGIC: ::c_int = 0x0000ef53; +pub const EXT4_SUPER_MAGIC: ::c_int = 0x0000ef53; +pub const HPFS_SUPER_MAGIC: ::c_int = 0xf995e849; +pub const HUGETLBFS_MAGIC: ::c_int = 0x958458f6; +pub const ISOFS_SUPER_MAGIC: ::c_int = 0x00009660; +pub const JFFS2_SUPER_MAGIC: ::c_int = 0x000072b6; +pub const MINIX_SUPER_MAGIC: ::c_int = 0x0000137f; +pub const MINIX_SUPER_MAGIC2: ::c_int = 0x0000138f; +pub const MINIX2_SUPER_MAGIC: ::c_int = 0x00002468; +pub const MINIX2_SUPER_MAGIC2: ::c_int = 0x00002478; +pub const MSDOS_SUPER_MAGIC: ::c_int = 0x00004d44; +pub const NCP_SUPER_MAGIC: ::c_int = 0x0000564c; +pub const NFS_SUPER_MAGIC: ::c_int = 0x00006969; +pub const OPENPROM_SUPER_MAGIC: ::c_int = 0x00009fa1; +pub const PROC_SUPER_MAGIC: ::c_int = 0x00009fa0; +pub const QNX4_SUPER_MAGIC: ::c_int = 0x0000002f; +pub const REISERFS_SUPER_MAGIC: ::c_int = 0x52654973; +pub const SMB_SUPER_MAGIC: ::c_int = 0x0000517b; +pub const TMPFS_MAGIC: ::c_int = 0x01021994; +pub const USBDEVICE_SUPER_MAGIC: ::c_int = 0x00009fa2; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 11; +pub const VEOL2: usize = 16; +pub const VMIN: usize = 6; +pub const IEXTEN: ::tcflag_t = 0x00008000; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const FLUSHO: ::tcflag_t = 0x00001000; + +pub const CPU_SETSIZE: ::c_int = 0x400; + +pub const EXTPROC: ::tcflag_t = 0x00010000; + +pub const PTRACE_TRACEME: ::c_uint = 0; +pub const PTRACE_PEEKTEXT: ::c_uint = 1; +pub const PTRACE_PEEKDATA: ::c_uint = 2; +pub const PTRACE_PEEKUSER: ::c_uint = 3; +pub const PTRACE_POKETEXT: ::c_uint = 4; +pub const PTRACE_POKEDATA: ::c_uint = 5; +pub const PTRACE_POKEUSER: ::c_uint = 6; +pub const PTRACE_CONT: ::c_uint = 7; +pub const PTRACE_KILL: ::c_uint = 8; +pub const PTRACE_SINGLESTEP: ::c_uint = 9; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_ATTACH: ::c_uint = 16; +pub const PTRACE_DETACH: ::c_uint = 17; +pub const PTRACE_SYSCALL: ::c_uint = 24; +pub const PTRACE_SETOPTIONS: ::c_uint = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_uint = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_uint = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_uint = 0x4203; +pub const PTRACE_GETREGSET: ::c_uint = 0x4204; +pub const PTRACE_SETREGSET: ::c_uint = 0x4205; +pub const PTRACE_SEIZE: ::c_uint = 0x4206; +pub const PTRACE_INTERRUPT: ::c_uint = 0x4207; +pub const PTRACE_LISTEN: ::c_uint = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_uint = 0x4209; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const EPOLLWAKEUP: ::c_int = 0x20000000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TCGETS: ::c_ulong = 0x5401; +pub const TCSETS: ::c_ulong = 0x5402; +pub const TCSETSW: ::c_ulong = 0x5403; +pub const TCSETSF: ::c_ulong = 0x5404; +pub const TCGETA: ::c_ulong = 0x5405; +pub const TCSETA: ::c_ulong = 0x5406; +pub const TCSETAW: ::c_ulong = 0x5407; +pub const TCSETAF: ::c_ulong = 0x5408; +pub const TCSBRK: ::c_ulong = 0x5409; +pub const TCXONC: ::c_ulong = 0x540A; +pub const TCFLSH: ::c_ulong = 0x540B; +pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; +pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; +pub const TIOCINQ: ::c_ulong = 0x541B; +pub const TIOCLINUX: ::c_ulong = 0x541C; +pub const TIOCGSERIAL: ::c_ulong = 0x541E; +pub const TIOCEXCL: ::c_ulong = 0x540C; +pub const TIOCNXCL: ::c_ulong = 0x540D; +pub const TIOCSCTTY: ::c_ulong = 0x540E; +pub const TIOCGPGRP: ::c_ulong = 0x540F; +pub const TIOCSPGRP: ::c_ulong = 0x5410; +pub const TIOCOUTQ: ::c_ulong = 0x5411; +pub const TIOCSTI: ::c_ulong = 0x5412; +pub const TIOCGWINSZ: ::c_ulong = 0x5413; +pub const TIOCSWINSZ: ::c_ulong = 0x5414; +pub const TIOCMGET: ::c_ulong = 0x5415; +pub const TIOCMBIS: ::c_ulong = 0x5416; +pub const TIOCMBIC: ::c_ulong = 0x5417; +pub const TIOCMSET: ::c_ulong = 0x5418; +pub const FIONREAD: ::c_ulong = 0x541B; +pub const TIOCCONS: ::c_ulong = 0x541D; + +pub const RTLD_DEEPBIND: ::c_int = 0x8; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; +pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; +pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; +pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; +pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; + +pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; +pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; +pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; +pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; +pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; +pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; +pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; +pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; + +pub const VTIME: usize = 5; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const FF1: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const TIOCM_LE: ::c_int = 0x001; +pub const TIOCM_DTR: ::c_int = 0x002; +pub const TIOCM_RTS: ::c_int = 0x004; +pub const TIOCM_ST: ::c_int = 0x008; +pub const TIOCM_SR: ::c_int = 0x010; +pub const TIOCM_CTS: ::c_int = 0x020; +pub const TIOCM_CAR: ::c_int = 0x040; +pub const TIOCM_RNG: ::c_int = 0x080; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const CBAUD: ::speed_t = 0o010017; +pub const B0: ::speed_t = 0o000000; +pub const B50: ::speed_t = 0o000001; +pub const B75: ::speed_t = 0o000002; +pub const B110: ::speed_t = 0o000003; +pub const B134: ::speed_t = 0o000004; +pub const B150: ::speed_t = 0o000005; +pub const B200: ::speed_t = 0o000006; +pub const B300: ::speed_t = 0o000007; +pub const B600: ::speed_t = 0o000010; +pub const B1200: ::speed_t = 0o000011; +pub const B1800: ::speed_t = 0o000012; +pub const B2400: ::speed_t = 0o000013; +pub const B4800: ::speed_t = 0o000014; +pub const B9600: ::speed_t = 0o000015; +pub const B19200: ::speed_t = 0o000016; +pub const B38400: ::speed_t = 0o000017; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const CREAD: ::tcflag_t = 0o000200; +pub const PARENB: ::tcflag_t = 0o000400; +pub const PARODD: ::tcflag_t = 0o001000; +pub const HUPCL: ::tcflag_t = 0o002000; +pub const CLOCAL: ::tcflag_t = 0o004000; +pub const CBAUDEX: ::tcflag_t = 0o010000; +pub const BOTHER: ::speed_t = 0o010000; +pub const B57600: ::speed_t = 0o010001; +pub const B115200: ::speed_t = 0o010002; +pub const B230400: ::speed_t = 0o010003; +pub const B460800: ::speed_t = 0o010004; +pub const B500000: ::speed_t = 0o010005; +pub const B576000: ::speed_t = 0o010006; +pub const B921600: ::speed_t = 0o010007; +pub const B1000000: ::speed_t = 0o010010; +pub const B1152000: ::speed_t = 0o010011; +pub const B1500000: ::speed_t = 0o010012; +pub const B2000000: ::speed_t = 0o010013; +pub const B2500000: ::speed_t = 0o010014; +pub const B3000000: ::speed_t = 0o010015; +pub const B3500000: ::speed_t = 0o010016; +pub const B4000000: ::speed_t = 0o010017; +pub const CIBAUD: ::tcflag_t = 0o02003600000; + +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const XCASE: ::tcflag_t = 0o000004; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const PENDIN: ::tcflag_t = 0o040000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; + +pub const SYS_exit: ::c_long = 1; +pub const SYS_fork: ::c_long = 2; +pub const SYS_read: ::c_long = 3; +pub const SYS_write: ::c_long = 4; +pub const SYS_open: ::c_long = 5; +pub const SYS_close: ::c_long = 6; +pub const SYS_restart_syscall: ::c_long = 7; +pub const SYS_creat: ::c_long = 8; +pub const SYS_link: ::c_long = 9; +pub const SYS_unlink: ::c_long = 10; +pub const SYS_execve: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_rename: ::c_long = 38; +pub const SYS_mkdir: ::c_long = 39; +pub const SYS_rmdir: ::c_long = 40; +pub const SYS_dup: ::c_long = 41; +pub const SYS_pipe: ::c_long = 42; +pub const SYS_times: ::c_long = 43; +pub const SYS_brk: ::c_long = 45; +pub const SYS_signal: ::c_long = 48; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_ustat: ::c_long = 62; +pub const SYS_dup2: ::c_long = 63; +pub const SYS_getppid: ::c_long = 64; +pub const SYS_getpgrp: ::c_long = 65; +pub const SYS_setsid: ::c_long = 66; +pub const SYS_sigaction: ::c_long = 67; +pub const SYS_sigsuspend: ::c_long = 72; +pub const SYS_sigpending: ::c_long = 73; +pub const SYS_sethostname: ::c_long = 74; +pub const SYS_setrlimit: ::c_long = 75; +pub const SYS_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_readlink: ::c_long = 85; +pub const SYS_uselib: ::c_long = 86; +pub const SYS_swapon: ::c_long = 87; +pub const SYS_reboot: ::c_long = 88; +pub const SYS_readdir: ::c_long = 89; +pub const SYS_mmap: ::c_long = 90; +pub const SYS_munmap: ::c_long = 91; +pub const SYS_truncate: ::c_long = 92; +pub const SYS_ftruncate: ::c_long = 93; +pub const SYS_fchmod: ::c_long = 94; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_socketcall: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_lookup_dcookie: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_wait4: ::c_long = 114; +pub const SYS_swapoff: ::c_long = 115; +pub const SYS_sysinfo: ::c_long = 116; +pub const SYS_ipc: ::c_long = 117; +pub const SYS_fsync: ::c_long = 118; +pub const SYS_sigreturn: ::c_long = 119; +pub const SYS_clone: ::c_long = 120; +pub const SYS_setdomainname: ::c_long = 121; +pub const SYS_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_create_module: ::c_long = 127; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +pub const SYS_get_kernel_syms: ::c_long = 130; +pub const SYS_quotactl: ::c_long = 131; +pub const SYS_getpgid: ::c_long = 132; +pub const SYS_fchdir: ::c_long = 133; +pub const SYS_bdflush: ::c_long = 134; +pub const SYS_sysfs: ::c_long = 135; +pub const SYS_personality: ::c_long = 136; +pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_getdents: ::c_long = 141; +pub const SYS_flock: ::c_long = 143; +pub const SYS_msync: ::c_long = 144; +pub const SYS_readv: ::c_long = 145; +pub const SYS_writev: ::c_long = 146; +pub const SYS_getsid: ::c_long = 147; +pub const SYS_fdatasync: ::c_long = 148; +pub const SYS__sysctl: ::c_long = 149; +pub const SYS_mlock: ::c_long = 150; +pub const SYS_munlock: ::c_long = 151; +pub const SYS_mlockall: ::c_long = 152; +pub const SYS_munlockall: ::c_long = 153; +pub const SYS_sched_setparam: ::c_long = 154; +pub const SYS_sched_getparam: ::c_long = 155; +pub const SYS_sched_setscheduler: ::c_long = 156; +pub const SYS_sched_getscheduler: ::c_long = 157; +pub const SYS_sched_yield: ::c_long = 158; +pub const SYS_sched_get_priority_max: ::c_long = 159; +pub const SYS_sched_get_priority_min: ::c_long = 160; +pub const SYS_sched_rr_get_interval: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_query_module: ::c_long = 167; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_prctl: ::c_long = 172; +pub const SYS_rt_sigreturn: ::c_long = 173; +pub const SYS_rt_sigaction: ::c_long = 174; +pub const SYS_rt_sigprocmask: ::c_long = 175; +pub const SYS_rt_sigpending: ::c_long = 176; +pub const SYS_rt_sigtimedwait: ::c_long = 177; +pub const SYS_rt_sigqueueinfo: ::c_long = 178; +pub const SYS_rt_sigsuspend: ::c_long = 179; +pub const SYS_pread64: ::c_long = 180; +pub const SYS_pwrite64: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 183; +pub const SYS_capget: ::c_long = 184; +pub const SYS_capset: ::c_long = 185; +pub const SYS_sigaltstack: ::c_long = 186; +pub const SYS_sendfile: ::c_long = 187; +pub const SYS_getpmsg: ::c_long = 188; +pub const SYS_putpmsg: ::c_long = 189; +pub const SYS_vfork: ::c_long = 190; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_readahead: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 224; +pub const SYS_lsetxattr: ::c_long = 225; +pub const SYS_fsetxattr: ::c_long = 226; +pub const SYS_getxattr: ::c_long = 227; +pub const SYS_lgetxattr: ::c_long = 228; +pub const SYS_fgetxattr: ::c_long = 229; +pub const SYS_listxattr: ::c_long = 230; +pub const SYS_llistxattr: ::c_long = 231; +pub const SYS_flistxattr: ::c_long = 232; +pub const SYS_removexattr: ::c_long = 233; +pub const SYS_lremovexattr: ::c_long = 234; +pub const SYS_fremovexattr: ::c_long = 235; +pub const SYS_gettid: ::c_long = 236; +pub const SYS_tkill: ::c_long = 237; +pub const SYS_futex: ::c_long = 238; +pub const SYS_sched_setaffinity: ::c_long = 239; +pub const SYS_sched_getaffinity: ::c_long = 240; +pub const SYS_tgkill: ::c_long = 241; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_epoll_create: ::c_long = 249; +pub const SYS_epoll_ctl: ::c_long = 250; +pub const SYS_epoll_wait: ::c_long = 251; +pub const SYS_set_tid_address: ::c_long = 252; +pub const SYS_fadvise64: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime: ::c_long = 255; +pub const SYS_timer_gettime: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime: ::c_long = 259; +pub const SYS_clock_gettime: ::c_long = 260; +pub const SYS_clock_getres: ::c_long = 261; +pub const SYS_clock_nanosleep: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 265; +pub const SYS_fstatfs64: ::c_long = 266; +pub const SYS_remap_file_pages: ::c_long = 267; +pub const SYS_mbind: ::c_long = 268; +pub const SYS_get_mempolicy: ::c_long = 269; +pub const SYS_set_mempolicy: ::c_long = 270; +pub const SYS_mq_open: ::c_long = 271; +pub const SYS_mq_unlink: ::c_long = 272; +pub const SYS_mq_timedsend: ::c_long = 273; +pub const SYS_mq_timedreceive: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_kexec_load: ::c_long = 277; +pub const SYS_add_key: ::c_long = 278; +pub const SYS_request_key: ::c_long = 279; +pub const SYS_keyctl: ::c_long = 280; +pub const SYS_waitid: ::c_long = 281; +pub const SYS_ioprio_set: ::c_long = 282; +pub const SYS_ioprio_get: ::c_long = 283; +pub const SYS_inotify_init: ::c_long = 284; +pub const SYS_inotify_add_watch: ::c_long = 285; +pub const SYS_inotify_rm_watch: ::c_long = 286; +pub const SYS_migrate_pages: ::c_long = 287; +pub const SYS_openat: ::c_long = 288; +pub const SYS_mkdirat: ::c_long = 289; +pub const SYS_mknodat: ::c_long = 290; +pub const SYS_fchownat: ::c_long = 291; +pub const SYS_futimesat: ::c_long = 292; +pub const SYS_unlinkat: ::c_long = 294; +pub const SYS_renameat: ::c_long = 295; +pub const SYS_linkat: ::c_long = 296; +pub const SYS_symlinkat: ::c_long = 297; +pub const SYS_readlinkat: ::c_long = 298; +pub const SYS_fchmodat: ::c_long = 299; +pub const SYS_faccessat: ::c_long = 300; +pub const SYS_pselect6: ::c_long = 301; +pub const SYS_ppoll: ::c_long = 302; +pub const SYS_unshare: ::c_long = 303; +pub const SYS_set_robust_list: ::c_long = 304; +pub const SYS_get_robust_list: ::c_long = 305; +pub const SYS_splice: ::c_long = 306; +pub const SYS_sync_file_range: ::c_long = 307; +pub const SYS_tee: ::c_long = 308; +pub const SYS_vmsplice: ::c_long = 309; +pub const SYS_move_pages: ::c_long = 310; +pub const SYS_getcpu: ::c_long = 311; +pub const SYS_epoll_pwait: ::c_long = 312; +pub const SYS_utimes: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_utimensat: ::c_long = 315; +pub const SYS_signalfd: ::c_long = 316; +pub const SYS_timerfd: ::c_long = 317; +pub const SYS_eventfd: ::c_long = 318; +pub const SYS_timerfd_create: ::c_long = 319; +pub const SYS_timerfd_settime: ::c_long = 320; +pub const SYS_timerfd_gettime: ::c_long = 321; +pub const SYS_signalfd4: ::c_long = 322; +pub const SYS_eventfd2: ::c_long = 323; +pub const SYS_inotify_init1: ::c_long = 324; +pub const SYS_pipe2: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_epoll_create1: ::c_long = 327; +pub const SYS_preadv: ::c_long = 328; +pub const SYS_pwritev: ::c_long = 329; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; +pub const SYS_perf_event_open: ::c_long = 331; +pub const SYS_fanotify_init: ::c_long = 332; +pub const SYS_fanotify_mark: ::c_long = 333; +pub const SYS_prlimit64: ::c_long = 334; +pub const SYS_name_to_handle_at: ::c_long = 335; +pub const SYS_open_by_handle_at: ::c_long = 336; +pub const SYS_clock_adjtime: ::c_long = 337; +pub const SYS_syncfs: ::c_long = 338; +pub const SYS_setns: ::c_long = 339; +pub const SYS_process_vm_readv: ::c_long = 340; +pub const SYS_process_vm_writev: ::c_long = 341; +pub const SYS_s390_runtime_instr: ::c_long = 342; +pub const SYS_kcmp: ::c_long = 343; +pub const SYS_finit_module: ::c_long = 344; +pub const SYS_sched_setattr: ::c_long = 345; +pub const SYS_sched_getattr: ::c_long = 346; +pub const SYS_renameat2: ::c_long = 347; +pub const SYS_seccomp: ::c_long = 348; +pub const SYS_getrandom: ::c_long = 349; +pub const SYS_memfd_create: ::c_long = 350; +pub const SYS_bpf: ::c_long = 351; +pub const SYS_s390_pci_mmio_write: ::c_long = 352; +pub const SYS_s390_pci_mmio_read: ::c_long = 353; +pub const SYS_execveat: ::c_long = 354; +pub const SYS_userfaultfd: ::c_long = 355; +pub const SYS_membarrier: ::c_long = 356; +pub const SYS_recvmmsg: ::c_long = 357; +pub const SYS_sendmmsg: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_mlock2: ::c_long = 374; +pub const SYS_copy_file_range: ::c_long = 375; +pub const SYS_preadv2: ::c_long = 376; +pub const SYS_pwritev2: ::c_long = 377; +pub const SYS_lchown: ::c_long = 198; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_select: ::c_long = 142; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_chown: ::c_long = 212; +pub const SYS_setfsuid: ::c_long = 215; +pub const SYS_setfsgid: ::c_long = 216; +pub const SYS_newfstatat: ::c_long = 293; + +#[link(name = "util")] +extern { + pub fn sysctl(name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t) + -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn backtrace(buf: *mut *mut ::c_void, + sz: ::c_int) -> ::c_int; + pub fn glob64(pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + pub fn pthread_attr_getaffinity_np(attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t) -> ::c_int; + pub fn pthread_attr_setaffinity_np(attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t) -> ::c_int; + pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which_t, who: ::id_t, + prio: ::c_int) -> ::c_int; + pub fn pthread_getaffinity_np(thread: ::pthread_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t) -> ::c_int; + pub fn pthread_setaffinity_np(thread: ::pthread_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t) -> ::c_int; + pub fn sched_getcpu() -> ::c_int; + pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; + pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; + pub fn makecontext(ucp: *mut ucontext_t, + func: extern fn (), + argc: ::c_int, ...); + pub fn swapcontext(uocp: *mut ucontext_t, + ucp: *const ucontext_t) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/no_align.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,7 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/linux/s390x.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/linux/s390x.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1336 +0,0 @@ -use pthread_mutex_t; - -pub type blkcnt_t = i64; -pub type blksize_t = i64; -pub type c_char = u8; -pub type c_long = i64; -pub type c_ulong = u64; -pub type fsblkcnt_t = u64; -pub type fsfilcnt_t = u64; -pub type ino_t = u64; -pub type nlink_t = u64; -pub type off_t = i64; -pub type rlim_t = u64; -pub type suseconds_t = i64; -pub type time_t = i64; -pub type wchar_t = i32; -pub type greg_t = u64; -pub type clock_t = i64; -pub type shmatt_t = ::c_ulong; -pub type msgqnum_t = ::c_ulong; -pub type msglen_t = ::c_ulong; -pub type __fsword_t = ::c_long; -pub type __priority_which_t = ::c_uint; -pub type __u64 = u64; - -s! { - pub struct aiocb { - pub aio_fildes: ::c_int, - pub aio_lio_opcode: ::c_int, - pub aio_reqprio: ::c_int, - pub aio_buf: *mut ::c_void, - pub aio_nbytes: ::size_t, - pub aio_sigevent: ::sigevent, - __next_prio: *mut aiocb, - __abs_prio: ::c_int, - __policy: ::c_int, - __error_code: ::c_int, - __return_value: ::ssize_t, - pub aio_offset: off_t, - #[cfg(target_pointer_width = "32")] - __unused1: [::c_char; 4], - __glibc_reserved: [::c_char; 32] - } - - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_nlink: ::nlink_t, - pub st_mode: ::mode_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - st_pad0: ::c_int, - pub st_rdev: ::dev_t, - pub st_size: ::off_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt_t, - __glibc_reserved: [::c_long; 3], - } - - pub struct stat64 { - pub st_dev: ::dev_t, - pub st_ino: ::ino64_t, - pub st_nlink: ::nlink_t, - pub st_mode: ::mode_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - st_pad0: ::c_int, - pub st_rdev: ::dev_t, - pub st_size: ::off_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt64_t, - __glibc_reserved: [::c_long; 3], - } - - pub struct pthread_attr_t { - __size: [::c_ulong; 7] - } - - pub struct sigaction { - pub sa_sigaction: ::sighandler_t, - __glibc_reserved0: ::c_int, - pub sa_flags: ::c_int, - pub sa_restorer: ::dox::Option, - pub sa_mask: sigset_t, - } - - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_flags: ::c_int, - pub ss_size: ::size_t, - } - - pub struct sigset_t { - __size: [::c_ulong; 16], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_errno: ::c_int, - pub si_code: ::c_int, - _pad: ::c_int, - _pad2: [::c_long; 14], - } - - pub struct ipc_perm { - pub __key: ::key_t, - pub uid: ::uid_t, - pub gid: ::gid_t, - pub cuid: ::uid_t, - pub cgid: ::gid_t, - pub mode: ::mode_t, - pub __seq: ::c_ushort, - __pad1: ::c_ushort, - __unused1: ::c_ulong, - __unused2: ::c_ulong - } - - pub struct shmid_ds { - pub shm_perm: ::ipc_perm, - pub shm_segsz: ::size_t, - pub shm_atime: ::time_t, - pub shm_dtime: ::time_t, - pub shm_ctime: ::time_t, - pub shm_cpid: ::pid_t, - pub shm_lpid: ::pid_t, - pub shm_nattch: ::shmatt_t, - __unused4: ::c_ulong, - __unused5: ::c_ulong - } - - pub struct statfs { - pub f_type: ::c_uint, - pub f_bsize: ::c_uint, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_fsid: ::fsid_t, - pub f_namelen: ::c_uint, - pub f_frsize: ::c_uint, - pub f_flags: ::c_uint, - f_spare: [::c_uint; 4], - } - - pub struct statvfs { - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_favail: ::fsfilcnt_t, - pub f_fsid: ::c_ulong, - pub f_flag: ::c_ulong, - pub f_namemax: ::c_ulong, - __f_spare: [::c_int; 6], - } - - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::size_t, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::size_t, - pub msg_flags: ::c_int, - } - - pub struct cmsghdr { - pub cmsg_len: ::size_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } - - pub struct termios { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_line: ::cc_t, - pub c_cc: [::cc_t; ::NCCS], - pub c_ispeed: ::speed_t, - pub c_ospeed: ::speed_t, - } - - pub struct termios2 { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_line: ::cc_t, - pub c_cc: [::cc_t; 19], - pub c_ispeed: ::speed_t, - pub c_ospeed: ::speed_t, - } - - pub struct sysinfo { - pub uptime: ::c_long, - pub loads: [::c_ulong; 3], - pub totalram: ::c_ulong, - pub freeram: ::c_ulong, - pub sharedram: ::c_ulong, - pub bufferram: ::c_ulong, - pub totalswap: ::c_ulong, - pub freeswap: ::c_ulong, - pub procs: ::c_ushort, - pub pad: ::c_ushort, - pub totalhigh: ::c_ulong, - pub freehigh: ::c_ulong, - pub mem_unit: ::c_uint, - pub _f: [::c_char; 0], - } - - pub struct glob64_t { - pub gl_pathc: ::size_t, - pub gl_pathv: *mut *mut ::c_char, - pub gl_offs: ::size_t, - pub gl_flags: ::c_int, - - __unused1: *mut ::c_void, - __unused2: *mut ::c_void, - __unused3: *mut ::c_void, - __unused4: *mut ::c_void, - __unused5: *mut ::c_void, - } - - pub struct flock { - pub l_type: ::c_short, - pub l_whence: ::c_short, - pub l_start: ::off_t, - pub l_len: ::off_t, - pub l_pid: ::pid_t, - } - - // FIXME this is actually a union - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } - - pub struct __psw_t { - pub mask: u64, - pub addr: u64, - } - - // FIXME: This is actually a union. - pub struct fpreg_t { - pub d: ::c_double, - // f: ::c_float, - } - - pub struct fpregset_t { - pub fpc: u32, - __pad: u32, - pub fprs: [fpreg_t; 16], - } - - pub struct mcontext_t { - pub psw: __psw_t, - pub gregs: [u64; 16], - pub aregs: [u32; 16], - pub fpregs: fpregset_t, - } - - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - } - - pub struct msqid_ds { - pub msg_perm: ::ipc_perm, - pub msg_stime: ::time_t, - pub msg_rtime: ::time_t, - pub msg_ctime: ::time_t, - __msg_cbytes: ::c_ulong, - pub msg_qnum: ::msgqnum_t, - pub msg_qbytes: ::msglen_t, - pub msg_lspid: ::pid_t, - pub msg_lrpid: ::pid_t, - __glibc_reserved4: ::c_ulong, - __glibc_reserved5: ::c_ulong, - } - - pub struct statfs64 { - pub f_type: ::c_uint, - pub f_bsize: ::c_uint, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_fsid: ::fsid_t, - pub f_namelen: ::c_uint, - pub f_frsize: ::c_uint, - pub f_flags: ::c_uint, - pub f_spare: [::c_uint; 4], - } - - pub struct statvfs64 { - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_favail: u64, - pub f_fsid: ::c_ulong, - pub f_flag: ::c_ulong, - pub f_namemax: ::c_ulong, - __f_spare: [::c_int; 6], - } -} - -pub const SFD_CLOEXEC: ::c_int = 0x080000; - -pub const NCCS: usize = 32; - -pub const O_TRUNC: ::c_int = 512; -pub const O_LARGEFILE: ::c_int = 0; -pub const O_NOATIME: ::c_int = 0o1000000; -pub const O_CLOEXEC: ::c_int = 0x80000; -pub const O_PATH: ::c_int = 0o10000000; -pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; - -pub const EBFONT: ::c_int = 59; -pub const ENOSTR: ::c_int = 60; -pub const ENODATA: ::c_int = 61; -pub const ETIME: ::c_int = 62; -pub const ENOSR: ::c_int = 63; -pub const ENONET: ::c_int = 64; -pub const ENOPKG: ::c_int = 65; -pub const EREMOTE: ::c_int = 66; -pub const ENOLINK: ::c_int = 67; -pub const EADV: ::c_int = 68; -pub const ESRMNT: ::c_int = 69; -pub const ECOMM: ::c_int = 70; -pub const EPROTO: ::c_int = 71; -pub const EDOTDOT: ::c_int = 73; - -pub const SA_NODEFER: ::c_int = 0x40000000; -pub const SA_RESETHAND: ::c_int = 0x80000000; -pub const SA_RESTART: ::c_int = 0x10000000; -pub const SA_NOCLDSTOP: ::c_int = 0x00000001; - -pub const EPOLL_CLOEXEC: ::c_int = 0x80000; - -pub const EFD_CLOEXEC: ::c_int = 0x80000; - -pub const POSIX_FADV_DONTNEED: ::c_int = 6; -pub const POSIX_FADV_NOREUSE: ::c_int = 7; - -pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; -pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; -pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; - -align_const! { - pub const PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = - pthread_mutex_t { - size: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - }; - pub const PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = - pthread_mutex_t { - size: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - }; - pub const PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP: ::pthread_mutex_t = - pthread_mutex_t { - size: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - }; -} - -pub const EADDRINUSE: ::c_int = 98; -pub const EADDRNOTAVAIL: ::c_int = 99; -pub const ECONNABORTED: ::c_int = 103; -pub const ECONNREFUSED: ::c_int = 111; -pub const ECONNRESET: ::c_int = 104; -pub const EDEADLK: ::c_int = 35; -pub const ENOSYS: ::c_int = 38; -pub const ENOTCONN: ::c_int = 107; -pub const ETIMEDOUT: ::c_int = 110; -pub const FIOCLEX: ::c_ulong = 0x5451; -pub const FIONBIO: ::c_ulong = 0x5421; -pub const MAP_ANON: ::c_int = 0x20; -pub const O_ACCMODE: ::c_int = 3; -pub const O_APPEND: ::c_int = 1024; -pub const O_CREAT: ::c_int = 64; -pub const O_EXCL: ::c_int = 128; -pub const O_NONBLOCK: ::c_int = 2048; -pub const PTHREAD_STACK_MIN: ::size_t = 16384; -pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 3; -pub const RLIM_INFINITY: ::rlim_t = 0xffffffffffffffff; -pub const SA_NOCLDWAIT: ::c_int = 2; -pub const SA_ONSTACK: ::c_int = 0x08000000; -pub const SA_SIGINFO: ::c_int = 4; -pub const SIGBUS: ::c_int = 7; -pub const SIGSTKSZ: ::size_t = 0x2000; -pub const MINSIGSTKSZ: ::size_t = 2048; -pub const SIG_SETMASK: ::c_int = 2; -pub const SOCK_DGRAM: ::c_int = 2; -pub const SOCK_STREAM: ::c_int = 1; -pub const SOL_SOCKET: ::c_int = 1; -pub const SO_BROADCAST: ::c_int = 6; -pub const SO_ERROR: ::c_int = 4; -pub const SO_RCVTIMEO: ::c_int = 20; -pub const SO_REUSEADDR: ::c_int = 2; -pub const SO_SNDTIMEO: ::c_int = 21; -pub const SO_BINDTODEVICE: ::c_int = 25; -pub const SO_TIMESTAMP: ::c_int = 29; -pub const SO_MARK: ::c_int = 36; -pub const SO_PROTOCOL: ::c_int = 38; -pub const SO_DOMAIN: ::c_int = 39; -pub const SO_RXQ_OVFL: ::c_int = 40; -pub const SO_PEEK_OFF: ::c_int = 42; -pub const SO_BUSY_POLL: ::c_int = 46; - -pub const RLIMIT_RSS: ::c_int = 5; -pub const RLIMIT_NOFILE: ::c_int = 7; -pub const RLIMIT_AS: ::c_int = 9; -pub const RLIMIT_NPROC: ::c_int = 6; -pub const RLIMIT_MEMLOCK: ::c_int = 8; -pub const RLIMIT_RTTIME: ::c_int = 15; -pub const RLIMIT_NLIMITS: ::c_int = 16; - -pub const O_NOCTTY: ::c_int = 256; -pub const O_SYNC: ::c_int = 1052672; -pub const O_RSYNC: ::c_int = 1052672; -pub const O_DSYNC: ::c_int = 4096; -pub const O_FSYNC: ::c_int = 0x101000; -pub const O_DIRECT: ::c_int = 0x4000; -pub const O_DIRECTORY: ::c_int = 0x10000; -pub const O_NOFOLLOW: ::c_int = 0x20000; - -pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; - -pub const LC_PAPER: ::c_int = 7; -pub const LC_NAME: ::c_int = 8; -pub const LC_ADDRESS: ::c_int = 9; -pub const LC_TELEPHONE: ::c_int = 10; -pub const LC_MEASUREMENT: ::c_int = 11; -pub const LC_IDENTIFICATION: ::c_int = 12; -pub const LC_PAPER_MASK: ::c_int = (1 << LC_PAPER); -pub const LC_NAME_MASK: ::c_int = (1 << LC_NAME); -pub const LC_ADDRESS_MASK: ::c_int = (1 << LC_ADDRESS); -pub const LC_TELEPHONE_MASK: ::c_int = (1 << LC_TELEPHONE); -pub const LC_MEASUREMENT_MASK: ::c_int = (1 << LC_MEASUREMENT); -pub const LC_IDENTIFICATION_MASK: ::c_int = (1 << LC_IDENTIFICATION); -pub const LC_ALL_MASK: ::c_int = ::LC_CTYPE_MASK - | ::LC_NUMERIC_MASK - | ::LC_TIME_MASK - | ::LC_COLLATE_MASK - | ::LC_MONETARY_MASK - | ::LC_MESSAGES_MASK - | LC_PAPER_MASK - | LC_NAME_MASK - | LC_ADDRESS_MASK - | LC_TELEPHONE_MASK - | LC_MEASUREMENT_MASK - | LC_IDENTIFICATION_MASK; - -pub const MAP_ANONYMOUS: ::c_int = 0x0020; -pub const MAP_GROWSDOWN: ::c_int = 0x0100; -pub const MAP_DENYWRITE: ::c_int = 0x0800; -pub const MAP_EXECUTABLE: ::c_int = 0x01000; -pub const MAP_LOCKED: ::c_int = 0x02000; -pub const MAP_NORESERVE: ::c_int = 0x04000; -pub const MAP_POPULATE: ::c_int = 0x08000; -pub const MAP_NONBLOCK: ::c_int = 0x010000; -pub const MAP_STACK: ::c_int = 0x020000; - -pub const EDEADLOCK: ::c_int = 35; -pub const ENAMETOOLONG: ::c_int = 36; -pub const ENOLCK: ::c_int = 37; -pub const ENOTEMPTY: ::c_int = 39; -pub const ELOOP: ::c_int = 40; -pub const ENOMSG: ::c_int = 42; -pub const EIDRM: ::c_int = 43; -pub const ECHRNG: ::c_int = 44; -pub const EL2NSYNC: ::c_int = 45; -pub const EL3HLT: ::c_int = 46; -pub const EL3RST: ::c_int = 47; -pub const ELNRNG: ::c_int = 48; -pub const EUNATCH: ::c_int = 49; -pub const ENOCSI: ::c_int = 50; -pub const EL2HLT: ::c_int = 51; -pub const EBADE: ::c_int = 52; -pub const EBADR: ::c_int = 53; -pub const EXFULL: ::c_int = 54; -pub const ENOANO: ::c_int = 55; -pub const EBADRQC: ::c_int = 56; -pub const EBADSLT: ::c_int = 57; -pub const EMULTIHOP: ::c_int = 72; -pub const EOVERFLOW: ::c_int = 75; -pub const ENOTUNIQ: ::c_int = 76; -pub const EBADFD: ::c_int = 77; -pub const EBADMSG: ::c_int = 74; -pub const EREMCHG: ::c_int = 78; -pub const ELIBACC: ::c_int = 79; -pub const ELIBBAD: ::c_int = 80; -pub const ELIBSCN: ::c_int = 81; -pub const ELIBMAX: ::c_int = 82; -pub const ELIBEXEC: ::c_int = 83; -pub const EILSEQ: ::c_int = 84; -pub const ERESTART: ::c_int = 85; -pub const ESTRPIPE: ::c_int = 86; -pub const EUSERS: ::c_int = 87; -pub const ENOTSOCK: ::c_int = 88; -pub const EDESTADDRREQ: ::c_int = 89; -pub const EMSGSIZE: ::c_int = 90; -pub const EPROTOTYPE: ::c_int = 91; -pub const ENOPROTOOPT: ::c_int = 92; -pub const EPROTONOSUPPORT: ::c_int = 93; -pub const ESOCKTNOSUPPORT: ::c_int = 94; -pub const EOPNOTSUPP: ::c_int = 95; -pub const ENOTSUP: ::c_int = EOPNOTSUPP; -pub const EPFNOSUPPORT: ::c_int = 96; -pub const EAFNOSUPPORT: ::c_int = 97; -pub const ENETDOWN: ::c_int = 100; -pub const ENETUNREACH: ::c_int = 101; -pub const ENETRESET: ::c_int = 102; -pub const ENOBUFS: ::c_int = 105; -pub const EISCONN: ::c_int = 106; -pub const ESHUTDOWN: ::c_int = 108; -pub const ETOOMANYREFS: ::c_int = 109; -pub const EHOSTDOWN: ::c_int = 112; -pub const EHOSTUNREACH: ::c_int = 113; -pub const EALREADY: ::c_int = 114; -pub const EINPROGRESS: ::c_int = 115; -pub const ESTALE: ::c_int = 116; -pub const EUCLEAN: ::c_int = 117; -pub const ENOTNAM: ::c_int = 118; -pub const ENAVAIL: ::c_int = 119; -pub const EISNAM: ::c_int = 120; -pub const EREMOTEIO: ::c_int = 121; -pub const EDQUOT: ::c_int = 122; -pub const ENOMEDIUM: ::c_int = 123; -pub const EMEDIUMTYPE: ::c_int = 124; -pub const ECANCELED: ::c_int = 125; -pub const ENOKEY: ::c_int = 126; -pub const EKEYEXPIRED: ::c_int = 127; -pub const EKEYREVOKED: ::c_int = 128; -pub const EKEYREJECTED: ::c_int = 129; -pub const EOWNERDEAD: ::c_int = 130; -pub const ENOTRECOVERABLE: ::c_int = 131; -pub const EHWPOISON: ::c_int = 133; -pub const ERFKILL: ::c_int = 132; - -pub const SOCK_SEQPACKET: ::c_int = 5; - -pub const SO_TYPE: ::c_int = 3; -pub const SO_DONTROUTE: ::c_int = 5; -pub const SO_SNDBUF: ::c_int = 7; -pub const SO_RCVBUF: ::c_int = 8; -pub const SO_KEEPALIVE: ::c_int = 9; -pub const SO_OOBINLINE: ::c_int = 10; -pub const SO_PRIORITY: ::c_int = 12; -pub const SO_LINGER: ::c_int = 13; -pub const SO_BSDCOMPAT: ::c_int = 14; -pub const SO_REUSEPORT: ::c_int = 15; -pub const SO_PASSCRED: ::c_int = 16; -pub const SO_PEERCRED: ::c_int = 17; -pub const SO_RCVLOWAT: ::c_int = 18; -pub const SO_SNDLOWAT: ::c_int = 19; -pub const SO_ACCEPTCONN: ::c_int = 30; -pub const SO_SNDBUFFORCE: ::c_int = 32; -pub const SO_RCVBUFFORCE: ::c_int = 33; - -pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; -pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; -pub const TCP_THIN_DUPACK: ::c_int = 17; -pub const TCP_USER_TIMEOUT: ::c_int = 18; -pub const TCP_REPAIR: ::c_int = 19; -pub const TCP_REPAIR_QUEUE: ::c_int = 20; -pub const TCP_QUEUE_SEQ: ::c_int = 21; -pub const TCP_REPAIR_OPTIONS: ::c_int = 22; -pub const TCP_FASTOPEN: ::c_int = 23; -pub const TCP_TIMESTAMP: ::c_int = 24; - -pub const SIGCHLD: ::c_int = 17; -pub const SIGUSR1: ::c_int = 10; -pub const SIGUSR2: ::c_int = 12; -pub const SIGCONT: ::c_int = 18; -pub const SIGSTOP: ::c_int = 19; -pub const SIGTSTP: ::c_int = 20; -pub const SIGURG: ::c_int = 23; -pub const SIGIO: ::c_int = 29; -pub const SIGSYS: ::c_int = 31; -pub const SIGSTKFLT: ::c_int = 16; -pub const SIGUNUSED: ::c_int = 31; -pub const SIGTTIN: ::c_int = 21; -pub const SIGTTOU: ::c_int = 22; -pub const SIGXCPU: ::c_int = 24; -pub const SIGXFSZ: ::c_int = 25; -pub const SIGVTALRM: ::c_int = 26; -pub const SIGPROF: ::c_int = 27; -pub const SIGWINCH: ::c_int = 28; -pub const SIGPOLL: ::c_int = 29; -pub const SIGPWR: ::c_int = 30; -pub const SIG_BLOCK: ::c_int = 0x000000; -pub const SIG_UNBLOCK: ::c_int = 0x01; - -pub const BUFSIZ: ::c_uint = 8192; -pub const TMP_MAX: ::c_uint = 238328; -pub const FOPEN_MAX: ::c_uint = 16; -pub const POSIX_MADV_DONTNEED: ::c_int = 4; -pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; -pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; -pub const _SC_PII: ::c_int = 53; -pub const _SC_PII_XTI: ::c_int = 54; -pub const _SC_PII_SOCKET: ::c_int = 55; -pub const _SC_PII_INTERNET: ::c_int = 56; -pub const _SC_PII_OSI: ::c_int = 57; -pub const _SC_POLL: ::c_int = 58; -pub const _SC_SELECT: ::c_int = 59; -pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; -pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; -pub const _SC_PII_OSI_COTS: ::c_int = 63; -pub const _SC_PII_OSI_CLTS: ::c_int = 64; -pub const _SC_PII_OSI_M: ::c_int = 65; -pub const _SC_T_IOV_MAX: ::c_int = 66; -pub const _SC_2_C_VERSION: ::c_int = 96; -pub const _SC_CHAR_BIT: ::c_int = 101; -pub const _SC_CHAR_MAX: ::c_int = 102; -pub const _SC_CHAR_MIN: ::c_int = 103; -pub const _SC_INT_MAX: ::c_int = 104; -pub const _SC_INT_MIN: ::c_int = 105; -pub const _SC_LONG_BIT: ::c_int = 106; -pub const _SC_WORD_BIT: ::c_int = 107; -pub const _SC_MB_LEN_MAX: ::c_int = 108; -pub const _SC_SSIZE_MAX: ::c_int = 110; -pub const _SC_SCHAR_MAX: ::c_int = 111; -pub const _SC_SCHAR_MIN: ::c_int = 112; -pub const _SC_SHRT_MAX: ::c_int = 113; -pub const _SC_SHRT_MIN: ::c_int = 114; -pub const _SC_UCHAR_MAX: ::c_int = 115; -pub const _SC_UINT_MAX: ::c_int = 116; -pub const _SC_ULONG_MAX: ::c_int = 117; -pub const _SC_USHRT_MAX: ::c_int = 118; -pub const _SC_NL_ARGMAX: ::c_int = 119; -pub const _SC_NL_LANGMAX: ::c_int = 120; -pub const _SC_NL_MSGMAX: ::c_int = 121; -pub const _SC_NL_NMAX: ::c_int = 122; -pub const _SC_NL_SETMAX: ::c_int = 123; -pub const _SC_NL_TEXTMAX: ::c_int = 124; -pub const _SC_BASE: ::c_int = 134; -pub const _SC_C_LANG_SUPPORT: ::c_int = 135; -pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; -pub const _SC_DEVICE_IO: ::c_int = 140; -pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; -pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; -pub const _SC_FD_MGMT: ::c_int = 143; -pub const _SC_FIFO: ::c_int = 144; -pub const _SC_PIPE: ::c_int = 145; -pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; -pub const _SC_FILE_LOCKING: ::c_int = 147; -pub const _SC_FILE_SYSTEM: ::c_int = 148; -pub const _SC_MULTI_PROCESS: ::c_int = 150; -pub const _SC_SINGLE_PROCESS: ::c_int = 151; -pub const _SC_NETWORKING: ::c_int = 152; -pub const _SC_REGEX_VERSION: ::c_int = 156; -pub const _SC_SIGNALS: ::c_int = 158; -pub const _SC_SYSTEM_DATABASE: ::c_int = 162; -pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; -pub const _SC_USER_GROUPS: ::c_int = 166; -pub const _SC_USER_GROUPS_R: ::c_int = 167; -pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; -pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; -pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; -pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; -pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; -pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; -pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; -pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; -pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; -pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; -pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; -pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; -pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; -pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; -pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; -pub const O_ASYNC: ::c_int = 0x2000; -pub const O_NDELAY: ::c_int = 0x800; -pub const ST_RELATIME: ::c_ulong = 4096; -pub const NI_MAXHOST: ::socklen_t = 1025; - -pub const ADFS_SUPER_MAGIC: ::c_int = 0x0000adf5; -pub const AFFS_SUPER_MAGIC: ::c_int = 0x0000adff; -pub const CODA_SUPER_MAGIC: ::c_int = 0x73757245; -pub const CRAMFS_MAGIC: ::c_int = 0x28cd3d45; -pub const EFS_SUPER_MAGIC: ::c_int = 0x00414a53; -pub const EXT2_SUPER_MAGIC: ::c_int = 0x0000ef53; -pub const EXT3_SUPER_MAGIC: ::c_int = 0x0000ef53; -pub const EXT4_SUPER_MAGIC: ::c_int = 0x0000ef53; -pub const HPFS_SUPER_MAGIC: ::c_int = 0xf995e849; -pub const HUGETLBFS_MAGIC: ::c_int = 0x958458f6; -pub const ISOFS_SUPER_MAGIC: ::c_int = 0x00009660; -pub const JFFS2_SUPER_MAGIC: ::c_int = 0x000072b6; -pub const MINIX_SUPER_MAGIC: ::c_int = 0x0000137f; -pub const MINIX_SUPER_MAGIC2: ::c_int = 0x0000138f; -pub const MINIX2_SUPER_MAGIC: ::c_int = 0x00002468; -pub const MINIX2_SUPER_MAGIC2: ::c_int = 0x00002478; -pub const MSDOS_SUPER_MAGIC: ::c_int = 0x00004d44; -pub const NCP_SUPER_MAGIC: ::c_int = 0x0000564c; -pub const NFS_SUPER_MAGIC: ::c_int = 0x00006969; -pub const OPENPROM_SUPER_MAGIC: ::c_int = 0x00009fa1; -pub const PROC_SUPER_MAGIC: ::c_int = 0x00009fa0; -pub const QNX4_SUPER_MAGIC: ::c_int = 0x0000002f; -pub const REISERFS_SUPER_MAGIC: ::c_int = 0x52654973; -pub const SMB_SUPER_MAGIC: ::c_int = 0x0000517b; -pub const TMPFS_MAGIC: ::c_int = 0x01021994; -pub const USBDEVICE_SUPER_MAGIC: ::c_int = 0x00009fa2; - -pub const VEOF: usize = 4; -pub const VEOL: usize = 11; -pub const VEOL2: usize = 16; -pub const VMIN: usize = 6; -pub const IEXTEN: ::tcflag_t = 0x00008000; -pub const TOSTOP: ::tcflag_t = 0x00000100; -pub const FLUSHO: ::tcflag_t = 0x00001000; - -pub const CPU_SETSIZE: ::c_int = 0x400; - -pub const EXTPROC: ::tcflag_t = 0x00010000; - -pub const PTRACE_TRACEME: ::c_uint = 0; -pub const PTRACE_PEEKTEXT: ::c_uint = 1; -pub const PTRACE_PEEKDATA: ::c_uint = 2; -pub const PTRACE_PEEKUSER: ::c_uint = 3; -pub const PTRACE_POKETEXT: ::c_uint = 4; -pub const PTRACE_POKEDATA: ::c_uint = 5; -pub const PTRACE_POKEUSER: ::c_uint = 6; -pub const PTRACE_CONT: ::c_uint = 7; -pub const PTRACE_KILL: ::c_uint = 8; -pub const PTRACE_SINGLESTEP: ::c_uint = 9; -pub const PTRACE_GETREGS: ::c_uint = 12; -pub const PTRACE_SETREGS: ::c_uint = 13; -pub const PTRACE_GETFPREGS: ::c_uint = 14; -pub const PTRACE_SETFPREGS: ::c_uint = 15; -pub const PTRACE_ATTACH: ::c_uint = 16; -pub const PTRACE_DETACH: ::c_uint = 17; -pub const PTRACE_SYSCALL: ::c_uint = 24; -pub const PTRACE_SETOPTIONS: ::c_uint = 0x4200; -pub const PTRACE_GETEVENTMSG: ::c_uint = 0x4201; -pub const PTRACE_GETSIGINFO: ::c_uint = 0x4202; -pub const PTRACE_SETSIGINFO: ::c_uint = 0x4203; -pub const PTRACE_GETREGSET: ::c_uint = 0x4204; -pub const PTRACE_SETREGSET: ::c_uint = 0x4205; -pub const PTRACE_SEIZE: ::c_uint = 0x4206; -pub const PTRACE_INTERRUPT: ::c_uint = 0x4207; -pub const PTRACE_LISTEN: ::c_uint = 0x4208; -pub const PTRACE_PEEKSIGINFO: ::c_uint = 0x4209; - -pub const MCL_CURRENT: ::c_int = 0x0001; -pub const MCL_FUTURE: ::c_int = 0x0002; - -pub const EPOLLWAKEUP: ::c_int = 0x20000000; - -pub const MAP_HUGETLB: ::c_int = 0x040000; - -pub const EFD_NONBLOCK: ::c_int = 0x800; - -pub const F_RDLCK: ::c_int = 0; -pub const F_WRLCK: ::c_int = 1; -pub const F_UNLCK: ::c_int = 2; -pub const F_GETLK: ::c_int = 5; -pub const F_GETOWN: ::c_int = 9; -pub const F_SETOWN: ::c_int = 8; -pub const F_SETLK: ::c_int = 6; -pub const F_SETLKW: ::c_int = 7; - -pub const SEEK_DATA: ::c_int = 3; -pub const SEEK_HOLE: ::c_int = 4; - -pub const SFD_NONBLOCK: ::c_int = 0x0800; - -pub const TCSANOW: ::c_int = 0; -pub const TCSADRAIN: ::c_int = 1; -pub const TCSAFLUSH: ::c_int = 2; - -pub const TCGETS: ::c_ulong = 0x5401; -pub const TCSETS: ::c_ulong = 0x5402; -pub const TCSETSW: ::c_ulong = 0x5403; -pub const TCSETSF: ::c_ulong = 0x5404; -pub const TCGETA: ::c_ulong = 0x5405; -pub const TCSETA: ::c_ulong = 0x5406; -pub const TCSETAW: ::c_ulong = 0x5407; -pub const TCSETAF: ::c_ulong = 0x5408; -pub const TCSBRK: ::c_ulong = 0x5409; -pub const TCXONC: ::c_ulong = 0x540A; -pub const TCFLSH: ::c_ulong = 0x540B; -pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; -pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; -pub const TIOCINQ: ::c_ulong = 0x541B; -pub const TIOCLINUX: ::c_ulong = 0x541C; -pub const TIOCGSERIAL: ::c_ulong = 0x541E; -pub const TIOCEXCL: ::c_ulong = 0x540C; -pub const TIOCNXCL: ::c_ulong = 0x540D; -pub const TIOCSCTTY: ::c_ulong = 0x540E; -pub const TIOCGPGRP: ::c_ulong = 0x540F; -pub const TIOCSPGRP: ::c_ulong = 0x5410; -pub const TIOCOUTQ: ::c_ulong = 0x5411; -pub const TIOCSTI: ::c_ulong = 0x5412; -pub const TIOCGWINSZ: ::c_ulong = 0x5413; -pub const TIOCSWINSZ: ::c_ulong = 0x5414; -pub const TIOCMGET: ::c_ulong = 0x5415; -pub const TIOCMBIS: ::c_ulong = 0x5416; -pub const TIOCMBIC: ::c_ulong = 0x5417; -pub const TIOCMSET: ::c_ulong = 0x5418; -pub const FIONREAD: ::c_ulong = 0x541B; -pub const TIOCCONS: ::c_ulong = 0x541D; - -pub const RTLD_DEEPBIND: ::c_int = 0x8; -pub const RTLD_GLOBAL: ::c_int = 0x100; -pub const RTLD_NOLOAD: ::c_int = 0x4; - -pub const LINUX_REBOOT_MAGIC1: ::c_int = 0xfee1dead; -pub const LINUX_REBOOT_MAGIC2: ::c_int = 672274793; -pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; -pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; -pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; - -pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; -pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; -pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; -pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; -pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; -pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; -pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; -pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; - -pub const VTIME: usize = 5; -pub const VSWTC: usize = 7; -pub const VSTART: usize = 8; -pub const VSTOP: usize = 9; -pub const VSUSP: usize = 10; -pub const VREPRINT: usize = 12; -pub const VDISCARD: usize = 13; -pub const VWERASE: usize = 14; -pub const OLCUC: ::tcflag_t = 0o000002; -pub const ONLCR: ::tcflag_t = 0o000004; -pub const NLDLY: ::tcflag_t = 0o000400; -pub const CRDLY: ::tcflag_t = 0o003000; -pub const CR1: ::tcflag_t = 0x00000200; -pub const CR2: ::tcflag_t = 0x00000400; -pub const CR3: ::tcflag_t = 0x00000600; -pub const TABDLY: ::tcflag_t = 0o014000; -pub const TAB1: ::tcflag_t = 0x00000800; -pub const TAB2: ::tcflag_t = 0x00001000; -pub const TAB3: ::tcflag_t = 0x00001800; -pub const BSDLY: ::tcflag_t = 0o020000; -pub const BS1: ::tcflag_t = 0x00002000; -pub const FFDLY: ::tcflag_t = 0o100000; -pub const FF1: ::tcflag_t = 0x00008000; -pub const VTDLY: ::tcflag_t = 0o040000; -pub const VT1: ::tcflag_t = 0x00004000; -pub const XTABS: ::tcflag_t = 0o014000; - -pub const TIOCM_LE: ::c_int = 0x001; -pub const TIOCM_DTR: ::c_int = 0x002; -pub const TIOCM_RTS: ::c_int = 0x004; -pub const TIOCM_ST: ::c_int = 0x008; -pub const TIOCM_SR: ::c_int = 0x010; -pub const TIOCM_CTS: ::c_int = 0x020; -pub const TIOCM_CAR: ::c_int = 0x040; -pub const TIOCM_RNG: ::c_int = 0x080; -pub const TIOCM_DSR: ::c_int = 0x100; -pub const TIOCM_CD: ::c_int = TIOCM_CAR; -pub const TIOCM_RI: ::c_int = TIOCM_RNG; - -pub const SIGEV_THREAD_ID: ::c_int = 4; - -pub const CBAUD: ::speed_t = 0o010017; -pub const B0: ::speed_t = 0o000000; -pub const B50: ::speed_t = 0o000001; -pub const B75: ::speed_t = 0o000002; -pub const B110: ::speed_t = 0o000003; -pub const B134: ::speed_t = 0o000004; -pub const B150: ::speed_t = 0o000005; -pub const B200: ::speed_t = 0o000006; -pub const B300: ::speed_t = 0o000007; -pub const B600: ::speed_t = 0o000010; -pub const B1200: ::speed_t = 0o000011; -pub const B1800: ::speed_t = 0o000012; -pub const B2400: ::speed_t = 0o000013; -pub const B4800: ::speed_t = 0o000014; -pub const B9600: ::speed_t = 0o000015; -pub const B19200: ::speed_t = 0o000016; -pub const B38400: ::speed_t = 0o000017; -pub const EXTA: ::speed_t = B19200; -pub const EXTB: ::speed_t = B38400; -pub const CSIZE: ::tcflag_t = 0o000060; -pub const CS6: ::tcflag_t = 0o000020; -pub const CS7: ::tcflag_t = 0o000040; -pub const CS8: ::tcflag_t = 0o000060; -pub const CSTOPB: ::tcflag_t = 0o000100; -pub const CREAD: ::tcflag_t = 0o000200; -pub const PARENB: ::tcflag_t = 0o000400; -pub const PARODD: ::tcflag_t = 0o001000; -pub const HUPCL: ::tcflag_t = 0o002000; -pub const CLOCAL: ::tcflag_t = 0o004000; -pub const CBAUDEX: ::tcflag_t = 0o010000; -pub const BOTHER: ::speed_t = 0o010000; -pub const B57600: ::speed_t = 0o010001; -pub const B115200: ::speed_t = 0o010002; -pub const B230400: ::speed_t = 0o010003; -pub const B460800: ::speed_t = 0o010004; -pub const B500000: ::speed_t = 0o010005; -pub const B576000: ::speed_t = 0o010006; -pub const B921600: ::speed_t = 0o010007; -pub const B1000000: ::speed_t = 0o010010; -pub const B1152000: ::speed_t = 0o010011; -pub const B1500000: ::speed_t = 0o010012; -pub const B2000000: ::speed_t = 0o010013; -pub const B2500000: ::speed_t = 0o010014; -pub const B3000000: ::speed_t = 0o010015; -pub const B3500000: ::speed_t = 0o010016; -pub const B4000000: ::speed_t = 0o010017; -pub const CIBAUD: ::tcflag_t = 0o02003600000; - -pub const ISIG: ::tcflag_t = 0o000001; -pub const ICANON: ::tcflag_t = 0o000002; -pub const XCASE: ::tcflag_t = 0o000004; -pub const ECHOE: ::tcflag_t = 0o000020; -pub const ECHOK: ::tcflag_t = 0o000040; -pub const ECHONL: ::tcflag_t = 0o000100; -pub const NOFLSH: ::tcflag_t = 0o000200; -pub const ECHOCTL: ::tcflag_t = 0o001000; -pub const ECHOPRT: ::tcflag_t = 0o002000; -pub const ECHOKE: ::tcflag_t = 0o004000; -pub const PENDIN: ::tcflag_t = 0o040000; - -pub const POLLWRNORM: ::c_short = 0x100; -pub const POLLWRBAND: ::c_short = 0x200; - -pub const IXON: ::tcflag_t = 0o002000; -pub const IXOFF: ::tcflag_t = 0o010000; - -pub const SYS_exit: ::c_long = 1; -pub const SYS_fork: ::c_long = 2; -pub const SYS_read: ::c_long = 3; -pub const SYS_write: ::c_long = 4; -pub const SYS_open: ::c_long = 5; -pub const SYS_close: ::c_long = 6; -pub const SYS_restart_syscall: ::c_long = 7; -pub const SYS_creat: ::c_long = 8; -pub const SYS_link: ::c_long = 9; -pub const SYS_unlink: ::c_long = 10; -pub const SYS_execve: ::c_long = 11; -pub const SYS_chdir: ::c_long = 12; -pub const SYS_mknod: ::c_long = 14; -pub const SYS_chmod: ::c_long = 15; -pub const SYS_lseek: ::c_long = 19; -pub const SYS_getpid: ::c_long = 20; -pub const SYS_mount: ::c_long = 21; -pub const SYS_umount: ::c_long = 22; -pub const SYS_ptrace: ::c_long = 26; -pub const SYS_alarm: ::c_long = 27; -pub const SYS_pause: ::c_long = 29; -pub const SYS_utime: ::c_long = 30; -pub const SYS_access: ::c_long = 33; -pub const SYS_nice: ::c_long = 34; -pub const SYS_sync: ::c_long = 36; -pub const SYS_kill: ::c_long = 37; -pub const SYS_rename: ::c_long = 38; -pub const SYS_mkdir: ::c_long = 39; -pub const SYS_rmdir: ::c_long = 40; -pub const SYS_dup: ::c_long = 41; -pub const SYS_pipe: ::c_long = 42; -pub const SYS_times: ::c_long = 43; -pub const SYS_brk: ::c_long = 45; -pub const SYS_signal: ::c_long = 48; -pub const SYS_acct: ::c_long = 51; -pub const SYS_umount2: ::c_long = 52; -pub const SYS_ioctl: ::c_long = 54; -pub const SYS_fcntl: ::c_long = 55; -pub const SYS_setpgid: ::c_long = 57; -pub const SYS_umask: ::c_long = 60; -pub const SYS_chroot: ::c_long = 61; -pub const SYS_ustat: ::c_long = 62; -pub const SYS_dup2: ::c_long = 63; -pub const SYS_getppid: ::c_long = 64; -pub const SYS_getpgrp: ::c_long = 65; -pub const SYS_setsid: ::c_long = 66; -pub const SYS_sigaction: ::c_long = 67; -pub const SYS_sigsuspend: ::c_long = 72; -pub const SYS_sigpending: ::c_long = 73; -pub const SYS_sethostname: ::c_long = 74; -pub const SYS_setrlimit: ::c_long = 75; -pub const SYS_getrusage: ::c_long = 77; -pub const SYS_gettimeofday: ::c_long = 78; -pub const SYS_settimeofday: ::c_long = 79; -pub const SYS_symlink: ::c_long = 83; -pub const SYS_readlink: ::c_long = 85; -pub const SYS_uselib: ::c_long = 86; -pub const SYS_swapon: ::c_long = 87; -pub const SYS_reboot: ::c_long = 88; -pub const SYS_readdir: ::c_long = 89; -pub const SYS_mmap: ::c_long = 90; -pub const SYS_munmap: ::c_long = 91; -pub const SYS_truncate: ::c_long = 92; -pub const SYS_ftruncate: ::c_long = 93; -pub const SYS_fchmod: ::c_long = 94; -pub const SYS_getpriority: ::c_long = 96; -pub const SYS_setpriority: ::c_long = 97; -pub const SYS_statfs: ::c_long = 99; -pub const SYS_fstatfs: ::c_long = 100; -pub const SYS_socketcall: ::c_long = 102; -pub const SYS_syslog: ::c_long = 103; -pub const SYS_setitimer: ::c_long = 104; -pub const SYS_getitimer: ::c_long = 105; -pub const SYS_stat: ::c_long = 106; -pub const SYS_lstat: ::c_long = 107; -pub const SYS_fstat: ::c_long = 108; -pub const SYS_lookup_dcookie: ::c_long = 110; -pub const SYS_vhangup: ::c_long = 111; -pub const SYS_idle: ::c_long = 112; -pub const SYS_wait4: ::c_long = 114; -pub const SYS_swapoff: ::c_long = 115; -pub const SYS_sysinfo: ::c_long = 116; -pub const SYS_ipc: ::c_long = 117; -pub const SYS_fsync: ::c_long = 118; -pub const SYS_sigreturn: ::c_long = 119; -pub const SYS_clone: ::c_long = 120; -pub const SYS_setdomainname: ::c_long = 121; -pub const SYS_uname: ::c_long = 122; -pub const SYS_adjtimex: ::c_long = 124; -pub const SYS_mprotect: ::c_long = 125; -pub const SYS_sigprocmask: ::c_long = 126; -pub const SYS_create_module: ::c_long = 127; -pub const SYS_init_module: ::c_long = 128; -pub const SYS_delete_module: ::c_long = 129; -pub const SYS_get_kernel_syms: ::c_long = 130; -pub const SYS_quotactl: ::c_long = 131; -pub const SYS_getpgid: ::c_long = 132; -pub const SYS_fchdir: ::c_long = 133; -pub const SYS_bdflush: ::c_long = 134; -pub const SYS_sysfs: ::c_long = 135; -pub const SYS_personality: ::c_long = 136; -pub const SYS_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ -pub const SYS_getdents: ::c_long = 141; -pub const SYS_flock: ::c_long = 143; -pub const SYS_msync: ::c_long = 144; -pub const SYS_readv: ::c_long = 145; -pub const SYS_writev: ::c_long = 146; -pub const SYS_getsid: ::c_long = 147; -pub const SYS_fdatasync: ::c_long = 148; -pub const SYS__sysctl: ::c_long = 149; -pub const SYS_mlock: ::c_long = 150; -pub const SYS_munlock: ::c_long = 151; -pub const SYS_mlockall: ::c_long = 152; -pub const SYS_munlockall: ::c_long = 153; -pub const SYS_sched_setparam: ::c_long = 154; -pub const SYS_sched_getparam: ::c_long = 155; -pub const SYS_sched_setscheduler: ::c_long = 156; -pub const SYS_sched_getscheduler: ::c_long = 157; -pub const SYS_sched_yield: ::c_long = 158; -pub const SYS_sched_get_priority_max: ::c_long = 159; -pub const SYS_sched_get_priority_min: ::c_long = 160; -pub const SYS_sched_rr_get_interval: ::c_long = 161; -pub const SYS_nanosleep: ::c_long = 162; -pub const SYS_mremap: ::c_long = 163; -pub const SYS_query_module: ::c_long = 167; -pub const SYS_poll: ::c_long = 168; -pub const SYS_nfsservctl: ::c_long = 169; -pub const SYS_prctl: ::c_long = 172; -pub const SYS_rt_sigreturn: ::c_long = 173; -pub const SYS_rt_sigaction: ::c_long = 174; -pub const SYS_rt_sigprocmask: ::c_long = 175; -pub const SYS_rt_sigpending: ::c_long = 176; -pub const SYS_rt_sigtimedwait: ::c_long = 177; -pub const SYS_rt_sigqueueinfo: ::c_long = 178; -pub const SYS_rt_sigsuspend: ::c_long = 179; -pub const SYS_pread64: ::c_long = 180; -pub const SYS_pwrite64: ::c_long = 181; -pub const SYS_getcwd: ::c_long = 183; -pub const SYS_capget: ::c_long = 184; -pub const SYS_capset: ::c_long = 185; -pub const SYS_sigaltstack: ::c_long = 186; -pub const SYS_sendfile: ::c_long = 187; -pub const SYS_getpmsg: ::c_long = 188; -pub const SYS_putpmsg: ::c_long = 189; -pub const SYS_vfork: ::c_long = 190; -pub const SYS_pivot_root: ::c_long = 217; -pub const SYS_mincore: ::c_long = 218; -pub const SYS_madvise: ::c_long = 219; -pub const SYS_getdents64: ::c_long = 220; -pub const SYS_readahead: ::c_long = 222; -pub const SYS_setxattr: ::c_long = 224; -pub const SYS_lsetxattr: ::c_long = 225; -pub const SYS_fsetxattr: ::c_long = 226; -pub const SYS_getxattr: ::c_long = 227; -pub const SYS_lgetxattr: ::c_long = 228; -pub const SYS_fgetxattr: ::c_long = 229; -pub const SYS_listxattr: ::c_long = 230; -pub const SYS_llistxattr: ::c_long = 231; -pub const SYS_flistxattr: ::c_long = 232; -pub const SYS_removexattr: ::c_long = 233; -pub const SYS_lremovexattr: ::c_long = 234; -pub const SYS_fremovexattr: ::c_long = 235; -pub const SYS_gettid: ::c_long = 236; -pub const SYS_tkill: ::c_long = 237; -pub const SYS_futex: ::c_long = 238; -pub const SYS_sched_setaffinity: ::c_long = 239; -pub const SYS_sched_getaffinity: ::c_long = 240; -pub const SYS_tgkill: ::c_long = 241; -pub const SYS_io_setup: ::c_long = 243; -pub const SYS_io_destroy: ::c_long = 244; -pub const SYS_io_getevents: ::c_long = 245; -pub const SYS_io_submit: ::c_long = 246; -pub const SYS_io_cancel: ::c_long = 247; -pub const SYS_exit_group: ::c_long = 248; -pub const SYS_epoll_create: ::c_long = 249; -pub const SYS_epoll_ctl: ::c_long = 250; -pub const SYS_epoll_wait: ::c_long = 251; -pub const SYS_set_tid_address: ::c_long = 252; -pub const SYS_fadvise64: ::c_long = 253; -pub const SYS_timer_create: ::c_long = 254; -pub const SYS_timer_settime: ::c_long = 255; -pub const SYS_timer_gettime: ::c_long = 256; -pub const SYS_timer_getoverrun: ::c_long = 257; -pub const SYS_timer_delete: ::c_long = 258; -pub const SYS_clock_settime: ::c_long = 259; -pub const SYS_clock_gettime: ::c_long = 260; -pub const SYS_clock_getres: ::c_long = 261; -pub const SYS_clock_nanosleep: ::c_long = 262; -pub const SYS_statfs64: ::c_long = 265; -pub const SYS_fstatfs64: ::c_long = 266; -pub const SYS_remap_file_pages: ::c_long = 267; -pub const SYS_mbind: ::c_long = 268; -pub const SYS_get_mempolicy: ::c_long = 269; -pub const SYS_set_mempolicy: ::c_long = 270; -pub const SYS_mq_open: ::c_long = 271; -pub const SYS_mq_unlink: ::c_long = 272; -pub const SYS_mq_timedsend: ::c_long = 273; -pub const SYS_mq_timedreceive: ::c_long = 274; -pub const SYS_mq_notify: ::c_long = 275; -pub const SYS_mq_getsetattr: ::c_long = 276; -pub const SYS_kexec_load: ::c_long = 277; -pub const SYS_add_key: ::c_long = 278; -pub const SYS_request_key: ::c_long = 279; -pub const SYS_keyctl: ::c_long = 280; -pub const SYS_waitid: ::c_long = 281; -pub const SYS_ioprio_set: ::c_long = 282; -pub const SYS_ioprio_get: ::c_long = 283; -pub const SYS_inotify_init: ::c_long = 284; -pub const SYS_inotify_add_watch: ::c_long = 285; -pub const SYS_inotify_rm_watch: ::c_long = 286; -pub const SYS_migrate_pages: ::c_long = 287; -pub const SYS_openat: ::c_long = 288; -pub const SYS_mkdirat: ::c_long = 289; -pub const SYS_mknodat: ::c_long = 290; -pub const SYS_fchownat: ::c_long = 291; -pub const SYS_futimesat: ::c_long = 292; -pub const SYS_unlinkat: ::c_long = 294; -pub const SYS_renameat: ::c_long = 295; -pub const SYS_linkat: ::c_long = 296; -pub const SYS_symlinkat: ::c_long = 297; -pub const SYS_readlinkat: ::c_long = 298; -pub const SYS_fchmodat: ::c_long = 299; -pub const SYS_faccessat: ::c_long = 300; -pub const SYS_pselect6: ::c_long = 301; -pub const SYS_ppoll: ::c_long = 302; -pub const SYS_unshare: ::c_long = 303; -pub const SYS_set_robust_list: ::c_long = 304; -pub const SYS_get_robust_list: ::c_long = 305; -pub const SYS_splice: ::c_long = 306; -pub const SYS_sync_file_range: ::c_long = 307; -pub const SYS_tee: ::c_long = 308; -pub const SYS_vmsplice: ::c_long = 309; -pub const SYS_move_pages: ::c_long = 310; -pub const SYS_getcpu: ::c_long = 311; -pub const SYS_epoll_pwait: ::c_long = 312; -pub const SYS_utimes: ::c_long = 313; -pub const SYS_fallocate: ::c_long = 314; -pub const SYS_utimensat: ::c_long = 315; -pub const SYS_signalfd: ::c_long = 316; -pub const SYS_timerfd: ::c_long = 317; -pub const SYS_eventfd: ::c_long = 318; -pub const SYS_timerfd_create: ::c_long = 319; -pub const SYS_timerfd_settime: ::c_long = 320; -pub const SYS_timerfd_gettime: ::c_long = 321; -pub const SYS_signalfd4: ::c_long = 322; -pub const SYS_eventfd2: ::c_long = 323; -pub const SYS_inotify_init1: ::c_long = 324; -pub const SYS_pipe2: ::c_long = 325; -pub const SYS_dup3: ::c_long = 326; -pub const SYS_epoll_create1: ::c_long = 327; -pub const SYS_preadv: ::c_long = 328; -pub const SYS_pwritev: ::c_long = 329; -pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; -pub const SYS_perf_event_open: ::c_long = 331; -pub const SYS_fanotify_init: ::c_long = 332; -pub const SYS_fanotify_mark: ::c_long = 333; -pub const SYS_prlimit64: ::c_long = 334; -pub const SYS_name_to_handle_at: ::c_long = 335; -pub const SYS_open_by_handle_at: ::c_long = 336; -pub const SYS_clock_adjtime: ::c_long = 337; -pub const SYS_syncfs: ::c_long = 338; -pub const SYS_setns: ::c_long = 339; -pub const SYS_process_vm_readv: ::c_long = 340; -pub const SYS_process_vm_writev: ::c_long = 341; -pub const SYS_s390_runtime_instr: ::c_long = 342; -pub const SYS_kcmp: ::c_long = 343; -pub const SYS_finit_module: ::c_long = 344; -pub const SYS_sched_setattr: ::c_long = 345; -pub const SYS_sched_getattr: ::c_long = 346; -pub const SYS_renameat2: ::c_long = 347; -pub const SYS_seccomp: ::c_long = 348; -pub const SYS_getrandom: ::c_long = 349; -pub const SYS_memfd_create: ::c_long = 350; -pub const SYS_bpf: ::c_long = 351; -pub const SYS_s390_pci_mmio_write: ::c_long = 352; -pub const SYS_s390_pci_mmio_read: ::c_long = 353; -pub const SYS_execveat: ::c_long = 354; -pub const SYS_userfaultfd: ::c_long = 355; -pub const SYS_membarrier: ::c_long = 356; -pub const SYS_recvmmsg: ::c_long = 357; -pub const SYS_sendmmsg: ::c_long = 358; -pub const SYS_socket: ::c_long = 359; -pub const SYS_socketpair: ::c_long = 360; -pub const SYS_bind: ::c_long = 361; -pub const SYS_connect: ::c_long = 362; -pub const SYS_listen: ::c_long = 363; -pub const SYS_accept4: ::c_long = 364; -pub const SYS_getsockopt: ::c_long = 365; -pub const SYS_setsockopt: ::c_long = 366; -pub const SYS_getsockname: ::c_long = 367; -pub const SYS_getpeername: ::c_long = 368; -pub const SYS_sendto: ::c_long = 369; -pub const SYS_sendmsg: ::c_long = 370; -pub const SYS_recvfrom: ::c_long = 371; -pub const SYS_recvmsg: ::c_long = 372; -pub const SYS_shutdown: ::c_long = 373; -pub const SYS_mlock2: ::c_long = 374; -pub const SYS_copy_file_range: ::c_long = 375; -pub const SYS_preadv2: ::c_long = 376; -pub const SYS_pwritev2: ::c_long = 377; -pub const SYS_lchown: ::c_long = 198; -pub const SYS_setuid: ::c_long = 213; -pub const SYS_getuid: ::c_long = 199; -pub const SYS_setgid: ::c_long = 214; -pub const SYS_getgid: ::c_long = 200; -pub const SYS_geteuid: ::c_long = 201; -pub const SYS_setreuid: ::c_long = 203; -pub const SYS_setregid: ::c_long = 204; -pub const SYS_getrlimit: ::c_long = 191; -pub const SYS_getgroups: ::c_long = 205; -pub const SYS_fchown: ::c_long = 207; -pub const SYS_setresuid: ::c_long = 208; -pub const SYS_setresgid: ::c_long = 210; -pub const SYS_getresgid: ::c_long = 211; -pub const SYS_select: ::c_long = 142; -pub const SYS_getegid: ::c_long = 202; -pub const SYS_setgroups: ::c_long = 206; -pub const SYS_getresuid: ::c_long = 209; -pub const SYS_chown: ::c_long = 212; -pub const SYS_setfsuid: ::c_long = 215; -pub const SYS_setfsgid: ::c_long = 216; -pub const SYS_newfstatat: ::c_long = 293; - -#[link(name = "util")] -extern { - pub fn sysctl(name: *mut ::c_int, - namelen: ::c_int, - oldp: *mut ::c_void, - oldlenp: *mut ::size_t, - newp: *mut ::c_void, - newlen: ::size_t) - -> ::c_int; - pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; - pub fn backtrace(buf: *mut *mut ::c_void, - sz: ::c_int) -> ::c_int; - pub fn glob64(pattern: *const ::c_char, - flags: ::c_int, - errfunc: ::dox::Option ::c_int>, - pglob: *mut glob64_t) -> ::c_int; - pub fn globfree64(pglob: *mut glob64_t); - pub fn ptrace(request: ::c_uint, ...) -> ::c_long; - pub fn pthread_attr_getaffinity_np(attr: *const ::pthread_attr_t, - cpusetsize: ::size_t, - cpuset: *mut ::cpu_set_t) -> ::c_int; - pub fn pthread_attr_setaffinity_np(attr: *mut ::pthread_attr_t, - cpusetsize: ::size_t, - cpuset: *const ::cpu_set_t) -> ::c_int; - pub fn getpriority(which: ::__priority_which_t, who: ::id_t) -> ::c_int; - pub fn setpriority(which: ::__priority_which_t, who: ::id_t, - prio: ::c_int) -> ::c_int; - pub fn pthread_getaffinity_np(thread: ::pthread_t, - cpusetsize: ::size_t, - cpuset: *mut ::cpu_set_t) -> ::c_int; - pub fn pthread_setaffinity_np(thread: ::pthread_t, - cpusetsize: ::size_t, - cpuset: *const ::cpu_set_t) -> ::c_int; - pub fn sched_getcpu() -> ::c_int; - pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int; - pub fn setcontext(ucp: *const ucontext_t) -> ::c_int; - pub fn makecontext(ucp: *mut ucontext_t, - func: extern fn (), - argc: ::c_int, ...); - pub fn swapcontext(uocp: *mut ucontext_t, - ucp: *const ucontext_t) -> ::c_int; -} diff -Nru cargo-0.33.0/vendor/libc/src/unix/notbsd/mod.rs cargo-0.35.0/vendor/libc/src/unix/notbsd/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/notbsd/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/notbsd/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::mem; - pub type sa_family_t = u16; pub type pthread_key_t = ::c_uint; pub type speed_t = ::c_uint; @@ -8,9 +6,23 @@ pub type key_t = ::c_int; pub type id_t = ::c_uint; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct sockaddr { pub sa_family: sa_family_t, pub sa_data: [::c_char; 14], @@ -31,20 +43,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108] - } - - pub struct sockaddr_storage { - pub ss_family: sa_family_t, - __ss_align: ::size_t, - #[cfg(target_pointer_width = "32")] - __ss_pad2: [u8; 128 - 2 * 4], - #[cfg(target_pointer_width = "64")] - __ss_pad2: [u8; 128 - 2 * 8], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -118,25 +116,6 @@ pub dli_saddr: *mut ::c_void, } - #[cfg_attr(any(all(target_arch = "x86", - not(target_env = "musl"), - not(target_os = "android")), - target_arch = "x86_64"), - repr(packed))] - pub struct epoll_event { - pub events: ::uint32_t, - pub u64: ::uint64_t, - } - - pub struct utsname { - pub sysname: [::c_char; 65], - pub nodename: [::c_char; 65], - pub release: [::c_char; 65], - pub version: [::c_char; 65], - pub machine: [::c_char; 65], - pub domainname: [::c_char; 65] - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -228,6 +207,195 @@ pub ar_pln: u8, pub ar_op: u16, } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } +} + +s_no_extra_traits!{ + #[cfg_attr( + any( + all( + target_arch = "x86", + not(target_env = "musl"), + not(target_os = "android")), + target_arch = "x86_64"), + repr(packed))] + pub struct epoll_event { + pub events: ::uint32_t, + pub u64: ::uint64_t, + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_align: ::size_t, + #[cfg(target_pointer_width = "32")] + __ss_pad2: [u8; 128 - 2 * 4], + #[cfg(target_pointer_width = "64")] + __ss_pad2: [u8; 128 - 2 * 8], + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + && self + .domainname + .iter() + .zip(other.domainname.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for utsname {} + + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + // FIXME: .field("domainname", &self.domainname) + .finish() + } + } + + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + self.domainname.hash(state); + } + } + } } // intentionally not public, only used for fd_set @@ -514,6 +682,7 @@ pub const SOL_NETLINK: ::c_int = 270; pub const SOL_TIPC: ::c_int = 271; pub const SOL_BLUETOOTH: ::c_int = 274; +pub const SOL_ALG: ::c_int = 279; pub const AF_UNSPEC: ::c_int = 0; pub const AF_UNIX: ::c_int = 1; @@ -985,60 +1154,48 @@ pub const ARPHRD_VOID: u16 = 0xFFFF; pub const ARPHRD_NONE: u16 = 0xFFFE; +fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) +} + f! { pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { - if (*mhdr).msg_controllen as usize >= mem::size_of::() { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { (*mhdr).msg_control as *mut cmsghdr } else { 0 as *mut cmsghdr } } - pub fn CMSG_NXTHDR(mhdr: *const msghdr, - cmsg: *const cmsghdr) -> *mut cmsghdr { - if cmsg.is_null() { - return CMSG_FIRSTHDR(mhdr); - }; - let pad = mem::align_of::() - 1; - let next = cmsg as usize + (*cmsg).cmsg_len as usize + pad & !pad; - let max = (*mhdr).msg_control as usize - + (*mhdr).msg_controllen as usize; - if next < max { - next as *mut cmsghdr - } else { - 0 as *mut cmsghdr - } - } - pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { cmsg.offset(1) as *mut ::c_uchar } pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { - let pad = mem::align_of::() as ::c_uint - 1; - mem::size_of::() as ::c_uint + ((length + pad) & !pad) + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint } pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { - mem::size_of::() as ::c_uint + length + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length } pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] &= !(1 << (fd % size)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] |= 1 << (fd % size); return } @@ -1103,6 +1260,12 @@ } extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_uchar) -> ::c_int; @@ -1220,6 +1383,11 @@ name: *mut ::c_char, termp: *const termios, winp: *const ::winsize) -> ::c_int; + pub fn forkpty(amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; pub fn execvpe(file: *const ::c_char, argv: *const *const ::c_char, envp: *const *const ::c_char) -> ::c_int; pub fn fexecve(fd: ::c_int, argv: *const *const ::c_char, @@ -1259,7 +1427,3 @@ // Unknown target_os } } - // pub fn forkpty(amaster: *mut ::c_int, - // name: *mut ::c_char, - // termp: *const termios, - // winp: *const ::winsize) -> ::pid_t; diff -Nru cargo-0.33.0/vendor/libc/src/unix/solaris/mod.rs cargo-0.35.0/vendor/libc/src/unix/solaris/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/solaris/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/solaris/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1470 +0,0 @@ -use dox::{mem, Option}; - -pub type c_char = i8; -pub type c_long = i64; -pub type c_ulong = u64; - -pub type clockid_t = ::c_int; -pub type blkcnt_t = ::c_long; -pub type clock_t = ::c_long; -pub type daddr_t = ::c_long; -pub type dev_t = ::c_ulong; -pub type fsblkcnt_t = ::c_ulong; -pub type fsfilcnt_t = ::c_ulong; -pub type ino_t = ::c_ulong; -pub type key_t = ::c_int; -pub type major_t = ::c_uint; -pub type minor_t = ::c_uint; -pub type mode_t = ::c_uint; -pub type nlink_t = ::c_uint; -pub type rlim_t = ::c_ulong; -pub type speed_t = ::c_uint; -pub type tcflag_t = ::c_uint; -pub type time_t = ::c_long; -pub type wchar_t = ::c_int; -pub type nfds_t = ::c_ulong; - -pub type suseconds_t = ::c_long; -pub type off_t = ::c_long; -pub type useconds_t = ::c_uint; -pub type socklen_t = ::c_uint; -pub type sa_family_t = u16; -pub type pthread_t = ::c_uint; -pub type pthread_key_t = ::c_uint; -pub type blksize_t = ::c_int; -pub type nl_item = ::c_int; -pub type id_t = ::c_int; -pub type idtype_t = ::c_uint; - -pub enum timezone {} - -s! { - pub struct sockaddr { - pub sa_family: sa_family_t, - pub sa_data: [::c_char; 14], - } - - pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: ::in_port_t, - pub sin_addr: ::in_addr, - pub sin_zero: [::c_char; 8] - } - - pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: ::in_port_t, - pub sin6_flowinfo: u32, - pub sin6_addr: ::in6_addr, - pub sin6_scope_id: u32, - pub __sin6_src_id: u32 - } - - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [c_char; 108] - } - - pub struct passwd { - pub pw_name: *mut ::c_char, - pub pw_passwd: *mut ::c_char, - pub pw_uid: ::uid_t, - pub pw_gid: ::gid_t, - pub pw_age: *mut ::c_char, - pub pw_comment: *mut ::c_char, - pub pw_gecos: *mut ::c_char, - pub pw_dir: *mut ::c_char, - pub pw_shell: *mut ::c_char - } - - pub struct ifaddrs { - pub ifa_next: *mut ifaddrs, - pub ifa_name: *mut ::c_char, - pub ifa_flags: ::c_ulong, - pub ifa_addr: *mut ::sockaddr, - pub ifa_netmask: *mut ::sockaddr, - pub ifa_dstaddr: *mut ::sockaddr, - pub ifa_data: *mut ::c_void - } - - pub struct tm { - pub tm_sec: ::c_int, - pub tm_min: ::c_int, - pub tm_hour: ::c_int, - pub tm_mday: ::c_int, - pub tm_mon: ::c_int, - pub tm_year: ::c_int, - pub tm_wday: ::c_int, - pub tm_yday: ::c_int, - pub tm_isdst: ::c_int - } - - pub struct utsname { - pub sysname: [::c_char; 257], - pub nodename: [::c_char; 257], - pub release: [::c_char; 257], - pub version: [::c_char; 257], - pub machine: [::c_char; 257], - } - - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::c_int, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::socklen_t, - pub msg_flags: ::c_int, - } - - pub struct cmsghdr { - pub cmsg_len: ::socklen_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } - - pub struct fd_set { - #[cfg(target_pointer_width = "64")] - fds_bits: [i64; FD_SETSIZE / 64], - #[cfg(target_pointer_width = "32")] - fds_bits: [i32; FD_SETSIZE / 32], - } - - pub struct pthread_attr_t { - __pthread_attrp: *mut ::c_void - } - - pub struct pthread_mutex_t { - __pthread_mutex_flag1: u16, - __pthread_mutex_flag2: u8, - __pthread_mutex_ceiling: u8, - __pthread_mutex_type: u16, - __pthread_mutex_magic: u16, - __pthread_mutex_lock: u64, - __pthread_mutex_data: u64 - } - - pub struct pthread_mutexattr_t { - __pthread_mutexattrp: *mut ::c_void - } - - pub struct pthread_cond_t { - __pthread_cond_flag: [u8; 4], - __pthread_cond_type: u16, - __pthread_cond_magic: u16, - __pthread_cond_data: u64 - } - - pub struct pthread_condattr_t { - __pthread_condattrp: *mut ::c_void, - } - - pub struct pthread_rwlock_t { - __pthread_rwlock_readers: i32, - __pthread_rwlock_type: u16, - __pthread_rwlock_magic: u16, - __pthread_rwlock_mutex: ::pthread_mutex_t, - __pthread_rwlock_readercv: ::pthread_cond_t, - __pthread_rwlock_writercv: ::pthread_cond_t - } - - pub struct pthread_rwlockattr_t { - __pthread_rwlockattrp: *mut ::c_void, - } - - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: u16, - pub d_name: [::c_char; 3] - } - - pub struct glob_t { - pub gl_pathc: ::size_t, - pub gl_pathv: *mut *mut ::c_char, - pub gl_offs: ::size_t, - __unused1: *mut ::c_void, - __unused2: ::c_int, - __unused3: ::c_int, - __unused4: ::c_int, - __unused5: *mut ::c_void, - __unused6: *mut ::c_void, - __unused7: *mut ::c_void, - __unused8: *mut ::c_void, - __unused9: *mut ::c_void, - __unused10: *mut ::c_void, - } - - pub struct sockaddr_storage { - pub ss_family: ::sa_family_t, - __ss_pad1: [u8; 6], - __ss_align: i64, - __ss_pad2: [u8; 240], - } - - pub struct addrinfo { - pub ai_flags: ::c_int, - pub ai_family: ::c_int, - pub ai_socktype: ::c_int, - pub ai_protocol: ::c_int, - #[cfg(target_arch = "sparc64")] - __sparcv9_pad: ::c_int, - pub ai_addrlen: ::socklen_t, - pub ai_canonname: *mut ::c_char, - pub ai_addr: *mut ::sockaddr, - pub ai_next: *mut addrinfo, - } - - pub struct sigset_t { - bits: [u32; 4], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_code: ::c_int, - pub si_errno: ::c_int, - pub si_pad: ::c_int, - pub si_addr: *mut ::c_void, - __pad: [u8; 232], - } - - pub struct sigaction { - pub sa_flags: ::c_int, - pub sa_sigaction: ::sighandler_t, - pub sa_mask: sigset_t, - } - - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_size: ::size_t, - pub ss_flags: ::c_int, - } - - pub struct statvfs { - pub f_bsize: ::c_ulong, - pub f_frsize: ::c_ulong, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_files: ::fsfilcnt_t, - pub f_ffree: ::fsfilcnt_t, - pub f_favail: ::fsfilcnt_t, - pub f_fsid: ::c_ulong, - pub f_basetype: [::c_char; 16], - pub f_flag: ::c_ulong, - pub f_namemax: ::c_ulong, - pub f_fstr: [::c_char; 32] - } - - pub struct sched_param { - pub sched_priority: ::c_int, - sched_pad: [::c_int; 8] - } - - pub struct Dl_info { - pub dli_fname: *const ::c_char, - pub dli_fbase: *mut ::c_void, - pub dli_sname: *const ::c_char, - pub dli_saddr: *mut ::c_void, - } - - pub struct stat { - pub st_dev: ::dev_t, - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - pub st_size: ::off_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt_t, - __unused: [::c_char; 16] - } - - pub struct termios { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_cc: [::cc_t; ::NCCS] - } - - pub struct lconv { - pub decimal_point: *mut ::c_char, - pub thousands_sep: *mut ::c_char, - pub grouping: *mut ::c_char, - pub int_curr_symbol: *mut ::c_char, - pub currency_symbol: *mut ::c_char, - pub mon_decimal_point: *mut ::c_char, - pub mon_thousands_sep: *mut ::c_char, - pub mon_grouping: *mut ::c_char, - pub positive_sign: *mut ::c_char, - pub negative_sign: *mut ::c_char, - pub int_frac_digits: ::c_char, - pub frac_digits: ::c_char, - pub p_cs_precedes: ::c_char, - pub p_sep_by_space: ::c_char, - pub n_cs_precedes: ::c_char, - pub n_sep_by_space: ::c_char, - pub p_sign_posn: ::c_char, - pub n_sign_posn: ::c_char, - pub int_p_cs_precedes: ::c_char, - pub int_p_sep_by_space: ::c_char, - pub int_n_cs_precedes: ::c_char, - pub int_n_sep_by_space: ::c_char, - pub int_p_sign_posn: ::c_char, - pub int_n_sign_posn: ::c_char, - } - - pub struct sem_t { - pub sem_count: u32, - pub sem_type: u16, - pub sem_magic: u16, - pub sem_pad1: [u64; 3], - pub sem_pad2: [u64; 2] - } - - pub struct flock { - pub l_type: ::c_short, - pub l_whence: ::c_short, - pub l_start: ::off_t, - pub l_len: ::off_t, - pub l_sysid: ::c_int, - pub l_pid: ::pid_t, - pub l_pad: [::c_long; 4] - } - - pub struct if_nameindex { - pub if_index: ::c_uint, - pub if_name: *mut ::c_char, - } - - pub struct port_event { - pub portev_events: ::c_int, - pub portev_source: ::c_ushort, - pub portev_pad: ::c_ushort, - pub portev_object: ::uintptr_t, - pub portev_user: *mut ::c_void, - } - - #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))] - pub struct epoll_event { - pub events: ::uint32_t, - pub u64: ::uint64_t, - } -} - -pub const LC_CTYPE: ::c_int = 0; -pub const LC_NUMERIC: ::c_int = 1; -pub const LC_TIME: ::c_int = 2; -pub const LC_COLLATE: ::c_int = 3; -pub const LC_MONETARY: ::c_int = 4; -pub const LC_MESSAGES: ::c_int = 5; -pub const LC_ALL: ::c_int = 6; -pub const LC_CTYPE_MASK: ::c_int = (1 << LC_CTYPE); -pub const LC_NUMERIC_MASK: ::c_int = (1 << LC_NUMERIC); -pub const LC_TIME_MASK: ::c_int = (1 << LC_TIME); -pub const LC_COLLATE_MASK: ::c_int = (1 << LC_COLLATE); -pub const LC_MONETARY_MASK: ::c_int = (1 << LC_MONETARY); -pub const LC_MESSAGES_MASK: ::c_int = (1 << LC_MESSAGES); -pub const LC_ALL_MASK: ::c_int = LC_CTYPE_MASK - | LC_NUMERIC_MASK - | LC_TIME_MASK - | LC_COLLATE_MASK - | LC_MONETARY_MASK - | LC_MESSAGES_MASK; - -pub const DAY_1: ::nl_item = 1; -pub const DAY_2: ::nl_item = 2; -pub const DAY_3: ::nl_item = 3; -pub const DAY_4: ::nl_item = 4; -pub const DAY_5: ::nl_item = 5; -pub const DAY_6: ::nl_item = 6; -pub const DAY_7: ::nl_item = 7; - -pub const ABDAY_1: ::nl_item = 8; -pub const ABDAY_2: ::nl_item = 9; -pub const ABDAY_3: ::nl_item = 10; -pub const ABDAY_4: ::nl_item = 11; -pub const ABDAY_5: ::nl_item = 12; -pub const ABDAY_6: ::nl_item = 13; -pub const ABDAY_7: ::nl_item = 14; - -pub const MON_1: ::nl_item = 15; -pub const MON_2: ::nl_item = 16; -pub const MON_3: ::nl_item = 17; -pub const MON_4: ::nl_item = 18; -pub const MON_5: ::nl_item = 19; -pub const MON_6: ::nl_item = 20; -pub const MON_7: ::nl_item = 21; -pub const MON_8: ::nl_item = 22; -pub const MON_9: ::nl_item = 23; -pub const MON_10: ::nl_item = 24; -pub const MON_11: ::nl_item = 25; -pub const MON_12: ::nl_item = 26; - -pub const ABMON_1: ::nl_item = 27; -pub const ABMON_2: ::nl_item = 28; -pub const ABMON_3: ::nl_item = 29; -pub const ABMON_4: ::nl_item = 30; -pub const ABMON_5: ::nl_item = 31; -pub const ABMON_6: ::nl_item = 32; -pub const ABMON_7: ::nl_item = 33; -pub const ABMON_8: ::nl_item = 34; -pub const ABMON_9: ::nl_item = 35; -pub const ABMON_10: ::nl_item = 36; -pub const ABMON_11: ::nl_item = 37; -pub const ABMON_12: ::nl_item = 38; - -pub const RADIXCHAR: ::nl_item = 39; -pub const THOUSEP: ::nl_item = 40; -pub const YESSTR: ::nl_item = 41; -pub const NOSTR: ::nl_item = 42; -pub const CRNCYSTR: ::nl_item = 43; - -pub const D_T_FMT: ::nl_item = 44; -pub const D_FMT: ::nl_item = 45; -pub const T_FMT: ::nl_item = 46; -pub const AM_STR: ::nl_item = 47; -pub const PM_STR: ::nl_item = 48; - -pub const CODESET: ::nl_item = 49; -pub const T_FMT_AMPM: ::nl_item = 50; -pub const ERA: ::nl_item = 51; -pub const ERA_D_FMT: ::nl_item = 52; -pub const ERA_D_T_FMT: ::nl_item = 53; -pub const ERA_T_FMT: ::nl_item = 54; -pub const ALT_DIGITS: ::nl_item = 55; -pub const YESEXPR: ::nl_item = 56; -pub const NOEXPR: ::nl_item = 57; -pub const _DATE_FMT: ::nl_item = 58; -pub const MAXSTRMSG: ::nl_item = 58; - -pub const PATH_MAX: ::c_int = 1024; - -pub const SA_ONSTACK: ::c_int = 0x00000001; -pub const SA_RESETHAND: ::c_int = 0x00000002; -pub const SA_RESTART: ::c_int = 0x00000004; -pub const SA_SIGINFO: ::c_int = 0x00000008; -pub const SA_NODEFER: ::c_int = 0x00000010; -pub const SA_NOCLDWAIT: ::c_int = 0x00010000; -pub const SA_NOCLDSTOP: ::c_int = 0x00020000; - -pub const SS_ONSTACK: ::c_int = 1; -pub const SS_DISABLE: ::c_int = 2; - -pub const FIOCLEX: ::c_int = 0x20006601; -pub const FIONCLEX: ::c_int = 0x20006602; -pub const FIONREAD: ::c_int = 0x4004667f; -pub const FIONBIO: ::c_int = 0x8004667e; -pub const FIOASYNC: ::c_int = 0x8004667d; -pub const FIOSETOWN: ::c_int = 0x8004667c; -pub const FIOGETOWN: ::c_int = 0x4004667b; - -pub const SIGCHLD: ::c_int = 18; -pub const SIGBUS: ::c_int = 10; -pub const SIGINFO: ::c_int = 41; -pub const SIG_BLOCK: ::c_int = 1; -pub const SIG_UNBLOCK: ::c_int = 2; -pub const SIG_SETMASK: ::c_int = 3; - -pub const IPV6_UNICAST_HOPS: ::c_int = 0x5; -pub const IPV6_MULTICAST_IF: ::c_int = 0x6; -pub const IPV6_MULTICAST_HOPS: ::c_int = 0x7; -pub const IPV6_MULTICAST_LOOP: ::c_int = 0x8; -pub const IPV6_V6ONLY: ::c_int = 0x27; - -cfg_if! { - if #[cfg(target_pointer_width = "64")] { - pub const FD_SETSIZE: usize = 65536; - } else { - pub const FD_SETSIZE: usize = 1024; - } -} - -pub const ST_RDONLY: ::c_ulong = 1; -pub const ST_NOSUID: ::c_ulong = 2; - -pub const NI_MAXHOST: ::socklen_t = 1025; - -pub const EXIT_FAILURE: ::c_int = 1; -pub const EXIT_SUCCESS: ::c_int = 0; -pub const RAND_MAX: ::c_int = 32767; -pub const EOF: ::c_int = -1; -pub const SEEK_SET: ::c_int = 0; -pub const SEEK_CUR: ::c_int = 1; -pub const SEEK_END: ::c_int = 2; -pub const _IOFBF: ::c_int = 0; -pub const _IONBF: ::c_int = 4; -pub const _IOLBF: ::c_int = 64; -pub const BUFSIZ: ::c_uint = 1024; -pub const FOPEN_MAX: ::c_uint = 20; -pub const FILENAME_MAX: ::c_uint = 1024; -pub const L_tmpnam: ::c_uint = 25; -pub const TMP_MAX: ::c_uint = 17576; - -pub const O_RDONLY: ::c_int = 0; -pub const O_WRONLY: ::c_int = 1; -pub const O_RDWR: ::c_int = 2; -pub const O_SEARCH: ::c_int = 0x200000; -pub const O_EXEC: ::c_int = 0x400000; -pub const O_APPEND: ::c_int = 8; -pub const O_CREAT: ::c_int = 256; -pub const O_EXCL: ::c_int = 1024; -pub const O_NOCTTY: ::c_int = 2048; -pub const O_TRUNC: ::c_int = 512; -pub const O_CLOEXEC: ::c_int = 0x800000; -pub const O_ACCMODE: ::c_int = 0x600003; -pub const S_IFIFO: mode_t = 4096; -pub const S_IFCHR: mode_t = 8192; -pub const S_IFBLK: mode_t = 24576; -pub const S_IFDIR: mode_t = 16384; -pub const S_IFREG: mode_t = 32768; -pub const S_IFLNK: mode_t = 40960; -pub const S_IFSOCK: mode_t = 49152; -pub const S_IFMT: mode_t = 61440; -pub const S_IEXEC: mode_t = 64; -pub const S_IWRITE: mode_t = 128; -pub const S_IREAD: mode_t = 256; -pub const S_IRWXU: mode_t = 448; -pub const S_IXUSR: mode_t = 64; -pub const S_IWUSR: mode_t = 128; -pub const S_IRUSR: mode_t = 256; -pub const S_IRWXG: mode_t = 56; -pub const S_IXGRP: mode_t = 8; -pub const S_IWGRP: mode_t = 16; -pub const S_IRGRP: mode_t = 32; -pub const S_IRWXO: mode_t = 7; -pub const S_IXOTH: mode_t = 1; -pub const S_IWOTH: mode_t = 2; -pub const S_IROTH: mode_t = 4; -pub const F_OK: ::c_int = 0; -pub const R_OK: ::c_int = 4; -pub const W_OK: ::c_int = 2; -pub const X_OK: ::c_int = 1; -pub const STDIN_FILENO: ::c_int = 0; -pub const STDOUT_FILENO: ::c_int = 1; -pub const STDERR_FILENO: ::c_int = 2; -pub const F_LOCK: ::c_int = 1; -pub const F_TEST: ::c_int = 3; -pub const F_TLOCK: ::c_int = 2; -pub const F_ULOCK: ::c_int = 0; -pub const F_DUPFD_CLOEXEC: ::c_int = 37; -pub const F_SETLK: ::c_int = 6; -pub const F_SETLKW: ::c_int = 7; -pub const F_GETLK: ::c_int = 14; -pub const SIGHUP: ::c_int = 1; -pub const SIGINT: ::c_int = 2; -pub const SIGQUIT: ::c_int = 3; -pub const SIGILL: ::c_int = 4; -pub const SIGABRT: ::c_int = 6; -pub const SIGEMT: ::c_int = 7; -pub const SIGFPE: ::c_int = 8; -pub const SIGKILL: ::c_int = 9; -pub const SIGSEGV: ::c_int = 11; -pub const SIGSYS: ::c_int = 12; -pub const SIGPIPE: ::c_int = 13; -pub const SIGALRM: ::c_int = 14; -pub const SIGTERM: ::c_int = 15; -pub const SIGUSR1: ::c_int = 16; -pub const SIGUSR2: ::c_int = 17; -pub const SIGPWR: ::c_int = 19; -pub const SIGWINCH: ::c_int = 20; -pub const SIGURG: ::c_int = 21; -pub const SIGPOLL: ::c_int = 22; -pub const SIGIO: ::c_int = SIGPOLL; -pub const SIGSTOP: ::c_int = 23; -pub const SIGTSTP: ::c_int = 24; -pub const SIGCONT: ::c_int = 25; -pub const SIGTTIN: ::c_int = 26; -pub const SIGTTOU: ::c_int = 27; -pub const SIGVTALRM: ::c_int = 28; -pub const SIGPROF: ::c_int = 29; -pub const SIGXCPU: ::c_int = 30; -pub const SIGXFSZ: ::c_int = 31; - -pub const WNOHANG: ::c_int = 0x40; -pub const WUNTRACED: ::c_int = 0x04; - -pub const WEXITED: ::c_int = 0x01; -pub const WTRAPPED: ::c_int = 0x02; -pub const WSTOPPED: ::c_int = WUNTRACED; -pub const WCONTINUED: ::c_int = 0x08; -pub const WNOWAIT: ::c_int = 0x80; - -pub const AT_FDCWD: ::c_int = 0xffd19553; -pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x1000; - -// Solaris defines a great many more of these; we only expose the -// standardized ones. -pub const P_PID: idtype_t = 0; -pub const P_PGID: idtype_t = 2; -pub const P_ALL: idtype_t = 7; - -pub const PROT_NONE: ::c_int = 0; -pub const PROT_READ: ::c_int = 1; -pub const PROT_WRITE: ::c_int = 2; -pub const PROT_EXEC: ::c_int = 4; - -pub const MAP_SHARED: ::c_int = 0x0001; -pub const MAP_PRIVATE: ::c_int = 0x0002; -pub const MAP_FIXED: ::c_int = 0x0010; -pub const MAP_NORESERVE: ::c_int = 0x40; -pub const MAP_ANON: ::c_int = 0x0100; -pub const MAP_RENAME: ::c_int = 0x20; -pub const MAP_ALIGN: ::c_int = 0x200; -pub const MAP_TEXT: ::c_int = 0x400; -pub const MAP_INITDATA: ::c_int = 0x800; -pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; - -pub const MCL_CURRENT: ::c_int = 0x0001; -pub const MCL_FUTURE: ::c_int = 0x0002; - -pub const MS_SYNC: ::c_int = 0x0004; -pub const MS_ASYNC: ::c_int = 0x0001; -pub const MS_INVALIDATE: ::c_int = 0x0002; -pub const MS_INVALCURPROC: ::c_int = 0x0008; - -pub const EPERM: ::c_int = 1; -pub const ENOENT: ::c_int = 2; -pub const ESRCH: ::c_int = 3; -pub const EINTR: ::c_int = 4; -pub const EIO: ::c_int = 5; -pub const ENXIO: ::c_int = 6; -pub const E2BIG: ::c_int = 7; -pub const ENOEXEC: ::c_int = 8; -pub const EBADF: ::c_int = 9; -pub const ECHILD: ::c_int = 10; -pub const EAGAIN: ::c_int = 11; -pub const ENOMEM: ::c_int = 12; -pub const EACCES: ::c_int = 13; -pub const EFAULT: ::c_int = 14; -pub const ENOTBLK: ::c_int = 15; -pub const EBUSY: ::c_int = 16; -pub const EEXIST: ::c_int = 17; -pub const EXDEV: ::c_int = 18; -pub const ENODEV: ::c_int = 19; -pub const ENOTDIR: ::c_int = 20; -pub const EISDIR: ::c_int = 21; -pub const EINVAL: ::c_int = 22; -pub const ENFILE: ::c_int = 23; -pub const EMFILE: ::c_int = 24; -pub const ENOTTY: ::c_int = 25; -pub const ETXTBSY: ::c_int = 26; -pub const EFBIG: ::c_int = 27; -pub const ENOSPC: ::c_int = 28; -pub const ESPIPE: ::c_int = 29; -pub const EROFS: ::c_int = 30; -pub const EMLINK: ::c_int = 31; -pub const EPIPE: ::c_int = 32; -pub const EDOM: ::c_int = 33; -pub const ERANGE: ::c_int = 34; -pub const ENOMSG: ::c_int = 35; -pub const EIDRM: ::c_int = 36; -pub const ECHRNG: ::c_int = 37; -pub const EL2NSYNC: ::c_int = 38; -pub const EL3HLT: ::c_int = 39; -pub const EL3RST: ::c_int = 40; -pub const ELNRNG: ::c_int = 41; -pub const EUNATCH: ::c_int = 42; -pub const ENOCSI: ::c_int = 43; -pub const EL2HLT: ::c_int = 44; -pub const EDEADLK: ::c_int = 45; -pub const ENOLCK: ::c_int = 46; -pub const ECANCELED: ::c_int = 47; -pub const ENOTSUP: ::c_int = 48; -pub const EDQUOT: ::c_int = 49; -pub const EBADE: ::c_int = 50; -pub const EBADR: ::c_int = 51; -pub const EXFULL: ::c_int = 52; -pub const ENOANO: ::c_int = 53; -pub const EBADRQC: ::c_int = 54; -pub const EBADSLT: ::c_int = 55; -pub const EDEADLOCK: ::c_int = 56; -pub const EBFONT: ::c_int = 57; -pub const EOWNERDEAD: ::c_int = 58; -pub const ENOTRECOVERABLE: ::c_int = 59; -pub const ENOSTR: ::c_int = 60; -pub const ENODATA: ::c_int = 61; -pub const ETIME: ::c_int = 62; -pub const ENOSR: ::c_int = 63; -pub const ENONET: ::c_int = 64; -pub const ENOPKG: ::c_int = 65; -pub const EREMOTE: ::c_int = 66; -pub const ENOLINK: ::c_int = 67; -pub const EADV: ::c_int = 68; -pub const ESRMNT: ::c_int = 69; -pub const ECOMM: ::c_int = 70; -pub const EPROTO: ::c_int = 71; -pub const ELOCKUNMAPPED: ::c_int = 72; -pub const ENOTACTIVE: ::c_int = 73; -pub const EMULTIHOP: ::c_int = 74; -pub const EADI: ::c_int = 75; -pub const EBADMSG: ::c_int = 77; -pub const ENAMETOOLONG: ::c_int = 78; -pub const EOVERFLOW: ::c_int = 79; -pub const ENOTUNIQ: ::c_int = 80; -pub const EBADFD: ::c_int = 81; -pub const EREMCHG: ::c_int = 82; -pub const ELIBACC: ::c_int = 83; -pub const ELIBBAD: ::c_int = 84; -pub const ELIBSCN: ::c_int = 85; -pub const ELIBMAX: ::c_int = 86; -pub const ELIBEXEC: ::c_int = 87; -pub const EILSEQ: ::c_int = 88; -pub const ENOSYS: ::c_int = 89; -pub const ELOOP: ::c_int = 90; -pub const ERESTART: ::c_int = 91; -pub const ESTRPIPE: ::c_int = 92; -pub const ENOTEMPTY: ::c_int = 93; -pub const EUSERS: ::c_int = 94; -pub const ENOTSOCK: ::c_int = 95; -pub const EDESTADDRREQ: ::c_int = 96; -pub const EMSGSIZE: ::c_int = 97; -pub const EPROTOTYPE: ::c_int = 98; -pub const ENOPROTOOPT: ::c_int = 99; -pub const EPROTONOSUPPORT: ::c_int = 120; -pub const ESOCKTNOSUPPORT: ::c_int = 121; -pub const EOPNOTSUPP: ::c_int = 122; -pub const EPFNOSUPPORT: ::c_int = 123; -pub const EAFNOSUPPORT: ::c_int = 124; -pub const EADDRINUSE: ::c_int = 125; -pub const EADDRNOTAVAIL: ::c_int = 126; -pub const ENETDOWN: ::c_int = 127; -pub const ENETUNREACH: ::c_int = 128; -pub const ENETRESET: ::c_int = 129; -pub const ECONNABORTED: ::c_int = 130; -pub const ECONNRESET: ::c_int = 131; -pub const ENOBUFS: ::c_int = 132; -pub const EISCONN: ::c_int = 133; -pub const ENOTCONN: ::c_int = 134; -pub const ESHUTDOWN: ::c_int = 143; -pub const ETOOMANYREFS: ::c_int = 144; -pub const ETIMEDOUT: ::c_int = 145; -pub const ECONNREFUSED: ::c_int = 146; -pub const EHOSTDOWN: ::c_int = 147; -pub const EHOSTUNREACH: ::c_int = 148; -pub const EWOULDBLOCK: ::c_int = EAGAIN; -pub const EALREADY: ::c_int = 149; -pub const EINPROGRESS: ::c_int = 150; - -pub const EAI_AGAIN: ::c_int = 2; -pub const EAI_BADFLAGS: ::c_int = 3; -pub const EAI_FAIL: ::c_int = 4; -pub const EAI_FAMILY: ::c_int = 5; -pub const EAI_MEMORY: ::c_int = 6; -pub const EAI_NODATA: ::c_int = 7; -pub const EAI_NONAME: ::c_int = 8; -pub const EAI_SERVICE: ::c_int = 9; -pub const EAI_SOCKTYPE: ::c_int = 10; -pub const EAI_SYSTEM: ::c_int = 11; -pub const EAI_OVERFLOW: ::c_int = 12; - -pub const F_DUPFD: ::c_int = 0; -pub const F_GETFD: ::c_int = 1; -pub const F_SETFD: ::c_int = 2; -pub const F_GETFL: ::c_int = 3; -pub const F_SETFL: ::c_int = 4; - -pub const SIGTRAP: ::c_int = 5; - -pub const GLOB_APPEND : ::c_int = 32; -pub const GLOB_DOOFFS : ::c_int = 16; -pub const GLOB_ERR : ::c_int = 1; -pub const GLOB_MARK : ::c_int = 2; -pub const GLOB_NOCHECK : ::c_int = 8; -pub const GLOB_NOSORT : ::c_int = 4; -pub const GLOB_NOESCAPE: ::c_int = 64; - -pub const GLOB_NOSPACE : ::c_int = -2; -pub const GLOB_ABORTED : ::c_int = -1; -pub const GLOB_NOMATCH : ::c_int = -3; - -pub const POLLIN: ::c_short = 0x1; -pub const POLLPRI: ::c_short = 0x2; -pub const POLLOUT: ::c_short = 0x4; -pub const POLLERR: ::c_short = 0x8; -pub const POLLHUP: ::c_short = 0x10; -pub const POLLNVAL: ::c_short = 0x20; - -pub const POSIX_MADV_NORMAL: ::c_int = 0; -pub const POSIX_MADV_RANDOM: ::c_int = 1; -pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; -pub const POSIX_MADV_WILLNEED: ::c_int = 3; -pub const POSIX_MADV_DONTNEED: ::c_int = 4; - -pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; -pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x40; -pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; -pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 0; -pub const PTHREAD_STACK_MIN: ::size_t = 4096; - -pub const SIGSTKSZ: ::size_t = 8192; - -// https://illumos.org/man/3c/clock_gettime -// https://github.com/illumos/illumos-gate/ -// blob/HEAD/usr/src/lib/libc/amd64/sys/__clock_gettime.s -// clock_gettime(3c) doesn't seem to accept anything other than CLOCK_REALTIME -// or __CLOCK_REALTIME0 -// -// https://github.com/illumos/illumos-gate/ -// blob/HEAD/usr/src/uts/common/sys/time_impl.h -// Confusing! CLOCK_HIGHRES==CLOCK_MONOTONIC==4 -// __CLOCK_REALTIME0==0 is an obsoleted version of CLOCK_REALTIME==3 -pub const CLOCK_REALTIME: ::clockid_t = 3; -pub const CLOCK_MONOTONIC: ::clockid_t = 4; -pub const TIMER_RELTIME: ::c_int = 0; -pub const TIMER_ABSTIME: ::c_int = 1; - -pub const RLIMIT_CPU: ::c_int = 0; -pub const RLIMIT_FSIZE: ::c_int = 1; -pub const RLIMIT_DATA: ::c_int = 2; -pub const RLIMIT_STACK: ::c_int = 3; -pub const RLIMIT_CORE: ::c_int = 4; -pub const RLIMIT_NOFILE: ::c_int = 5; -pub const RLIMIT_VMEM: ::c_int = 6; -pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; - -pub const RLIM_NLIMITS: rlim_t = 7; -pub const RLIM_INFINITY: rlim_t = 0x7fffffff; - -pub const RUSAGE_SELF: ::c_int = 0; -pub const RUSAGE_CHILDREN: ::c_int = -1; - -pub const MADV_NORMAL: ::c_int = 0; -pub const MADV_RANDOM: ::c_int = 1; -pub const MADV_SEQUENTIAL: ::c_int = 2; -pub const MADV_WILLNEED: ::c_int = 3; -pub const MADV_DONTNEED: ::c_int = 4; -pub const MADV_FREE: ::c_int = 5; - -pub const AF_INET: ::c_int = 2; -pub const AF_INET6: ::c_int = 26; -pub const AF_UNIX: ::c_int = 1; -pub const SOCK_DGRAM: ::c_int = 1; -pub const SOCK_STREAM: ::c_int = 2; -pub const SOCK_RAW: ::c_int = 4; -pub const SOCK_RDM: ::c_int = 5; -pub const SOCK_SEQPACKET: ::c_int = 6; -pub const IP_MULTICAST_IF: ::c_int = 16; -pub const IP_MULTICAST_TTL: ::c_int = 17; -pub const IP_MULTICAST_LOOP: ::c_int = 18; -pub const IP_TTL: ::c_int = 4; -pub const IP_HDRINCL: ::c_int = 2; -pub const IP_ADD_MEMBERSHIP: ::c_int = 19; -pub const IP_DROP_MEMBERSHIP: ::c_int = 20; -pub const IPV6_JOIN_GROUP: ::c_int = 9; -pub const IPV6_LEAVE_GROUP: ::c_int = 10; - -pub const TCP_NODELAY: ::c_int = 1; -pub const TCP_KEEPIDLE: ::c_int = 34; -pub const SOL_SOCKET: ::c_int = 0xffff; -pub const SO_DEBUG: ::c_int = 0x01; -pub const SO_ACCEPTCONN: ::c_int = 0x0002; -pub const SO_REUSEADDR: ::c_int = 0x0004; -pub const SO_KEEPALIVE: ::c_int = 0x0008; -pub const SO_DONTROUTE: ::c_int = 0x0010; -pub const SO_BROADCAST: ::c_int = 0x0020; -pub const SO_USELOOPBACK: ::c_int = 0x0040; -pub const SO_LINGER: ::c_int = 0x0080; -pub const SO_OOBINLINE: ::c_int = 0x0100; -pub const SO_SNDBUF: ::c_int = 0x1001; -pub const SO_RCVBUF: ::c_int = 0x1002; -pub const SO_SNDLOWAT: ::c_int = 0x1003; -pub const SO_RCVLOWAT: ::c_int = 0x1004; -pub const SO_SNDTIMEO: ::c_int = 0x1005; -pub const SO_RCVTIMEO: ::c_int = 0x1006; -pub const SO_ERROR: ::c_int = 0x1007; -pub const SO_TYPE: ::c_int = 0x1008; - -pub const MSG_PEEK: ::c_int = 0x2; - -// https://docs.oracle.com/cd/E23824_01/html/821-1475/if-7p.html -pub const IFF_UP: ::c_int = 0x0000000001; // Address is up -pub const IFF_BROADCAST: ::c_int = 0x0000000002; // Broadcast address valid -pub const IFF_DEBUG: ::c_int = 0x0000000004; // Turn on debugging -pub const IFF_LOOPBACK: ::c_int = 0x0000000008; // Loopback net -pub const IFF_POINTOPOINT: ::c_int = 0x0000000010; // Interface is p-to-p -pub const IFF_NOTRAILERS: ::c_int = 0x0000000020; // Avoid use of trailers -pub const IFF_RUNNING: ::c_int = 0x0000000040; // Resources allocated -pub const IFF_NOARP: ::c_int = 0x0000000080; // No address res. protocol -pub const IFF_PROMISC: ::c_int = 0x0000000100; // Receive all packets -pub const IFF_ALLMULTI: ::c_int = 0x0000000200; // Receive all multicast pkts -pub const IFF_INTELLIGENT: ::c_int = 0x0000000400; // Protocol code on board -pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast -// Multicast using broadcst. add. -pub const IFF_MULTI_BCAST: ::c_int = 0x0000001000; -pub const IFF_UNNUMBERED: ::c_int = 0x0000002000; // Non-unique address -pub const IFF_DHCPRUNNING: ::c_int = 0x0000004000; // DHCP controls interface -pub const IFF_PRIVATE: ::c_int = 0x0000008000; // Do not advertise -pub const IFF_NOXMIT: ::c_int = 0x0000010000; // Do not transmit pkts -// No address - just on-link subnet -pub const IFF_NOLOCAL: ::c_int = 0x0000020000; -pub const IFF_DEPRECATED: ::c_int = 0x0000040000; // Address is deprecated -pub const IFF_ADDRCONF: ::c_int = 0x0000080000; // Addr. from stateless addrconf -pub const IFF_ROUTER: ::c_int = 0x0000100000; // Router on interface -pub const IFF_NONUD: ::c_int = 0x0000200000; // No NUD on interface -pub const IFF_ANYCAST: ::c_int = 0x0000400000; // Anycast address -pub const IFF_NORTEXCH: ::c_int = 0x0000800000; // Don't xchange rout. info -pub const IFF_IPV4: ::c_int = 0x0001000000; // IPv4 interface -pub const IFF_IPV6: ::c_int = 0x0002000000; // IPv6 interface -pub const IFF_NOFAILOVER: ::c_int = 0x0008000000; // in.mpathd test address -pub const IFF_FAILED: ::c_int = 0x0010000000; // Interface has failed -pub const IFF_STANDBY: ::c_int = 0x0020000000; // Interface is a hot-spare -pub const IFF_INACTIVE: ::c_int = 0x0040000000; // Functioning but not used -pub const IFF_OFFLINE: ::c_int = 0x0080000000; // Interface is offline -// If CoS marking is supported -pub const IFF_COS_ENABLED: ::c_longlong = 0x0200000000; -pub const IFF_PREFERRED: ::c_longlong = 0x0400000000; // Prefer as source addr. -pub const IFF_TEMPORARY: ::c_longlong = 0x0800000000; // RFC3041 -pub const IFF_FIXEDMTU: ::c_longlong = 0x1000000000; // MTU set with SIOCSLIFMTU -pub const IFF_VIRTUAL: ::c_longlong = 0x2000000000; // Cannot send/receive pkts -pub const IFF_DUPLICATE: ::c_longlong = 0x4000000000; // Local address in use -pub const IFF_IPMP: ::c_longlong = 0x8000000000; // IPMP IP interface - -pub const SHUT_RD: ::c_int = 0; -pub const SHUT_WR: ::c_int = 1; -pub const SHUT_RDWR: ::c_int = 2; - -pub const LOCK_SH: ::c_int = 1; -pub const LOCK_EX: ::c_int = 2; -pub const LOCK_NB: ::c_int = 4; -pub const LOCK_UN: ::c_int = 8; - -pub const F_RDLCK: ::c_short = 1; -pub const F_WRLCK: ::c_short = 2; -pub const F_UNLCK: ::c_short = 3; - -pub const O_SYNC: ::c_int = 16; -pub const O_NONBLOCK: ::c_int = 128; - -pub const IPPROTO_RAW: ::c_int = 255; - -pub const _PC_LINK_MAX: ::c_int = 1; -pub const _PC_MAX_CANON: ::c_int = 2; -pub const _PC_MAX_INPUT: ::c_int = 3; -pub const _PC_NAME_MAX: ::c_int = 4; -pub const _PC_PATH_MAX: ::c_int = 5; -pub const _PC_PIPE_BUF: ::c_int = 6; -pub const _PC_NO_TRUNC: ::c_int = 7; -pub const _PC_VDISABLE: ::c_int = 8; -pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; -pub const _PC_ASYNC_IO: ::c_int = 10; -pub const _PC_PRIO_IO: ::c_int = 11; -pub const _PC_SYNC_IO: ::c_int = 12; -pub const _PC_ALLOC_SIZE_MIN: ::c_int = 13; -pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; -pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; -pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; -pub const _PC_REC_XFER_ALIGN: ::c_int = 17; -pub const _PC_SYMLINK_MAX: ::c_int = 18; -pub const _PC_2_SYMLINKS: ::c_int = 19; -pub const _PC_ACL_ENABLED: ::c_int = 20; -pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; -pub const _PC_CASE_BEHAVIOR: ::c_int = 22; -pub const _PC_SATTR_ENABLED: ::c_int = 23; -pub const _PC_SATTR_EXISTS: ::c_int = 24; -pub const _PC_ACCESS_FILTERING: ::c_int = 25; -pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 26; -pub const _PC_FILESIZEBITS: ::c_int = 67; -pub const _PC_XATTR_ENABLED: ::c_int = 100; -pub const _PC_LAST: ::c_int = 101; -pub const _PC_XATTR_EXISTS: ::c_int = 101; - -pub const _SC_ARG_MAX: ::c_int = 1; -pub const _SC_CHILD_MAX: ::c_int = 2; -pub const _SC_CLK_TCK: ::c_int = 3; -pub const _SC_NGROUPS_MAX: ::c_int = 4; -pub const _SC_OPEN_MAX: ::c_int = 5; -pub const _SC_JOB_CONTROL: ::c_int = 6; -pub const _SC_SAVED_IDS: ::c_int = 7; -pub const _SC_VERSION: ::c_int = 8; -pub const _SC_PASS_MAX: ::c_int = 9; -pub const _SC_LOGNAME_MAX: ::c_int = 10; -pub const _SC_PAGESIZE: ::c_int = 11; -pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; -pub const _SC_XOPEN_VERSION: ::c_int = 12; -pub const _SC_NPROCESSORS_CONF: ::c_int = 14; -pub const _SC_NPROCESSORS_ONLN: ::c_int = 15; -pub const _SC_STREAM_MAX: ::c_int = 16; -pub const _SC_TZNAME_MAX: ::c_int = 17; -pub const _SC_AIO_LISTIO_MAX: ::c_int = 18; -pub const _SC_AIO_MAX: ::c_int = 19; -pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 20; -pub const _SC_ASYNCHRONOUS_IO: ::c_int = 21; -pub const _SC_DELAYTIMER_MAX: ::c_int = 22; -pub const _SC_FSYNC: ::c_int = 23; -pub const _SC_MAPPED_FILES: ::c_int = 24; -pub const _SC_MEMLOCK: ::c_int = 25; -pub const _SC_MEMLOCK_RANGE: ::c_int = 26; -pub const _SC_MEMORY_PROTECTION: ::c_int = 27; -pub const _SC_MESSAGE_PASSING: ::c_int = 28; -pub const _SC_MQ_OPEN_MAX: ::c_int = 29; -pub const _SC_MQ_PRIO_MAX: ::c_int = 30; -pub const _SC_PRIORITIZED_IO: ::c_int = 31; -pub const _SC_PRIORITY_SCHEDULING: ::c_int = 32; -pub const _SC_REALTIME_SIGNALS: ::c_int = 33; -pub const _SC_RTSIG_MAX: ::c_int = 34; -pub const _SC_SEMAPHORES: ::c_int = 35; -pub const _SC_SEM_NSEMS_MAX: ::c_int = 36; -pub const _SC_SEM_VALUE_MAX: ::c_int = 37; -pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 38; -pub const _SC_SIGQUEUE_MAX: ::c_int = 39; -pub const _SC_SIGRT_MIN: ::c_int = 40; -pub const _SC_SIGRT_MAX: ::c_int = 41; -pub const _SC_SYNCHRONIZED_IO: ::c_int = 42; -pub const _SC_TIMERS: ::c_int = 43; -pub const _SC_TIMER_MAX: ::c_int = 44; -pub const _SC_2_C_BIND: ::c_int = 45; -pub const _SC_2_C_DEV: ::c_int = 46; -pub const _SC_2_C_VERSION: ::c_int = 47; -pub const _SC_2_FORT_DEV: ::c_int = 48; -pub const _SC_2_FORT_RUN: ::c_int = 49; -pub const _SC_2_LOCALEDEF: ::c_int = 50; -pub const _SC_2_SW_DEV: ::c_int = 51; -pub const _SC_2_UPE: ::c_int = 52; -pub const _SC_2_VERSION: ::c_int = 53; -pub const _SC_BC_BASE_MAX: ::c_int = 54; -pub const _SC_BC_DIM_MAX: ::c_int = 55; -pub const _SC_BC_SCALE_MAX: ::c_int = 56; -pub const _SC_BC_STRING_MAX: ::c_int = 57; -pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 58; -pub const _SC_EXPR_NEST_MAX: ::c_int = 59; -pub const _SC_LINE_MAX: ::c_int = 60; -pub const _SC_RE_DUP_MAX: ::c_int = 61; -pub const _SC_XOPEN_CRYPT: ::c_int = 62; -pub const _SC_XOPEN_ENH_I18N: ::c_int = 63; -pub const _SC_XOPEN_SHM: ::c_int = 64; -pub const _SC_2_CHAR_TERM: ::c_int = 66; -pub const _SC_XOPEN_XCU_VERSION: ::c_int = 67; -pub const _SC_ATEXIT_MAX: ::c_int = 76; -pub const _SC_IOV_MAX: ::c_int = 77; -pub const _SC_XOPEN_UNIX: ::c_int = 78; -pub const _SC_T_IOV_MAX: ::c_int = 79; -pub const _SC_PHYS_PAGES: ::c_int = 500; -pub const _SC_AVPHYS_PAGES: ::c_int = 501; -pub const _SC_COHER_BLKSZ: ::c_int = 503; -pub const _SC_SPLIT_CACHE: ::c_int = 504; -pub const _SC_ICACHE_SZ: ::c_int = 505; -pub const _SC_DCACHE_SZ: ::c_int = 506; -pub const _SC_ICACHE_LINESZ: ::c_int = 507; -pub const _SC_DCACHE_LINESZ: ::c_int = 508; -pub const _SC_ICACHE_BLKSZ: ::c_int = 509; -pub const _SC_DCACHE_BLKSZ: ::c_int = 510; -pub const _SC_DCACHE_TBLKSZ: ::c_int = 511; -pub const _SC_ICACHE_ASSOC: ::c_int = 512; -pub const _SC_DCACHE_ASSOC: ::c_int = 513; -pub const _SC_MAXPID: ::c_int = 514; -pub const _SC_STACK_PROT: ::c_int = 515; -pub const _SC_NPROCESSORS_MAX: ::c_int = 516; -pub const _SC_CPUID_MAX: ::c_int = 517; -pub const _SC_EPHID_MAX: ::c_int = 518; -pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 568; -pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 569; -pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 570; -pub const _SC_LOGIN_NAME_MAX: ::c_int = 571; -pub const _SC_THREAD_KEYS_MAX: ::c_int = 572; -pub const _SC_THREAD_STACK_MIN: ::c_int = 573; -pub const _SC_THREAD_THREADS_MAX: ::c_int = 574; -pub const _SC_TTY_NAME_MAX: ::c_int = 575; -pub const _SC_THREADS: ::c_int = 576; -pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 577; -pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 578; -pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 579; -pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 580; -pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 581; -pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 582; -pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 583; -pub const _SC_XOPEN_LEGACY: ::c_int = 717; -pub const _SC_XOPEN_REALTIME: ::c_int = 718; -pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 719; -pub const _SC_XBS5_ILP32_OFF32: ::c_int = 720; -pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 721; -pub const _SC_XBS5_LP64_OFF64: ::c_int = 722; -pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 723; -pub const _SC_2_PBS: ::c_int = 724; -pub const _SC_2_PBS_ACCOUNTING: ::c_int = 725; -pub const _SC_2_PBS_CHECKPOINT: ::c_int = 726; -pub const _SC_2_PBS_LOCATE: ::c_int = 728; -pub const _SC_2_PBS_MESSAGE: ::c_int = 729; -pub const _SC_2_PBS_TRACK: ::c_int = 730; -pub const _SC_ADVISORY_INFO: ::c_int = 731; -pub const _SC_BARRIERS: ::c_int = 732; -pub const _SC_CLOCK_SELECTION: ::c_int = 733; -pub const _SC_CPUTIME: ::c_int = 734; -pub const _SC_HOST_NAME_MAX: ::c_int = 735; -pub const _SC_MONOTONIC_CLOCK: ::c_int = 736; -pub const _SC_READER_WRITER_LOCKS: ::c_int = 737; -pub const _SC_REGEXP: ::c_int = 738; -pub const _SC_SHELL: ::c_int = 739; -pub const _SC_SPAWN: ::c_int = 740; -pub const _SC_SPIN_LOCKS: ::c_int = 741; -pub const _SC_SPORADIC_SERVER: ::c_int = 742; -pub const _SC_SS_REPL_MAX: ::c_int = 743; -pub const _SC_SYMLOOP_MAX: ::c_int = 744; -pub const _SC_THREAD_CPUTIME: ::c_int = 745; -pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 746; -pub const _SC_TIMEOUTS: ::c_int = 747; -pub const _SC_TRACE: ::c_int = 748; -pub const _SC_TRACE_EVENT_FILTER: ::c_int = 749; -pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 750; -pub const _SC_TRACE_INHERIT: ::c_int = 751; -pub const _SC_TRACE_LOG: ::c_int = 752; -pub const _SC_TRACE_NAME_MAX: ::c_int = 753; -pub const _SC_TRACE_SYS_MAX: ::c_int = 754; -pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 755; -pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 756; -pub const _SC_V6_ILP32_OFF32: ::c_int = 757; -pub const _SC_V6_ILP32_OFFBIG: ::c_int = 758; -pub const _SC_V6_LP64_OFF64: ::c_int = 759; -pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 760; -pub const _SC_XOPEN_STREAMS: ::c_int = 761; -pub const _SC_IPV6: ::c_int = 762; -pub const _SC_RAW_SOCKETS: ::c_int = 763; - -pub const _MUTEX_MAGIC: u16 = 0x4d58; // MX -pub const _COND_MAGIC: u16 = 0x4356; // CV -pub const _RWL_MAGIC: u16 = 0x5257; // RW - -pub const NCCS: usize = 19; - -pub const LOG_CRON: ::c_int = 15 << 3; - -pub const SYS_epoll_create: ::c_long = 213; -pub const SYS_epoll_create1: ::c_long = 291; - -pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { - __pthread_mutex_flag1: 0, - __pthread_mutex_flag2: 0, - __pthread_mutex_ceiling: 0, - __pthread_mutex_type: PTHREAD_PROCESS_PRIVATE, - __pthread_mutex_magic: _MUTEX_MAGIC, - __pthread_mutex_lock: 0, - __pthread_mutex_data: 0 -}; -pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { - __pthread_cond_flag: [0; 4], - __pthread_cond_type: PTHREAD_PROCESS_PRIVATE, - __pthread_cond_magic: _COND_MAGIC, - __pthread_cond_data: 0 -}; -pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { - __pthread_rwlock_readers: 0, - __pthread_rwlock_type: PTHREAD_PROCESS_PRIVATE, - __pthread_rwlock_magic: _RWL_MAGIC, - __pthread_rwlock_mutex: PTHREAD_MUTEX_INITIALIZER, - __pthread_rwlock_readercv: PTHREAD_COND_INITIALIZER, - __pthread_rwlock_writercv: PTHREAD_COND_INITIALIZER -}; -pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; -pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; -pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; -pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; - -pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; -pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; -pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; -pub const RTLD_PROBE: *mut ::c_void = -4isize as *mut ::c_void; - -pub const RTLD_LAZY: ::c_int = 0x1; -pub const RTLD_NOW: ::c_int = 0x2; -pub const RTLD_NOLOAD: ::c_int = 0x4; -pub const RTLD_GLOBAL: ::c_int = 0x100; -pub const RTLD_LOCAL: ::c_int = 0x0; -pub const RTLD_PARENT: ::c_int = 0x200; -pub const RTLD_GROUP: ::c_int = 0x400; -pub const RTLD_WORLD: ::c_int = 0x800; -pub const RTLD_NODELETE: ::c_int = 0x1000; -pub const RTLD_FIRST: ::c_int = 0x2000; -pub const RTLD_CONFGEN: ::c_int = 0x10000; - -pub const PORT_SOURCE_AIO: ::c_int = 1; -pub const PORT_SOURCE_TIMER: ::c_int = 2; -pub const PORT_SOURCE_USER: ::c_int = 3; -pub const PORT_SOURCE_FD: ::c_int = 4; -pub const PORT_SOURCE_ALERT: ::c_int = 5; -pub const PORT_SOURCE_MQ: ::c_int = 6; -pub const PORT_SOURCE_FILE: ::c_int = 7; -pub const PORT_SOURCE_POSTWAIT: ::c_int = 8; -pub const PORT_SOURCE_SIGNAL: ::c_int = 9; - -pub const TIOCGWINSZ: ::c_int = 0x5468; -pub const TIOCSWINSZ: ::c_int = 0x5467; - -pub const EPOLLIN: ::c_int = 0x1; -pub const EPOLLPRI: ::c_int = 0x2; -pub const EPOLLOUT: ::c_int = 0x4; -pub const EPOLLRDNORM: ::c_int = 0x40; -pub const EPOLLRDBAND: ::c_int = 0x80; -pub const EPOLLWRNORM: ::c_int = 0x100; -pub const EPOLLWRBAND: ::c_int = 0x200; -pub const EPOLLMSG: ::c_int = 0x400; -pub const EPOLLERR: ::c_int = 0x8; -pub const EPOLLHUP: ::c_int = 0x10; -pub const EPOLLET: ::c_int = 0x80000000; -pub const EPOLLRDHUP: ::c_int = 0x2000; -pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; -pub const EPOLLONESHOT: ::c_int = 0x40000000; -pub const EPOLL_CLOEXEC: ::c_int = 0x80000; -pub const EPOLL_CTL_ADD: ::c_int = 1; -pub const EPOLL_CTL_MOD: ::c_int = 3; -pub const EPOLL_CTL_DEL: ::c_int = 2; - -f! { - pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; - let fd = fd as usize; - (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); - return - } - - pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; - let fd = fd as usize; - return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 - } - - pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { - let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8; - let fd = fd as usize; - (*set).fds_bits[fd / bits] |= 1 << (fd % bits); - return - } - - pub fn FD_ZERO(set: *mut fd_set) -> () { - for slot in (*set).fds_bits.iter_mut() { - *slot = 0; - } - } - - pub fn WIFEXITED(status: ::c_int) -> bool { - (status & 0xFF) == 0 - } - - pub fn WEXITSTATUS(status: ::c_int) -> ::c_int { - (status >> 8) & 0xFF - } - - pub fn WTERMSIG(status: ::c_int) -> ::c_int { - status & 0x7F - } -} - -extern { - pub fn abs(i: ::c_int) -> ::c_int; - pub fn atof(s: *const ::c_char) -> ::c_double; - pub fn labs(i: ::c_long) -> ::c_long; - pub fn rand() -> ::c_int; - pub fn srand(seed: ::c_uint); - - pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; - pub fn freeifaddrs(ifa: *mut ::ifaddrs); - - pub fn stack_getbounds(sp: *mut ::stack_t) -> ::c_int; - pub fn mincore(addr: *const ::c_void, len: ::size_t, - vec: *mut c_char) -> ::c_int; - pub fn setgroups(ngroups: ::c_int, - ptr: *const ::gid_t) -> ::c_int; - pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; - pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) - -> ::c_int; - pub fn ___errno() -> *mut ::c_int; - pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; - pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; - pub fn clock_nanosleep(clk_id: ::clockid_t, - flags: ::c_int, - rqtp: *const ::timespec, - rmtp: *mut ::timespec) -> ::c_int; - pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; - pub fn getnameinfo(sa: *const ::sockaddr, - salen: ::socklen_t, - host: *mut ::c_char, - hostlen: ::socklen_t, - serv: *mut ::c_char, - sevlen: ::socklen_t, - flags: ::c_int) -> ::c_int; - pub fn setpwent(); - pub fn endpwent(); - pub fn getpwent() -> *mut passwd; - pub fn fdatasync(fd: ::c_int) -> ::c_int; - pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; - pub fn duplocale(base: ::locale_t) -> ::locale_t; - pub fn freelocale(loc: ::locale_t); - pub fn newlocale(mask: ::c_int, - locale: *const ::c_char, - base: ::locale_t) -> ::locale_t; - pub fn uselocale(loc: ::locale_t) -> ::locale_t; - pub fn getprogname() -> *const ::c_char; - pub fn setprogname(name: *const ::c_char); - pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; - pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; - pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int; - - pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char, - mode: ::mode_t, dev: dev_t) -> ::c_int; - pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, - mode: ::mode_t) -> ::c_int; - pub fn sethostname(name: *mut ::c_char, len: ::c_int) -> ::c_int; - pub fn if_nameindex() -> *mut if_nameindex; - pub fn if_freenameindex(ptr: *mut if_nameindex); - pub fn pthread_create(native: *mut ::pthread_t, - attr: *const ::pthread_attr_t, - f: extern fn(*mut ::c_void) -> *mut ::c_void, - value: *mut ::c_void) -> ::c_int; - pub fn pthread_condattr_getclock(attr: *const pthread_condattr_t, - clock_id: *mut clockid_t) -> ::c_int; - pub fn pthread_condattr_setclock(attr: *mut pthread_condattr_t, - clock_id: ::clockid_t) -> ::c_int; - pub fn sem_timedwait(sem: *mut sem_t, - abstime: *const ::timespec) -> ::c_int; - pub fn sem_getvalue(sem: *mut sem_t, - sval: *mut ::c_int) -> ::c_int; - pub fn pthread_mutex_timedlock(lock: *mut pthread_mutex_t, - abstime: *const ::timespec) -> ::c_int; - pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, - options: ::c_int) -> ::c_int; - - pub fn glob(pattern: *const ::c_char, - flags: ::c_int, - errfunc: Option ::c_int>, - pglob: *mut ::glob_t) -> ::c_int; - - pub fn globfree(pglob: *mut ::glob_t); - - pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) - -> ::c_int; - - pub fn shm_unlink(name: *const ::c_char) -> ::c_int; - - pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); - - pub fn telldir(dirp: *mut ::DIR) -> ::c_long; - pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) - -> ::c_int; - - pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; - - pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; - - pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, - flags: ::c_int, addr: *mut ::sockaddr, - addrlen: *mut ::socklen_t) -> ::ssize_t; - pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; - pub fn futimesat(fd: ::c_int, path: *const ::c_char, - times: *const ::timeval) -> ::c_int; - pub fn utimensat(dirfd: ::c_int, path: *const ::c_char, - times: *const ::timespec, flag: ::c_int) -> ::c_int; - pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; - - pub fn bind(socket: ::c_int, address: *const ::sockaddr, - address_len: ::socklen_t) -> ::c_int; - - pub fn writev(fd: ::c_int, - iov: *const ::iovec, - iovcnt: ::c_int) -> ::ssize_t; - pub fn readv(fd: ::c_int, - iov: *const ::iovec, - iovcnt: ::c_int) -> ::ssize_t; - - pub fn sendmsg(fd: ::c_int, - msg: *const ::msghdr, - flags: ::c_int) -> ::ssize_t; - pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) - -> ::ssize_t; - - pub fn port_create() -> ::c_int; - pub fn port_associate(port: ::c_int, source: ::c_int, object: ::uintptr_t, - events: ::c_int, user: *mut ::c_void) -> ::c_int; - pub fn port_dissociate(port: ::c_int, source: ::c_int, object: ::uintptr_t) - -> ::c_int; - pub fn port_get(port: ::c_int, pe: *mut port_event, - timeout: *mut ::timespec) -> ::c_int; - pub fn port_getn(port: ::c_int, pe_list: *mut port_event, max: ::c_uint, - nget: *mut ::c_uint, timeout: *mut ::timespec) - -> ::c_int; - pub fn fexecve(fd: ::c_int, argv: *const *const ::c_char, - envp: *const *const ::c_char) - -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, - grp: *mut ::group, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut ::group) -> ::c_int; - pub fn sigaltstack(ss: *const stack_t, - oss: *mut stack_t) -> ::c_int; - pub fn sem_close(sem: *mut sem_t) -> ::c_int; - pub fn getdtablesize() -> ::c_int; - - pub fn epoll_pwait(epfd: ::c_int, - events: *mut ::epoll_event, - maxevents: ::c_int, - timeout: ::c_int, - sigmask: *const ::sigset_t) -> ::c_int; - pub fn epoll_create(size: ::c_int) -> ::c_int; - pub fn epoll_create1(flags: ::c_int) -> ::c_int; - pub fn epoll_wait(epfd: ::c_int, - events: *mut ::epoll_event, - maxevents: ::c_int, - timeout: ::c_int) -> ::c_int; - pub fn epoll_ctl(epfd: ::c_int, - op: ::c_int, - fd: ::c_int, - event: *mut ::epoll_event) -> ::c_int; - - #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrnam_r")] - pub fn getgrnam_r(name: *const ::c_char, - grp: *mut ::group, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut ::group) -> ::c_int; - pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, - oldset: *mut sigset_t) -> ::c_int; - pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; - pub fn getgrnam(name: *const ::c_char) -> *mut ::group; - pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; - pub fn sem_unlink(name: *const ::c_char) -> ::c_int; - pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwnam_r")] - pub fn getpwnam_r(name: *const ::c_char, - pwd: *mut passwd, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut passwd) -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwuid_r")] - pub fn getpwuid_r(uid: ::uid_t, - pwd: *mut passwd, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut passwd) -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwent_r")] - pub fn getpwent_r(pwd: *mut passwd, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut passwd) -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrent_r")] - pub fn getgrent_r(grp: *mut ::group, - buf: *mut ::c_char, - buflen: ::size_t, - result: *mut *mut ::group) -> ::c_int; - #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] - pub fn sigwait(set: *const sigset_t, - sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; - pub fn getgrgid(gid: ::gid_t) -> *mut ::group; - pub fn popen(command: *const c_char, - mode: *const c_char) -> *mut ::FILE; - - pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; - pub fn uname(buf: *mut ::utsname) -> ::c_int; -} diff -Nru cargo-0.33.0/vendor/libc/src/unix/solarish/compat.rs cargo-0.35.0/vendor/libc/src/unix/solarish/compat.rs --- cargo-0.33.0/vendor/libc/src/unix/solarish/compat.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/solarish/compat.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +// Common functions that are unfortunately missing on illumos and +// Solaris, but often needed by other crates. + +use unix::solarish::*; + +pub unsafe fn cfmakeraw(termios: *mut ::termios) { + let mut t = *termios as ::termios; + t.c_iflag &= !(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); + t.c_oflag &= !OPOST; + t.c_lflag &= !(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + t.c_cflag &= !(CSIZE|PARENB); + t.c_cflag |= CS8; +} + +pub unsafe fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int { + // Neither of these functions on illumos or Solaris actually ever + // return an error + ::cfsetispeed(termios, speed); + ::cfsetospeed(termios, speed); + 0 +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/solarish/mod.rs cargo-0.35.0/vendor/libc/src/unix/solarish/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/solarish/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/solarish/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,2031 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; + +pub type clockid_t = ::c_int; +pub type blkcnt_t = ::c_long; +pub type clock_t = ::c_long; +pub type daddr_t = ::c_long; +pub type dev_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type key_t = ::c_int; +pub type major_t = ::c_uint; +pub type minor_t = ::c_uint; +pub type mode_t = ::c_uint; +pub type nlink_t = ::c_uint; +pub type rlim_t = ::c_ulong; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type time_t = ::c_long; +pub type wchar_t = ::c_int; +pub type nfds_t = ::c_ulong; + +pub type suseconds_t = ::c_long; +pub type off_t = ::c_long; +pub type useconds_t = ::c_uint; +pub type socklen_t = ::c_uint; +pub type sa_family_t = u16; +pub type pthread_t = ::c_uint; +pub type pthread_key_t = ::c_uint; +pub type blksize_t = ::c_int; +pub type nl_item = ::c_int; +pub type id_t = ::c_int; +pub type idtype_t = ::c_uint; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [::c_char; 8] + } + + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: ::in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + pub __sin6_src_id: u32 + } + + pub struct passwd { + pub pw_name: *mut ::c_char, + pub pw_passwd: *mut ::c_char, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_age: *mut ::c_char, + pub pw_comment: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char + } + + pub struct ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut ::c_char, + pub ifa_flags: ::c_ulong, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void + } + + pub struct tm { + pub tm_sec: ::c_int, + pub tm_min: ::c_int, + pub tm_hour: ::c_int, + pub tm_mday: ::c_int, + pub tm_mon: ::c_int, + pub tm_year: ::c_int, + pub tm_wday: ::c_int, + pub tm_yday: ::c_int, + pub tm_isdst: ::c_int + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct pthread_attr_t { + __pthread_attrp: *mut ::c_void + } + + pub struct pthread_mutex_t { + __pthread_mutex_flag1: u16, + __pthread_mutex_flag2: u8, + __pthread_mutex_ceiling: u8, + __pthread_mutex_type: u16, + __pthread_mutex_magic: u16, + __pthread_mutex_lock: u64, + __pthread_mutex_data: u64 + } + + pub struct pthread_mutexattr_t { + __pthread_mutexattrp: *mut ::c_void + } + + pub struct pthread_cond_t { + __pthread_cond_flag: [u8; 4], + __pthread_cond_type: u16, + __pthread_cond_magic: u16, + __pthread_cond_data: u64 + } + + pub struct pthread_condattr_t { + __pthread_condattrp: *mut ::c_void, + } + + pub struct pthread_rwlock_t { + __pthread_rwlock_readers: i32, + __pthread_rwlock_type: u16, + __pthread_rwlock_magic: u16, + __pthread_rwlock_mutex: ::pthread_mutex_t, + __pthread_rwlock_readercv: ::pthread_cond_t, + __pthread_rwlock_writercv: ::pthread_cond_t + } + + pub struct pthread_rwlockattr_t { + __pthread_rwlockattrp: *mut ::c_void, + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_name: [::c_char; 3] + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + __unused1: *mut ::c_void, + __unused2: ::c_int, + __unused3: ::c_int, + __unused4: ::c_int, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + __unused9: *mut ::c_void, + __unused10: *mut ::c_void, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + #[cfg(target_arch = "sparc64")] + __sparcv9_pad: ::c_int, + pub ai_addrlen: ::socklen_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct sigset_t { + bits: [u32; 4], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + pub ss_sp: *mut ::c_void, + pub sigev_notify_attributes: *const ::pthread_attr_t, + __sigev_pad2: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct statvfs { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fsid: ::c_ulong, + pub f_basetype: [::c_char; 16], + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_fstr: [::c_char; 32] + } + + pub struct sched_param { + pub sched_priority: ::c_int, + sched_pad: [::c_int; 8] + } + + pub struct Dl_info { + pub dli_fname: *const ::c_char, + pub dli_fbase: *mut ::c_void, + pub dli_sname: *const ::c_char, + pub dli_saddr: *mut ::c_void, + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __unused: [::c_char; 16] + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_cc: [::cc_t; ::NCCS] + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + pub grouping: *mut ::c_char, + pub int_curr_symbol: *mut ::c_char, + pub currency_symbol: *mut ::c_char, + pub mon_decimal_point: *mut ::c_char, + pub mon_thousands_sep: *mut ::c_char, + pub mon_grouping: *mut ::c_char, + pub positive_sign: *mut ::c_char, + pub negative_sign: *mut ::c_char, + pub int_frac_digits: ::c_char, + pub frac_digits: ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub n_sign_posn: ::c_char, + pub int_p_cs_precedes: ::c_char, + pub int_p_sep_by_space: ::c_char, + pub int_n_cs_precedes: ::c_char, + pub int_n_sep_by_space: ::c_char, + pub int_p_sign_posn: ::c_char, + pub int_n_sign_posn: ::c_char, + } + + pub struct sem_t { + pub sem_count: u32, + pub sem_type: u16, + pub sem_magic: u16, + pub sem_pad1: [u64; 3], + pub sem_pad2: [u64; 2] + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_sysid: ::c_int, + pub l_pid: ::pid_t, + pub l_pad: [::c_long; 4] + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct port_event { + pub portev_events: ::c_int, + pub portev_source: ::c_ushort, + pub portev_pad: ::c_ushort, + pub portev_object: ::uintptr_t, + pub portev_user: *mut ::c_void, + } +} + +s_no_extra_traits! { + #[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), repr(packed))] + pub struct epoll_event { + pub events: ::uint32_t, + pub u64: ::uint64_t, + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [c_char; 108] + } + + pub struct utsname { + pub sysname: [::c_char; 257], + pub nodename: [::c_char; 257], + pub release: [::c_char; 257], + pub version: [::c_char; 257], + pub machine: [::c_char; 257], + } + + pub struct fd_set { + #[cfg(target_pointer_width = "64")] + fds_bits: [i64; FD_SETSIZE / 64], + #[cfg(target_pointer_width = "32")] + fds_bits: [i32; FD_SETSIZE / 32], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 240], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_pad: ::c_int, + pub si_addr: *mut ::c_void, + __pad: [u8; 232], + } + + pub struct sockaddr_dl { + pub sdl_family: ::c_ushort, + pub sdl_index: ::c_ushort, + pub sdl_type: ::c_uchar, + pub sdl_nlen: ::c_uchar, + pub sdl_alen: ::c_uchar, + pub sdl_slen: ::c_uchar, + pub sdl_data: [::c_char; 244], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for fd_set { + fn eq(&self, other: &fd_set) -> bool { + self.fds_bits + .iter() + .zip(other.fds_bits.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for fd_set {} + impl ::fmt::Debug for fd_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fd_set") + // FIXME: .field("fds_bits", &self.fds_bits) + .finish() + } + } + impl ::hash::Hash for fd_set { + fn hash(&self, state: &mut H) { + self.fds_bits.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_code == other.si_code + && self.si_errno == other.si_errno + && self.si_addr == other.si_addr + && self + .__pad + .iter() + .zip(other.__pad.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for siginfo_t {} + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + .field("si_addr", &self.si_addr) + // FIXME: .field("__pad", &self.__pad) + .finish() + } + } + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); + self.si_addr.hash(state); + self.__pad.hash(state); + } + } + + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + // FIXME: .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } + } +} + +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 2; +pub const LC_COLLATE: ::c_int = 3; +pub const LC_MONETARY: ::c_int = 4; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +pub const LC_CTYPE_MASK: ::c_int = (1 << LC_CTYPE); +pub const LC_NUMERIC_MASK: ::c_int = (1 << LC_NUMERIC); +pub const LC_TIME_MASK: ::c_int = (1 << LC_TIME); +pub const LC_COLLATE_MASK: ::c_int = (1 << LC_COLLATE); +pub const LC_MONETARY_MASK: ::c_int = (1 << LC_MONETARY); +pub const LC_MESSAGES_MASK: ::c_int = (1 << LC_MESSAGES); +pub const LC_ALL_MASK: ::c_int = LC_CTYPE_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK + | LC_COLLATE_MASK + | LC_MONETARY_MASK + | LC_MESSAGES_MASK; + +pub const DAY_1: ::nl_item = 1; +pub const DAY_2: ::nl_item = 2; +pub const DAY_3: ::nl_item = 3; +pub const DAY_4: ::nl_item = 4; +pub const DAY_5: ::nl_item = 5; +pub const DAY_6: ::nl_item = 6; +pub const DAY_7: ::nl_item = 7; + +pub const ABDAY_1: ::nl_item = 8; +pub const ABDAY_2: ::nl_item = 9; +pub const ABDAY_3: ::nl_item = 10; +pub const ABDAY_4: ::nl_item = 11; +pub const ABDAY_5: ::nl_item = 12; +pub const ABDAY_6: ::nl_item = 13; +pub const ABDAY_7: ::nl_item = 14; + +pub const MON_1: ::nl_item = 15; +pub const MON_2: ::nl_item = 16; +pub const MON_3: ::nl_item = 17; +pub const MON_4: ::nl_item = 18; +pub const MON_5: ::nl_item = 19; +pub const MON_6: ::nl_item = 20; +pub const MON_7: ::nl_item = 21; +pub const MON_8: ::nl_item = 22; +pub const MON_9: ::nl_item = 23; +pub const MON_10: ::nl_item = 24; +pub const MON_11: ::nl_item = 25; +pub const MON_12: ::nl_item = 26; + +pub const ABMON_1: ::nl_item = 27; +pub const ABMON_2: ::nl_item = 28; +pub const ABMON_3: ::nl_item = 29; +pub const ABMON_4: ::nl_item = 30; +pub const ABMON_5: ::nl_item = 31; +pub const ABMON_6: ::nl_item = 32; +pub const ABMON_7: ::nl_item = 33; +pub const ABMON_8: ::nl_item = 34; +pub const ABMON_9: ::nl_item = 35; +pub const ABMON_10: ::nl_item = 36; +pub const ABMON_11: ::nl_item = 37; +pub const ABMON_12: ::nl_item = 38; + +pub const RADIXCHAR: ::nl_item = 39; +pub const THOUSEP: ::nl_item = 40; +pub const YESSTR: ::nl_item = 41; +pub const NOSTR: ::nl_item = 42; +pub const CRNCYSTR: ::nl_item = 43; + +pub const D_T_FMT: ::nl_item = 44; +pub const D_FMT: ::nl_item = 45; +pub const T_FMT: ::nl_item = 46; +pub const AM_STR: ::nl_item = 47; +pub const PM_STR: ::nl_item = 48; + +pub const CODESET: ::nl_item = 49; +pub const T_FMT_AMPM: ::nl_item = 50; +pub const ERA: ::nl_item = 51; +pub const ERA_D_FMT: ::nl_item = 52; +pub const ERA_D_T_FMT: ::nl_item = 53; +pub const ERA_T_FMT: ::nl_item = 54; +pub const ALT_DIGITS: ::nl_item = 55; +pub const YESEXPR: ::nl_item = 56; +pub const NOEXPR: ::nl_item = 57; +pub const _DATE_FMT: ::nl_item = 58; +pub const MAXSTRMSG: ::nl_item = 58; + +pub const PATH_MAX: ::c_int = 1024; + +pub const SA_ONSTACK: ::c_int = 0x00000001; +pub const SA_RESETHAND: ::c_int = 0x00000002; +pub const SA_RESTART: ::c_int = 0x00000004; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NODEFER: ::c_int = 0x00000010; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +pub const SA_NOCLDSTOP: ::c_int = 0x00020000; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const FIOCLEX: ::c_int = 0x20006601; +pub const FIONCLEX: ::c_int = 0x20006602; +pub const FIONREAD: ::c_int = 0x4004667f; +pub const FIONBIO: ::c_int = 0x8004667e; +pub const FIOASYNC: ::c_int = 0x8004667d; +pub const FIOSETOWN: ::c_int = 0x8004667c; +pub const FIOGETOWN: ::c_int = 0x4004667b; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +pub const SIGINFO: ::c_int = 41; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_SIGNAL: ::c_int =2; +pub const SIGEV_THREAD: ::c_int = 3; + +pub const IPV6_UNICAST_HOPS: ::c_int = 0x5; +pub const IPV6_MULTICAST_IF: ::c_int = 0x6; +pub const IPV6_MULTICAST_HOPS: ::c_int = 0x7; +pub const IPV6_MULTICAST_LOOP: ::c_int = 0x8; +pub const IPV6_V6ONLY: ::c_int = 0x27; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const FD_SETSIZE: usize = 65536; + } else { + pub const FD_SETSIZE: usize = 1024; + } +} + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; + +pub const NI_MAXHOST: ::socklen_t = 1025; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 32767; +pub const EOF: ::c_int = -1; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 4; +pub const _IOLBF: ::c_int = 64; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 25; +pub const TMP_MAX: ::c_uint = 17576; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_NDELAY: ::c_int = 0x04; +pub const O_APPEND: ::c_int = 8; +pub const O_DSYNC: ::c_int = 0x40; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_TRUNC: ::c_int = 512; +pub const O_NOFOLLOW: ::c_int = 0x200000; +pub const O_SEARCH: ::c_int = 0x200000; +pub const O_EXEC: ::c_int = 0x400000; +pub const O_CLOEXEC: ::c_int = 0x800000; +pub const O_ACCMODE: ::c_int = 0x600003; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +pub const S_IFREG: mode_t = 32768; +pub const S_IFLNK: mode_t = 40960; +pub const S_IFSOCK: mode_t = 49152; +pub const S_IFMT: mode_t = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +pub const F_OK: ::c_int = 0; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +pub const F_LOCK: ::c_int = 1; +pub const F_TEST: ::c_int = 3; +pub const F_TLOCK: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_DUPFD_CLOEXEC: ::c_int = 37; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_GETLK: ::c_int = 14; +pub const SIGHUP: ::c_int = 1; +pub const SIGINT: ::c_int = 2; +pub const SIGQUIT: ::c_int = 3; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGEMT: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSEGV: ::c_int = 11; +pub const SIGSYS: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGUSR1: ::c_int = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGPWR: ::c_int = 19; +pub const SIGWINCH: ::c_int = 20; +pub const SIGURG: ::c_int = 21; +pub const SIGPOLL: ::c_int = 22; +pub const SIGIO: ::c_int = SIGPOLL; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGCONT: ::c_int = 25; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; + +pub const WNOHANG: ::c_int = 0x40; +pub const WUNTRACED: ::c_int = 0x04; + +pub const WEXITED: ::c_int = 0x01; +pub const WTRAPPED: ::c_int = 0x02; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WCONTINUED: ::c_int = 0x08; +pub const WNOWAIT: ::c_int = 0x80; + +pub const AT_FDCWD: ::c_int = 0xffd19553; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x1000; + +pub const P_PID: idtype_t = 0; +pub const P_PPID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; +pub const P_SID: idtype_t = 3; +pub const P_CID: idtype_t = 4; +pub const P_UID: idtype_t = 5; +pub const P_GID: idtype_t = 6; +pub const P_ALL: idtype_t = 7; +pub const P_LWPID: idtype_t = 8; +pub const P_TASKID: idtype_t = 9; +pub const P_PROJID: idtype_t = 10; +pub const P_POOLID: idtype_t = 11; +pub const P_ZONEID: idtype_t = 12; +pub const P_CTID: idtype_t = 13; +pub const P_CPUID: idtype_t = 14; +pub const P_PSETID: idtype_t = 15; + +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const MAP_FILE: ::c_int = 0; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_NORESERVE: ::c_int = 0x40; +pub const MAP_ANON: ::c_int = 0x0100; +pub const MAP_RENAME: ::c_int = 0x20; +pub const MAP_ALIGN: ::c_int = 0x200; +pub const MAP_TEXT: ::c_int = 0x400; +pub const MAP_INITDATA: ::c_int = 0x800; +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const MS_SYNC: ::c_int = 0x0004; +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_INVALCURPROC: ::c_int = 0x0008; + +pub const EPERM: ::c_int = 1; +pub const ENOENT: ::c_int = 2; +pub const ESRCH: ::c_int = 3; +pub const EINTR: ::c_int = 4; +pub const EIO: ::c_int = 5; +pub const ENXIO: ::c_int = 6; +pub const E2BIG: ::c_int = 7; +pub const ENOEXEC: ::c_int = 8; +pub const EBADF: ::c_int = 9; +pub const ECHILD: ::c_int = 10; +pub const EAGAIN: ::c_int = 11; +pub const ENOMEM: ::c_int = 12; +pub const EACCES: ::c_int = 13; +pub const EFAULT: ::c_int = 14; +pub const ENOTBLK: ::c_int = 15; +pub const EBUSY: ::c_int = 16; +pub const EEXIST: ::c_int = 17; +pub const EXDEV: ::c_int = 18; +pub const ENODEV: ::c_int = 19; +pub const ENOTDIR: ::c_int = 20; +pub const EISDIR: ::c_int = 21; +pub const EINVAL: ::c_int = 22; +pub const ENFILE: ::c_int = 23; +pub const EMFILE: ::c_int = 24; +pub const ENOTTY: ::c_int = 25; +pub const ETXTBSY: ::c_int = 26; +pub const EFBIG: ::c_int = 27; +pub const ENOSPC: ::c_int = 28; +pub const ESPIPE: ::c_int = 29; +pub const EROFS: ::c_int = 30; +pub const EMLINK: ::c_int = 31; +pub const EPIPE: ::c_int = 32; +pub const EDOM: ::c_int = 33; +pub const ERANGE: ::c_int = 34; +pub const ENOMSG: ::c_int = 35; +pub const EIDRM: ::c_int = 36; +pub const ECHRNG: ::c_int = 37; +pub const EL2NSYNC: ::c_int = 38; +pub const EL3HLT: ::c_int = 39; +pub const EL3RST: ::c_int = 40; +pub const ELNRNG: ::c_int = 41; +pub const EUNATCH: ::c_int = 42; +pub const ENOCSI: ::c_int = 43; +pub const EL2HLT: ::c_int = 44; +pub const EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 46; +pub const ECANCELED: ::c_int = 47; +pub const ENOTSUP: ::c_int = 48; +pub const EDQUOT: ::c_int = 49; +pub const EBADE: ::c_int = 50; +pub const EBADR: ::c_int = 51; +pub const EXFULL: ::c_int = 52; +pub const ENOANO: ::c_int = 53; +pub const EBADRQC: ::c_int = 54; +pub const EBADSLT: ::c_int = 55; +pub const EDEADLOCK: ::c_int = 56; +pub const EBFONT: ::c_int = 57; +pub const EOWNERDEAD: ::c_int = 58; +pub const ENOTRECOVERABLE: ::c_int = 59; +pub const ENOSTR: ::c_int = 60; +pub const ENODATA: ::c_int = 61; +pub const ETIME: ::c_int = 62; +pub const ENOSR: ::c_int = 63; +pub const ENONET: ::c_int = 64; +pub const ENOPKG: ::c_int = 65; +pub const EREMOTE: ::c_int = 66; +pub const ENOLINK: ::c_int = 67; +pub const EADV: ::c_int = 68; +pub const ESRMNT: ::c_int = 69; +pub const ECOMM: ::c_int = 70; +pub const EPROTO: ::c_int = 71; +pub const ELOCKUNMAPPED: ::c_int = 72; +pub const ENOTACTIVE: ::c_int = 73; +pub const EMULTIHOP: ::c_int = 74; +pub const EADI: ::c_int = 75; +pub const EBADMSG: ::c_int = 77; +pub const ENAMETOOLONG: ::c_int = 78; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EREMCHG: ::c_int = 82; +pub const ELIBACC: ::c_int = 83; +pub const ELIBBAD: ::c_int = 84; +pub const ELIBSCN: ::c_int = 85; +pub const ELIBMAX: ::c_int = 86; +pub const ELIBEXEC: ::c_int = 87; +pub const EILSEQ: ::c_int = 88; +pub const ENOSYS: ::c_int = 89; +pub const ELOOP: ::c_int = 90; +pub const ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const ENOTEMPTY: ::c_int = 93; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +pub const ENOPROTOOPT: ::c_int = 99; +pub const EPROTONOSUPPORT: ::c_int = 120; +pub const ESOCKTNOSUPPORT: ::c_int = 121; +pub const EOPNOTSUPP: ::c_int = 122; +pub const EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; + +pub const EAI_AGAIN: ::c_int = 2; +pub const EAI_BADFLAGS: ::c_int = 3; +pub const EAI_FAIL: ::c_int = 4; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +pub const EAI_NODATA: ::c_int = 7; +pub const EAI_NONAME: ::c_int = 8; +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; +pub const EAI_OVERFLOW: ::c_int = 12; + +pub const F_DUPFD: ::c_int = 0; +pub const F_GETFD: ::c_int = 1; +pub const F_SETFD: ::c_int = 2; +pub const F_GETFL: ::c_int = 3; +pub const F_SETFL: ::c_int = 4; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND : ::c_int = 32; +pub const GLOB_DOOFFS : ::c_int = 16; +pub const GLOB_ERR : ::c_int = 1; +pub const GLOB_MARK : ::c_int = 2; +pub const GLOB_NOCHECK : ::c_int = 8; +pub const GLOB_NOSORT : ::c_int = 4; +pub const GLOB_NOESCAPE: ::c_int = 64; + +pub const GLOB_NOSPACE : ::c_int = -2; +pub const GLOB_ABORTED : ::c_int = -1; +pub const GLOB_NOMATCH : ::c_int = -3; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLNORM: ::c_short = 0x0040; +pub const POLLRDNORM: ::c_short = 0x0040; +pub const POLLWRNORM: ::c_short = 0x4; /* POLLOUT */ +pub const POLLRDBAND: ::c_short = 0x0080; +pub const POLLWRBAND: ::c_short = 0x0100; + +pub const POSIX_MADV_NORMAL: ::c_int = 0; +pub const POSIX_MADV_RANDOM: ::c_int = 1; +pub const POSIX_MADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_MADV_WILLNEED: ::c_int = 3; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x40; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 0; +pub const PTHREAD_STACK_MIN: ::size_t = 4096; + +pub const SIGSTKSZ: ::size_t = 8192; + +// https://illumos.org/man/3c/clock_gettime +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/lib/libc/amd64/sys/__clock_gettime.s +// clock_gettime(3c) doesn't seem to accept anything other than CLOCK_REALTIME +// or __CLOCK_REALTIME0 +// +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/uts/common/sys/time_impl.h +// Confusing! CLOCK_HIGHRES==CLOCK_MONOTONIC==4 +// __CLOCK_REALTIME0==0 is an obsoleted version of CLOCK_REALTIME==3 +pub const CLOCK_REALTIME: ::clockid_t = 3; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const TIMER_RELTIME: ::c_int = 0; +pub const TIMER_ABSTIME: ::c_int = 1; + +pub const RLIMIT_CPU: ::c_int = 0; +pub const RLIMIT_FSIZE: ::c_int = 1; +pub const RLIMIT_DATA: ::c_int = 2; +pub const RLIMIT_STACK: ::c_int = 3; +pub const RLIMIT_CORE: ::c_int = 4; +pub const RLIMIT_NOFILE: ::c_int = 5; +pub const RLIMIT_VMEM: ::c_int = 6; +pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; + +pub const RLIM_NLIMITS: rlim_t = 7; +pub const RLIM_INFINITY: rlim_t = 0x7fffffff; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const MADV_NORMAL: ::c_int = 0; +pub const MADV_RANDOM: ::c_int = 1; +pub const MADV_SEQUENTIAL: ::c_int = 2; +pub const MADV_WILLNEED: ::c_int = 3; +pub const MADV_DONTNEED: ::c_int = 4; +pub const MADV_FREE: ::c_int = 5; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_LOCAL: ::c_int = 0; +pub const AF_FILE: ::c_int = 0; +pub const AF_INET: ::c_int = 2; +pub const AF_IMPLINK: ::c_int = 3; +pub const AF_PUP: ::c_int = 4; +pub const AF_CHAOS: ::c_int = 5; +pub const AF_NS: ::c_int = 6; +pub const AF_NBS: ::c_int = 7; +pub const AF_ECMA: ::c_int = 8; +pub const AF_DATAKIT: ::c_int = 9; +pub const AF_CCITT: ::c_int = 10; +pub const AF_SNA: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_DLI: ::c_int = 13; +pub const AF_LAT: ::c_int = 14; +pub const AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_NIT: ::c_int = 17; +pub const AF_802: ::c_int = 18; +pub const AF_OSI: ::c_int = 19; +pub const AF_X25: ::c_int = 20; +pub const AF_OSINET: ::c_int = 21; +pub const AF_GOSIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_ROUTE: ::c_int = 24; +pub const AF_LINK: ::c_int = 25; +pub const AF_INET6: ::c_int = 26; +pub const AF_KEY: ::c_int = 27; +pub const AF_NCA: ::c_int = 28; +pub const AF_POLICY: ::c_int = 29; +pub const AF_INET_OFFLOAD: ::c_int = 30; +pub const AF_TRILL: ::c_int = 31; +pub const AF_PACKET: ::c_int = 32; +pub const AF_LX_NETLINK: ::c_int = 33; +pub const AF_MAX: ::c_int = 33; +pub const SOCK_DGRAM: ::c_int = 1; +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 4; +pub const SOCK_RDM: ::c_int = 5; +pub const SOCK_SEQPACKET: ::c_int = 6; +pub const IP_MULTICAST_IF: ::c_int = 16; +pub const IP_MULTICAST_TTL: ::c_int = 17; +pub const IP_MULTICAST_LOOP: ::c_int = 18; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_ADD_MEMBERSHIP: ::c_int = 19; +pub const IP_DROP_MEMBERSHIP: ::c_int = 20; +pub const IPV6_JOIN_GROUP: ::c_int = 9; +pub const IPV6_LEAVE_GROUP: ::c_int = 10; + +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_KEEPIDLE: ::c_int = 34; +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +pub const SO_ACCEPTCONN: ::c_int = 0x0002; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDLOWAT: ::c_int = 0x1003; +pub const SO_RCVLOWAT: ::c_int = 0x1004; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_TIMESTAMP: ::c_int = 0x1013; + +pub const SCM_RIGHTS: ::c_int = 0x1010; +pub const SCM_UCRED: ::c_int = 0x1012; +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const MSG_OOB: ::c_int = 0x1; +pub const MSG_PEEK: ::c_int = 0x2; +pub const MSG_DONTROUTE: ::c_int = 0x4; +pub const MSG_EOR: ::c_int = 0x8; +pub const MSG_CTRUNC: ::c_int = 0x10; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_NOTIFICATION: ::c_int = 0x100; +pub const MSG_NOSIGNAL: ::c_int = 0x200; +pub const MSG_DUPCTRL: ::c_int = 0x800; +pub const MSG_XPG4_2: ::c_int = 0x8000; +pub const MSG_MAXIOVLEN: ::c_int = 16; + +// https://docs.oracle.com/cd/E23824_01/html/821-1475/if-7p.html +pub const IFF_UP: ::c_int = 0x0000000001; // Address is up +pub const IFF_BROADCAST: ::c_int = 0x0000000002; // Broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x0000000004; // Turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x0000000008; // Loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x0000000010; // Interface is p-to-p +pub const IFF_NOTRAILERS: ::c_int = 0x0000000020; // Avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x0000000040; // Resources allocated +pub const IFF_NOARP: ::c_int = 0x0000000080; // No address res. protocol +pub const IFF_PROMISC: ::c_int = 0x0000000100; // Receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0000000200; // Receive all multicast pkts +pub const IFF_INTELLIGENT: ::c_int = 0x0000000400; // Protocol code on board +pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast +// Multicast using broadcst. add. +pub const IFF_MULTI_BCAST: ::c_int = 0x0000001000; +pub const IFF_UNNUMBERED: ::c_int = 0x0000002000; // Non-unique address +pub const IFF_DHCPRUNNING: ::c_int = 0x0000004000; // DHCP controls interface +pub const IFF_PRIVATE: ::c_int = 0x0000008000; // Do not advertise +pub const IFF_NOXMIT: ::c_int = 0x0000010000; // Do not transmit pkts +// No address - just on-link subnet +pub const IFF_NOLOCAL: ::c_int = 0x0000020000; +pub const IFF_DEPRECATED: ::c_int = 0x0000040000; // Address is deprecated +pub const IFF_ADDRCONF: ::c_int = 0x0000080000; // Addr. from stateless addrconf +pub const IFF_ROUTER: ::c_int = 0x0000100000; // Router on interface +pub const IFF_NONUD: ::c_int = 0x0000200000; // No NUD on interface +pub const IFF_ANYCAST: ::c_int = 0x0000400000; // Anycast address +pub const IFF_NORTEXCH: ::c_int = 0x0000800000; // Don't xchange rout. info +pub const IFF_IPV4: ::c_int = 0x0001000000; // IPv4 interface +pub const IFF_IPV6: ::c_int = 0x0002000000; // IPv6 interface +pub const IFF_NOFAILOVER: ::c_int = 0x0008000000; // in.mpathd test address +pub const IFF_FAILED: ::c_int = 0x0010000000; // Interface has failed +pub const IFF_STANDBY: ::c_int = 0x0020000000; // Interface is a hot-spare +pub const IFF_INACTIVE: ::c_int = 0x0040000000; // Functioning but not used +pub const IFF_OFFLINE: ::c_int = 0x0080000000; // Interface is offline +// If CoS marking is supported +pub const IFF_COS_ENABLED: ::c_longlong = 0x0200000000; +pub const IFF_PREFERRED: ::c_longlong = 0x0400000000; // Prefer as source addr. +pub const IFF_TEMPORARY: ::c_longlong = 0x0800000000; // RFC3041 +pub const IFF_FIXEDMTU: ::c_longlong = 0x1000000000; // MTU set with SIOCSLIFMTU +pub const IFF_VIRTUAL: ::c_longlong = 0x2000000000; // Cannot send/receive pkts +pub const IFF_DUPLICATE: ::c_longlong = 0x4000000000; // Local address in use +pub const IFF_IPMP: ::c_longlong = 0x8000000000; // IPMP IP interface + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const F_RDLCK: ::c_short = 1; +pub const F_WRLCK: ::c_short = 2; +pub const F_UNLCK: ::c_short = 3; + +pub const O_SYNC: ::c_int = 16; +pub const O_NONBLOCK: ::c_int = 128; + +pub const IPPROTO_RAW: ::c_int = 255; + +pub const _PC_LINK_MAX: ::c_int = 1; +pub const _PC_MAX_CANON: ::c_int = 2; +pub const _PC_MAX_INPUT: ::c_int = 3; +pub const _PC_NAME_MAX: ::c_int = 4; +pub const _PC_PATH_MAX: ::c_int = 5; +pub const _PC_PIPE_BUF: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SYNC_IO: ::c_int = 12; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_SYMLINK_MAX: ::c_int = 18; +pub const _PC_2_SYMLINKS: ::c_int = 19; +pub const _PC_ACL_ENABLED: ::c_int = 20; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; +pub const _PC_CASE_BEHAVIOR: ::c_int = 22; +pub const _PC_SATTR_ENABLED: ::c_int = 23; +pub const _PC_SATTR_EXISTS: ::c_int = 24; +pub const _PC_ACCESS_FILTERING: ::c_int = 25; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 26; +pub const _PC_FILESIZEBITS: ::c_int = 67; +pub const _PC_XATTR_ENABLED: ::c_int = 100; +pub const _PC_LAST: ::c_int = 101; +pub const _PC_XATTR_EXISTS: ::c_int = 101; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_NGROUPS_MAX: ::c_int = 4; +pub const _SC_OPEN_MAX: ::c_int = 5; +pub const _SC_JOB_CONTROL: ::c_int = 6; +pub const _SC_SAVED_IDS: ::c_int = 7; +pub const _SC_VERSION: ::c_int = 8; +pub const _SC_PASS_MAX: ::c_int = 9; +pub const _SC_LOGNAME_MAX: ::c_int = 10; +pub const _SC_PAGESIZE: ::c_int = 11; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_XOPEN_VERSION: ::c_int = 12; +pub const _SC_NPROCESSORS_CONF: ::c_int = 14; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 15; +pub const _SC_STREAM_MAX: ::c_int = 16; +pub const _SC_TZNAME_MAX: ::c_int = 17; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 18; +pub const _SC_AIO_MAX: ::c_int = 19; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 20; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 21; +pub const _SC_DELAYTIMER_MAX: ::c_int = 22; +pub const _SC_FSYNC: ::c_int = 23; +pub const _SC_MAPPED_FILES: ::c_int = 24; +pub const _SC_MEMLOCK: ::c_int = 25; +pub const _SC_MEMLOCK_RANGE: ::c_int = 26; +pub const _SC_MEMORY_PROTECTION: ::c_int = 27; +pub const _SC_MESSAGE_PASSING: ::c_int = 28; +pub const _SC_MQ_OPEN_MAX: ::c_int = 29; +pub const _SC_MQ_PRIO_MAX: ::c_int = 30; +pub const _SC_PRIORITIZED_IO: ::c_int = 31; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 32; +pub const _SC_REALTIME_SIGNALS: ::c_int = 33; +pub const _SC_RTSIG_MAX: ::c_int = 34; +pub const _SC_SEMAPHORES: ::c_int = 35; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 36; +pub const _SC_SEM_VALUE_MAX: ::c_int = 37; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 38; +pub const _SC_SIGQUEUE_MAX: ::c_int = 39; +pub const _SC_SIGRT_MIN: ::c_int = 40; +pub const _SC_SIGRT_MAX: ::c_int = 41; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 42; +pub const _SC_TIMERS: ::c_int = 43; +pub const _SC_TIMER_MAX: ::c_int = 44; +pub const _SC_2_C_BIND: ::c_int = 45; +pub const _SC_2_C_DEV: ::c_int = 46; +pub const _SC_2_C_VERSION: ::c_int = 47; +pub const _SC_2_FORT_DEV: ::c_int = 48; +pub const _SC_2_FORT_RUN: ::c_int = 49; +pub const _SC_2_LOCALEDEF: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_UPE: ::c_int = 52; +pub const _SC_2_VERSION: ::c_int = 53; +pub const _SC_BC_BASE_MAX: ::c_int = 54; +pub const _SC_BC_DIM_MAX: ::c_int = 55; +pub const _SC_BC_SCALE_MAX: ::c_int = 56; +pub const _SC_BC_STRING_MAX: ::c_int = 57; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 58; +pub const _SC_EXPR_NEST_MAX: ::c_int = 59; +pub const _SC_LINE_MAX: ::c_int = 60; +pub const _SC_RE_DUP_MAX: ::c_int = 61; +pub const _SC_XOPEN_CRYPT: ::c_int = 62; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 63; +pub const _SC_XOPEN_SHM: ::c_int = 64; +pub const _SC_2_CHAR_TERM: ::c_int = 66; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 67; +pub const _SC_ATEXIT_MAX: ::c_int = 76; +pub const _SC_IOV_MAX: ::c_int = 77; +pub const _SC_XOPEN_UNIX: ::c_int = 78; +pub const _SC_T_IOV_MAX: ::c_int = 79; +pub const _SC_PHYS_PAGES: ::c_int = 500; +pub const _SC_AVPHYS_PAGES: ::c_int = 501; +pub const _SC_COHER_BLKSZ: ::c_int = 503; +pub const _SC_SPLIT_CACHE: ::c_int = 504; +pub const _SC_ICACHE_SZ: ::c_int = 505; +pub const _SC_DCACHE_SZ: ::c_int = 506; +pub const _SC_ICACHE_LINESZ: ::c_int = 507; +pub const _SC_DCACHE_LINESZ: ::c_int = 508; +pub const _SC_ICACHE_BLKSZ: ::c_int = 509; +pub const _SC_DCACHE_BLKSZ: ::c_int = 510; +pub const _SC_DCACHE_TBLKSZ: ::c_int = 511; +pub const _SC_ICACHE_ASSOC: ::c_int = 512; +pub const _SC_DCACHE_ASSOC: ::c_int = 513; +pub const _SC_MAXPID: ::c_int = 514; +pub const _SC_STACK_PROT: ::c_int = 515; +pub const _SC_NPROCESSORS_MAX: ::c_int = 516; +pub const _SC_CPUID_MAX: ::c_int = 517; +pub const _SC_EPHID_MAX: ::c_int = 518; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 568; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 569; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 570; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 571; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 572; +pub const _SC_THREAD_STACK_MIN: ::c_int = 573; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 574; +pub const _SC_TTY_NAME_MAX: ::c_int = 575; +pub const _SC_THREADS: ::c_int = 576; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 577; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 578; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 579; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 580; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 581; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 582; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 583; +pub const _SC_XOPEN_LEGACY: ::c_int = 717; +pub const _SC_XOPEN_REALTIME: ::c_int = 718; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 719; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 720; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 721; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 722; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 723; +pub const _SC_2_PBS: ::c_int = 724; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 725; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 726; +pub const _SC_2_PBS_LOCATE: ::c_int = 728; +pub const _SC_2_PBS_MESSAGE: ::c_int = 729; +pub const _SC_2_PBS_TRACK: ::c_int = 730; +pub const _SC_ADVISORY_INFO: ::c_int = 731; +pub const _SC_BARRIERS: ::c_int = 732; +pub const _SC_CLOCK_SELECTION: ::c_int = 733; +pub const _SC_CPUTIME: ::c_int = 734; +pub const _SC_HOST_NAME_MAX: ::c_int = 735; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 736; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 737; +pub const _SC_REGEXP: ::c_int = 738; +pub const _SC_SHELL: ::c_int = 739; +pub const _SC_SPAWN: ::c_int = 740; +pub const _SC_SPIN_LOCKS: ::c_int = 741; +pub const _SC_SPORADIC_SERVER: ::c_int = 742; +pub const _SC_SS_REPL_MAX: ::c_int = 743; +pub const _SC_SYMLOOP_MAX: ::c_int = 744; +pub const _SC_THREAD_CPUTIME: ::c_int = 745; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 746; +pub const _SC_TIMEOUTS: ::c_int = 747; +pub const _SC_TRACE: ::c_int = 748; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 749; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 750; +pub const _SC_TRACE_INHERIT: ::c_int = 751; +pub const _SC_TRACE_LOG: ::c_int = 752; +pub const _SC_TRACE_NAME_MAX: ::c_int = 753; +pub const _SC_TRACE_SYS_MAX: ::c_int = 754; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 755; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 756; +pub const _SC_V6_ILP32_OFF32: ::c_int = 757; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 758; +pub const _SC_V6_LP64_OFF64: ::c_int = 759; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 760; +pub const _SC_XOPEN_STREAMS: ::c_int = 761; +pub const _SC_IPV6: ::c_int = 762; +pub const _SC_RAW_SOCKETS: ::c_int = 763; + +pub const _MUTEX_MAGIC: u16 = 0x4d58; // MX +pub const _COND_MAGIC: u16 = 0x4356; // CV +pub const _RWL_MAGIC: u16 = 0x5257; // RW + +pub const NCCS: usize = 19; + +pub const LOG_CRON: ::c_int = 15 << 3; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __pthread_mutex_flag1: 0, + __pthread_mutex_flag2: 0, + __pthread_mutex_ceiling: 0, + __pthread_mutex_type: PTHREAD_PROCESS_PRIVATE, + __pthread_mutex_magic: _MUTEX_MAGIC, + __pthread_mutex_lock: 0, + __pthread_mutex_data: 0 +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __pthread_cond_flag: [0; 4], + __pthread_cond_type: PTHREAD_PROCESS_PRIVATE, + __pthread_cond_magic: _COND_MAGIC, + __pthread_cond_data: 0 +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __pthread_rwlock_readers: 0, + __pthread_rwlock_type: PTHREAD_PROCESS_PRIVATE, + __pthread_rwlock_magic: _RWL_MAGIC, + __pthread_rwlock_mutex: PTHREAD_MUTEX_INITIALIZER, + __pthread_rwlock_readercv: PTHREAD_COND_INITIALIZER, + __pthread_rwlock_writercv: PTHREAD_COND_INITIALIZER +}; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + +pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; +pub const RTLD_PROBE: *mut ::c_void = -4isize as *mut ::c_void; + +pub const RTLD_LAZY: ::c_int = 0x1; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_LOCAL: ::c_int = 0x0; +pub const RTLD_PARENT: ::c_int = 0x200; +pub const RTLD_GROUP: ::c_int = 0x400; +pub const RTLD_WORLD: ::c_int = 0x800; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_FIRST: ::c_int = 0x2000; +pub const RTLD_CONFGEN: ::c_int = 0x10000; + +pub const PORT_SOURCE_AIO: ::c_int = 1; +pub const PORT_SOURCE_TIMER: ::c_int = 2; +pub const PORT_SOURCE_USER: ::c_int = 3; +pub const PORT_SOURCE_FD: ::c_int = 4; +pub const PORT_SOURCE_ALERT: ::c_int = 5; +pub const PORT_SOURCE_MQ: ::c_int = 6; +pub const PORT_SOURCE_FILE: ::c_int = 7; +pub const PORT_SOURCE_POSTWAIT: ::c_int = 8; +pub const PORT_SOURCE_SIGNAL: ::c_int = 9; + +const _TIOC: ::c_int = ('T' as i32) << 8; +const tIOC: ::c_int = ('t' as i32) << 8; +pub const TCGETA: ::c_int = (_TIOC|1); +pub const TCSETA: ::c_int = (_TIOC|2); +pub const TCSETAW: ::c_int = (_TIOC|3); +pub const TCSETAF: ::c_int = (_TIOC|4); +pub const TCSBRK: ::c_int = (_TIOC|5); +pub const TCXONC: ::c_int = (_TIOC|6); +pub const TCFLSH: ::c_int = (_TIOC|7); +pub const TCDSET: ::c_int = (_TIOC|32); +pub const TCGETS: ::c_int = (_TIOC|13); +pub const TCSETS: ::c_int = (_TIOC|14); +pub const TCSANOW: ::c_int = (_TIOC|14); +pub const TCSETSW: ::c_int = (_TIOC|15); +pub const TCSADRAIN: ::c_int = (_TIOC|15); +pub const TCSETSF: ::c_int = (_TIOC|16); +pub const TCSAFLUSH: ::c_int = (_TIOC|16); +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TIOC: ::c_int = _TIOC; +pub const TIOCKBON: ::c_int = (_TIOC|8); +pub const TIOCKBOF: ::c_int = (_TIOC|9); +pub const TIOCGWINSZ: ::c_int = (_TIOC|104); +pub const TIOCSWINSZ: ::c_int = (_TIOC|103); +pub const TIOCGSOFTCAR: ::c_int = (_TIOC|105); +pub const TIOCSSOFTCAR: ::c_int = (_TIOC|106); +pub const TIOCSETLD: ::c_int = (_TIOC|123); +pub const TIOCGETLD: ::c_int = (_TIOC|124); +pub const TIOCGPPS: ::c_int = (_TIOC|125); +pub const TIOCSPPS: ::c_int = (_TIOC|126); +pub const TIOCGPPSEV: ::c_int = (_TIOC|127); +pub const TIOCGETD: ::c_int = (tIOC|0); +pub const TIOCSETD: ::c_int = (tIOC|1); +pub const TIOCHPCL: ::c_int = (tIOC|2); +pub const TIOCGETP: ::c_int = (tIOC|8); +pub const TIOCSETP: ::c_int = (tIOC|9); +pub const TIOCSETN: ::c_int = (tIOC|10); +pub const TIOCEXCL: ::c_int = (tIOC|13); +pub const TIOCNXCL: ::c_int = (tIOC|14); +pub const TIOCFLUSH: ::c_int = (tIOC|16); +pub const TIOCSETC: ::c_int = (tIOC|17); +pub const TIOCGETC: ::c_int = (tIOC|18); +pub const TIOCLBIS: ::c_int = (tIOC|127); +pub const TIOCLBIC: ::c_int = (tIOC|126); +pub const TIOCLSET: ::c_int = (tIOC|125); +pub const TIOCLGET: ::c_int = (tIOC|124); +pub const TIOCSBRK: ::c_int = (tIOC|123); +pub const TIOCCBRK: ::c_int = (tIOC|122); +pub const TIOCSDTR: ::c_int = (tIOC|121); +pub const TIOCCDTR: ::c_int = (tIOC|120); +pub const TIOCSLTC: ::c_int = (tIOC|117); +pub const TIOCGLTC: ::c_int = (tIOC|116); +pub const TIOCOUTQ: ::c_int = (tIOC|115); +pub const TIOCNOTTY: ::c_int = (tIOC|113); +pub const TIOCSCTTY: ::c_int = (tIOC|132); +pub const TIOCSTOP: ::c_int = (tIOC|111); +pub const TIOCSTART: ::c_int = (tIOC|110); +pub const TIOCSILOOP: ::c_int = (tIOC|109); +pub const TIOCCILOOP: ::c_int = (tIOC|108); +pub const TIOCGPGRP: ::c_int = (tIOC|20); +pub const TIOCSPGRP: ::c_int = (tIOC|21); +pub const TIOCGSID: ::c_int = (tIOC|22); +pub const TIOCSTI: ::c_int = (tIOC|23); +pub const TIOCMSET: ::c_int = (tIOC|26); +pub const TIOCMBIS: ::c_int = (tIOC|27); +pub const TIOCMBIC: ::c_int = (tIOC|28); +pub const TIOCMGET: ::c_int = (tIOC|29); +pub const TIOCREMOTE: ::c_int = (tIOC|30); +pub const TIOCSIGNAL: ::c_int = (tIOC|31); + +pub const EPOLLIN: ::c_int = 0x1; +pub const EPOLLPRI: ::c_int = 0x2; +pub const EPOLLOUT: ::c_int = 0x4; +pub const EPOLLRDNORM: ::c_int = 0x40; +pub const EPOLLRDBAND: ::c_int = 0x80; +pub const EPOLLWRNORM: ::c_int = 0x100; +pub const EPOLLWRBAND: ::c_int = 0x200; +pub const EPOLLMSG: ::c_int = 0x400; +pub const EPOLLERR: ::c_int = 0x8; +pub const EPOLLHUP: ::c_int = 0x10; +pub const EPOLLET: ::c_int = 0x80000000; +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLL_CTL_DEL: ::c_int = 2; + +/* termios */ +pub const B0: speed_t = 0; +pub const B50: speed_t = 1; +pub const B75: speed_t = 2; +pub const B110: speed_t = 3; +pub const B134: speed_t = 4; +pub const B150: speed_t = 5; +pub const B200: speed_t = 6; +pub const B300: speed_t = 7; +pub const B600: speed_t = 8; +pub const B1200: speed_t = 9; +pub const B1800: speed_t = 10; +pub const B2400: speed_t = 11; +pub const B4800: speed_t = 12; +pub const B9600: speed_t = 13; +pub const B19200: speed_t = 14; +pub const B38400: speed_t = 15; +pub const B57600: speed_t = 16; +pub const B76800: speed_t = 17; +pub const B115200: speed_t = 18; +pub const B153600: speed_t = 19; +pub const B230400: speed_t = 20; +pub const B307200: speed_t = 21; +pub const B460800: speed_t = 22; +pub const B921600: speed_t = 23; +pub const CSTART: ::tcflag_t = 021; +pub const CSTOP: ::tcflag_t = 023; +pub const CSWTCH: ::tcflag_t = 032; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS5: ::tcflag_t = 0; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const ECHO: ::tcflag_t = 0o000010; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const IGNBRK: ::tcflag_t = 0o000001; +pub const BRKINT: ::tcflag_t = 0o000002; +pub const IGNPAR: ::tcflag_t = 0o000004; +pub const PARMRK: ::tcflag_t = 0o000010; +pub const INPCK: ::tcflag_t = 0o000020; +pub const ISTRIP: ::tcflag_t = 0o000040; +pub const INLCR: ::tcflag_t = 0o000100; +pub const IGNCR: ::tcflag_t = 0o000200; +pub const ICRNL: ::tcflag_t = 0o000400; +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; +pub const IXANY: ::tcflag_t = 0o004000; +pub const IMAXBEL: ::tcflag_t = 0o020000; +pub const OPOST: ::tcflag_t = 0o000001; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const CREAD: ::tcflag_t = 0o000200; +pub const PARENB: ::tcflag_t = 0o000400; +pub const PARODD: ::tcflag_t = 0o001000; +pub const HUPCL: ::tcflag_t = 0o002000; +pub const CLOCAL: ::tcflag_t = 0o004000; +pub const CRTSCTS: ::tcflag_t = 0o20000000000; +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const IEXTEN: ::tcflag_t = 0o100000; +pub const TOSTOP: ::tcflag_t = 0o000400; +pub const FLUSHO: ::tcflag_t = 0o020000; +pub const PENDIN: ::tcflag_t = 0o040000; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const VINTR: usize = 0; +pub const VQUIT: usize = 1; +pub const VERASE: usize = 2; +pub const VKILL: usize = 3; +pub const VEOF: usize = 4; +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VSWTCH: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const VLNEXT: usize = 15; +pub const VSTATUS: usize = 16; +pub const VERASE2: usize = 17; + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF) == 0 + } + + pub fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xFF + } + + pub fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7F + } + + pub fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0xffff) == 0xffff + } + + pub fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status & 0xff00) >> 8 + } + + pub fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0xff) > 0) && (status & 0xff00 == 0) + } + + pub fn WIFSTOPPED(status: ::c_int) -> bool { + ((status & 0xff) == 0x7f) && ((status & 0xff00) != 0) + } + + pub fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x80) != 0 + } +} + +extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn atof(s: *const ::c_char) -> ::c_double; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + pub fn rand() -> ::c_int; + pub fn srand(seed: ::c_uint); + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn stack_getbounds(sp: *mut ::stack_t) -> ::c_int; + pub fn mincore(addr: *const ::c_void, len: ::size_t, + vec: *mut c_char) -> ::c_int; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn setgroups(ngroups: ::c_int, + ptr: *const ::gid_t) -> ::c_int; + pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int; + pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) + -> ::c_int; + pub fn ___errno() -> *mut ::c_int; + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + pub fn clock_nanosleep(clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn getnameinfo(sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + sevlen: ::socklen_t, + flags: ::c_int) -> ::c_int; + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, + locale: *const ::c_char, + base: ::locale_t) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn getprogname() -> *const ::c_char; + pub fn setprogname(name: *const ::c_char); + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int; + + pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char, + mode: ::mode_t, dev: dev_t) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, + mode: ::mode_t) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + pub fn pthread_create(native: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + f: extern fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void) -> ::c_int; + pub fn pthread_condattr_getclock(attr: *const pthread_condattr_t, + clock_id: *mut clockid_t) -> ::c_int; + pub fn pthread_condattr_setclock(attr: *mut pthread_condattr_t, + clock_id: ::clockid_t) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, + abstime: *const ::timespec) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, + sval: *mut ::c_int) -> ::c_int; + pub fn pthread_mutex_timedlock(lock: *mut pthread_mutex_t, + abstime: *const ::timespec) -> ::c_int; + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, + options: ::c_int) -> ::c_int; + + pub fn glob(pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t) -> ::c_int; + + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) + -> ::c_int; + + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) + -> ::c_int; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) + -> ::c_int; + + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, + flags: ::c_int, addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t) -> ::ssize_t; + pub fn mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn futimesat(fd: ::c_int, path: *const ::c_char, + times: *const ::timeval) -> ::c_int; + pub fn utimensat(dirfd: ::c_int, path: *const ::c_char, + times: *const ::timespec, flag: ::c_int) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_bind")] + pub fn bind(socket: ::c_int, address: *const ::sockaddr, + address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int) -> ::ssize_t; + + #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendmsg")] + pub fn sendmsg(fd: ::c_int, + msg: *const ::msghdr, + flags: ::c_int) -> ::ssize_t; + #[cfg_attr(target_os = "illumos", link_name = "__xnet_recvmsg")] + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) + -> ::ssize_t; + + pub fn port_create() -> ::c_int; + pub fn port_associate(port: ::c_int, source: ::c_int, object: ::uintptr_t, + events: ::c_int, user: *mut ::c_void) -> ::c_int; + pub fn port_dissociate(port: ::c_int, source: ::c_int, object: ::uintptr_t) + -> ::c_int; + pub fn port_get(port: ::c_int, pe: *mut port_event, + timeout: *mut ::timespec) -> ::c_int; + pub fn port_getn(port: ::c_int, pe_list: *mut port_event, max: ::c_uint, + nget: *mut ::c_uint, timeout: *mut ::timespec) + -> ::c_int; + pub fn fexecve(fd: ::c_int, argv: *const *const ::c_char, + envp: *const *const ::c_char) + -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrgid_r")] + pub fn getgrgid_r(gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group) -> ::c_int; + pub fn sigaltstack(ss: *const stack_t, + oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + + // The epoll functions are actually only present on illumos. However, + // there are things using epoll on illumos (built using the + // x86_64-sun-solaris target) which would break until the illumos target is + // present in rustc. + pub fn epoll_pwait(epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + sigmask: *const ::sigset_t) -> ::c_int; + + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait(epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, + op: ::c_int, + fd: ::c_int, + event: *mut ::epoll_event) -> ::c_int; + + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrnam_r")] + pub fn getgrnam_r(name: *const ::c_char, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group) -> ::c_int; + pub fn pthread_sigmask(how: ::c_int, set: *const sigset_t, + oldset: *mut sigset_t) -> ::c_int; + pub fn sem_open(name: *const ::c_char, oflag: ::c_int, ...) -> *mut sem_t; + pub fn getgrnam(name: *const ::c_char) -> *mut ::group; + pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int; + pub fn sem_unlink(name: *const ::c_char) -> ::c_int; + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwnam_r")] + pub fn getpwnam_r(name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd) -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwuid_r")] + pub fn getpwuid_r(uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd) -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwent_r")] + pub fn getpwent_r(pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd) -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrent_r")] + pub fn getgrent_r(grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group) -> ::c_int; + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_sigwait")] + pub fn sigwait(set: *const sigset_t, + sig: *mut ::c_int) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + pub fn setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn popen(command: *const c_char, + mode: *const c_char) -> *mut ::FILE; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; +} + +mod compat; +pub use self::compat::*; diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,66 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + #[allow(missing_debug_implementations)] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + #[allow(missing_debug_implementations)] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/mod.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,687 @@ +pub type c_char = u8; +pub type wchar_t = ::c_uint; +pub type c_long = i32; +pub type c_ulong = u32; +pub type time_t = ::c_long; + +pub type clock_t = ::c_long; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type off_t = ::c_long; +pub type pthread_t = ::c_ulong; +pub type rlim_t = ::c_ulong; +pub type suseconds_t = ::c_long; + +pub type nlink_t = ::c_uint; +pub type blksize_t = ::c_long; +pub type blkcnt_t = ::c_long; + +s! { + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct pthread_attr_t { + __size: [::c_long; 9], + } + + pub struct stat { + pub st_dev: ::c_ulonglong, + pub __pad1: ::c_ushort, + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + pub __pad2: ::c_ushort, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub __unused4: ::c_ulong, + pub __unused5: ::c_ulong, + } + + pub struct stat64 + { + pub st_dev: ::c_ulonglong, + pub __pad1: ::c_uint, + pub __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + pub __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub st_ino: ::ino64_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct statfs { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_int, + pub f_frsize: ::c_int, + pub f_spare: [::c_int; 5], + } + + pub struct sigset_t { + __val: [::c_ulong; 2], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + // uClibc defines sa_flags as `unsigned long int`, + // but nix crate expects `int` + pub sa_flags: ::c_int, + pub sa_restorer: *mut ::c_void, + pub sa_mask: sigset_t, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + ss_flags: ::c_int, + ss_size: ::size_t, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + pub __pad1: ::c_ushort, + pub __seq: ::c_ushort, + pub __pad2: ::c_ushort, + pub __unused1: ::c_ulong, + pub __unused2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub __unused1: ::c_ulong, + pub msg_rtime: ::time_t, + pub __unused2: ::c_ulong, + pub msg_ctime: ::time_t, + pub __unused3: ::c_ulong, + pub __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + pub __unused4: ::c_ulong, + pub __unused5: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + pub __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + pub __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub __unused4: ::c_ulong, + pub __unused5: ::c_ulong, + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + +} + +pub const O_CLOEXEC: ::c_int = 0o2000000; +pub const RLIM_INFINITY: rlim_t = !0; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_COND_COMPAT_T: usize = 12; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const NCCS: usize = 32; + +// I wasn't able to find those constants +// in uclibc build environment for armv7 +pub const AIO_ALLDONE: ::c_int = 2; // from linux/mod.rs +pub const AIO_CANCELED: ::c_int = 0; // from linux/mod.rs +pub const AIO_NOTCANCELED: ::c_int = 1; // from linux/mod.rs +pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; // from linux/mod.rs +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; // from linux/mod.rs +pub const EPOLLWAKEUP: ::c_int = 0x20000000; // from linux/other/mod.rs +pub const EXTPROC: ::tcflag_t = 0o200000; // from asm-generic/termbits.h +pub const F_GETPIPE_SZ: ::c_int = 1032; // from notbsd/mod.rs +pub const F_SETPIPE_SZ: ::c_int = 1031; // from notbsd/mod.rs +pub const LIO_NOP: ::c_int = 2; // from linux/mod.rs +pub const LIO_NOWAIT: ::c_int = 1; // from linux/mod.rs +pub const LIO_READ: ::c_int = 0; // from linux/mod.rs +pub const LIO_WAIT: ::c_int = 0; // from linux/mod.rs +pub const LIO_WRITE: ::c_int = 1; // from linux/mod.rs +pub const MAP_HUGETLB: ::c_int = 0x040000; // from linux/other/mod.rs +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; // from linux/mod.rs +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; // from linux/mod.rs +pub const SO_BUSY_POLL: ::c_int = 46; // from src/unix/notbsd/mod.rs +pub const SO_PEEK_OFF: ::c_int = 42; // from src/unix/notbsd/mod.rs +pub const SO_REUSEPORT: ::c_int = 15; // from src/unix/notbsd/mod.rs +pub const SOL_NETLINK: ::c_int = 270; // from src/unix/notbsd/mod.rs +pub const _POSIX_VDISABLE: ::cc_t = 0; // from linux/mod.rs +pub const AT_EMPTY_PATH: ::c_int = 0x1000; // from notbsd/mod.rs + +// autogenerated constants with hand tuned types +pub const AT_NO_AUTOMOUNT: ::c_int = 0x800; +pub const B0: ::speed_t = 0; +pub const B1000000: ::speed_t = 0x1008; +pub const B110: ::speed_t = 0x3; +pub const B115200: ::speed_t = 0x1002; +pub const B1152000: ::speed_t = 0x1009; +pub const B1200: ::speed_t = 0x9; +pub const B134: ::speed_t = 0x4; +pub const B150: ::speed_t = 0x5; +pub const B1500000: ::speed_t = 0x100a; +pub const B1800: ::speed_t = 0xa; +pub const B19200: ::speed_t = 0xe; +pub const B200: ::speed_t = 0x6; +pub const B2000000: ::speed_t = 0x100b; +pub const B230400: ::speed_t = 0x1003; +pub const B2400: ::speed_t = 0xb; +pub const B2500000: ::speed_t = 0x100c; +pub const B300: ::speed_t = 0x7; +pub const B3000000: ::speed_t = 0x100d; +pub const B3500000: ::speed_t = 0x100e; +pub const B38400: ::speed_t = 0xf; +pub const B4000000: ::speed_t = 0x100f; +pub const B460800: ::speed_t = 0x1004; +pub const B4800: ::speed_t = 0xc; +pub const B50: ::speed_t = 0x1; +pub const B500000: ::speed_t = 0x1005; +pub const B57600: ::speed_t = 0x1001; +pub const B576000: ::speed_t = 0x1006; +pub const B600: ::speed_t = 0x8; +pub const B75: ::speed_t = 0x2; +pub const B921600: ::speed_t = 0x1007; +pub const B9600: ::speed_t = 0xd; +pub const BS1: ::c_int = 0x2000; +pub const BSDLY: ::c_int = 0x2000; +pub const CBAUD: ::tcflag_t = 0x100f; +pub const CBAUDEX: ::tcflag_t = 0x1000; +pub const CIBAUD: ::tcflag_t = 0x100f0000; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const CMSPAR: ::tcflag_t = 0x40000000; +pub const CPU_SETSIZE: ::c_int = 0x400; +pub const CR1: ::c_int = 0x200; +pub const CR2: ::c_int = 0x400; +pub const CR3: ::c_int = 0x600; +pub const CRDLY: ::c_int = 0x600; +pub const CREAD: ::tcflag_t = 0x80; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const EADDRINUSE: ::c_int = 0x62; +pub const EADDRNOTAVAIL: ::c_int = 0x63; +pub const EADV: ::c_int = 0x44; +pub const EAFNOSUPPORT: ::c_int = 0x61; +pub const EALREADY: ::c_int = 0x72; +pub const EBADE: ::c_int = 0x34; +pub const EBADFD: ::c_int = 0x4d; +pub const EBADMSG: ::c_int = 0x4a; +pub const EBADR: ::c_int = 0x35; +pub const EBADRQC: ::c_int = 0x38; +pub const EBADSLT: ::c_int = 0x39; +pub const EBFONT: ::c_int = 0x3b; +pub const ECANCELED: ::c_int = 0x7d; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHRNG: ::c_int = 0x2c; +pub const ECOMM: ::c_int = 0x46; +pub const ECONNABORTED: ::c_int = 0x67; +pub const ECONNREFUSED: ::c_int = 0x6f; +pub const ECONNRESET: ::c_int = 0x68; +pub const EDEADLK: ::c_int = 0x23; +pub const EDESTADDRREQ: ::c_int = 0x59; +pub const EDOTDOT: ::c_int = 0x49; +pub const EDQUOT: ::c_int = 0x7a; +pub const EFD_CLOEXEC: ::c_int = 0x80000; +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const EHOSTDOWN: ::c_int = 0x70; +pub const EHOSTUNREACH: ::c_int = 0x71; +pub const EHWPOISON: ::c_int = 0x85; +pub const EIDRM: ::c_int = 0x2b; +pub const EILSEQ: ::c_int = 0x54; +pub const EINPROGRESS: ::c_int = 0x73; +pub const EISCONN: ::c_int = 0x6a; +pub const EISNAM: ::c_int = 0x78; +pub const EKEYEXPIRED: ::c_int = 0x7f; +pub const EKEYREJECTED: ::c_int = 0x81; +pub const EKEYREVOKED: ::c_int = 0x80; +pub const EL2HLT: ::c_int = 0x33; +pub const EL2NSYNC: ::c_int = 0x2d; +pub const EL3HLT: ::c_int = 0x2e; +pub const EL3RST: ::c_int = 0x2f; +pub const ELIBACC: ::c_int = 0x4f; +pub const ELIBBAD: ::c_int = 0x50; +pub const ELIBEXEC: ::c_int = 0x53; +pub const ELIBMAX: ::c_int = 0x52; +pub const ELIBSCN: ::c_int = 0x51; +pub const ELNRNG: ::c_int = 0x30; +pub const ELOOP: ::c_int = 0x28; +pub const EMEDIUMTYPE: ::c_int = 0x7c; +pub const EMSGSIZE: ::c_int = 0x5a; +pub const EMULTIHOP: ::c_int = 0x48; +pub const ENAMETOOLONG: ::c_int = 0x24; +pub const ENAVAIL: ::c_int = 0x77; +pub const ENETDOWN: ::c_int = 0x64; +pub const ENETRESET: ::c_int = 0x66; +pub const ENETUNREACH: ::c_int = 0x65; +pub const ENOANO: ::c_int = 0x37; +pub const ENOBUFS: ::c_int = 0x69; +pub const ENOCSI: ::c_int = 0x32; +pub const ENODATA: ::c_int = 0x3d; +pub const ENOKEY: ::c_int = 0x7e; +pub const ENOLCK: ::c_int = 0x25; +pub const ENOLINK: ::c_int = 0x43; +pub const ENOMEDIUM: ::c_int = 0x7b; +pub const ENOMSG: ::c_int = 0x2a; +pub const ENONET: ::c_int = 0x40; +pub const ENOPKG: ::c_int = 0x41; +pub const ENOPROTOOPT: ::c_int = 0x5c; +pub const ENOSR: ::c_int = 0x3f; +pub const ENOSTR: ::c_int = 0x3c; +pub const ENOSYS: ::c_int = 0x26; +pub const ENOTCONN: ::c_int = 0x6b; +pub const ENOTEMPTY: ::c_int = 0x27; +pub const ENOTNAM: ::c_int = 0x76; +pub const ENOTRECOVERABLE: ::c_int = 0x83; +pub const ENOTSOCK: ::c_int = 0x58; +pub const ENOTUNIQ: ::c_int = 0x4c; +pub const EOPNOTSUPP: ::c_int = 0x5f; +pub const EOVERFLOW: ::c_int = 0x4b; +pub const EOWNERDEAD: ::c_int = 0x82; +pub const EPFNOSUPPORT: ::c_int = 0x60; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPROTO: ::c_int = 0x47; +pub const EPROTONOSUPPORT: ::c_int = 0x5d; +pub const EPROTOTYPE: ::c_int = 0x5b; +pub const EREMCHG: ::c_int = 0x4e; +pub const EREMOTE: ::c_int = 0x42; +pub const EREMOTEIO: ::c_int = 0x79; +pub const ERESTART: ::c_int = 0x55; +pub const ERFKILL: ::c_int = 0x84; +pub const ESHUTDOWN: ::c_int = 0x6c; +pub const ESOCKTNOSUPPORT: ::c_int = 0x5e; +pub const ESRMNT: ::c_int = 0x45; +pub const ESTALE: ::c_int = 0x74; +pub const ESTRPIPE: ::c_int = 0x56; +pub const ETIME: ::c_int = 0x3e; +pub const ETIMEDOUT: ::c_int = 0x6e; +pub const ETOOMANYREFS: ::c_int = 0x6d; +pub const EUCLEAN: ::c_int = 0x75; +pub const EUNATCH: ::c_int = 0x31; +pub const EUSERS: ::c_int = 0x57; +pub const EXFULL: ::c_int = 0x36; +pub const FF1: ::c_int = 0x8000; +pub const FFDLY: ::c_int = 0x8000; +pub const FIONBIO: ::c_ulong = 0x5421; +pub const FIOCLEX: ::c_ulong = 0x5451; +pub const FLUSHO: ::tcflag_t = 0x1000; +pub const F_GETLK: ::c_int = 0x5; +pub const F_SETLK: ::c_int = 0x6; +pub const F_SETLKW: ::c_int = 0x7; +pub const HUPCL: ::tcflag_t = 0x400; +pub const ICANON: ::tcflag_t = 0x2; +pub const IEXTEN: ::tcflag_t = 0x8000; +pub const IPV6_MULTICAST_HOPS: ::c_int = 0x12; +pub const IPV6_MULTICAST_IF: ::c_int = 0x11; +pub const IPV6_UNICAST_HOPS: ::c_int = 0x10; +pub const IP_MULTICAST_IF: ::c_int = 0x20; +pub const ISIG: ::tcflag_t = 0x1; +pub const IUTF8: ::tcflag_t = 0x4000; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const IXON: ::tcflag_t = 0x400; +pub const MAP_ANON: ::c_int = 0x20; +pub const MAP_ANONYMOUS: ::c_int = 0x20; +pub const MAP_DENYWRITE: ::c_int = 0x800; +pub const MAP_EXECUTABLE: ::c_int = 0x1000; +pub const MAP_GROWSDOWN: ::c_int = 0x100; +pub const MAP_LOCKED: ::c_int = 0x2000; +pub const MAP_NONBLOCK: ::c_int = 0x10000; +pub const MAP_NORESERVE: ::c_int = 0x4000; +pub const MAP_POPULATE: ::c_int = 0x8000; +pub const MAP_STACK: ::c_int = 0x20000; +pub const MS_ACTIVE: u32 = 0x40000000; +pub const MS_DIRSYNC: u32 = 0x80; +pub const MS_I_VERSION: u32 = 0x800000; +pub const MS_KERNMOUNT: u32 = 0x400000; +pub const MS_MOVE: u32 = 0x2000; +pub const MS_POSIXACL: u32 = 0x10000; +pub const MS_PRIVATE: u32 = 0x40000; +pub const MS_REC: u32 = 0x4000; +pub const MS_RELATIME: u32 = 0x200000; +pub const MS_SHARED: u32 = 0x100000; +pub const MS_SILENT: u32 = 0x8000; +pub const MS_SLAVE: u32 = 0x80000; +pub const MS_STRICTATIME: u32 = 0x1000000; +pub const MS_UNBINDABLE: u32 = 0x20000; +pub const NLDLY: ::tcflag_t = 0x100; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const OCRNL: ::c_int = 0x8; +pub const OFDEL: ::c_int = 0x80; +pub const OFILL: ::c_int = 0x40; +pub const OLCUC: ::tcflag_t = 0x2; +pub const ONLCR: ::tcflag_t = 0x4; +pub const ONLRET: ::tcflag_t = 0x20; +pub const ONOCR: ::tcflag_t = 0x10; +pub const O_ACCMODE: ::c_int = 0x3; +pub const O_APPEND: ::c_int = 0x400; +pub const O_CREAT: ::c_int = 0x40; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_DSYNC: ::c_int = 0x1000; +pub const O_EXCL: ::c_int = 0x80; +pub const O_NDELAY: ::c_int = 0x800; +pub const O_NOCTTY: ::c_int = 0x100; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x800; +pub const O_SYNC: ::c_int = 0o10000; +pub const O_TRUNC: ::c_int = 0x200; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const POLLRDBAND: ::c_short = 0x80; +pub const POLLRDNORM: ::c_short = 0x40; +pub const POLLWRBAND: ::c_short = 0x200; +pub const POLLWRNORM: ::c_short = 0x100; +pub const QIF_ALL: ::uint32_t = 0x3f; +pub const QIF_BLIMITS: ::uint32_t = 0x1; +pub const QIF_BTIME: ::uint32_t = 0x10; +pub const QIF_ILIMITS: ::uint32_t = 0x4; +pub const QIF_INODES: ::uint32_t = 0x8; +pub const QIF_ITIME: ::uint32_t = 0x20; +pub const QIF_LIMITS: ::uint32_t = 0x5; +pub const QIF_SPACE: ::uint32_t = 0x2; +pub const QIF_TIMES: ::uint32_t = 0x30; +pub const QIF_USAGE: ::uint32_t = 0xa; +pub const SA_NOCLDSTOP: ::c_int = 0x1; +pub const SA_NOCLDWAIT: ::c_int = 0x2; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_ONSTACK: ::c_int = 0x8000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_SIGINFO: ::c_int = 0x4; +pub const SFD_CLOEXEC: ::c_int = 0x80000; +pub const SFD_NONBLOCK: ::c_int = 0x800; +pub const SIGBUS: ::c_int = 0x7; +pub const SIGCHLD: ::c_int = 0x11; +pub const SIGCONT: ::c_int = 0x12; +pub const SIGIO: ::c_int = 0x1d; +pub const SIGPROF: ::c_int = 0x1b; +pub const SIGPWR: ::c_int = 0x1e; +pub const SIGSTKFLT: ::c_int = 0x10; +pub const SIGSTOP: ::c_int = 0x13; +pub const SIGSYS: ::c_int = 0x1f; +pub const SIGTSTP: ::c_int = 0x14; +pub const SIGTTIN: ::c_int = 0x15; +pub const SIGTTOU: ::c_int = 0x16; +pub const SIGURG: ::c_int = 0x17; +pub const SIGUSR1: ::c_int = 0xa; +pub const SIGUSR2: ::c_int = 0xc; +pub const SIGVTALRM: ::c_int = 0x1a; +pub const SIGWINCH: ::c_int = 0x1c; +pub const SIGXCPU: ::c_int = 0x18; +pub const SIGXFSZ: ::c_int = 0x19; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_SETMASK: ::c_int = 0x2; +pub const SIG_UNBLOCK: ::c_int = 0x1; +pub const SOCK_DGRAM: ::c_int = 0x2; +pub const SOCK_NONBLOCK: ::c_int = 0o0004000; +pub const SOCK_SEQPACKET: ::c_int = 0x5; +pub const SOCK_STREAM: ::c_int = 0x1; +pub const SOL_SOCKET: ::c_int = 0x1; +pub const SO_ACCEPTCONN: ::c_int = 0x1e; +pub const SO_BINDTODEVICE: ::c_int = 0x19; +pub const SO_BROADCAST: ::c_int = 0x6; +pub const SO_BSDCOMPAT: ::c_int = 0xe; +pub const SO_DOMAIN: ::c_int = 0x27; +pub const SO_DONTROUTE: ::c_int = 0x5; +pub const SO_ERROR: ::c_int = 0x4; +pub const SO_KEEPALIVE: ::c_int = 0x9; +pub const SO_LINGER: ::c_int = 0xd; +pub const SO_MARK: ::c_int = 0x24; +pub const SO_OOBINLINE: ::c_int = 0xa; +pub const SO_PASSCRED: ::c_int = 0x10; +pub const SO_PEERCRED: ::c_int = 0x11; +pub const SO_PRIORITY: ::c_int = 0xc; +pub const SO_PROTOCOL: ::c_int = 0x26; +pub const SO_RCVBUF: ::c_int = 0x8; +pub const SO_RCVLOWAT: ::c_int = 0x12; +pub const SO_RCVTIMEO: ::c_int = 0x14; +pub const SO_REUSEADDR: ::c_int = 0x2; +pub const SO_RXQ_OVFL: ::c_int = 0x28; +pub const SO_SNDBUF: ::c_int = 0x7; +pub const SO_SNDBUFFORCE: ::c_int = 0x20; +pub const SO_SNDLOWAT: ::c_int = 0x13; +pub const SO_SNDTIMEO: ::c_int = 0x15; +pub const SO_TIMESTAMP: ::c_int = 0x1d; +pub const SO_TYPE: ::c_int = 0x3; +pub const SYS_gettid: ::c_int = 0xe0; +pub const TAB1: ::c_int = 0x800; +pub const TAB2: ::c_int = 0x1000; +pub const TAB3: ::c_int = 0x1800; +pub const TABDLY: ::c_int = 0x1800; +pub const TCSADRAIN: ::c_int = 0x1; +pub const TCSAFLUSH: ::c_int = 0x2; +pub const TCSANOW: ::c_int = 0; +pub const TOSTOP: ::tcflag_t = 0x100; +pub const VDISCARD: usize = 0xd; +pub const VEOF: usize = 0x4; +pub const VEOL: usize = 0xb; +pub const VEOL2: usize = 0x10; +pub const VMIN: usize = 0x6; +pub const VREPRINT: usize = 0xc; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VSUSP: usize = 0xa; +pub const VSWTC: usize = 0x7; +pub const VT1: ::c_int = 0x4000; +pub const VTDLY: ::c_int = 0x4000; +pub const VTIME: usize = 0x5; +pub const VWERASE: usize = 0xe; +pub const XTABS: ::tcflag_t = 0x1800; +pub const _PC_2_SYMLINKS: ::c_int = 0x14; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 0x12; +pub const _PC_ASYNC_IO: ::c_int = 0xa; +pub const _PC_FILESIZEBITS: ::c_int = 0xd; +pub const _PC_PRIO_IO: ::c_int = 0xb; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 0xe; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 0xf; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 0x10; +pub const _PC_REC_XFER_ALIGN: ::c_int = 0x11; +pub const _PC_SYMLINK_MAX: ::c_int = 0x13; +pub const _PC_SYNC_IO: ::c_int = 0x9; +pub const _SC_2_PBS: ::c_int = 0xa8; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 0xa9; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 0xaf; +pub const _SC_2_PBS_LOCATE: ::c_int = 0xaa; +pub const _SC_2_PBS_MESSAGE: ::c_int = 0xab; +pub const _SC_2_PBS_TRACK: ::c_int = 0xac; +pub const _SC_ADVISORY_INFO: ::c_int = 0x84; +pub const _SC_BARRIERS: ::c_int = 0x85; +pub const _SC_CLOCK_SELECTION: ::c_int = 0x89; +pub const _SC_CPUTIME: ::c_int = 0x8a; +pub const _SC_IPV6: ::c_int = 0xeb; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 0x95; +pub const _SC_RAW_SOCKETS: ::c_int = 0xec; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 0x99; +pub const _SC_REGEXP: ::c_int = 0x9b; +pub const _SC_SHELL: ::c_int = 0x9d; +pub const _SC_SPAWN: ::c_int = 0x9f; +pub const _SC_SPIN_LOCKS: ::c_int = 0x9a; +pub const _SC_SPORADIC_SERVER: ::c_int = 0xa0; +pub const _SC_SS_REPL_MAX: ::c_int = 0xf1; +pub const _SC_SYMLOOP_MAX: ::c_int = 0xad; +pub const _SC_THREAD_CPUTIME: ::c_int = 0x8b; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 0x52; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 0xf7; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 0xf8; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 0xa1; +pub const _SC_TIMEOUTS: ::c_int = 0xa4; +pub const _SC_TRACE: ::c_int = 0xb5; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 0xb6; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 0xf2; +pub const _SC_TRACE_INHERIT: ::c_int = 0xb7; +pub const _SC_TRACE_LOG: ::c_int = 0xb8; +pub const _SC_TRACE_NAME_MAX: ::c_int = 0xf3; +pub const _SC_TRACE_SYS_MAX: ::c_int = 0xf4; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 0xf5; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 0xa5; +pub const _SC_V6_ILP32_OFF32: ::c_int = 0xb0; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 0xb1; +pub const _SC_V6_LP64_OFF64: ::c_int = 0xb2; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 0xb3; +pub const _SC_XOPEN_STREAMS: ::c_int = 0xf6; + +fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) +} + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::() { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 as *mut cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + cmsg.offset(1) as *mut ::c_uchar + } + + pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max || + next as usize + CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + +} + +extern { + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn openpty(amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize) -> ::c_int; + pub fn setns(fd: ::c_int, nstype: ::c_int) -> ::c_int; + pub fn pwritev(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t) -> ::ssize_t; + pub fn preadv(fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/no_align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/arm/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/arm/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/mod.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,635 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type clock_t = i32; +pub type time_t = i32; +pub type suseconds_t = i32; +pub type wchar_t = i32; +pub type off_t = i32; +pub type ino_t = u32; +pub type blkcnt_t = i32; +pub type blksize_t = i32; +pub type nlink_t = u32; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type rlim_t = c_ulong; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_pad2: [::c_long; 1], + pub st_size: ::off_t, + st_pad3: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 14], + } + + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigaction { + pub sa_flags: ::c_uint, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __val: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: ::c_ulong, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved2: ::c_ulong, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved3: ::c_ulong, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: ::c_ulong, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_sysid: ::c_long, + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } +} + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + +pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_unused18: ::c_long = 4000 + 18; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_unused28: ::c_long = 4000 + 28; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_unused59: ::c_long = 4000 + 59; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_reserved82: ::c_long = 4000 + 82; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_unused84: ::c_long = 4000 + 84; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_unused109: ::c_long = 4000 + 109; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS__newselect: ::c_long = 4000 + 142; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_unused150: ::c_long = 4000 + 150; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_pread64: ::c_long = 4000 + 200; +pub const SYS_pwrite64: ::c_long = 4000 + 201; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_reserved221: ::c_long = 4000 + 221; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_fadvise64: ::c_long = 4000 + 254; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_fstatat64: ::c_long = 4000 + 293; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +pub const SYS_pwritev2: ::c_long = 4000 + 362; +pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; +pub const SYS_pkey_alloc: ::c_long = 4000 + 364; +pub const SYS_pkey_free: ::c_long = 4000 + 365; + +#[link(name = "util")] +extern { + pub fn sysctl(name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t) + -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn backtrace(buf: *mut *mut ::c_void, + sz: ::c_int) -> ::c_int; + pub fn glob64(pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + pub fn pthread_attr_getaffinity_np(attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t) -> ::c_int; + pub fn pthread_attr_setaffinity_np(attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/no_align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips32.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips32.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,639 +0,0 @@ -pub type c_char = i8; -pub type c_long = i32; -pub type c_ulong = u32; -pub type clock_t = i32; -pub type time_t = i32; -pub type suseconds_t = i32; -pub type wchar_t = i32; -pub type off_t = i32; -pub type ino_t = u32; -pub type blkcnt_t = i32; -pub type blksize_t = i32; -pub type nlink_t = u32; -pub type fsblkcnt_t = ::c_ulong; -pub type fsfilcnt_t = ::c_ulong; -pub type rlim_t = c_ulong; - -s! { - pub struct stat { - pub st_dev: ::dev_t, - st_pad1: [::c_long; 2], - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - pub st_pad2: [::c_long; 1], - pub st_size: ::off_t, - st_pad3: ::c_long, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - pub st_blocks: ::blkcnt_t, - st_pad5: [::c_long; 14], - } - - pub struct stat64 { - pub st_dev: ::dev_t, - st_pad1: [::c_long; 2], - pub st_ino: ::ino64_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::dev_t, - st_pad2: [::c_long; 2], - pub st_size: ::off64_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - st_pad3: ::c_long, - pub st_blocks: ::blkcnt64_t, - st_pad5: [::c_long; 14], - } - - pub struct pthread_attr_t { - __size: [u32; 9] - } - - pub struct sigaction { - pub sa_flags: ::c_uint, - pub sa_sigaction: ::sighandler_t, - pub sa_mask: sigset_t, - _restorer: *mut ::c_void, - } - - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_size: ::size_t, - pub ss_flags: ::c_int, - } - - pub struct sigset_t { - __val: [::c_ulong; 4], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_code: ::c_int, - pub si_errno: ::c_int, - pub _pad: [::c_int; 29], - } - - pub struct glob64_t { - pub gl_pathc: ::size_t, - pub gl_pathv: *mut *mut ::c_char, - pub gl_offs: ::size_t, - pub gl_flags: ::c_int, - - __unused1: *mut ::c_void, - __unused2: *mut ::c_void, - __unused3: *mut ::c_void, - __unused4: *mut ::c_void, - __unused5: *mut ::c_void, - } - - pub struct ipc_perm { - pub __key: ::key_t, - pub uid: ::uid_t, - pub gid: ::gid_t, - pub cuid: ::uid_t, - pub cgid: ::gid_t, - pub mode: ::c_uint, - pub __seq: ::c_ushort, - __pad1: ::c_ushort, - __unused1: ::c_ulong, - __unused2: ::c_ulong - } - - pub struct shmid_ds { - pub shm_perm: ::ipc_perm, - pub shm_segsz: ::size_t, - pub shm_atime: ::time_t, - pub shm_dtime: ::time_t, - pub shm_ctime: ::time_t, - pub shm_cpid: ::pid_t, - pub shm_lpid: ::pid_t, - pub shm_nattch: ::shmatt_t, - __unused4: ::c_ulong, - __unused5: ::c_ulong - } - - pub struct msqid_ds { - pub msg_perm: ::ipc_perm, - #[cfg(target_endian = "big")] - __glibc_reserved1: ::c_ulong, - pub msg_stime: ::time_t, - #[cfg(target_endian = "little")] - __glibc_reserved1: ::c_ulong, - #[cfg(target_endian = "big")] - __glibc_reserved2: ::c_ulong, - pub msg_rtime: ::time_t, - #[cfg(target_endian = "little")] - __glibc_reserved2: ::c_ulong, - #[cfg(target_endian = "big")] - __glibc_reserved3: ::c_ulong, - pub msg_ctime: ::time_t, - #[cfg(target_endian = "little")] - __glibc_reserved3: ::c_ulong, - __msg_cbytes: ::c_ulong, - pub msg_qnum: ::msgqnum_t, - pub msg_qbytes: ::msglen_t, - pub msg_lspid: ::pid_t, - pub msg_lrpid: ::pid_t, - __glibc_reserved4: ::c_ulong, - __glibc_reserved5: ::c_ulong, - } - - pub struct statfs { - pub f_type: ::c_long, - pub f_bsize: ::c_long, - pub f_frsize: ::c_long, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_files: ::fsblkcnt_t, - pub f_ffree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_fsid: ::fsid_t, - - pub f_namelen: ::c_long, - f_spare: [::c_long; 6], - } - - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::c_int, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::size_t, - pub msg_flags: ::c_int, - } - - pub struct cmsghdr { - pub cmsg_len: ::size_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } - - pub struct termios { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_line: ::cc_t, - pub c_cc: [::cc_t; ::NCCS], - } - - pub struct flock { - pub l_type: ::c_short, - pub l_whence: ::c_short, - pub l_start: ::off_t, - pub l_len: ::off_t, - pub l_sysid: ::c_long, - pub l_pid: ::pid_t, - pad: [::c_long; 4], - } - - pub struct sysinfo { - pub uptime: ::c_long, - pub loads: [::c_ulong; 3], - pub totalram: ::c_ulong, - pub freeram: ::c_ulong, - pub sharedram: ::c_ulong, - pub bufferram: ::c_ulong, - pub totalswap: ::c_ulong, - pub freeswap: ::c_ulong, - pub procs: ::c_ushort, - pub pad: ::c_ushort, - pub totalhigh: ::c_ulong, - pub freehigh: ::c_ulong, - pub mem_unit: ::c_uint, - pub _f: [::c_char; 8], - } - - // FIXME this is actually a union - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { - #[cfg(target_pointer_width = "32")] - __size: [::c_char; 16], - #[cfg(target_pointer_width = "64")] - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } -} - -pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; -pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; -pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; - -pub const RLIM_INFINITY: ::rlim_t = 0x7fffffff; - -pub const SYS_syscall: ::c_long = 4000 + 0; -pub const SYS_exit: ::c_long = 4000 + 1; -pub const SYS_fork: ::c_long = 4000 + 2; -pub const SYS_read: ::c_long = 4000 + 3; -pub const SYS_write: ::c_long = 4000 + 4; -pub const SYS_open: ::c_long = 4000 + 5; -pub const SYS_close: ::c_long = 4000 + 6; -pub const SYS_waitpid: ::c_long = 4000 + 7; -pub const SYS_creat: ::c_long = 4000 + 8; -pub const SYS_link: ::c_long = 4000 + 9; -pub const SYS_unlink: ::c_long = 4000 + 10; -pub const SYS_execve: ::c_long = 4000 + 11; -pub const SYS_chdir: ::c_long = 4000 + 12; -pub const SYS_time: ::c_long = 4000 + 13; -pub const SYS_mknod: ::c_long = 4000 + 14; -pub const SYS_chmod: ::c_long = 4000 + 15; -pub const SYS_lchown: ::c_long = 4000 + 16; -pub const SYS_break: ::c_long = 4000 + 17; -pub const SYS_unused18: ::c_long = 4000 + 18; -pub const SYS_lseek: ::c_long = 4000 + 19; -pub const SYS_getpid: ::c_long = 4000 + 20; -pub const SYS_mount: ::c_long = 4000 + 21; -pub const SYS_umount: ::c_long = 4000 + 22; -pub const SYS_setuid: ::c_long = 4000 + 23; -pub const SYS_getuid: ::c_long = 4000 + 24; -pub const SYS_stime: ::c_long = 4000 + 25; -pub const SYS_ptrace: ::c_long = 4000 + 26; -pub const SYS_alarm: ::c_long = 4000 + 27; -pub const SYS_unused28: ::c_long = 4000 + 28; -pub const SYS_pause: ::c_long = 4000 + 29; -pub const SYS_utime: ::c_long = 4000 + 30; -pub const SYS_stty: ::c_long = 4000 + 31; -pub const SYS_gtty: ::c_long = 4000 + 32; -pub const SYS_access: ::c_long = 4000 + 33; -pub const SYS_nice: ::c_long = 4000 + 34; -pub const SYS_ftime: ::c_long = 4000 + 35; -pub const SYS_sync: ::c_long = 4000 + 36; -pub const SYS_kill: ::c_long = 4000 + 37; -pub const SYS_rename: ::c_long = 4000 + 38; -pub const SYS_mkdir: ::c_long = 4000 + 39; -pub const SYS_rmdir: ::c_long = 4000 + 40; -pub const SYS_dup: ::c_long = 4000 + 41; -pub const SYS_pipe: ::c_long = 4000 + 42; -pub const SYS_times: ::c_long = 4000 + 43; -pub const SYS_prof: ::c_long = 4000 + 44; -pub const SYS_brk: ::c_long = 4000 + 45; -pub const SYS_setgid: ::c_long = 4000 + 46; -pub const SYS_getgid: ::c_long = 4000 + 47; -pub const SYS_signal: ::c_long = 4000 + 48; -pub const SYS_geteuid: ::c_long = 4000 + 49; -pub const SYS_getegid: ::c_long = 4000 + 50; -pub const SYS_acct: ::c_long = 4000 + 51; -pub const SYS_umount2: ::c_long = 4000 + 52; -pub const SYS_lock: ::c_long = 4000 + 53; -pub const SYS_ioctl: ::c_long = 4000 + 54; -pub const SYS_fcntl: ::c_long = 4000 + 55; -pub const SYS_mpx: ::c_long = 4000 + 56; -pub const SYS_setpgid: ::c_long = 4000 + 57; -pub const SYS_ulimit: ::c_long = 4000 + 58; -pub const SYS_unused59: ::c_long = 4000 + 59; -pub const SYS_umask: ::c_long = 4000 + 60; -pub const SYS_chroot: ::c_long = 4000 + 61; -pub const SYS_ustat: ::c_long = 4000 + 62; -pub const SYS_dup2: ::c_long = 4000 + 63; -pub const SYS_getppid: ::c_long = 4000 + 64; -pub const SYS_getpgrp: ::c_long = 4000 + 65; -pub const SYS_setsid: ::c_long = 4000 + 66; -pub const SYS_sigaction: ::c_long = 4000 + 67; -pub const SYS_sgetmask: ::c_long = 4000 + 68; -pub const SYS_ssetmask: ::c_long = 4000 + 69; -pub const SYS_setreuid: ::c_long = 4000 + 70; -pub const SYS_setregid: ::c_long = 4000 + 71; -pub const SYS_sigsuspend: ::c_long = 4000 + 72; -pub const SYS_sigpending: ::c_long = 4000 + 73; -pub const SYS_sethostname: ::c_long = 4000 + 74; -pub const SYS_setrlimit: ::c_long = 4000 + 75; -pub const SYS_getrlimit: ::c_long = 4000 + 76; -pub const SYS_getrusage: ::c_long = 4000 + 77; -pub const SYS_gettimeofday: ::c_long = 4000 + 78; -pub const SYS_settimeofday: ::c_long = 4000 + 79; -pub const SYS_getgroups: ::c_long = 4000 + 80; -pub const SYS_setgroups: ::c_long = 4000 + 81; -pub const SYS_reserved82: ::c_long = 4000 + 82; -pub const SYS_symlink: ::c_long = 4000 + 83; -pub const SYS_unused84: ::c_long = 4000 + 84; -pub const SYS_readlink: ::c_long = 4000 + 85; -pub const SYS_uselib: ::c_long = 4000 + 86; -pub const SYS_swapon: ::c_long = 4000 + 87; -pub const SYS_reboot: ::c_long = 4000 + 88; -pub const SYS_readdir: ::c_long = 4000 + 89; -pub const SYS_mmap: ::c_long = 4000 + 90; -pub const SYS_munmap: ::c_long = 4000 + 91; -pub const SYS_truncate: ::c_long = 4000 + 92; -pub const SYS_ftruncate: ::c_long = 4000 + 93; -pub const SYS_fchmod: ::c_long = 4000 + 94; -pub const SYS_fchown: ::c_long = 4000 + 95; -pub const SYS_getpriority: ::c_long = 4000 + 96; -pub const SYS_setpriority: ::c_long = 4000 + 97; -pub const SYS_profil: ::c_long = 4000 + 98; -pub const SYS_statfs: ::c_long = 4000 + 99; -pub const SYS_fstatfs: ::c_long = 4000 + 100; -pub const SYS_ioperm: ::c_long = 4000 + 101; -pub const SYS_socketcall: ::c_long = 4000 + 102; -pub const SYS_syslog: ::c_long = 4000 + 103; -pub const SYS_setitimer: ::c_long = 4000 + 104; -pub const SYS_getitimer: ::c_long = 4000 + 105; -pub const SYS_stat: ::c_long = 4000 + 106; -pub const SYS_lstat: ::c_long = 4000 + 107; -pub const SYS_fstat: ::c_long = 4000 + 108; -pub const SYS_unused109: ::c_long = 4000 + 109; -pub const SYS_iopl: ::c_long = 4000 + 110; -pub const SYS_vhangup: ::c_long = 4000 + 111; -pub const SYS_idle: ::c_long = 4000 + 112; -pub const SYS_vm86: ::c_long = 4000 + 113; -pub const SYS_wait4: ::c_long = 4000 + 114; -pub const SYS_swapoff: ::c_long = 4000 + 115; -pub const SYS_sysinfo: ::c_long = 4000 + 116; -pub const SYS_ipc: ::c_long = 4000 + 117; -pub const SYS_fsync: ::c_long = 4000 + 118; -pub const SYS_sigreturn: ::c_long = 4000 + 119; -pub const SYS_clone: ::c_long = 4000 + 120; -pub const SYS_setdomainname: ::c_long = 4000 + 121; -pub const SYS_uname: ::c_long = 4000 + 122; -pub const SYS_modify_ldt: ::c_long = 4000 + 123; -pub const SYS_adjtimex: ::c_long = 4000 + 124; -pub const SYS_mprotect: ::c_long = 4000 + 125; -pub const SYS_sigprocmask: ::c_long = 4000 + 126; -pub const SYS_create_module: ::c_long = 4000 + 127; -pub const SYS_init_module: ::c_long = 4000 + 128; -pub const SYS_delete_module: ::c_long = 4000 + 129; -pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; -pub const SYS_quotactl: ::c_long = 4000 + 131; -pub const SYS_getpgid: ::c_long = 4000 + 132; -pub const SYS_fchdir: ::c_long = 4000 + 133; -pub const SYS_bdflush: ::c_long = 4000 + 134; -pub const SYS_sysfs: ::c_long = 4000 + 135; -pub const SYS_personality: ::c_long = 4000 + 136; -pub const SYS_afs_syscall: ::c_long = 4000 + 137; -pub const SYS_setfsuid: ::c_long = 4000 + 138; -pub const SYS_setfsgid: ::c_long = 4000 + 139; -pub const SYS__llseek: ::c_long = 4000 + 140; -pub const SYS_getdents: ::c_long = 4000 + 141; -pub const SYS__newselect: ::c_long = 4000 + 142; -pub const SYS_flock: ::c_long = 4000 + 143; -pub const SYS_msync: ::c_long = 4000 + 144; -pub const SYS_readv: ::c_long = 4000 + 145; -pub const SYS_writev: ::c_long = 4000 + 146; -pub const SYS_cacheflush: ::c_long = 4000 + 147; -pub const SYS_cachectl: ::c_long = 4000 + 148; -pub const SYS_sysmips: ::c_long = 4000 + 149; -pub const SYS_unused150: ::c_long = 4000 + 150; -pub const SYS_getsid: ::c_long = 4000 + 151; -pub const SYS_fdatasync: ::c_long = 4000 + 152; -pub const SYS__sysctl: ::c_long = 4000 + 153; -pub const SYS_mlock: ::c_long = 4000 + 154; -pub const SYS_munlock: ::c_long = 4000 + 155; -pub const SYS_mlockall: ::c_long = 4000 + 156; -pub const SYS_munlockall: ::c_long = 4000 + 157; -pub const SYS_sched_setparam: ::c_long = 4000 + 158; -pub const SYS_sched_getparam: ::c_long = 4000 + 159; -pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; -pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; -pub const SYS_sched_yield: ::c_long = 4000 + 162; -pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; -pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; -pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; -pub const SYS_nanosleep: ::c_long = 4000 + 166; -pub const SYS_mremap: ::c_long = 4000 + 167; -pub const SYS_accept: ::c_long = 4000 + 168; -pub const SYS_bind: ::c_long = 4000 + 169; -pub const SYS_connect: ::c_long = 4000 + 170; -pub const SYS_getpeername: ::c_long = 4000 + 171; -pub const SYS_getsockname: ::c_long = 4000 + 172; -pub const SYS_getsockopt: ::c_long = 4000 + 173; -pub const SYS_listen: ::c_long = 4000 + 174; -pub const SYS_recv: ::c_long = 4000 + 175; -pub const SYS_recvfrom: ::c_long = 4000 + 176; -pub const SYS_recvmsg: ::c_long = 4000 + 177; -pub const SYS_send: ::c_long = 4000 + 178; -pub const SYS_sendmsg: ::c_long = 4000 + 179; -pub const SYS_sendto: ::c_long = 4000 + 180; -pub const SYS_setsockopt: ::c_long = 4000 + 181; -pub const SYS_shutdown: ::c_long = 4000 + 182; -pub const SYS_socket: ::c_long = 4000 + 183; -pub const SYS_socketpair: ::c_long = 4000 + 184; -pub const SYS_setresuid: ::c_long = 4000 + 185; -pub const SYS_getresuid: ::c_long = 4000 + 186; -pub const SYS_query_module: ::c_long = 4000 + 187; -pub const SYS_poll: ::c_long = 4000 + 188; -pub const SYS_nfsservctl: ::c_long = 4000 + 189; -pub const SYS_setresgid: ::c_long = 4000 + 190; -pub const SYS_getresgid: ::c_long = 4000 + 191; -pub const SYS_prctl: ::c_long = 4000 + 192; -pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; -pub const SYS_rt_sigaction: ::c_long = 4000 + 194; -pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; -pub const SYS_rt_sigpending: ::c_long = 4000 + 196; -pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; -pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; -pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; -pub const SYS_pread64: ::c_long = 4000 + 200; -pub const SYS_pwrite64: ::c_long = 4000 + 201; -pub const SYS_chown: ::c_long = 4000 + 202; -pub const SYS_getcwd: ::c_long = 4000 + 203; -pub const SYS_capget: ::c_long = 4000 + 204; -pub const SYS_capset: ::c_long = 4000 + 205; -pub const SYS_sigaltstack: ::c_long = 4000 + 206; -pub const SYS_sendfile: ::c_long = 4000 + 207; -pub const SYS_getpmsg: ::c_long = 4000 + 208; -pub const SYS_putpmsg: ::c_long = 4000 + 209; -pub const SYS_mmap2: ::c_long = 4000 + 210; -pub const SYS_truncate64: ::c_long = 4000 + 211; -pub const SYS_ftruncate64: ::c_long = 4000 + 212; -pub const SYS_stat64: ::c_long = 4000 + 213; -pub const SYS_lstat64: ::c_long = 4000 + 214; -pub const SYS_fstat64: ::c_long = 4000 + 215; -pub const SYS_pivot_root: ::c_long = 4000 + 216; -pub const SYS_mincore: ::c_long = 4000 + 217; -pub const SYS_madvise: ::c_long = 4000 + 218; -pub const SYS_getdents64: ::c_long = 4000 + 219; -pub const SYS_fcntl64: ::c_long = 4000 + 220; -pub const SYS_reserved221: ::c_long = 4000 + 221; -pub const SYS_gettid: ::c_long = 4000 + 222; -pub const SYS_readahead: ::c_long = 4000 + 223; -pub const SYS_setxattr: ::c_long = 4000 + 224; -pub const SYS_lsetxattr: ::c_long = 4000 + 225; -pub const SYS_fsetxattr: ::c_long = 4000 + 226; -pub const SYS_getxattr: ::c_long = 4000 + 227; -pub const SYS_lgetxattr: ::c_long = 4000 + 228; -pub const SYS_fgetxattr: ::c_long = 4000 + 229; -pub const SYS_listxattr: ::c_long = 4000 + 230; -pub const SYS_llistxattr: ::c_long = 4000 + 231; -pub const SYS_flistxattr: ::c_long = 4000 + 232; -pub const SYS_removexattr: ::c_long = 4000 + 233; -pub const SYS_lremovexattr: ::c_long = 4000 + 234; -pub const SYS_fremovexattr: ::c_long = 4000 + 235; -pub const SYS_tkill: ::c_long = 4000 + 236; -pub const SYS_sendfile64: ::c_long = 4000 + 237; -pub const SYS_futex: ::c_long = 4000 + 238; -pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; -pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; -pub const SYS_io_setup: ::c_long = 4000 + 241; -pub const SYS_io_destroy: ::c_long = 4000 + 242; -pub const SYS_io_getevents: ::c_long = 4000 + 243; -pub const SYS_io_submit: ::c_long = 4000 + 244; -pub const SYS_io_cancel: ::c_long = 4000 + 245; -pub const SYS_exit_group: ::c_long = 4000 + 246; -pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; -pub const SYS_epoll_create: ::c_long = 4000 + 248; -pub const SYS_epoll_ctl: ::c_long = 4000 + 249; -pub const SYS_epoll_wait: ::c_long = 4000 + 250; -pub const SYS_remap_file_pages: ::c_long = 4000 + 251; -pub const SYS_set_tid_address: ::c_long = 4000 + 252; -pub const SYS_restart_syscall: ::c_long = 4000 + 253; -pub const SYS_fadvise64: ::c_long = 4000 + 254; -pub const SYS_statfs64: ::c_long = 4000 + 255; -pub const SYS_fstatfs64: ::c_long = 4000 + 256; -pub const SYS_timer_create: ::c_long = 4000 + 257; -pub const SYS_timer_settime: ::c_long = 4000 + 258; -pub const SYS_timer_gettime: ::c_long = 4000 + 259; -pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; -pub const SYS_timer_delete: ::c_long = 4000 + 261; -pub const SYS_clock_settime: ::c_long = 4000 + 262; -pub const SYS_clock_gettime: ::c_long = 4000 + 263; -pub const SYS_clock_getres: ::c_long = 4000 + 264; -pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; -pub const SYS_tgkill: ::c_long = 4000 + 266; -pub const SYS_utimes: ::c_long = 4000 + 267; -pub const SYS_mbind: ::c_long = 4000 + 268; -pub const SYS_get_mempolicy: ::c_long = 4000 + 269; -pub const SYS_set_mempolicy: ::c_long = 4000 + 270; -pub const SYS_mq_open: ::c_long = 4000 + 271; -pub const SYS_mq_unlink: ::c_long = 4000 + 272; -pub const SYS_mq_timedsend: ::c_long = 4000 + 273; -pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; -pub const SYS_mq_notify: ::c_long = 4000 + 275; -pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; -pub const SYS_vserver: ::c_long = 4000 + 277; -pub const SYS_waitid: ::c_long = 4000 + 278; -/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ -pub const SYS_add_key: ::c_long = 4000 + 280; -pub const SYS_request_key: ::c_long = 4000 + 281; -pub const SYS_keyctl: ::c_long = 4000 + 282; -pub const SYS_set_thread_area: ::c_long = 4000 + 283; -pub const SYS_inotify_init: ::c_long = 4000 + 284; -pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; -pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; -pub const SYS_migrate_pages: ::c_long = 4000 + 287; -pub const SYS_openat: ::c_long = 4000 + 288; -pub const SYS_mkdirat: ::c_long = 4000 + 289; -pub const SYS_mknodat: ::c_long = 4000 + 290; -pub const SYS_fchownat: ::c_long = 4000 + 291; -pub const SYS_futimesat: ::c_long = 4000 + 292; -pub const SYS_fstatat64: ::c_long = 4000 + 293; -pub const SYS_unlinkat: ::c_long = 4000 + 294; -pub const SYS_renameat: ::c_long = 4000 + 295; -pub const SYS_linkat: ::c_long = 4000 + 296; -pub const SYS_symlinkat: ::c_long = 4000 + 297; -pub const SYS_readlinkat: ::c_long = 4000 + 298; -pub const SYS_fchmodat: ::c_long = 4000 + 299; -pub const SYS_faccessat: ::c_long = 4000 + 300; -pub const SYS_pselect6: ::c_long = 4000 + 301; -pub const SYS_ppoll: ::c_long = 4000 + 302; -pub const SYS_unshare: ::c_long = 4000 + 303; -pub const SYS_splice: ::c_long = 4000 + 304; -pub const SYS_sync_file_range: ::c_long = 4000 + 305; -pub const SYS_tee: ::c_long = 4000 + 306; -pub const SYS_vmsplice: ::c_long = 4000 + 307; -pub const SYS_move_pages: ::c_long = 4000 + 308; -pub const SYS_set_robust_list: ::c_long = 4000 + 309; -pub const SYS_get_robust_list: ::c_long = 4000 + 310; -pub const SYS_kexec_load: ::c_long = 4000 + 311; -pub const SYS_getcpu: ::c_long = 4000 + 312; -pub const SYS_epoll_pwait: ::c_long = 4000 + 313; -pub const SYS_ioprio_set: ::c_long = 4000 + 314; -pub const SYS_ioprio_get: ::c_long = 4000 + 315; -pub const SYS_utimensat: ::c_long = 4000 + 316; -pub const SYS_signalfd: ::c_long = 4000 + 317; -pub const SYS_timerfd: ::c_long = 4000 + 318; -pub const SYS_eventfd: ::c_long = 4000 + 319; -pub const SYS_fallocate: ::c_long = 4000 + 320; -pub const SYS_timerfd_create: ::c_long = 4000 + 321; -pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; -pub const SYS_timerfd_settime: ::c_long = 4000 + 323; -pub const SYS_signalfd4: ::c_long = 4000 + 324; -pub const SYS_eventfd2: ::c_long = 4000 + 325; -pub const SYS_epoll_create1: ::c_long = 4000 + 326; -pub const SYS_dup3: ::c_long = 4000 + 327; -pub const SYS_pipe2: ::c_long = 4000 + 328; -pub const SYS_inotify_init1: ::c_long = 4000 + 329; -pub const SYS_preadv: ::c_long = 4000 + 330; -pub const SYS_pwritev: ::c_long = 4000 + 331; -pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; -pub const SYS_perf_event_open: ::c_long = 4000 + 333; -pub const SYS_accept4: ::c_long = 4000 + 334; -pub const SYS_recvmmsg: ::c_long = 4000 + 335; -pub const SYS_fanotify_init: ::c_long = 4000 + 336; -pub const SYS_fanotify_mark: ::c_long = 4000 + 337; -pub const SYS_prlimit64: ::c_long = 4000 + 338; -pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; -pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; -pub const SYS_clock_adjtime: ::c_long = 4000 + 341; -pub const SYS_syncfs: ::c_long = 4000 + 342; -pub const SYS_sendmmsg: ::c_long = 4000 + 343; -pub const SYS_setns: ::c_long = 4000 + 344; -pub const SYS_process_vm_readv: ::c_long = 4000 + 345; -pub const SYS_process_vm_writev: ::c_long = 4000 + 346; -pub const SYS_kcmp: ::c_long = 4000 + 347; -pub const SYS_finit_module: ::c_long = 4000 + 348; -pub const SYS_sched_setattr: ::c_long = 4000 + 349; -pub const SYS_sched_getattr: ::c_long = 4000 + 350; -pub const SYS_renameat2: ::c_long = 4000 + 351; -pub const SYS_seccomp: ::c_long = 4000 + 352; -pub const SYS_getrandom: ::c_long = 4000 + 353; -pub const SYS_memfd_create: ::c_long = 4000 + 354; -pub const SYS_bpf: ::c_long = 4000 + 355; -pub const SYS_execveat: ::c_long = 4000 + 356; -pub const SYS_userfaultfd: ::c_long = 4000 + 357; -pub const SYS_membarrier: ::c_long = 4000 + 358; -pub const SYS_mlock2: ::c_long = 4000 + 359; -pub const SYS_copy_file_range: ::c_long = 4000 + 360; -pub const SYS_preadv2: ::c_long = 4000 + 361; -pub const SYS_pwritev2: ::c_long = 4000 + 362; -pub const SYS_pkey_mprotect: ::c_long = 4000 + 363; -pub const SYS_pkey_alloc: ::c_long = 4000 + 364; -pub const SYS_pkey_free: ::c_long = 4000 + 365; - -#[link(name = "util")] -extern { - pub fn sysctl(name: *mut ::c_int, - namelen: ::c_int, - oldp: *mut ::c_void, - oldlenp: *mut ::size_t, - newp: *mut ::c_void, - newlen: ::size_t) - -> ::c_int; - pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; - pub fn backtrace(buf: *mut *mut ::c_void, - sz: ::c_int) -> ::c_int; - pub fn glob64(pattern: *const ::c_char, - flags: ::c_int, - errfunc: ::dox::Option ::c_int>, - pglob: *mut glob64_t) -> ::c_int; - pub fn globfree64(pglob: *mut glob64_t); - pub fn ptrace(request: ::c_uint, ...) -> ::c_long; - pub fn pthread_attr_getaffinity_np(attr: *const ::pthread_attr_t, - cpusetsize: ::size_t, - cpuset: *mut ::cpu_set_t) -> ::c_int; - pub fn pthread_attr_setaffinity_np(attr: *mut ::pthread_attr_t, - cpusetsize: ::size_t, - cpuset: *const ::cpu_set_t) -> ::c_int; -} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 32], + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/mod.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,213 @@ +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = u64; +pub type nlink_t = u64; +pub type off_t = i64; +pub type rlim_t = ::c_ulong; +pub type suseconds_t = i64; +pub type time_t = i64; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_ulong; 1], + pub st_size: ::off_t, + st_pad3: ::c_long, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad4: ::c_long, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 7], + } + + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + pub st_ino: ::ino64_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + pub st_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 7], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __size: [::c_ulong; 16], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } +} + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; + +pub const RLIM_INFINITY: ::rlim_t = 0xffff_ffff_ffff_ffff; + +pub const SYS_gettid: ::c_long = 5178; // Valid for n64 + +#[link(name = "util")] +extern { + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/no_align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,8 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} + diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mips/mips64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mips/mips64.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -pub type blkcnt_t = i64; -pub type blksize_t = i64; -pub type c_char = i8; -pub type c_long = i64; -pub type c_ulong = u64; -pub type fsblkcnt_t = ::c_ulong; -pub type fsfilcnt_t = ::c_ulong; -pub type ino_t = u64; -pub type nlink_t = u64; -pub type off_t = i64; -pub type rlim_t = ::c_ulong; -pub type suseconds_t = i64; -pub type time_t = i64; -pub type wchar_t = i32; - -s! { - pub struct stat { - pub st_dev: ::c_ulong, - st_pad1: [::c_long; 2], - pub st_ino: ::ino_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::c_ulong, - st_pad2: [::c_ulong; 1], - pub st_size: ::off_t, - st_pad3: ::c_long, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - st_pad4: ::c_long, - pub st_blocks: ::blkcnt_t, - st_pad5: [::c_long; 7], - } - - pub struct stat64 { - pub st_dev: ::c_ulong, - st_pad1: [::c_long; 2], - pub st_ino: ::ino64_t, - pub st_mode: ::mode_t, - pub st_nlink: ::nlink_t, - pub st_uid: ::uid_t, - pub st_gid: ::gid_t, - pub st_rdev: ::c_ulong, - st_pad2: [::c_long; 2], - pub st_size: ::off64_t, - pub st_atime: ::time_t, - pub st_atime_nsec: ::c_long, - pub st_mtime: ::time_t, - pub st_mtime_nsec: ::c_long, - pub st_ctime: ::time_t, - pub st_ctime_nsec: ::c_long, - pub st_blksize: ::blksize_t, - st_pad3: ::c_long, - pub st_blocks: ::blkcnt64_t, - st_pad5: [::c_long; 7], - } - - pub struct pthread_attr_t { - __size: [::c_ulong; 7] - } - - pub struct sigaction { - pub sa_flags: ::c_int, - pub sa_sigaction: ::sighandler_t, - pub sa_mask: sigset_t, - _restorer: *mut ::c_void, - } - - pub struct stack_t { - pub ss_sp: *mut ::c_void, - pub ss_size: ::size_t, - pub ss_flags: ::c_int, - } - - pub struct sigset_t { - __size: [::c_ulong; 16], - } - - pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_code: ::c_int, - pub si_errno: ::c_int, - _pad: ::c_int, - _pad2: [::c_long; 14], - } - - pub struct ipc_perm { - pub __key: ::key_t, - pub uid: ::uid_t, - pub gid: ::gid_t, - pub cuid: ::uid_t, - pub cgid: ::gid_t, - pub mode: ::c_uint, - pub __seq: ::c_ushort, - __pad1: ::c_ushort, - __unused1: ::c_ulong, - __unused2: ::c_ulong - } - - pub struct shmid_ds { - pub shm_perm: ::ipc_perm, - pub shm_segsz: ::size_t, - pub shm_atime: ::time_t, - pub shm_dtime: ::time_t, - pub shm_ctime: ::time_t, - pub shm_cpid: ::pid_t, - pub shm_lpid: ::pid_t, - pub shm_nattch: ::shmatt_t, - __unused4: ::c_ulong, - __unused5: ::c_ulong - } - - pub struct msqid_ds { - pub msg_perm: ::ipc_perm, - pub msg_stime: ::time_t, - pub msg_rtime: ::time_t, - pub msg_ctime: ::time_t, - __msg_cbytes: ::c_ulong, - pub msg_qnum: ::msgqnum_t, - pub msg_qbytes: ::msglen_t, - pub msg_lspid: ::pid_t, - pub msg_lrpid: ::pid_t, - __glibc_reserved4: ::c_ulong, - __glibc_reserved5: ::c_ulong, - } - - pub struct statfs { - pub f_type: ::c_long, - pub f_bsize: ::c_long, - pub f_frsize: ::c_long, - pub f_blocks: ::fsblkcnt_t, - pub f_bfree: ::fsblkcnt_t, - pub f_files: ::fsblkcnt_t, - pub f_ffree: ::fsblkcnt_t, - pub f_bavail: ::fsblkcnt_t, - pub f_fsid: ::fsid_t, - - pub f_namelen: ::c_long, - f_spare: [::c_long; 6], - } - - pub struct msghdr { - pub msg_name: *mut ::c_void, - pub msg_namelen: ::socklen_t, - pub msg_iov: *mut ::iovec, - pub msg_iovlen: ::size_t, - pub msg_control: *mut ::c_void, - pub msg_controllen: ::size_t, - pub msg_flags: ::c_int, - } - - pub struct cmsghdr { - pub cmsg_len: ::size_t, - pub cmsg_level: ::c_int, - pub cmsg_type: ::c_int, - } - - pub struct termios { - pub c_iflag: ::tcflag_t, - pub c_oflag: ::tcflag_t, - pub c_cflag: ::tcflag_t, - pub c_lflag: ::tcflag_t, - pub c_line: ::cc_t, - pub c_cc: [::cc_t; ::NCCS], - } - - pub struct sysinfo { - pub uptime: ::c_long, - pub loads: [::c_ulong; 3], - pub totalram: ::c_ulong, - pub freeram: ::c_ulong, - pub sharedram: ::c_ulong, - pub bufferram: ::c_ulong, - pub totalswap: ::c_ulong, - pub freeswap: ::c_ulong, - pub procs: ::c_ushort, - pub pad: ::c_ushort, - pub totalhigh: ::c_ulong, - pub freehigh: ::c_ulong, - pub mem_unit: ::c_uint, - pub _f: [::c_char; 0], - } - - // FIXME this is actually a union - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } -} - -pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; -pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; -pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; - -pub const RLIM_INFINITY: ::rlim_t = 0xffff_ffff_ffff_ffff; - -pub const SYS_gettid: ::c_long = 5178; // Valid for n64 - -#[link(name = "util")] -extern { - pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; -} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/mod.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,3 @@ -use dox::{mem, Option}; - pub type sa_family_t = u16; pub type pthread_key_t = ::c_uint; pub type speed_t = ::c_uint; @@ -24,11 +22,30 @@ pub type nl_item = ::c_int; pub type idtype_t = ::c_uint; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos64_t {} // TODO: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + pub struct sockaddr { pub sa_family: sa_family_t, pub sa_data: [::c_char; 14], @@ -49,20 +66,6 @@ pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108] - } - - pub struct sockaddr_storage { - pub ss_family: sa_family_t, - __ss_align: ::size_t, - #[cfg(target_pointer_width = "32")] - __ss_pad2: [u8; 128 - 2 * 4], - #[cfg(target_pointer_width = "64")] - __ss_pad2: [u8; 128 - 2 * 8], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -123,23 +126,6 @@ pub dli_saddr: *mut ::c_void, } - #[cfg_attr(any(all(target_arch = "x86", - target_arch = "x86_64")), - repr(packed))] - pub struct epoll_event { - pub events: ::uint32_t, - pub u64: ::uint64_t, - } - - pub struct utsname { - pub sysname: [::c_char; 65], - pub nodename: [::c_char; 65], - pub release: [::c_char; 65], - pub version: [::c_char; 65], - pub machine: [::c_char; 65], - pub domainname: [::c_char; 65] - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -180,22 +166,6 @@ __unused1: [::c_int; 12] } - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - pub struct rlimit64 { pub rlim_cur: rlim64_t, pub rlim_max: rlim64_t, @@ -224,103 +194,11 @@ pub ifa_data: *mut ::c_void } - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_mutex_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_rwlock_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))), - repr(align(8)))] - pub struct pthread_mutexattr_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")))] - __align: [::c_int; 0], - #[cfg(all(not(feature = "align"), - not(any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - pub struct pthread_rwlockattr_t { __lockkind: ::c_int, __pshared: ::c_int, } - #[cfg_attr(feature = "align", repr(align(8)))] - pub struct pthread_cond_t { - #[cfg(not(feature = "align"))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - pub struct passwd { pub pw_name: *mut ::c_char, pub pw_passwd: *mut ::c_char, @@ -436,6 +314,62 @@ } } +s_no_extra_traits! { + #[cfg_attr( + any(target_arch = "x86", target_arch = "x86_64"), + repr(packed) + )] + #[allow(missing_debug_implementations)] + pub struct epoll_event { + pub events: ::uint32_t, + pub u64: ::uint64_t, + } + + #[allow(missing_debug_implementations)] + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + #[allow(missing_debug_implementations)] + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_align: ::size_t, + #[cfg(target_pointer_width = "32")] + __ss_pad2: [u8; 128 - 2 * 4], + #[cfg(target_pointer_width = "64")] + __ss_pad2: [u8; 128 - 2 * 8], + } + + #[allow(missing_debug_implementations)] + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + #[allow(missing_debug_implementations)] + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + #[allow(missing_debug_implementations)] + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } +} + // intentionally not public, only used for fd_set cfg_if! { if #[cfg(target_pointer_width = "32")] { @@ -1459,20 +1393,20 @@ f! { pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] &= !(1 << (fd % size)); return } pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 } pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { let fd = fd as usize; - let size = mem::size_of_val(&(*set).fds_bits[0]) * 8; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; (*set).fds_bits[fd / size] |= 1 << (fd % size); return } @@ -1522,21 +1456,23 @@ } pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] |= 1 << offset; () } pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); cpuset.bits[idx] &= !(1 << offset); () } pub fn CPU_ISSET(cpu: usize, cpuset: &cpu_set_t) -> bool { - let size_in_bits = 8 * mem::size_of_val(&cpuset.bits[0]); + let size_in_bits = 8 * ::mem::size_of_val(&cpuset.bits[0]); let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); 0 != (cpuset.bits[idx] & (1 << offset)) } @@ -1551,6 +1487,12 @@ } extern { + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, + pshared: ::c_int, + value: ::c_uint) + -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; pub fn atof(s: *const ::c_char) -> ::c_double; pub fn labs(i: ::c_long) -> ::c_long; @@ -1857,7 +1799,7 @@ pub fn glob(pattern: *const c_char, flags: ::c_int, - errfunc: Option ::c_int>, pglob: *mut ::glob_t) -> ::c_int; pub fn globfree(pglob: *mut ::glob_t); @@ -1895,7 +1837,7 @@ pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")] - pub fn getgrgid_r(uid: ::uid_t, + pub fn getgrgid_r(gid: ::gid_t, grp: *mut ::group, buf: *mut ::c_char, buflen: ::size_t, @@ -1941,9 +1883,9 @@ #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")] pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; - pub fn pthread_atfork(prepare: Option, - parent: Option, - child: Option) -> ::c_int; + pub fn pthread_atfork(prepare: ::Option, + parent: ::Option, + child: ::Option) -> ::c_int; pub fn pthread_create(native: *mut ::pthread_t, attr: *const ::pthread_attr_t, f: extern fn(*mut ::c_void) -> *mut ::c_void, @@ -1963,8 +1905,22 @@ } else if #[cfg(target_arch = "x86_64")] { mod x86_64; pub use self::x86_64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; } else { pub use unsupported_target; } } +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} + +expand_align!(); diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/no_align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,53 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(any(libc_align, + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any( + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,77 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { // ToDo + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } + + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { // ToDo + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { // ToDo + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(all(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))), + repr(align(8)))] + #[allow(missing_debug_implementations)] + pub struct pthread_mutex_t { // ToDo + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct pthread_cond_t { // ToDo + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + #[allow(missing_debug_implementations)] + pub struct pthread_rwlock_t { // ToDo + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/l4re.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/l4re.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/l4re.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/l4re.rs 2019-05-15 11:26:24.000000000 +0000 @@ -27,6 +27,7 @@ } #[cfg(target_os = "l4re")] +#[allow(missing_debug_implementations)] pub struct pthread_attr_t { pub __detachstate: ::c_int, pub __schedpolicy: ::c_int, diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/mod.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/mod.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,4 @@ //! Definitions for uclibc on 64bit systems -//! pub type blkcnt_t = i64; pub type blksize_t = i64; pub type clock_t = i64; @@ -20,25 +19,7 @@ pub type time_t = ::c_int; pub type wchar_t = ::c_int; -pub type nfds_t = ::c_ulong; - s! { - pub struct dirent { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: u16, - pub d_type: u8, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: u16, - pub d_type: u8, - pub d_name: [::c_char; 256], - } - pub struct ipc_perm { pub __key: ::key_t, pub uid: ::uid_t, @@ -133,7 +114,7 @@ // // pub struct in6_addr { // pub s6_addr: [u8; 16], -// #[cfg(not(feature = "align"))] +// #[cfg(not(libc_align))] // __align: [u32; 0], // } @@ -205,111 +186,6 @@ pub c_cc: [::cc_t; ::NCCS], } - #[cfg_attr(all(feature = "align", target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", target_pointer_width = "64"), - repr(align(8)))] - pub struct sem_t { // ToDo - #[cfg(target_pointer_width = "32")] - __size: [::c_char; 16], - #[cfg(target_pointer_width = "64")] - __size: [::c_char; 32], - #[cfg(not(feature = "align"))] - __align: [::c_long; 0], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_mutex_t { // ToDo - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(any(target_pointer_width = "32", - target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))), - repr(align(8)))] - pub struct pthread_mutexattr_t { // ToDo - #[cfg(all(not(feature = "align"), - any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64")))] - __align: [::c_int; 0], - #[cfg(all(not(feature = "align"), - not(any(target_arch = "x86_64", target_arch = "powerpc64", - target_arch = "mips64", target_arch = "s390x", - target_arch = "sparc64"))))] - __align: [::c_long; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], - } - - #[cfg_attr(feature = "align", repr(align(8)))] - pub struct pthread_cond_t { // ToDo - #[cfg(not(feature = "align"))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - - #[cfg_attr(feature = "align", repr(align(4)))] - pub struct pthread_condattr_t { // ToDo - #[cfg(not(feature = "align"))] - __align: [::c_int; 0], - size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))), - repr(align(8)))] - pub struct pthread_rwlock_t { // ToDo - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - pub struct sigset_t { // ToDo __val: [::c_ulong; 16], } @@ -360,6 +236,25 @@ } } +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct dirent { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_name: [::c_char; 256], + } + #[allow(missing_debug_implementations)] + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_name: [::c_char; 256], + } +} + // constants pub const EADDRINUSE: ::c_int = 98; // Address already in use pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address @@ -380,7 +275,6 @@ pub const O_TRUNC: ::c_int = 01000; pub const NCCS: usize = 32; pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals -pub const PTHREAD_STACK_MIN: usize = 16384; pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; pub const SO_BROADCAST: ::c_int = 6; @@ -391,19 +285,11 @@ pub const SO_RCVTIMEO: ::c_int = 20; pub const SO_REUSEADDR: ::c_int = 2; pub const SO_SNDTIMEO: ::c_int = 21; -pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; -pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; -pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; -pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; pub const RLIM_INFINITY: u64 = 0xffffffffffffffff; pub const __SIZEOF_PTHREAD_COND_T: usize = 48; pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; -extern { - pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; -} - cfg_if! { if #[cfg(target_os = "l4re")] { mod l4re; @@ -414,3 +300,13 @@ } } +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/no_align.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/no_align.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/no_align.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/no_align.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,59 @@ +macro_rules! expand_align { + () => { + s! { + pub struct sem_t { // ToDo + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } + + pub struct pthread_mutex_t { // ToDo + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_mutexattr_t { // ToDo + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { // ToDo + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { // ToDo + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + + pub struct pthread_rwlock_t { // ToDo + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + } + } +} diff -Nru cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/other.rs cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/other.rs --- cargo-0.33.0/vendor/libc/src/unix/uclibc/x86_64/other.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/unix/uclibc/x86_64/other.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,3 +2,4 @@ // separate module pub type pthread_t = ::c_ulong; +pub const PTHREAD_STACK_MIN: usize = 16384; diff -Nru cargo-0.33.0/vendor/libc/src/wasi.rs cargo-0.35.0/vendor/libc/src/wasi.rs --- cargo-0.33.0/vendor/libc/src/wasi.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/wasi.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1318 @@ +pub use ffi::c_void; + +pub type c_char = i8; +pub type c_uchar = u8; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type size_t = usize; +pub type ssize_t = isize; +pub type off_t = i64; +pub type pid_t = i32; +pub type int8_t = i8; +pub type uint8_t = u8; +pub type int16_t = i16; +pub type uint16_t = u16; +pub type int32_t = i32; +pub type uint32_t = u32; +pub type int64_t = i64; +pub type uint64_t = u64; +pub type clock_t = c_longlong; +pub type time_t = c_longlong; +pub type c_double = f64; +pub type c_float = f32; +pub type ino_t = u64; +pub type sigset_t = c_uchar; +pub type suseconds_t = c_longlong; +pub type mode_t = u32; +pub type dev_t = u64; +pub type uid_t = u32; +pub type gid_t = u32; +pub type nlink_t = u64; +pub type blksize_t = c_long; +pub type blkcnt_t = i64; +pub type nfds_t = c_ulong; + +pub type __wasi_advice_t = u8; +pub type __wasi_clockid_t = u32; +pub type __wasi_device_t = u64; +pub type __wasi_dircookie_t = u64; +pub type __wasi_errno_t = u16; +pub type __wasi_eventrwflags_t = u16; +pub type __wasi_eventtype_t = u8; +pub type __wasi_exitcode_t = u32; +pub type __wasi_fd_t = u32; +pub type __wasi_fdflags_t = u16; +pub type __wasi_filedelta_t = i64; +pub type __wasi_filesize_t = u64; +pub type __wasi_filetype_t = u8; +pub type __wasi_fstflags_t = u16; +pub type __wasi_inode_t = u64; +pub type __wasi_linkcount_t = u32; +pub type __wasi_lookupflags_t = u32; +pub type __wasi_oflags_t = u16; +pub type __wasi_riflags_t = u16; +pub type __wasi_rights_t = u64; +pub type __wasi_roflags_t = u16; +pub type __wasi_sdflags_t = u8; +pub type __wasi_siflags_t = u16; +pub type __wasi_signal_t = u8; +pub type __wasi_subclockflags_t = u16; +pub type __wasi_timestamp_t = u64; +pub type __wasi_userdata_t = u64; +pub type __wasi_whence_t = u8; +pub type __wasi_preopentype_t = u8; + +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum FILE {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum __locale_struct {} + +pub type locale_t = *mut __locale_struct; + +s! { + #[repr(align(8))] + pub struct fpos_t { + data: [u8; 16], + } + + pub struct tm { + pub tm_sec: c_int, + pub tm_min: c_int, + pub tm_hour: c_int, + pub tm_mday: c_int, + pub tm_mon: c_int, + pub tm_year: c_int, + pub tm_wday: c_int, + pub tm_yday: c_int, + pub tm_isdst: c_int, + pub __tm_gmtoff: c_int, + pub __tm_zone: *const c_char, + pub __tm_nsec: c_int, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + pub struct tms { + pub tms_utime: clock_t, + pub tms_stime: clock_t, + pub tms_cutime: clock_t, + pub tms_cstime: clock_t, + } + + pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, + } + + pub struct iovec { + pub iov_base: *mut c_void, + pub iov_len: size_t, + } + + pub struct lconv { + pub decimal_point: *mut c_char, + pub thousands_sep: *mut c_char, + pub grouping: *mut c_char, + pub int_curr_symbol: *mut c_char, + pub currency_symbol: *mut c_char, + pub mon_decimal_point: *mut c_char, + pub mon_thousands_sep: *mut c_char, + pub mon_grouping: *mut c_char, + pub positive_sign: *mut c_char, + pub negative_sign: *mut c_char, + pub int_frac_digits: c_char, + pub frac_digits: c_char, + pub p_cs_precedes: c_char, + pub p_sep_by_space: c_char, + pub n_cs_precedes: c_char, + pub n_sep_by_space: c_char, + pub p_sign_posn: c_char, + pub n_sign_posn: c_char, + pub int_p_cs_precedes: c_char, + pub int_p_sep_by_space: c_char, + pub int_n_cs_precedes: c_char, + pub int_n_sep_by_space: c_char, + pub int_p_sign_posn: c_char, + pub int_n_sign_posn: c_char, + } + + pub struct pollfd { + pub fd: c_int, + pub events: c_short, + pub revents: c_short, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + } + + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_nlink: nlink_t, + pub st_mode: mode_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + __pad0: c_uint, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + __reserved: [c_longlong; 3], + } + + pub struct __wasi_dirent_t { + pub d_next: __wasi_dircookie_t, + pub d_ino: __wasi_inode_t, + pub d_namlen: u32, + pub d_type: __wasi_filetype_t, + } + + pub struct __wasi_event_u_fd_readwrite_t { + pub nbytes: __wasi_filesize_t, + pub flags: __wasi_eventrwflags_t, + } + + pub struct __wasi_fdstat_t { + pub fs_filetype: __wasi_filetype_t, + pub fs_flags: __wasi_fdflags_t, + pub fs_rights_base: __wasi_rights_t, + pub fs_rights_inheriting: __wasi_rights_t, + } + + pub struct __wasi_filestat_t { + pub st_dev: __wasi_device_t, + pub st_ino: __wasi_inode_t, + pub st_filetype: __wasi_filetype_t, + pub st_nlink: __wasi_linkcount_t, + pub st_size: __wasi_filesize_t, + pub st_atim: __wasi_timestamp_t, + pub st_mtim: __wasi_timestamp_t, + pub st_ctim: __wasi_timestamp_t, + } + + pub struct __wasi_ciovec_t { + pub buf: *const ::c_void, + pub buf_len: size_t, + } + + pub struct __wasi_iovec_t { + pub buf: *mut ::c_void, + pub buf_len: size_t, + } + + pub struct __wasi_subscription_u_clock_t { + pub identifier: __wasi_userdata_t, + pub clock_id: __wasi_clockid_t, + pub timeout: __wasi_timestamp_t, + pub precision: __wasi_timestamp_t, + pub flags: __wasi_subclockflags_t, + } + + pub struct __wasi_subscription_u_fd_readwrite_t { + pub fd: __wasi_fd_t, + } + + pub struct __wasi_prestat_u_dir_t { + pub pr_name_len: size_t, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct __wasi_subscription_t { + pub userdata: __wasi_userdata_t, + pub type_: __wasi_eventtype_t, + pub u: __wasi_subscription_u, + } + + #[allow(missing_debug_implementations)] + pub struct __wasi_event_t { + pub userdata: __wasi_userdata_t, + pub error: __wasi_errno_t, + pub type_: __wasi_eventtype_t, + pub u: __wasi_event_u, + } + + #[allow(missing_debug_implementations)] + pub union __wasi_event_u { + pub fd_readwrite: __wasi_event_u_fd_readwrite_t, + _bindgen_union_align: [u64; 2], + } + + #[allow(missing_debug_implementations)] + pub union __wasi_subscription_u { + pub clock: __wasi_subscription_u_clock_t, + pub fd_readwrite: + __wasi_subscription_u_fd_readwrite_t, + _bindgen_union_align: [u64; 5], + } + + #[allow(missing_debug_implementations)] + pub struct __wasi_prestat_t { + pub pr_type: __wasi_preopentype_t, + pub u: __wasi_prestat_u, + } + + #[allow(missing_debug_implementations)] + pub union __wasi_prestat_u { + pub dir: __wasi_prestat_u_dir_t, + } + +} + +// Declare dirent outside of s! so that it doesn't implement Copy, Eq, Hash, +// etc., since it contains a flexible array member with a dynamic size. +#[repr(C)] +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub struct dirent { + pub d_ino: ino_t, + pub d_type: c_uchar, + /// d_name is declared in WASI libc as a flexible array member, which + /// can't be directly expressed in Rust. As an imperfect workaround, + /// declare it as a zero-length array instead. + pub d_name: [c_char; 0], +} + +pub const EXIT_SUCCESS: c_int = 0; +pub const EXIT_FAILURE: c_int = 1; +pub const STDIN_FILENO: c_int = 0; +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; +pub const SEEK_SET: c_int = 2; +pub const SEEK_CUR: c_int = 0; +pub const SEEK_END: c_int = 1; +pub const _IOFBF: c_int = 0; +pub const _IONBF: c_int = 2; +pub const _IOLBF: c_int = 1; +pub const FD_SETSIZE: size_t = 1024; +pub const O_APPEND: c_int = __WASI_FDFLAG_APPEND as c_int; +pub const O_DSYNC: c_int = __WASI_FDFLAG_DSYNC as c_int; +pub const O_NONBLOCK: c_int = __WASI_FDFLAG_NONBLOCK as c_int; +pub const O_RSYNC: c_int = __WASI_FDFLAG_RSYNC as c_int; +pub const O_SYNC: c_int = __WASI_FDFLAG_SYNC as c_int; +pub const O_CREAT: c_int = (__WASI_O_CREAT as c_int) << 12; +pub const O_DIRECTORY: c_int = (__WASI_O_DIRECTORY as c_int) << 12; +pub const O_EXCL: c_int = (__WASI_O_EXCL as c_int) << 12; +pub const O_TRUNC: c_int = (__WASI_O_TRUNC as c_int) << 12; +pub const O_NOFOLLOW: c_int = 0x01000000; +pub const O_EXEC: c_int = 0x02000000; +pub const O_RDONLY: c_int = 0x04000000; +pub const O_SEARCH: c_int = 0x08000000; +pub const O_WRONLY: c_int = 0x10000000; +pub const O_RDWR: c_int = O_WRONLY | O_RDONLY; +pub const O_ACCMODE: c_int = O_EXEC | O_RDWR | O_SEARCH; +pub const POSIX_FADV_DONTNEED: c_int = __WASI_ADVICE_DONTNEED as c_int; +pub const POSIX_FADV_NOREUSE: c_int = __WASI_ADVICE_NOREUSE as c_int; +pub const POSIX_FADV_NORMAL: c_int = __WASI_ADVICE_NORMAL as c_int; +pub const POSIX_FADV_RANDOM: c_int = __WASI_ADVICE_RANDOM as c_int; +pub const POSIX_FADV_SEQUENTIAL: c_int = __WASI_ADVICE_SEQUENTIAL as c_int; +pub const POSIX_FADV_WILLNEED: c_int = __WASI_ADVICE_WILLNEED as c_int; +pub const AT_EACCESS: c_int = 0x0; +pub const AT_SYMLINK_NOFOLLOW: c_int = 0x1; +pub const AT_SYMLINK_FOLLOW: c_int = 0x2; +pub const AT_REMOVEDIR: c_int = 0x4; + +pub const E2BIG: c_int = __WASI_E2BIG as c_int; +pub const EACCES: c_int = __WASI_EACCES as c_int; +pub const EADDRINUSE: c_int = __WASI_EADDRINUSE as c_int; +pub const EADDRNOTAVAIL: c_int = __WASI_EADDRNOTAVAIL as c_int; +pub const EAFNOSUPPORT: c_int = __WASI_EAFNOSUPPORT as c_int; +pub const EAGAIN: c_int = __WASI_EAGAIN as c_int; +pub const EALREADY: c_int = __WASI_EALREADY as c_int; +pub const EBADF: c_int = __WASI_EBADF as c_int; +pub const EBADMSG: c_int = __WASI_EBADMSG as c_int; +pub const EBUSY: c_int = __WASI_EBUSY as c_int; +pub const ECANCELED: c_int = __WASI_ECANCELED as c_int; +pub const ECHILD: c_int = __WASI_ECHILD as c_int; +pub const ECONNABORTED: c_int = __WASI_ECONNABORTED as c_int; +pub const ECONNREFUSED: c_int = __WASI_ECONNREFUSED as c_int; +pub const ECONNRESET: c_int = __WASI_ECONNRESET as c_int; +pub const EDEADLK: c_int = __WASI_EDEADLK as c_int; +pub const EDESTADDRREQ: c_int = __WASI_EDESTADDRREQ as c_int; +pub const EDOM: c_int = __WASI_EDOM as c_int; +pub const EDQUOT: c_int = __WASI_EDQUOT as c_int; +pub const EEXIST: c_int = __WASI_EEXIST as c_int; +pub const EFAULT: c_int = __WASI_EFAULT as c_int; +pub const EFBIG: c_int = __WASI_EFBIG as c_int; +pub const EHOSTUNREACH: c_int = __WASI_EHOSTUNREACH as c_int; +pub const EIDRM: c_int = __WASI_EIDRM as c_int; +pub const EILSEQ: c_int = __WASI_EILSEQ as c_int; +pub const EINPROGRESS: c_int = __WASI_EINPROGRESS as c_int; +pub const EINTR: c_int = __WASI_EINTR as c_int; +pub const EINVAL: c_int = __WASI_EINVAL as c_int; +pub const EIO: c_int = __WASI_EIO as c_int; +pub const EISCONN: c_int = __WASI_EISCONN as c_int; +pub const EISDIR: c_int = __WASI_EISDIR as c_int; +pub const ELOOP: c_int = __WASI_ELOOP as c_int; +pub const EMFILE: c_int = __WASI_EMFILE as c_int; +pub const EMLINK: c_int = __WASI_EMLINK as c_int; +pub const EMSGSIZE: c_int = __WASI_EMSGSIZE as c_int; +pub const EMULTIHOP: c_int = __WASI_EMULTIHOP as c_int; +pub const ENAMETOOLONG: c_int = __WASI_ENAMETOOLONG as c_int; +pub const ENETDOWN: c_int = __WASI_ENETDOWN as c_int; +pub const ENETRESET: c_int = __WASI_ENETRESET as c_int; +pub const ENETUNREACH: c_int = __WASI_ENETUNREACH as c_int; +pub const ENFILE: c_int = __WASI_ENFILE as c_int; +pub const ENOBUFS: c_int = __WASI_ENOBUFS as c_int; +pub const ENODEV: c_int = __WASI_ENODEV as c_int; +pub const ENOENT: c_int = __WASI_ENOENT as c_int; +pub const ENOEXEC: c_int = __WASI_ENOEXEC as c_int; +pub const ENOLCK: c_int = __WASI_ENOLCK as c_int; +pub const ENOLINK: c_int = __WASI_ENOLINK as c_int; +pub const ENOMEM: c_int = __WASI_ENOMEM as c_int; +pub const ENOMSG: c_int = __WASI_ENOMSG as c_int; +pub const ENOPROTOOPT: c_int = __WASI_ENOPROTOOPT as c_int; +pub const ENOSPC: c_int = __WASI_ENOSPC as c_int; +pub const ENOSYS: c_int = __WASI_ENOSYS as c_int; +pub const ENOTCONN: c_int = __WASI_ENOTCONN as c_int; +pub const ENOTDIR: c_int = __WASI_ENOTDIR as c_int; +pub const ENOTEMPTY: c_int = __WASI_ENOTEMPTY as c_int; +pub const ENOTRECOVERABLE: c_int = __WASI_ENOTRECOVERABLE as c_int; +pub const ENOTSOCK: c_int = __WASI_ENOTSOCK as c_int; +pub const ENOTSUP: c_int = __WASI_ENOTSUP as c_int; +pub const ENOTTY: c_int = __WASI_ENOTTY as c_int; +pub const ENXIO: c_int = __WASI_ENXIO as c_int; +pub const EOVERFLOW: c_int = __WASI_EOVERFLOW as c_int; +pub const EOWNERDEAD: c_int = __WASI_EOWNERDEAD as c_int; +pub const EPERM: c_int = __WASI_EPERM as c_int; +pub const EPIPE: c_int = __WASI_EPIPE as c_int; +pub const EPROTO: c_int = __WASI_EPROTO as c_int; +pub const EPROTONOSUPPORT: c_int = __WASI_EPROTONOSUPPORT as c_int; +pub const EPROTOTYPE: c_int = __WASI_EPROTOTYPE as c_int; +pub const ERANGE: c_int = __WASI_ERANGE as c_int; +pub const EROFS: c_int = __WASI_EROFS as c_int; +pub const ESPIPE: c_int = __WASI_ESPIPE as c_int; +pub const ESRCH: c_int = __WASI_ESRCH as c_int; +pub const ESTALE: c_int = __WASI_ESTALE as c_int; +pub const ETIMEDOUT: c_int = __WASI_ETIMEDOUT as c_int; +pub const ETXTBSY: c_int = __WASI_ETXTBSY as c_int; +pub const EXDEV: c_int = __WASI_EXDEV as c_int; +pub const ENOTCAPABLE: c_int = __WASI_ENOTCAPABLE as c_int; +pub const EOPNOTSUPP: c_int = ENOTSUP; +pub const EWOULDBLOCK: c_int = EAGAIN; + +pub const __WASI_ADVICE_NORMAL: u8 = 0; +pub const __WASI_ADVICE_SEQUENTIAL: u8 = 1; +pub const __WASI_ADVICE_RANDOM: u8 = 2; +pub const __WASI_ADVICE_WILLNEED: u8 = 3; +pub const __WASI_ADVICE_DONTNEED: u8 = 4; +pub const __WASI_ADVICE_NOREUSE: u8 = 5; +pub const __WASI_CLOCK_REALTIME: u32 = 0; +pub const __WASI_CLOCK_MONOTONIC: u32 = 1; +pub const __WASI_CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const __WASI_CLOCK_THREAD_CPUTIME_ID: u32 = 3; +pub const __WASI_DIRCOOKIE_START: u64 = 0; +pub const __WASI_ESUCCESS: u16 = 0; +pub const __WASI_E2BIG: u16 = 1; +pub const __WASI_EACCES: u16 = 2; +pub const __WASI_EADDRINUSE: u16 = 3; +pub const __WASI_EADDRNOTAVAIL: u16 = 4; +pub const __WASI_EAFNOSUPPORT: u16 = 5; +pub const __WASI_EAGAIN: u16 = 6; +pub const __WASI_EALREADY: u16 = 7; +pub const __WASI_EBADF: u16 = 8; +pub const __WASI_EBADMSG: u16 = 9; +pub const __WASI_EBUSY: u16 = 10; +pub const __WASI_ECANCELED: u16 = 11; +pub const __WASI_ECHILD: u16 = 12; +pub const __WASI_ECONNABORTED: u16 = 13; +pub const __WASI_ECONNREFUSED: u16 = 14; +pub const __WASI_ECONNRESET: u16 = 15; +pub const __WASI_EDEADLK: u16 = 16; +pub const __WASI_EDESTADDRREQ: u16 = 17; +pub const __WASI_EDOM: u16 = 18; +pub const __WASI_EDQUOT: u16 = 19; +pub const __WASI_EEXIST: u16 = 20; +pub const __WASI_EFAULT: u16 = 21; +pub const __WASI_EFBIG: u16 = 22; +pub const __WASI_EHOSTUNREACH: u16 = 23; +pub const __WASI_EIDRM: u16 = 24; +pub const __WASI_EILSEQ: u16 = 25; +pub const __WASI_EINPROGRESS: u16 = 26; +pub const __WASI_EINTR: u16 = 27; +pub const __WASI_EINVAL: u16 = 28; +pub const __WASI_EIO: u16 = 29; +pub const __WASI_EISCONN: u16 = 30; +pub const __WASI_EISDIR: u16 = 31; +pub const __WASI_ELOOP: u16 = 32; +pub const __WASI_EMFILE: u16 = 33; +pub const __WASI_EMLINK: u16 = 34; +pub const __WASI_EMSGSIZE: u16 = 35; +pub const __WASI_EMULTIHOP: u16 = 36; +pub const __WASI_ENAMETOOLONG: u16 = 37; +pub const __WASI_ENETDOWN: u16 = 38; +pub const __WASI_ENETRESET: u16 = 39; +pub const __WASI_ENETUNREACH: u16 = 40; +pub const __WASI_ENFILE: u16 = 41; +pub const __WASI_ENOBUFS: u16 = 42; +pub const __WASI_ENODEV: u16 = 43; +pub const __WASI_ENOENT: u16 = 44; +pub const __WASI_ENOEXEC: u16 = 45; +pub const __WASI_ENOLCK: u16 = 46; +pub const __WASI_ENOLINK: u16 = 47; +pub const __WASI_ENOMEM: u16 = 48; +pub const __WASI_ENOMSG: u16 = 49; +pub const __WASI_ENOPROTOOPT: u16 = 50; +pub const __WASI_ENOSPC: u16 = 51; +pub const __WASI_ENOSYS: u16 = 52; +pub const __WASI_ENOTCONN: u16 = 53; +pub const __WASI_ENOTDIR: u16 = 54; +pub const __WASI_ENOTEMPTY: u16 = 55; +pub const __WASI_ENOTRECOVERABLE: u16 = 56; +pub const __WASI_ENOTSOCK: u16 = 57; +pub const __WASI_ENOTSUP: u16 = 58; +pub const __WASI_ENOTTY: u16 = 59; +pub const __WASI_ENXIO: u16 = 60; +pub const __WASI_EOVERFLOW: u16 = 61; +pub const __WASI_EOWNERDEAD: u16 = 62; +pub const __WASI_EPERM: u16 = 63; +pub const __WASI_EPIPE: u16 = 64; +pub const __WASI_EPROTO: u16 = 65; +pub const __WASI_EPROTONOSUPPORT: u16 = 66; +pub const __WASI_EPROTOTYPE: u16 = 67; +pub const __WASI_ERANGE: u16 = 68; +pub const __WASI_EROFS: u16 = 69; +pub const __WASI_ESPIPE: u16 = 70; +pub const __WASI_ESRCH: u16 = 71; +pub const __WASI_ESTALE: u16 = 72; +pub const __WASI_ETIMEDOUT: u16 = 73; +pub const __WASI_ETXTBSY: u16 = 74; +pub const __WASI_EXDEV: u16 = 75; +pub const __WASI_ENOTCAPABLE: u16 = 76; +pub const __WASI_EVENT_FD_READWRITE_HANGUP: u16 = 0x0001; +pub const __WASI_EVENTTYPE_CLOCK: u8 = 0; +pub const __WASI_EVENTTYPE_FD_READ: u8 = 1; +pub const __WASI_EVENTTYPE_FD_WRITE: u8 = 2; +pub const __WASI_FDFLAG_APPEND: u16 = 0x0001; +pub const __WASI_FDFLAG_DSYNC: u16 = 0x0002; +pub const __WASI_FDFLAG_NONBLOCK: u16 = 0x0004; +pub const __WASI_FDFLAG_RSYNC: u16 = 0x0008; +pub const __WASI_FDFLAG_SYNC: u16 = 0x0010; +pub const __WASI_FILETYPE_UNKNOWN: u8 = 0; +pub const __WASI_FILETYPE_BLOCK_DEVICE: u8 = 1; +pub const __WASI_FILETYPE_CHARACTER_DEVICE: u8 = 2; +pub const __WASI_FILETYPE_DIRECTORY: u8 = 3; +pub const __WASI_FILETYPE_REGULAR_FILE: u8 = 4; +pub const __WASI_FILETYPE_SOCKET_DGRAM: u8 = 5; +pub const __WASI_FILETYPE_SOCKET_STREAM: u8 = 6; +pub const __WASI_FILETYPE_SYMBOLIC_LINK: u8 = 7; +pub const __WASI_FILESTAT_SET_ATIM: u16 = 0x0001; +pub const __WASI_FILESTAT_SET_ATIM_NOW: u16 = 0x0002; +pub const __WASI_FILESTAT_SET_MTIM: u16 = 0x0004; +pub const __WASI_FILESTAT_SET_MTIM_NOW: u16 = 0x0008; +pub const __WASI_LOOKUP_SYMLINK_FOLLOW: u32 = 0x00000001; +pub const __WASI_O_CREAT: u16 = 0x0001; +pub const __WASI_O_DIRECTORY: u16 = 0x0002; +pub const __WASI_O_EXCL: u16 = 0x0004; +pub const __WASI_O_TRUNC: u16 = 0x0008; +pub const __WASI_PREOPENTYPE_DIR: u8 = 0; +pub const __WASI_SOCK_RECV_PEEK: u16 = 0x0001; +pub const __WASI_SOCK_RECV_WAITALL: u16 = 0x0002; +pub const __WASI_RIGHT_FD_DATASYNC: u64 = 0x0000000000000001; +pub const __WASI_RIGHT_FD_READ: u64 = 0x0000000000000002; +pub const __WASI_RIGHT_FD_SEEK: u64 = 0x0000000000000004; +pub const __WASI_RIGHT_FD_FDSTAT_SET_FLAGS: u64 = 0x0000000000000008; +pub const __WASI_RIGHT_FD_SYNC: u64 = 0x0000000000000010; +pub const __WASI_RIGHT_FD_TELL: u64 = 0x0000000000000020; +pub const __WASI_RIGHT_FD_WRITE: u64 = 0x0000000000000040; +pub const __WASI_RIGHT_FD_ADVISE: u64 = 0x0000000000000080; +pub const __WASI_RIGHT_FD_ALLOCATE: u64 = 0x0000000000000100; +pub const __WASI_RIGHT_PATH_CREATE_DIRECTORY: u64 = 0x0000000000000200; +pub const __WASI_RIGHT_PATH_CREATE_FILE: u64 = 0x0000000000000400; +pub const __WASI_RIGHT_PATH_LINK_SOURCE: u64 = 0x0000000000000800; +pub const __WASI_RIGHT_PATH_LINK_TARGET: u64 = 0x0000000000001000; +pub const __WASI_RIGHT_PATH_OPEN: u64 = 0x0000000000002000; +pub const __WASI_RIGHT_FD_READDIR: u64 = 0x0000000000004000; +pub const __WASI_RIGHT_PATH_READLINK: u64 = 0x0000000000008000; +pub const __WASI_RIGHT_PATH_RENAME_SOURCE: u64 = 0x0000000000010000; +pub const __WASI_RIGHT_PATH_RENAME_TARGET: u64 = 0x0000000000020000; +pub const __WASI_RIGHT_PATH_FILESTAT_GET: u64 = 0x0000000000040000; +pub const __WASI_RIGHT_PATH_FILESTAT_SET_SIZE: u64 = 0x0000000000080000; +pub const __WASI_RIGHT_PATH_FILESTAT_SET_TIMES: u64 = 0x0000000000100000; +pub const __WASI_RIGHT_FD_FILESTAT_GET: u64 = 0x0000000000200000; +pub const __WASI_RIGHT_FD_FILESTAT_SET_SIZE: u64 = 0x0000000000400000; +pub const __WASI_RIGHT_FD_FILESTAT_SET_TIMES: u64 = 0x0000000000800000; +pub const __WASI_RIGHT_PATH_SYMLINK: u64 = 0x0000000001000000; +pub const __WASI_RIGHT_PATH_REMOVE_DIRECTORY: u64 = 0x0000000002000000; +pub const __WASI_RIGHT_PATH_UNLINK_FILE: u64 = 0x0000000004000000; +pub const __WASI_RIGHT_POLL_FD_READWRITE: u64 = 0x0000000008000000; +pub const __WASI_RIGHT_SOCK_SHUTDOWN: u64 = 0x0000000010000000; +pub const __WASI_SOCK_RECV_DATA_TRUNCATED: u16 = 0x0001; +pub const __WASI_SHUT_RD: u8 = 0x01; +pub const __WASI_SHUT_WR: u8 = 0x02; +pub const __WASI_SIGHUP: u8 = 1; +pub const __WASI_SIGINT: u8 = 2; +pub const __WASI_SIGQUIT: u8 = 3; +pub const __WASI_SIGILL: u8 = 4; +pub const __WASI_SIGTRAP: u8 = 5; +pub const __WASI_SIGABRT: u8 = 6; +pub const __WASI_SIGBUS: u8 = 7; +pub const __WASI_SIGFPE: u8 = 8; +pub const __WASI_SIGKILL: u8 = 9; +pub const __WASI_SIGUSR1: u8 = 10; +pub const __WASI_SIGSEGV: u8 = 11; +pub const __WASI_SIGUSR2: u8 = 12; +pub const __WASI_SIGPIPE: u8 = 13; +pub const __WASI_SIGALRM: u8 = 14; +pub const __WASI_SIGTERM: u8 = 15; +pub const __WASI_SIGCHLD: u8 = 16; +pub const __WASI_SIGCONT: u8 = 17; +pub const __WASI_SIGSTOP: u8 = 18; +pub const __WASI_SIGTSTP: u8 = 19; +pub const __WASI_SIGTTIN: u8 = 20; +pub const __WASI_SIGTTOU: u8 = 21; +pub const __WASI_SIGURG: u8 = 22; +pub const __WASI_SIGXCPU: u8 = 23; +pub const __WASI_SIGXFSZ: u8 = 24; +pub const __WASI_SIGVTALRM: u8 = 25; +pub const __WASI_SIGPROF: u8 = 26; +pub const __WASI_SIGWINCH: u8 = 27; +pub const __WASI_SIGPOLL: u8 = 28; +pub const __WASI_SIGPWR: u8 = 29; +pub const __WASI_SIGSYS: u8 = 30; +pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u16 = 0x0001; +pub const __WASI_WHENCE_CUR: u8 = 0; +pub const __WASI_WHENCE_END: u8 = 1; +pub const __WASI_WHENCE_SET: u8 = 2; + +#[cfg_attr( + feature = "rustc-dep-of-std", + link(name = "c", kind = "static", cfg(target_feature = "crt-static")) +)] +#[cfg_attr( + feature = "rustc-dep-of-std", + link(name = "c", cfg(not(target_feature = "crt-static"))) +)] +extern { + pub fn _Exit(code: c_int) -> !; + pub fn _exit(code: c_int) -> !; + pub fn abort() -> !; + pub fn aligned_alloc(a: size_t, b: size_t) -> *mut c_void; + pub fn calloc(amt: size_t, amt2: size_t) -> *mut c_void; + pub fn exit(code: c_int) -> !; + pub fn free(ptr: *mut c_void); + pub fn getenv(s: *const c_char) -> *mut c_char; + pub fn malloc(amt: size_t) -> *mut c_void; + pub fn malloc_usable_size(ptr: *mut c_void) -> size_t; + pub fn rand() -> c_int; + pub fn read(fd: c_int, ptr: *mut c_void, size: size_t) -> ssize_t; + pub fn realloc(ptr: *mut c_void, amt: size_t) -> *mut c_void; + pub fn setenv(k: *const c_char, v: *const c_char, a: c_int) -> c_int; + pub fn unsetenv(k: *const c_char) -> c_int; + pub fn write(fd: c_int, ptr: *const c_void, size: size_t) -> ssize_t; + pub static mut environ: *mut *mut c_char; + pub fn fopen(a: *const c_char, b: *const c_char) -> *mut FILE; + pub fn freopen( + a: *const c_char, + b: *const c_char, + f: *mut FILE, + ) -> *mut FILE; + pub fn fclose(f: *mut FILE) -> c_int; + pub fn remove(a: *const c_char) -> c_int; + pub fn rename(a: *const c_char, b: *const c_char) -> c_int; + pub fn feof(f: *mut FILE) -> c_int; + pub fn ferror(f: *mut FILE) -> c_int; + pub fn fflush(f: *mut FILE) -> c_int; + pub fn clearerr(f: *mut FILE); + pub fn fseek(f: *mut FILE, b: c_long, c: c_int) -> c_int; + pub fn ftell(f: *mut FILE) -> c_long; + pub fn rewind(f: *mut FILE); + pub fn fgetpos(f: *mut FILE, pos: *mut fpos_t) -> c_int; + pub fn fsetpos(f: *mut FILE, pos: *const fpos_t) -> c_int; + pub fn fread( + buf: *mut c_void, + a: size_t, + b: size_t, + f: *mut FILE, + ) -> size_t; + pub fn fwrite( + buf: *const c_void, + a: size_t, + b: size_t, + f: *mut FILE, + ) -> size_t; + pub fn fgetc(f: *mut FILE) -> c_int; + pub fn getc(f: *mut FILE) -> c_int; + pub fn getchar() -> c_int; + pub fn ungetc(a: c_int, f: *mut FILE) -> c_int; + pub fn fputc(a: c_int, f: *mut FILE) -> c_int; + pub fn putc(a: c_int, f: *mut FILE) -> c_int; + pub fn putchar(a: c_int) -> c_int; + pub fn fputs(a: *const c_char, f: *mut FILE) -> c_int; + pub fn puts(a: *const c_char) -> c_int; + pub fn perror(a: *const c_char); + pub fn srand(a: c_uint); + pub fn atexit(a: extern fn()) -> c_int; + pub fn at_quick_exit(a: extern fn()) -> c_int; + pub fn quick_exit(a: c_int) -> !; + pub fn posix_memalign(a: *mut *mut c_void, b: size_t, c: size_t) -> c_int; + pub fn rand_r(a: *mut c_uint) -> c_int; + pub fn random() -> c_long; + pub fn srandom(a: c_uint); + pub fn putenv(a: *mut c_char) -> c_int; + pub fn clock() -> clock_t; + pub fn time(a: *mut time_t) -> time_t; + pub fn difftime(a: time_t, b: time_t) -> c_double; + pub fn mktime(a: *mut tm) -> time_t; + pub fn strftime( + a: *mut c_char, + b: size_t, + c: *const c_char, + d: *const tm, + ) -> size_t; + pub fn gmtime(a: *const time_t) -> *mut tm; + pub fn gmtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + pub fn localtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + pub fn asctime_r(a: *const tm, b: *mut c_char) -> *mut c_char; + pub fn ctime_r(a: *const time_t, b: *mut c_char) -> *mut c_char; + + pub fn nanosleep(a: *const timespec, b: *mut timespec) -> c_int; + // pub fn clock_getres(a: clockid_t, b: *mut timespec) -> c_int; + // pub fn clock_gettime(a: clockid_t, b: *mut timespec) -> c_int; + // pub fn clock_nanosleep( + // a: clockid_t, + // a2: c_int, + // b: *const timespec, + // c: *mut timespec, + // ) -> c_int; + + pub fn isalnum(c: c_int) -> c_int; + pub fn isalpha(c: c_int) -> c_int; + pub fn iscntrl(c: c_int) -> c_int; + pub fn isdigit(c: c_int) -> c_int; + pub fn isgraph(c: c_int) -> c_int; + pub fn islower(c: c_int) -> c_int; + pub fn isprint(c: c_int) -> c_int; + pub fn ispunct(c: c_int) -> c_int; + pub fn isspace(c: c_int) -> c_int; + pub fn isupper(c: c_int) -> c_int; + pub fn isxdigit(c: c_int) -> c_int; + pub fn tolower(c: c_int) -> c_int; + pub fn toupper(c: c_int) -> c_int; + pub fn setvbuf( + stream: *mut FILE, + buffer: *mut c_char, + mode: c_int, + size: size_t, + ) -> c_int; + pub fn setbuf(stream: *mut FILE, buf: *mut c_char); + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) + -> *mut c_char; + pub fn atoi(s: *const c_char) -> c_int; + pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double; + pub fn strtol( + s: *const c_char, + endp: *mut *mut c_char, + base: c_int, + ) -> c_long; + pub fn strtoul( + s: *const c_char, + endp: *mut *mut c_char, + base: c_int, + ) -> c_ulong; + + pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char; + pub fn strncpy( + dst: *mut c_char, + src: *const c_char, + n: size_t, + ) -> *mut c_char; + pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char; + pub fn strncat( + s: *mut c_char, + ct: *const c_char, + n: size_t, + ) -> *mut c_char; + pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp( + s1: *const c_char, + s2: *const c_char, + n: size_t, + ) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + pub fn strerror(n: c_int) -> *mut c_char; + pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char; + pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy( + dest: *mut c_void, + src: *const c_void, + n: size_t, + ) -> *mut c_void; + pub fn memmove( + dest: *mut c_void, + src: *const c_void, + n: size_t, + ) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn fprintf( + stream: *mut ::FILE, + format: *const ::c_char, + ... + ) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf( + s: *mut ::c_char, + n: ::size_t, + format: *const ::c_char, + ... + ) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf( + stream: *mut ::FILE, + format: *const ::c_char, + ... + ) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) + -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::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; + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + + pub fn openat( + dirfd: ::c_int, + pathname: *const ::c_char, + flags: ::c_int, + ... + ) -> ::c_int; + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn mkdirat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + ) -> ::c_int; + pub fn readlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t, + ) -> ::ssize_t; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn close(fd: ::c_int) -> ::c_int; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getopt( + argc: ::c_int, + argv: *const *mut c_char, + optstr: *const c_char, + ) -> ::c_int; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pause() -> ::c_int; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn unlink(c: *const c_char) -> ::c_int; + pub fn pread( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: off_t, + ) -> ::ssize_t; + pub fn pwrite( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off_t, + ) -> ::ssize_t; + + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn fsync(fd: ::c_int) -> ::c_int; + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn strerror_r( + errnum: ::c_int, + buf: *mut c_char, + buflen: ::size_t, + ) -> ::c_int; + + pub fn usleep(secs: ::c_uint) -> ::c_int; + pub fn send( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn recv( + socket: ::c_int, + buf: *mut ::c_void, + len: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn setlocale( + category: ::c_int, + locale: *const ::c_char, + ) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + pub fn readlink( + path: *const c_char, + buf: *mut c_char, + bufsz: ::size_t, + ) -> ::ssize_t; + + pub fn timegm(tm: *mut ::tm) -> time_t; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn fseeko( + stream: *mut ::FILE, + offset: ::off_t, + whence: ::c_int, + ) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + + pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn getline( + lineptr: *mut *mut c_char, + n: *mut size_t, + stream: *mut FILE, + ) -> ssize_t; + + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + pub fn writev( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + ) -> ::ssize_t; + pub fn readv( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + ) -> ::ssize_t; + pub fn pwritev( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn preadv( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn posix_fadvise( + fd: ::c_int, + offset: ::off_t, + len: ::off_t, + advise: ::c_int, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn memrchr( + cx: *const ::c_void, + c: ::c_int, + n: ::size_t, + ) -> *mut ::c_void; + pub fn abs(i: c_int) -> c_int; + pub fn labs(i: c_long) -> c_long; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale( + mask: ::c_int, + locale: *const ::c_char, + base: ::locale_t, + ) -> ::locale_t; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + + pub fn __wasilibc_register_preopened_fd( + fd: c_int, + path: *const c_char, + ) -> c_int; + pub fn __wasilibc_fd_renumber(fd: c_int, newfd: c_int) -> c_int; + pub fn __wasilibc_rmfileat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_rmdirat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_init_preopen(); + pub fn __wasilibc_find_relpath( + path: *const c_char, + rights_base: __wasi_rights_t, + rights_inheriting: __wasi_rights_t, + relative_path: *mut *const c_char, + ) -> c_int; + + pub fn arc4random() -> u32; + pub fn arc4random_buf(a: *mut c_void, b: size_t); + pub fn arc4random_uniform(a: u32) -> u32; +} + +#[link(wasm_import_module = "wasi_unstable")] +extern { + #[link_name = "clock_res_get"] + pub fn __wasi_clock_res_get( + clock_id: __wasi_clockid_t, + resolution: *mut __wasi_timestamp_t, + ) -> __wasi_errno_t; + #[link_name = "clock_time_get"] + pub fn __wasi_clock_time_get( + clock_id: __wasi_clockid_t, + precision: __wasi_timestamp_t, + time: *mut __wasi_timestamp_t, + ) -> __wasi_errno_t; + #[link_name = "fd_close"] + pub fn __wasi_fd_close(fd: __wasi_fd_t) -> __wasi_errno_t; + #[link_name = "fd_datasync"] + pub fn __wasi_fd_datasync(fd: __wasi_fd_t) -> __wasi_errno_t; + #[link_name = "fd_pread"] + pub fn __wasi_fd_pread( + fd: __wasi_fd_t, + iovs: *const __wasi_iovec_t, + iovs_len: size_t, + offset: __wasi_filesize_t, + nread: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_pwrite"] + pub fn __wasi_fd_pwrite( + fd: __wasi_fd_t, + iovs: *const __wasi_ciovec_t, + iovs_len: size_t, + offset: __wasi_filesize_t, + nwritten: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_read"] + pub fn __wasi_fd_read( + fd: __wasi_fd_t, + iovs: *const __wasi_iovec_t, + iovs_len: size_t, + nread: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_renumber"] + pub fn __wasi_fd_renumber( + from: __wasi_fd_t, + to: __wasi_fd_t, + ) -> __wasi_errno_t; + #[link_name = "fd_seek"] + pub fn __wasi_fd_seek( + fd: __wasi_fd_t, + offset: __wasi_filedelta_t, + whence: __wasi_whence_t, + newoffset: *mut __wasi_filesize_t, + ) -> __wasi_errno_t; + #[link_name = "fd_tell"] + pub fn __wasi_fd_tell( + fd: __wasi_fd_t, + newoffset: *mut __wasi_filesize_t, + ) -> __wasi_errno_t; + #[link_name = "fd_fdstat_get"] + pub fn __wasi_fd_fdstat_get( + fd: __wasi_fd_t, + buf: *mut __wasi_fdstat_t, + ) -> __wasi_errno_t; + #[link_name = "fd_fdstat_set_flags"] + pub fn __wasi_fd_fdstat_set_flags( + fd: __wasi_fd_t, + flags: __wasi_fdflags_t, + ) -> __wasi_errno_t; + #[link_name = "fd_fdstat_set_rights"] + pub fn __wasi_fd_fdstat_set_rights( + fd: __wasi_fd_t, + fs_rights_base: __wasi_rights_t, + fs_rights_inheriting: __wasi_rights_t, + ) -> __wasi_errno_t; + #[link_name = "fd_sync"] + pub fn __wasi_fd_sync(fd: __wasi_fd_t) -> __wasi_errno_t; + #[link_name = "fd_write"] + pub fn __wasi_fd_write( + fd: __wasi_fd_t, + iovs: *const __wasi_ciovec_t, + iovs_len: size_t, + nwritten: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_advise"] + pub fn __wasi_fd_advise( + fd: __wasi_fd_t, + offset: __wasi_filesize_t, + len: __wasi_filesize_t, + advice: __wasi_advice_t, + ) -> __wasi_errno_t; + #[link_name = "fd_allocate"] + pub fn __wasi_fd_allocate( + fd: __wasi_fd_t, + offset: __wasi_filesize_t, + len: __wasi_filesize_t, + ) -> __wasi_errno_t; + #[link_name = "path_create_directory"] + pub fn __wasi_path_create_directory( + fd: __wasi_fd_t, + path: *const ::c_char, + path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "path_link"] + pub fn __wasi_path_link( + old_fd: __wasi_fd_t, + old_flags: __wasi_lookupflags_t, + old_path: *const ::c_char, + old_path_len: size_t, + new_fd: __wasi_fd_t, + new_path: *const ::c_char, + new_path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "path_open"] + pub fn __wasi_path_open( + dirfd: __wasi_fd_t, + dirflags: __wasi_lookupflags_t, + path: *const ::c_char, + path_len: size_t, + oflags: __wasi_oflags_t, + fs_rights_base: __wasi_rights_t, + fs_rights_inheriting: __wasi_rights_t, + fs_flags: __wasi_fdflags_t, + fd: *mut __wasi_fd_t, + ) -> __wasi_errno_t; + #[link_name = "fd_readdir"] + pub fn __wasi_fd_readdir( + fd: __wasi_fd_t, + buf: *mut ::c_void, + buf_len: size_t, + cookie: __wasi_dircookie_t, + bufused: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "path_readlink"] + pub fn __wasi_path_readlink( + fd: __wasi_fd_t, + path: *const ::c_char, + path_len: size_t, + buf: *mut ::c_char, + buf_len: size_t, + bufused: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "path_rename"] + pub fn __wasi_path_rename( + old_fd: __wasi_fd_t, + old_path: *const ::c_char, + old_path_len: size_t, + new_fd: __wasi_fd_t, + new_path: *const ::c_char, + new_path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_filestat_get"] + pub fn __wasi_fd_filestat_get( + fd: __wasi_fd_t, + buf: *mut __wasi_filestat_t, + ) -> __wasi_errno_t; + #[link_name = "fd_filestat_set_times"] + pub fn __wasi_fd_filestat_set_times( + fd: __wasi_fd_t, + st_atim: __wasi_timestamp_t, + st_mtim: __wasi_timestamp_t, + fstflags: __wasi_fstflags_t, + ) -> __wasi_errno_t; + #[link_name = "fd_filestat_set_size"] + pub fn __wasi_fd_filestat_set_size( + fd: __wasi_fd_t, + st_size: __wasi_filesize_t, + ) -> __wasi_errno_t; + #[link_name = "path_filestat_get"] + pub fn __wasi_path_filestat_get( + fd: __wasi_fd_t, + flags: __wasi_lookupflags_t, + path: *const ::c_char, + path_len: size_t, + buf: *mut __wasi_filestat_t, + ) -> __wasi_errno_t; + #[link_name = "path_filestat_set_times"] + pub fn __wasi_path_filestat_set_times( + fd: __wasi_fd_t, + flags: __wasi_lookupflags_t, + path: *const ::c_char, + path_len: size_t, + st_atim: __wasi_timestamp_t, + st_mtim: __wasi_timestamp_t, + fstflags: __wasi_fstflags_t, + ) -> __wasi_errno_t; + #[link_name = "path_symlink"] + pub fn __wasi_path_symlink( + old_path: *const ::c_char, + old_path_len: size_t, + fd: __wasi_fd_t, + new_path: *const ::c_char, + new_path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "path_unlink_file"] + pub fn __wasi_path_unlink_file( + fd: __wasi_fd_t, + path: *const ::c_char, + path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "path_remove_directory"] + pub fn __wasi_path_remove_directory( + fd: __wasi_fd_t, + path: *const ::c_char, + path_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "poll_oneoff"] + pub fn __wasi_poll_oneoff( + in_: *const __wasi_subscription_t, + out: *mut __wasi_event_t, + nsubscriptions: size_t, + nevents: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "proc_exit"] + pub fn __wasi_proc_exit(rval: __wasi_exitcode_t); + #[link_name = "proc_raise"] + pub fn __wasi_proc_raise(sig: __wasi_signal_t) -> __wasi_errno_t; + #[link_name = "random_get"] + pub fn __wasi_random_get( + buf: *mut ::c_void, + buf_len: size_t, + ) -> __wasi_errno_t; + #[link_name = "sock_recv"] + pub fn __wasi_sock_recv( + sock: __wasi_fd_t, + ri_data: *const __wasi_iovec_t, + ri_data_len: size_t, + ri_flags: __wasi_riflags_t, + ro_datalen: *mut size_t, + ro_flags: *mut __wasi_roflags_t, + ) -> __wasi_errno_t; + #[link_name = "sock_send"] + pub fn __wasi_sock_send( + sock: __wasi_fd_t, + si_data: *const __wasi_ciovec_t, + si_data_len: size_t, + si_flags: __wasi_siflags_t, + so_datalen: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "sock_shutdown"] + pub fn __wasi_sock_shutdown( + sock: __wasi_fd_t, + how: __wasi_sdflags_t, + ) -> __wasi_errno_t; + #[link_name = "sched_yield"] + pub fn __wasi_sched_yield() -> __wasi_errno_t; + #[link_name = "args_get"] + pub fn __wasi_args_get( + argv: *mut *mut c_char, + argv_buf: *mut c_char, + ) -> __wasi_errno_t; + #[link_name = "args_sizes_get"] + pub fn __wasi_args_sizes_get( + argc: *mut size_t, + argv_buf_size: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "environ_get"] + pub fn __wasi_environ_get( + environ: *mut *mut c_char, + environ_buf: *mut c_char, + ) -> __wasi_errno_t; + #[link_name = "environ_sizes_get"] + pub fn __wasi_environ_sizes_get( + environ_count: *mut size_t, + environ_buf_size: *mut size_t, + ) -> __wasi_errno_t; + #[link_name = "fd_prestat_get"] + pub fn __wasi_fd_prestat_get( + fd: __wasi_fd_t, + buf: *mut __wasi_prestat_t, + ) -> __wasi_errno_t; + #[link_name = "fd_prestat_dir_name"] + pub fn __wasi_fd_prestat_dir_name( + fd: __wasi_fd_t, + path: *mut c_char, + path_len: size_t, + ) -> __wasi_errno_t; +} diff -Nru cargo-0.33.0/vendor/libc/src/windows/mod.rs cargo-0.35.0/vendor/libc/src/windows/mod.rs --- cargo-0.33.0/vendor/libc/src/windows/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libc/src/windows/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -47,7 +47,12 @@ pub type off_t = i32; pub type dev_t = u32; pub type ino_t = u16; +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { *self } +} pub type time64_t = i64; pub type SOCKET = ::uintptr_t; @@ -201,8 +206,18 @@ #[link(name = "libcmt", cfg(target_feature = "crt-static"))] extern {} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum FILE {} +impl ::Copy for FILE {} +impl ::Clone for FILE { + fn clone(&self) -> FILE { *self } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos_t {} // TODO: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { *self } +} extern { pub fn isalnum(c: c_int) -> c_int; @@ -419,13 +434,15 @@ } cfg_if! { - if #[cfg(core_cvoid)] { - pub use core::ffi::c_void; + if #[cfg(libc_core_cvoid)] { + pub use ::ffi::c_void; } else { // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help // enable more optimization opportunities around it recognizing things // like malloc/free. #[repr(u8)] + #[allow(missing_copy_implementations)] + #[allow(missing_debug_implementations)] pub enum c_void { // Two dummy variants so the #[repr] attribute can be used. #[doc(hidden)] @@ -446,4 +463,4 @@ } else { // Unknown target_env } -} \ No newline at end of file +} diff -Nru cargo-0.33.0/vendor/libnghttp2-sys/build.rs.orig cargo-0.35.0/vendor/libnghttp2-sys/build.rs.orig --- cargo-0.33.0/vendor/libnghttp2-sys/build.rs.orig 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/libnghttp2-sys/build.rs.orig 2019-05-15 11:26:24.000000000 +0000 @@ -1,83 +1,7 @@ -extern crate cc; +extern crate pkg_config; -use std::env; -use std::fs; -use std::path::PathBuf; - -const VERSION: &str = "1.33.90"; - -fn main() { - let target = env::var("TARGET").unwrap(); - let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - let ver = fs::read_to_string("nghttp2/lib/includes/nghttp2/nghttp2ver.h.in") - .unwrap() - .replace("@PACKAGE_VERSION@", VERSION) - .replace("@PACKAGE_VERSION_NUM@", "0x01214a"); - - let install = out_dir.join("i"); - let include = install.join("include"); - let lib = install.join("lib"); - let pkgconfig = lib.join("pkgconfig"); - fs::create_dir_all(include.join("nghttp2")).unwrap(); - fs::create_dir_all(&pkgconfig).unwrap(); - fs::write(include.join("nghttp2/nghttp2ver.h"), ver).unwrap(); - - let mut cfg = cc::Build::new(); - cfg.include("nghttp2/lib/includes") - .include(&include) - .file("nghttp2/lib/nghttp2_buf.c") - .file("nghttp2/lib/nghttp2_callbacks.c") - .file("nghttp2/lib/nghttp2_debug.c") - .file("nghttp2/lib/nghttp2_frame.c") - .file("nghttp2/lib/nghttp2_hd.c") - .file("nghttp2/lib/nghttp2_hd_huffman.c") - .file("nghttp2/lib/nghttp2_hd_huffman_data.c") - .file("nghttp2/lib/nghttp2_helper.c") - .file("nghttp2/lib/nghttp2_http.c") - .file("nghttp2/lib/nghttp2_map.c") - .file("nghttp2/lib/nghttp2_mem.c") - .file("nghttp2/lib/nghttp2_npn.c") - .file("nghttp2/lib/nghttp2_option.c") - .file("nghttp2/lib/nghttp2_outbound_item.c") - .file("nghttp2/lib/nghttp2_pq.c") - .file("nghttp2/lib/nghttp2_priority_spec.c") - .file("nghttp2/lib/nghttp2_queue.c") - .file("nghttp2/lib/nghttp2_rcbuf.c") - .file("nghttp2/lib/nghttp2_session.c") - .file("nghttp2/lib/nghttp2_stream.c") - .file("nghttp2/lib/nghttp2_submit.c") - .file("nghttp2/lib/nghttp2_version.c") - .warnings(false) - .define("NGHTTP2_STATICLIB", None) - .define("HAVE_NETINET_IN", None) - .out_dir(&lib); - - if target.contains("windows") { - // Apparently MSVC doesn't have `ssize_t` defined as a type - if target.contains("msvc") { - match &env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap()[..] { - "64" => { cfg.define("ssize_t", "int64_t"); } - "32" => { cfg.define("ssize_t", "int32_t"); } - s => panic!("unknown pointer size: {}", s), - } - } - } else { - cfg.define("HAVE_ARPA_INET_H", None); +pub fn main() { + if pkg_config::probe_library("libnghttp2").is_ok() { + return; } - cfg.compile("nghttp2"); - - println!("cargo:root={}", install.display()); - - let pc = fs::read_to_string("nghttp2/lib/libnghttp2.pc.in") - .unwrap() - .replace("@prefix@", install.to_str().unwrap()) - .replace("@exec_prefix@", "") - .replace("@libdir@", lib.to_str().unwrap()) - .replace("@includedir@", include.to_str().unwrap()) - .replace("@VERSION@", VERSION); - fs::write(pkgconfig.join("libnghttp2.pc"), pc).unwrap(); - fs::copy( - "nghttp2/lib/includes/nghttp2/nghttp2.h", - include.join("nghttp2/nghttp2.h"), - ).unwrap(); } diff -Nru cargo-0.33.0/vendor/memchr/build.rs cargo-0.35.0/vendor/memchr/build.rs --- cargo-0.33.0/vendor/memchr/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,10 +11,15 @@ } }; enable_simd_optimizations(version); + enable_libc(); } +// This adds various simd cfgs if this compiler supports it. +// +// This can be disabled with RUSTFLAGS="--cfg memchr_disable_auto_simd", but +// this is generally only intended for testing. fn enable_simd_optimizations(version: Version) { - if env::var_os("CARGO_CFG_MEMCHR_DISABLE_AUTO_SIMD").is_some() { + if is_env_set("CARGO_CFG_MEMCHR_DISABLE_AUTO_SIMD") { return; } if version < (Version { major: 1, minor: 27, patch: 0 }) { @@ -27,6 +32,47 @@ println!("cargo:rustc-cfg=memchr_runtime_avx"); } +// This adds a `memchr_libc` cfg if and only if libc can be used, if no other +// better option is available. +// +// This could be performed in the source code, but it's simpler to do it once +// here and consolidate it into one cfg knob. +// +// Basically, we use libc only if its enabled and if we aren't targeting a +// known bad platform. For example, wasm32 doesn't have a libc and the +// performance of memchr on Windows is seemingly worse than the fallback +// implementation. +fn enable_libc() { + const NO_ARCH: &'static [&'static str] = &["wasm32", "windows"]; + const NO_ENV: &'static [&'static str] = &["sgx"]; + + if !is_feature_set("LIBC") { + return; + } + + let arch = match env::var("CARGO_CFG_TARGET_ARCH") { + Err(_) => return, + Ok(arch) => arch, + }; + let env = match env::var("CARGO_CFG_TARGET_ENV") { + Err(_) => return, + Ok(env) => env, + }; + if NO_ARCH.contains(&&*arch) || NO_ENV.contains(&&*env) { + return; + } + + println!("cargo:rustc-cfg=memchr_libc"); +} + +fn is_feature_set(name: &str) -> bool { + is_env_set(&format!("CARGO_FEATURE_{}", name)) +} + +fn is_env_set(name: &str) -> bool { + env::var_os(name).is_some() +} + #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] struct Version { major: u32, diff -Nru cargo-0.33.0/vendor/memchr/.cargo-checksum.json cargo-0.35.0/vendor/memchr/.cargo-checksum.json --- cargo-0.33.0/vendor/memchr/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8"} \ No newline at end of file +{"files":{},"package":"2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/memchr/Cargo.toml cargo-0.35.0/vendor/memchr/Cargo.toml --- cargo-0.33.0/vendor/memchr/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,9 +12,9 @@ [package] name = "memchr" -version = "2.1.3" +version = "2.2.0" authors = ["Andrew Gallant ", "bluss"] -exclude = ["/ci/*", "/.travis.yml", "/Makefile", "/appveyor.yml", "/ctags.rust", "/session.vim"] +exclude = ["/ci/*", "/.travis.yml", "/Makefile", "/appveyor.yml"] description = "Safe interface to memchr." homepage = "https://github.com/BurntSushi/rust-memchr" documentation = "https://docs.rs/memchr/" @@ -28,9 +28,6 @@ [lib] name = "memchr" bench = false -[dependencies.cfg-if] -version = "0.1.5" - [dependencies.libc] version = "0.2.18" optional = true @@ -40,8 +37,8 @@ default-features = false [features] -default = ["use_std", "libc"] -use_std = ["libc", "libc/use_std"] +default = ["use_std"] +use_std = [] [badges.appveyor] repository = "BurntSushi/rust-memchr" diff -Nru cargo-0.33.0/vendor/memchr/README.md cargo-0.35.0/vendor/memchr/README.md --- cargo-0.33.0/vendor/memchr/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -43,3 +43,8 @@ [dependencies] memchr = { version = "2", default-features = false } ``` + +On x86 platforms, when the `use_std` feature is disabled, the SSE2 +implementation of memchr will be used in compilers that support it. When +`use_std` is enabled, the AVX implementation of memchr will be used if the CPU +is determined to support it at runtime. diff -Nru cargo-0.33.0/vendor/memchr/src/lib.rs cargo-0.35.0/vendor/memchr/src/lib.rs --- cargo-0.33.0/vendor/memchr/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -33,8 +33,6 @@ #[cfg(feature = "use_std")] extern crate core; -#[macro_use] -extern crate cfg_if; #[cfg(test)] #[macro_use] extern crate quickcheck; @@ -43,17 +41,14 @@ pub use iter::{Memchr, Memchr2, Memchr3}; -#[cfg(all( - feature = "libc", - not(target_arch = "wasm32"), - not(target_env = "sgx"), -))] +// N.B. If you're looking for the cfg knobs for libc, see build.rs. +#[cfg(memchr_libc)] mod c; #[allow(dead_code)] mod fallback; mod iter; mod naive; -#[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] +#[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] mod x86; #[cfg(test)] mod tests; @@ -134,29 +129,30 @@ /// ``` #[inline] pub fn memchr(needle: u8, haystack: &[u8]) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - x86::memchr(n1, haystack) - } - } else if #[cfg(all( - feature = "libc", - not(target_arch = "wasm32"), - not(target_arch = "windows"), - not(target_env = "sgx"), - ))] { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - c::memchr(n1, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - fallback::memchr(n1, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + x86::memchr(n1, haystack) + } + + #[cfg(all( + memchr_libc, + not(all(target_arch = "x86_64", memchr_runtime_simd)) + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + c::memchr(n1, haystack) + } + + #[cfg(all( + not(memchr_libc), + not(all(target_arch = "x86_64", memchr_runtime_simd)) + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + fallback::memchr(n1, haystack) } + if haystack.is_empty() { None } else { @@ -167,19 +163,18 @@ /// Like `memchr`, but searches for two bytes instead of one. #[inline] pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { - x86::memchr2(n1, n2, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { - fallback::memchr2(n1, n2, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + x86::memchr2(n1, n2, haystack) + } + + #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + fallback::memchr2(n1, n2, haystack) } + if haystack.is_empty() { None } else { @@ -195,19 +190,18 @@ needle3: u8, haystack: &[u8], ) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { - x86::memchr3(n1, n2, n3, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { - fallback::memchr3(n1, n2, n3, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + x86::memchr3(n1, n2, n3, haystack) + } + + #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + fallback::memchr3(n1, n2, n3, haystack) } + if haystack.is_empty() { None } else { @@ -237,30 +231,30 @@ /// ``` #[inline] pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - x86::memrchr(n1, haystack) - } - } else if #[cfg(all( - feature = "libc", - target_os = "linux", - not(target_arch = "wasm32"), - not(target_arch = "windows"), - not(target_env = "sgx"), - ))] { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - c::memrchr(n1, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, haystack: &[u8]) -> Option { - fallback::memrchr(n1, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + x86::memrchr(n1, haystack) + } + + #[cfg(all( + all(memchr_libc, target_os = "linux"), + not(all(target_arch = "x86_64", memchr_runtime_simd)) + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + c::memrchr(n1, haystack) + } + + #[cfg(all( + not(all(memchr_libc, target_os = "linux")), + not(all(target_arch = "x86_64", memchr_runtime_simd)) + ))] + #[inline(always)] + fn imp(n1: u8, haystack: &[u8]) -> Option { + fallback::memrchr(n1, haystack) } + if haystack.is_empty() { None } else { @@ -271,19 +265,18 @@ /// Like `memrchr`, but searches for two bytes instead of one. #[inline] pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { - x86::memrchr2(n1, n2, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { - fallback::memrchr2(n1, n2, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + x86::memrchr2(n1, n2, haystack) + } + + #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, haystack: &[u8]) -> Option { + fallback::memrchr2(n1, n2, haystack) } + if haystack.is_empty() { None } else { @@ -299,19 +292,18 @@ needle3: u8, haystack: &[u8], ) -> Option { - cfg_if! { - if #[cfg(all(target_arch = "x86_64", memchr_runtime_simd, feature = "use_std"))] { - #[inline(always)] - fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { - x86::memrchr3(n1, n2, n3, haystack) - } - } else { - #[inline(always)] - fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { - fallback::memrchr3(n1, n2, n3, haystack) - } - } + #[cfg(all(target_arch = "x86_64", memchr_runtime_simd))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + x86::memrchr3(n1, n2, n3, haystack) } + + #[cfg(not(all(target_arch = "x86_64", memchr_runtime_simd)))] + #[inline(always)] + fn imp(n1: u8, n2: u8, n3: u8, haystack: &[u8]) -> Option { + fallback::memrchr3(n1, n2, n3, haystack) + } + if haystack.is_empty() { None } else { diff -Nru cargo-0.33.0/vendor/memchr/src/x86/mod.rs cargo-0.35.0/vendor/memchr/src/x86/mod.rs --- cargo-0.33.0/vendor/memchr/src/x86/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/memchr/src/x86/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,8 @@ -use std::mem; -use std::sync::atomic::{AtomicUsize, Ordering}; - use fallback; +// We only use AVX when we can detect at runtime whether it's available, which +// requires std. +#[cfg(feature = "use_std")] mod avx; mod sse2; @@ -27,30 +27,49 @@ // probably can't be inlined anyway---unless you've compiled your entire // program with AVX2 enabled. However, even then, the various memchr // implementations aren't exactly small, so inlining might not help anyway! +#[cfg(feature = "use_std")] macro_rules! ifunc { ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{ - static mut FN: $fnty = detect; + use std::mem; + use std::sync::atomic::{AtomicPtr, Ordering}; + + type FnRaw = *mut (); + + static FN: AtomicPtr<()> = AtomicPtr::new(detect as FnRaw); fn detect($($needle: u8),+, haystack: &[u8]) -> Option { let fun = if cfg!(memchr_runtime_avx) && is_x86_feature_detected!("avx2") { - avx::$name as usize + avx::$name as FnRaw } else if cfg!(memchr_runtime_sse2) { - sse2::$name as usize + sse2::$name as FnRaw } else { - fallback::$name as usize + fallback::$name as FnRaw }; - let slot = unsafe { &*(&FN as *const _ as *const AtomicUsize) }; - slot.store(fun as usize, Ordering::Relaxed); + FN.store(fun as FnRaw, Ordering::Relaxed); unsafe { - mem::transmute::(fun)($($needle),+, haystack) + mem::transmute::(fun)($($needle),+, haystack) } } unsafe { - let slot = &*(&FN as *const _ as *const AtomicUsize); - let fun = slot.load(Ordering::Relaxed); - mem::transmute::(fun)($($needle),+, $haystack) + let fun = FN.load(Ordering::Relaxed); + mem::transmute::(fun)($($needle),+, $haystack) + } + }} +} + +// When std isn't enable (which provides runtime CPU feature detection), or if +// runtime CPU feature detection has been explicitly disabled, then just call +// our optimized SSE2 routine directly. SSE2 is avalbale on all x86_64 targets, +// so no CPU feature detection is necessary. +#[cfg(not(feature = "use_std"))] +macro_rules! ifunc { + ($fnty:ty, $name:ident, $haystack:ident, $($needle:ident),+) => {{ + if cfg!(memchr_runtime_sse2) { + unsafe { sse2::$name($($needle),+, $haystack) } + } else { + fallback::$name($($needle),+, $haystack) } }} } diff -Nru cargo-0.33.0/vendor/num_cpus/.cargo-checksum.json cargo-0.35.0/vendor/num_cpus/.cargo-checksum.json --- cargo-0.33.0/vendor/num_cpus/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/num_cpus/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"} \ No newline at end of file +{"files":{},"package":"1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/num_cpus/Cargo.toml cargo-0.35.0/vendor/num_cpus/Cargo.toml --- cargo-0.33.0/vendor/num_cpus/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/num_cpus/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "num_cpus" -version = "1.9.0" +version = "1.10.0" authors = ["Sean McArthur "] description = "Get the number of CPUs on a machine." documentation = "https://docs.rs/num_cpus" diff -Nru cargo-0.33.0/vendor/num_cpus/CHANGELOG.md cargo-0.35.0/vendor/num_cpus/CHANGELOG.md --- cargo-0.33.0/vendor/num_cpus/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/num_cpus/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,3 +1,10 @@ +## v1.10.0 + +#### Features + +- add `illumos` target OS support +- add default fallback if target is unknown to `1` + ## v1.9.0 #### Features diff -Nru cargo-0.33.0/vendor/num_cpus/src/lib.rs cargo-0.35.0/vendor/num_cpus/src/lib.rs --- cargo-0.33.0/vendor/num_cpus/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/num_cpus/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,10 +25,10 @@ //! number 8, it could use the number of CPUs). //! //! [processor tricks]: https://en.wikipedia.org/wiki/Simultaneous_multithreading -//! [`rayon::ThreadPool`]: https://docs.rs/rayon/0.8.2/rayon/struct.ThreadPool.html +//! [`rayon::ThreadPool`]: https://docs.rs/rayon/1.*/rayon/struct.ThreadPool.html #![cfg_attr(test, deny(warnings))] #![deny(missing_docs)] -#![doc(html_root_url = "https://docs.rs/num_cpus/1.9.0")] +#![doc(html_root_url = "https://docs.rs/num_cpus/1.10.0")] #![allow(non_snake_case)] #[cfg(not(windows))] @@ -356,6 +356,7 @@ target_os = "ios", target_os = "android", target_os = "solaris", + target_os = "illumos", target_os = "fuchsia") )] fn get_num_cpus() -> usize { @@ -374,13 +375,22 @@ } } -#[cfg(any( - target_os = "emscripten", - target_os = "redox", - target_os = "haiku", - target_arch = "wasm32", - target_env = "sgx" -))] +#[cfg(not(any( + target_os = "nacl", + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "solaris", + target_os = "illumos", + target_os = "fuchsia", + target_os = "linux", + target_os = "openbsd", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "netbsd", + windows, +)))] fn get_num_cpus() -> usize { 1 } diff -Nru cargo-0.33.0/vendor/numtoa/.cargo-checksum.json cargo-0.35.0/vendor/numtoa/.cargo-checksum.json --- cargo-0.33.0/vendor/numtoa/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/numtoa/Cargo.toml cargo-0.35.0/vendor/numtoa/Cargo.toml --- cargo-0.33.0/vendor/numtoa/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,26 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "numtoa" +version = "0.1.0" +authors = ["Michael Aaron Murphy "] +description = "Convert numbers into stack-allocated byte arrays" +documentation = "https://docs.rs/numtoa" +readme = "README.md" +keywords = ["numbers", "convert", "numtoa", "itoa", "no_std"] +categories = ["value-formatting"] +license = "MIT OR Apache-2.0" +repository = "https://gitlab.com/mmstick/numtoa" + +[features] +std = [] diff -Nru cargo-0.33.0/vendor/numtoa/LICENSE-APACHE cargo-0.35.0/vendor/numtoa/LICENSE-APACHE --- cargo-0.33.0/vendor/numtoa/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/LICENSE-APACHE 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff -Nru cargo-0.33.0/vendor/numtoa/LICENSE-MIT cargo-0.35.0/vendor/numtoa/LICENSE-MIT --- cargo-0.33.0/vendor/numtoa/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/LICENSE-MIT 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Michael Aaron Murphy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff -Nru cargo-0.33.0/vendor/numtoa/README.md cargo-0.35.0/vendor/numtoa/README.md --- cargo-0.33.0/vendor/numtoa/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,65 @@ +# NumToA + +## `#![no_std]` Compatible with Zero Heap Allocations + +The standard library provides a convenient method of converting numbers into strings, but these strings are +heap-allocated. If you have an application which needs to convert large volumes of numbers into strings, but don't +want to pay the price of heap allocation, this crate provides an efficient `no_std`-compatible method of heaplessly converting numbers +into their string representations, storing the representation within a reusable byte array. + +## Supports Multiple Bases + +In addition to supporting the standard base 10 conversion, this implementation allows you to select the base of +your choice. Therefore, if you want a binary representation, set the base to 2. If you want hexadecimal, set the +base to 16. + +## No Unsafe + +Both the standard library and itoa crate rely on unsafe functions, but this implementation has been able to avoid +the use of unsafe entirely. + +## Fast + +Performance is roughly identical to that of the `itoa` crate when performing base 10 conversions. Below is a benchmark +of printing 0 through 5,000,000 to `/dev/null` + +``` +std: 1150615048 ns +itoa: 838556714 ns +numtoa: 825544518 ns +``` + +## Base 10 Example + +```rust +use numtoa::NumToA; +use std::io::{self, Write}; + +let stdout = io::stdout(); +let mut stdout = stdout.lock(); +let mut buffer = [0u8; 20]; + +let number: u32 = 162392; +let mut start_index = number.numtoa(10, &mut buffer); +let _ = stdout.write(&buffer[start_index..]); +let _ = stdout.write(b"\n"); +assert_eq!(&buffer[start_index..], b"162392"); + +let other_number: i32 = -6235; +start_index = other_number.numtoa(10, &mut buffer); +let _ = stdout.write(&buffer[start_index..]); +let _ = stdout.write(b"\n"); +assert_eq!(&buffer[start_index..], b"-6235"); + +let large_num: u64 = 35320842; +start_index = large_num.numtoa(10, &mut buffer); +let _ = stdout.write(&buffer[start_index..]); +let _ = stdout.write(b"\n"); +assert_eq!(&buffer[start_index..], b"35320842"); + +let max_u64: u64 = 18446744073709551615; +start_index = max_u64.numtoa(10, &mut buffer); +let _ = stdout.write(&buffer[start_index..]); +let _ = stdout.write(b"\n"); +assert_eq!(&buffer[start_index..], b"18446744073709551615"); +``` diff -Nru cargo-0.33.0/vendor/numtoa/src/lib.rs cargo-0.35.0/vendor/numtoa/src/lib.rs --- cargo-0.33.0/vendor/numtoa/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/numtoa/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,540 @@ +//! The standard library provides a convenient method of converting numbers into strings, but these strings are +//! heap-allocated. If you have an application which needs to convert large volumes of numbers into strings, but don't +//! want to pay the price of heap allocation, this crate provides an efficient `no_std`-compatible method of heaplessly converting numbers +//! into their string representations, storing the representation within a reusable byte array. +//! +//! In addition to supporting the standard base 10 conversion, this implementation allows you to select the base of +//! your choice. Therefore, if you want a binary representation, set the base to 2. If you want hexadecimal, set the +//! base to 16. +//! +//! # Convenience Example +//! +//! ``` +//! use numtoa::NumToA; +//! +//! let mut buf = [0u8; 20]; +//! let mut string = String::new(); +//! +//! for number in (1..10) { +//! string.push_str(number.numtoa_str(10, &mut buf)); +//! string.push('\n'); +//! } +//! +//! println!("{}", string); +//! ``` +//! +//! ## Base 10 Example +//! ``` +//! use numtoa::NumToA; +//! use std::io::{self, Write}; +//! +//! let stdout = io::stdout(); +//! let mut stdout = stdout.lock(); +//! let mut buffer = [0u8; 20]; +//! +//! let number: u32 = 162392; +//! let mut start_indice = number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"162392"); +//! +//! let other_number: i32 = -6235; +//! start_indice = other_number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"-6235"); +//! +//! let other_number: i8 = -128; +//! start_indice = other_number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"-128"); +//! +//! let other_number: i8 = 53; +//! start_indice = other_number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"53"); +//! +//! let other_number: i16 = -256; +//! start_indice = other_number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"-256"); +//! +//! let other_number: i16 = -32768; +//! start_indice = other_number.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"-32768"); +//! +//! let large_num: u64 = 35320842; +//! start_indice = large_num.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"35320842"); +//! +//! let max_u64: u64 = 18446744073709551615; +//! start_indice = max_u64.numtoa(10, &mut buffer); +//! let _ = stdout.write(&buffer[start_indice..]); +//! let _ = stdout.write(b"\n"); +//! assert_eq!(&buffer[start_indice..], b"18446744073709551615"); +//! ``` + +#![no_std] +use core::mem::size_of; + +#[cfg(feature = "std")] +extern crate std; +#[cfg(feature = "std")] +use std::str; + +/// Converts a number into a string representation, storing the conversion into a mutable byte slice. +pub trait NumToA { + /// Given a base for encoding and a mutable byte slice, write the number into the byte slice and return the + /// indice where the inner string begins. The inner string can be extracted by slicing the byte slice from + /// that indice. + /// + /// # Panics + /// If the supplied buffer is smaller than the number of bytes needed to write the integer, this will panic. + /// On debug builds, this function will perform a check on base 10 conversions to ensure that the input array + /// is large enough to hold the largest possible value in digits. + /// + /// # Example + /// ``` + /// use numtoa::NumToA; + /// use std::io::{self, Write}; + /// + /// let stdout = io::stdout(); + /// let stdout = &mut io::stdout(); + /// + /// let mut buffer = [0u8; 20]; + /// let number = 15325; + /// let start_indice = number.numtoa(10, &mut buffer); + /// let _ = stdout.write(&buffer[start_indice..]); + /// assert_eq!(&buffer[start_indice..], b"15325"); + /// ``` + fn numtoa(self, base: T, string: &mut [u8]) -> usize; + + #[cfg(feature = "std")] + /// Convenience method for quickly getting a string from the input's array buffer. + fn numtoa_str(self, base: T, buf: &mut [u8; 20]) -> &str; +} + +// A lookup table to prevent the need for conditional branching +// The value of the remainder of each step will be used as the index +const LOOKUP: &[u8] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +// A lookup table optimized for decimal lookups. Each two indices represents one possible number. +const DEC_LOOKUP: &[u8; 200] = b"0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; + +macro_rules! base_10 { + ($number:ident, $index:ident, $string:ident) => { + // Decode four characters at the same time + while $number > 9999 { + let rem = ($number % 10000) as u16; + let (frst, scnd) = ((rem / 100) * 2, (rem % 100) * 2); + $string[$index-3..$index-1].copy_from_slice(&DEC_LOOKUP[frst as usize..frst as usize+2]); + $string[$index-1..$index+1].copy_from_slice(&DEC_LOOKUP[scnd as usize..scnd as usize+2]); + $index = $index.wrapping_sub(4); + $number /= 10000; + } + + if $number > 999 { + let (frst, scnd) = (($number / 100) * 2, ($number % 100) * 2); + $string[$index-3..$index-1].copy_from_slice(&DEC_LOOKUP[frst as usize..frst as usize+2]); + $string[$index-1..$index+1].copy_from_slice(&DEC_LOOKUP[scnd as usize..scnd as usize+2]); + $index = $index.wrapping_sub(4); + } else if $number > 99 { + let section = ($number as u16 / 10) * 2; + $string[$index-2..$index].copy_from_slice(&DEC_LOOKUP[section as usize..section as usize+2]); + $string[$index] = LOOKUP[($number % 10) as usize]; + $index = $index.wrapping_sub(3); + } else if $number > 9 { + $number *= 2; + $string[$index-1..$index+1].copy_from_slice(&DEC_LOOKUP[$number as usize..$number as usize+2]); + $index = $index.wrapping_sub(2); + } else { + $string[$index] = LOOKUP[$number as usize]; + $index = $index.wrapping_sub(1); + } + } +} + +macro_rules! impl_unsized_numtoa_for { + ($t:ty) => { + impl NumToA<$t> for $t { + fn numtoa(mut self, base: $t, string: &mut [u8]) -> usize { + // Check if the buffer is large enough and panic on debug builds if it isn't + if cfg!(debug_assertions) { + if base == 10 { + match size_of::<$t>() { + 2 => debug_assert!(string.len() >= 5, "u16 base 10 conversions require at least 5 bytes"), + 4 => debug_assert!(string.len() >= 10, "u32 base 10 conversions require at least 10 bytes"), + 8 => debug_assert!(string.len() >= 20, "u64 base 10 conversions require at least 20 bytes"), + _ => unreachable!() + } + } + } + + let mut index = string.len() - 1; + if self == 0 { + string[index] = b'0'; + return index; + } + + if base == 10 { + // Convert using optimized base 10 algorithm + base_10!(self, index, string); + } else { + while self != 0 { + let rem = self % base; + string[index] = LOOKUP[rem as usize]; + index = index.wrapping_sub(1); + self /= base; + } + } + + index.wrapping_add(1) + } + + #[cfg(feature = "std")] + fn numtoa_str(self, base: $t, buf: &mut [u8; 20]) -> &str { + let s = self.numtoa(base, buf); + unsafe { str::from_utf8_unchecked(&buf[s..]) } + } + } + } +} + +macro_rules! impl_sized_numtoa_for { + ($t:ty) => { + impl NumToA<$t> for $t { + fn numtoa(mut self, base: $t, string: &mut [u8]) -> usize { + if cfg!(debug_assertions) { + if base == 10 { + match size_of::<$t>() { + 2 => debug_assert!(string.len() >= 6, "i16 base 10 conversions require at least 6 bytes"), + 4 => debug_assert!(string.len() >= 11, "i32 base 10 conversions require at least 11 bytes"), + 8 => debug_assert!(string.len() >= 20, "i64 base 10 conversions require at least 20 bytes"), + _ => unreachable!() + } + } + } + + let mut index = string.len() - 1; + let mut is_negative = false; + + if self < 0 { + is_negative = true; + self = match self.checked_abs() { + Some(value) => value, + None => { + let value = <$t>::max_value(); + string[index] = LOOKUP[((value % base + 1) % base) as usize]; + index -= 1; + value / base + ((value % base == base - 1) as $t) + } + }; + } else if self == 0 { + string[index] = b'0'; + return index; + } + + if base == 10 { + // Convert using optimized base 10 algorithm + base_10!(self, index, string); + } else { + while self != 0 { + let rem = self % base; + string[index] = LOOKUP[rem as usize]; + index = index.wrapping_sub(1); + self /= base; + } + } + + if is_negative { + string[index] = b'-'; + index = index.wrapping_sub(1); + } + + index.wrapping_add(1) + } + + #[cfg(feature = "std")] + fn numtoa_str(self, base: $t, buf: &mut [u8; 20]) -> &str { + let s = self.numtoa(base, buf); + unsafe { str::from_utf8_unchecked(&buf[s..]) } + } + } + } +} + +impl_sized_numtoa_for!(i16); +impl_sized_numtoa_for!(i32); +impl_sized_numtoa_for!(i64); +impl_sized_numtoa_for!(isize); +impl_unsized_numtoa_for!(u16); +impl_unsized_numtoa_for!(u32); +impl_unsized_numtoa_for!(u64); +impl_unsized_numtoa_for!(usize); + +impl NumToA for i8 { + fn numtoa(mut self, base: i8, string: &mut [u8]) -> usize { + if cfg!(debug_assertions) { + if base == 10 { + debug_assert!(string.len() >= 4, "i8 conversions need at least 4 bytes"); + } + } + + let mut index = string.len() - 1; + let mut is_negative = false; + + if self < 0 { + is_negative = true; + self = match self.checked_abs() { + Some(value) => value, + None => { + let value = ::max_value(); + string[index] = LOOKUP[((value % base + 1) % base) as usize]; + index -= 1; + value / base + ((value % base == base - 1) as i8) + } + }; + } else if self == 0 { + string[index] = b'0'; + return index; + } + + if base == 10 { + if self > 99 { + let section = (self / 10) * 2; + string[index-2..index].copy_from_slice(&DEC_LOOKUP[section as usize..section as usize+2]); + string[index] = LOOKUP[(self % 10) as usize]; + index = index.wrapping_sub(3); + } else if self > 9 { + self *= 2; + string[index-1..index+1].copy_from_slice(&DEC_LOOKUP[self as usize..self as usize+2]); + index = index.wrapping_sub(2); + } else { + string[index] = LOOKUP[self as usize]; + index = index.wrapping_sub(1); + } + } else { + while self != 0 { + let rem = self % base; + string[index] = LOOKUP[rem as usize]; + index = index.wrapping_sub(1); + self /= base; + } + } + + if is_negative { + string[index] = b'-'; + index = index.wrapping_sub(1); + } + + index.wrapping_add(1) + } + + #[cfg(feature = "std")] + fn numtoa_str(self, base: Self, buf: &mut [u8; 20]) -> &str { + let s = self.numtoa(base, buf); + unsafe { str::from_utf8_unchecked(&buf[s..]) } + } +} + +impl NumToA for u8 { + fn numtoa(mut self, base: u8, string: &mut [u8]) -> usize { + if cfg!(debug_assertions) { + if base == 10 { + debug_assert!(string.len() >= 3, "u8 conversions need at least 3 bytes"); + } + } + + let mut index = string.len() - 1; + if self == 0 { + string[index] = b'0'; + return index; + } + + if base == 10 { + if self > 99 { + let section = (self / 10) * 2; + string[index-2..index].copy_from_slice(&DEC_LOOKUP[section as usize..section as usize+2]); + string[index] = LOOKUP[(self % 10) as usize]; + index = index.wrapping_sub(3); + } else if self > 9 { + self *= 2; + string[index-1..index+1].copy_from_slice(&DEC_LOOKUP[self as usize..self as usize+2]); + index = index.wrapping_sub(2); + } else { + string[index] = LOOKUP[self as usize]; + index = index.wrapping_sub(1); + } + } else { + while self != 0 { + let rem = self % base; + string[index] = LOOKUP[rem as usize]; + index = index.wrapping_sub(1); + self /= base; + } + } + + index.wrapping_add(1) + } + + #[cfg(feature = "std")] + fn numtoa_str(self, base: Self, buf: &mut [u8; 20]) -> &str { + let s = self.numtoa(base, buf); + unsafe { str::from_utf8_unchecked(&buf[s..]) } + } +} + +#[test] +fn str_convenience() { + let mut buffer = [0u8; 20]; + assert_eq!("256123", 256123.numtoa_str(10, &mut buffer)); +} + +#[test] +#[should_panic] +fn base10_u8_array_too_small() { + let mut buffer = [0u8; 2]; + let _ = 0u8.numtoa(10, &mut buffer); +} + +#[test] +fn base10_u8_array_just_right() { + let mut buffer = [0u8; 3]; + let _ = 0u8.numtoa(10, &mut buffer); +} + +#[test] +#[should_panic] +fn base10_i8_array_too_small() { + let mut buffer = [0u8; 3]; + let _ = 0i8.numtoa(10, &mut buffer); +} + +#[test] +fn base10_i8_array_just_right() { + let mut buffer = [0u8; 4]; + let i = (-127i8).numtoa(10, &mut buffer); + assert_eq!(&buffer[i..], b"-127"); +} + +#[test] +#[should_panic] +fn base10_i16_array_too_small() { + let mut buffer = [0u8; 5]; + let _ = 0i16.numtoa(10, &mut buffer); +} + +#[test] +fn base10_i16_array_just_right() { + let mut buffer = [0u8; 6]; + let i = (-12768i16).numtoa(10, &mut buffer); + assert_eq!(&buffer[i..], b"-12768"); +} + +#[test] +#[should_panic] +fn base10_u16_array_too_small() { + let mut buffer = [0u8; 4]; + let _ = 0u16.numtoa(10, &mut buffer); +} + +#[test] +fn base10_u16_array_just_right() { + let mut buffer = [0u8; 5]; + let _ = 0u16.numtoa(10, &mut buffer); +} + +#[test] +#[should_panic] +fn base10_i32_array_too_small() { + let mut buffer = [0u8; 10]; + let _ = 0i32.numtoa(10, &mut buffer); +} + +#[test] +fn base10_i32_array_just_right() { + let mut buffer = [0u8; 11]; + let _ = 0i32.numtoa(10, &mut buffer); +} + +#[test] +#[should_panic] +fn base10_u32_array_too_small() { + let mut buffer = [0u8; 9]; + let _ = 0u32.numtoa(10, &mut buffer); +} + +#[test] +fn base10_u32_array_just_right() { + let mut buffer = [0u8; 10]; + let _ = 0u32.numtoa(10, &mut buffer); +} + +#[test] +#[should_panic] +fn base10_i64_array_too_small() { + let mut buffer = [0u8; 19]; + let _ = 0i64.numtoa(10, &mut buffer); +} + +#[test] +fn base10_i64_array_just_right() { + let mut buffer = [0u8; 20]; + let _ = 0i64.numtoa(10, &mut buffer); +} + +#[test] +#[should_panic] +fn base10_u64_array_too_small() { + let mut buffer = [0u8; 19]; + let _ = 0u64.numtoa(10, &mut buffer); +} + +#[test] +fn base10_u64_array_just_right() { + let mut buffer = [0u8; 20]; + let _ = 0u64.numtoa(10, &mut buffer); +} + +#[test] +fn base8_min_signed_number() { + let mut buffer = [0u8; 30]; + let i = (-128i8).numtoa(8, &mut buffer); + assert_eq!(&buffer[i..], b"-200"); + + let i = (-32768i16).numtoa(8, &mut buffer); + assert_eq!(&buffer[i..], b"-100000"); + + let i = (-2147483648i32).numtoa(8, &mut buffer); + assert_eq!(&buffer[i..], b"-20000000000"); + + let i = (-9223372036854775808i64).numtoa(8, &mut buffer); + assert_eq!(&buffer[i..], b"-1000000000000000000000"); +} + +#[test] +fn base16_min_signed_number() { + let mut buffer = [0u8; 20]; + let i = (-128i8).numtoa(16, &mut buffer); + assert_eq!(&buffer[i..], b"-80"); + + let i = (-32768i16).numtoa(16, &mut buffer); + assert_eq!(&buffer[i..], b"-8000"); + + let i = (-2147483648i32).numtoa(16, &mut buffer); + assert_eq!(&buffer[i..], b"-80000000"); + + let i = (-9223372036854775808i64).numtoa(16, &mut buffer); + assert_eq!(&buffer[i..], b"-8000000000000000"); +} diff -Nru cargo-0.33.0/vendor/openssl/build.rs cargo-0.35.0/vendor/openssl/build.rs --- cargo-0.33.0/vendor/openssl/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -46,6 +46,10 @@ println!("cargo:rustc-cfg=libressl270"); } + if version >= 0x2_07_01_00_0 { + println!("cargo:rustc-cfg=libressl271"); + } + if version >= 0x2_07_03_00_0 { println!("cargo:rustc-cfg=libressl273"); } @@ -53,5 +57,9 @@ if version >= 0x2_08_00_00_0 { println!("cargo:rustc-cfg=libressl280"); } + + if version >= 0x2_09_01_00_0 { + println!("cargo:rustc-cfg=libressl291"); + } } } diff -Nru cargo-0.33.0/vendor/openssl/.cargo-checksum.json cargo-0.35.0/vendor/openssl/.cargo-checksum.json --- cargo-0.33.0/vendor/openssl/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9"} \ No newline at end of file +{"files":{},"package":"a51f452b82d622fc8dd973d7266e9055ac64af25b957d9ced3989142dc61cb6b"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/openssl/Cargo.toml cargo-0.35.0/vendor/openssl/Cargo.toml --- cargo-0.33.0/vendor/openssl/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "openssl" -version = "0.10.16" +version = "0.10.22" authors = ["Steven Fackler "] description = "OpenSSL bindings" readme = "README.md" @@ -36,10 +36,7 @@ version = "0.2" [dependencies.openssl-sys] -version = "0.9.40" -[dev-dependencies.data-encoding] -version = "2.0" - +version = "0.9.45" [dev-dependencies.hex] version = "0.3" diff -Nru cargo-0.33.0/vendor/openssl/CHANGELOG.md cargo-0.35.0/vendor/openssl/CHANGELOG.md --- cargo-0.33.0/vendor/openssl/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,386 @@ +# Change Log + +## [Unreleased] + +## [v0.10.22] + +### Added + +* Added support for the LibreSSL 2.9.x series. + +## [v0.10.21] - 2019-04-30 + +### Fixed + +* Fixed overly conservatifve buffer size checks in `Crypter` when using stream ciphers. + +### Added + +* Added bindings to envelope encryption APIs. +* Added `PkeyRef::size`. + +## [v0.10.20] - 2019-03-20 + +### Added + +* Added `CmsContentInfo::from_der` and `CmsContentInfo::encrypt`. +* Added `X509Ref::verify` and `X509ReqRef::verify`. +* Implemented `PartialEq` and `Eq` for `MessageDigest`. +* Added `MessageDigest::type_` and `EcGroupRef::curve_name`. + +## [v0.10.19] - 2019-03-01 + +### Added + +* The openssl-sys build script now logs the values of environment variables. +* Added `ERR_PACK` to openssl-sys. +* The `ERR_*` functions in openssl-sys are const functions when building against newer Rust versions. +* Implemented `Clone` for `Dsa`. +* Added `SslContextRef::add_session` and `SslContextRef::remove_session`. +* Added `SslSessionRef::time`, `SslSessionRef::timeout`, and `SslSessionRef::protocol_version`. +* Added `SslContextBuilder::set_session_cache_size` and `SslContextRef::session_cache_size`. + +## [v0.10.18] - 2019-02-22 + +### Fixed + +* Fixed the return type of `ssl::cipher_name`. + +## [v0.10.17] - 2019-02-22 + +### Added + +* Implemented `AsRef` and `AsRef<[u8]>` for `OpenSslString`. +* Added `Asn1Integer::from_bn`. +* Added `RsaRef::check_key`. +* Added `Asn1Time::from_str` and `Asn1Time::from_str_x509`. +* Added `Rsa::generate_with_e`. +* Added `Cipher::des_ede3_cfb64`. +* Added `SslCipherRef::standard_name` and `ssl::cipher_name`. + +## [v0.10.16] - 2018-12-16 + +### Added + +* Added SHA3 and SHAKE to `MessageDigest`. +* Added `rand::keep_random_devices_open`. +* Added support for LibreSSL 2.9.0. + +## [v0.10.15] - 2018-10-22 + +### Added + +* Implemented `DoubleEndedIterator` for stack iterators. + +## [v0.10.14] - 2018-10-18 + +### Fixed + +* Made some accidentally exposed internal functions private. + +### Added + +* Added support for LibreSSL 2.8. + +### Changed + +* The OpenSSL version used with the `vendored` feature has been upgraded from 1.1.0 to 1.1.1. + +## [v0.10.13] - 2018-10-14 + +### Fixed + +* Fixed a double-free in the `SslContextBuilder::set_get_session_callback` API. + +### Added + +* Added `SslContextBuilder::set_client_hello_callback`. +* Added support for LibreSSL 2.8.1. +* Added `EcdsaSig::from_der` and `EcdsaSig::to_der`. +* Added PKCS#7 support. + +## [v0.10.12] - 2018-09-13 + +### Fixed + +* Fixed handling of SNI callbacks during renegotiation. + +### Added + +* Added `SslRef::get_shutdown` and `SslRef::set_shutdown`. +* Added support for SRTP in DTLS sessions. +* Added support for LibreSSL 2.8.0. + +## [v0.10.11] - 2018-08-04 + +### Added + +* The new `vendored` cargo feature will cause openssl-sys to compile and statically link to a + vendored copy of OpenSSL. +* Added `SslContextBuilder::set_psk_server_callback`. +* Added `DsaRef::pub_key` and `DsaRef::priv_key`. +* Added `Dsa::from_private_components` and `Dsa::from_public_components`. +* Added `X509NameRef::entries`. + +### Deprecated + +* `SslContextBuilder::set_psk_callback` has been renamed to + `SslContextBuilder::set_psk_client_callback` and deprecated. + +## [v0.10.10] - 2018-06-06 + +### Added + +* Added `SslRef::set_alpn_protos`. +* Added `SslContextBuilder::set_ciphersuites`. + +## [v0.10.9] - 2018-06-01 + +### Fixed + +* Fixed a use-after-free in `CmsContentInfo::sign`. +* `SslRef::servername` now returns `None` rather than panicking on a non-UTF8 name. + +### Added + +* Added `MessageDigest::from_nid`. +* Added `Nid::signature_algorithms`, `Nid::long_name`, and `Nid::short_name`. +* Added early data and early keying material export support for TLS 1.3. +* Added `SslRef::verified_chain`. +* Added `SslRef::servername_raw` which returns a `&[u8]` rather than `&str`. +* Added `SslRef::finished` and `SslRef::peer_finished`. +* Added `X509Ref::digest` to replace `X509Ref::fingerprint`. +* `X509StoreBuilder` and `X509Store` now implement `Sync` and `Send`. + +### Deprecated + +* `X509Ref::fingerprint` has been deprecated in favor of `X509Ref::digest`. + +## [v0.10.8] - 2018-05-20 + +### Fixed + +* `openssl-sys` will now detect Homebrew-installed OpenSSL when installed to a non-default + directory. +* The `X509_V_ERR_INVALID_CALL`, `X509_V_ERR_STORE_LOOKUP`, and + `X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION` constants in `openssl-sys` are now only present when + building against 1.1.0g and up rather than 1.1.0. +* `SslContextBuilder::max_proto_version` and `SslContextBuilder::min_proto_version` are only present + when building against 1.1.0g and up rather than 1.1.0. + +### Added + +* Added `CmsContentInfo::sign`. +* Added `Clone` and `ToOwned` implementations to `Rsa` and `RsaRef` respectively. +* The `min_proto_version` and `max_proto_version` methods are available when linking against + LibreSSL 2.6.1 and up in addition to OpenSSL. +* `X509VerifyParam` is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL. +* ALPN support is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL. +* `Stack` and `StackRef` are now `Sync` and `Send`. + +## [v0.10.7] - 2018-04-30 + +### Added + +* Added `X509Req::public_key` and `X509Req::extensions`. +* Added `RsaPrivateKeyBuilder` to allow control over initialization of optional components of an RSA + private key. +* Added DER encode/decode support to `SslSession`. +* openssl-sys now provides the `DEP_OPENSSL_VERSION_NUMBER` and + `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` environment variables to downstream build scripts which + contains the hex-encoded version number of the OpenSSL or LibreSSL distribution being built + against. The other variables are deprecated. + +## [v0.10.6] - 2018-03-05 + +### Added + +* Added `SslOptions::ENABLE_MIDDLEBOX_COMPAT`. +* Added more `Sync` and `Send` implementations. +* Added `PKeyRef::id`. +* Added `Padding::PKCS1_PSS`. +* Added `Signer::set_rsa_pss_saltlen`, `Signer::set_rsa_mgf1_md`, `Signer::set_rsa_pss_saltlen`, and + `Signer::set_rsa_mgf1_md` +* Added `X509StoreContextRef::verify` to directly verify certificates. +* Added low level ECDSA support. +* Added support for TLSv1.3 custom extensions. (OpenSSL 1.1.1 only) +* Added AES-CCM support. +* Added `EcKey::from_private_components`. +* Added CMAC support. +* Added support for LibreSSL 2.7. +* Added `X509Ref::serial_number`. +* Added `Asn1IntegerRef::to_bn`. +* Added support for TLSv1.3 stateless handshakes. (OpenSSL 1.1.1 only) + +### Changed + +* The Cargo features previously used to gate access to version-specific OpenSSL APIs have been + removed. Those APIs will be available automatically when building against an appropriate OpenSSL + version. +* Fixed `PKey::private_key_from_der` to return a `PKey` rather than a `PKey`. This + is technically a breaking change but the function was pretty useless previously. + +### Deprecated + +* `X509CheckFlags::FLAG_NO_WILDCARDS` has been renamed to `X509CheckFlags::NO_WILDCARDS` and the old + name deprecated. + +## [v0.10.5] - 2018-02-28 + +### Fixed + +* `ErrorStack`'s `Display` implementation no longer writes an empty string if it contains no errors. + +### Added + +* Added `SslRef::version2`. +* Added `Cipher::des_ede3_cbc`. +* Added `SslRef::export_keying_material`. +* Added the ability to push an `Error` or `ErrorStack` back onto OpenSSL's error stack. Various + callback bindings use this to propagate errors properly. +* Added `SslContextBuilder::set_cookie_generate_cb` and `SslContextBuilder::set_cookie_verify_cb`. +* Added `SslContextBuilder::set_max_proto_version`, `SslContextBuilder::set_min_proto_version`, + `SslContextBuilder::max_proto_version`, and `SslContextBuilder::min_proto_version`. + +### Changed + +* Updated `SslConnector`'s default cipher list to match Python's. + +### Deprecated + +* `SslRef::version` has been deprecated. Use `SslRef::version_str` instead. + +## [v0.10.4] - 2018-02-18 + +### Added + +* Added OpenSSL 1.1.1 support. +* Added `Rsa::public_key_from_pem_pkcs1`. +* Added `SslOptions::NO_TLSV1_3`. (OpenSSL 1.1.1 only) +* Added `SslVersion`. +* Added `SslSessionCacheMode` and `SslContextBuilder::set_session_cache_mode`. +* Added `SslContextBuilder::set_new_session_callback`, + `SslContextBuilder::set_remove_session_callback`, and + `SslContextBuilder::set_get_session_callback`. +* Added `SslContextBuilder::set_keylog_callback`. (OpenSSL 1.1.1 only) +* Added `SslRef::client_random` and `SslRef::server_random`. (OpenSSL 1.1.0+ only) + +### Fixed + +* The `SslAcceptorBuilder::mozilla_modern` constructor now disables TLSv1.0 and TLSv1.1 in + accordance with Mozilla's recommendations. + +## [v0.10.3] - 2018-02-12 + +### Added + +* OpenSSL is now automatically detected on FreeBSD systems. +* Added `GeneralName` accessors for `rfc822Name` and `uri` variants. +* Added DES-EDE3 support. + +### Fixed + +* Fixed a memory leak in `X509StoreBuilder::add_cert`. + +## [v0.10.2] - 2018-01-11 + +### Added + +* Added `ConnectConfiguration::set_use_server_name_indication` and + `ConnectConfiguration::set_verify_hostname` for use in contexts where you don't have ownership + of the `ConnectConfiguration`. + +## [v0.10.1] - 2018-01-10 + +### Added + +* Added a `From for ssl::Error` implementation. + +## [v0.10.0] - 2018-01-10 + +### Compatibility + +* openssl 0.10 still uses openssl-sys 0.9, so openssl 0.9 and 0.10 can coexist without issue. + +### Added + +* The `ssl::select_next_proto` function can be used to easily implement the ALPN selection callback + in a "standard" way. +* FIPS mode support is available in the `fips` module. +* Accessors for the Issuer and Issuer Alternative Name fields of X509 certificates have been added. +* The `X509VerifyResult` can now be set in the certificate verification callback via + `X509StoreContextRef::set_error`. + +### Changed + +* All constants have been moved to associated constants of their type. For example, `bn::MSB_ONE` + is now `bn::MsbOption::ONE`. +* Asymmetric key types are now parameterized over what they contain. In OpenSSL, the same type is + used for key parameters, public keys, and private keys. Unfortunately, some APIs simply assume + that certain components are present and will segfault trying to use things that aren't there. + + The `pkey` module contains new tag types named `Params`, `Public`, and `Private`, and the + `Dh`, `Dsa`, `EcKey`, `Rsa`, and `PKey` have a type parameter set to one of those values. This + allows the `Signer` constructor to indicate that it requires a private key at compile time for + example. Previously, `Signer` would simply segfault if provided a key without private + components. +* ALPN support has been changed to more directly model OpenSSL's own APIs. Instead of a single + method used for both the server and client sides which performed everything automatically, the + `SslContextBuilder::set_alpn_protos` and `SslContextBuilder::set_alpn_select_callback` handle + the client and server sides respectively. +* `SslConnector::danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication` + has been removed in favor of new methods which provide more control. The + `ConnectConfiguration::use_server_name_indication` method controls the use of Server Name + Indication (SNI), and the `ConnectConfiguration::verify_hostname` method controls the use of + hostname verification. These can be controlled independently, and if both are disabled, the + domain argument to `ConnectConfiguration::connect` is ignored. +* Shared secret derivation is now handled by the new `derive::Deriver` type rather than + `pkey::PKeyContext`, which has been removed. +* `ssl::Error` is now no longer an enum, and provides more direct access to the relevant state. +* `SslConnectorBuilder::new` has been moved and renamed to `SslConnector::builder`. +* `SslAcceptorBuilder::mozilla_intermediate` and `SslAcceptorBuilder::mozilla_modern` have been + moved to `SslAcceptor` and no longer take the private key and certificate chain. Install those + manually after creating the builder. +* `X509VerifyError` is now `X509VerifyResult` and can now have the "ok" value in addition to error + values. +* `x509::X509FileType` is now `ssl::SslFiletype`. +* Asymmetric key serialization and deserialization methods now document the formats that they + correspond to, and some have been renamed to better indicate that. + +### Removed + +* All deprecated APIs have been removed. +* NPN support has been removed. It has been supersceded by ALPN, and is hopefully no longer being + used in practice. If you still depend on it, please file an issue! +* `SslRef::compression` has been removed. +* Some `ssl::SslOptions` flags have been removed as they no longer do anything. + +## Older + +Look at the [release tags] for information about older releases. + +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.22...master +[v0.10.22]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.21...openssl-v0.10.22 +[v0.10.21]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.20...openssl-v0.10.21 +[v0.10.20]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.19...openssl-v0.10.20 +[v0.10.19]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.18...openssl-v0.10.19 +[v0.10.18]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.17...openssl-v0.10.18 +[v0.10.17]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.16...openssl-v0.10.17 +[v0.10.16]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.15...openssl-v0.10.16 +[v0.10.15]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.14...openssl-v0.10.15 +[v0.10.14]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.13...openssl-v0.10.14 +[v0.10.13]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.12...openssl-v0.10.13 +[v0.10.12]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.11...openssl-v0.10.12 +[v0.10.11]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.10...openssl-v0.10.11 +[v0.10.10]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.9...openssl-v0.10.10 +[v0.10.9]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.8...openssl-v0.10.9 +[v0.10.8]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...openssl-v0.10.8 +[v0.10.7]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.6...openssl-v0.10.7 +[v0.10.6]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.5...openssl-v0.10.6 +[v0.10.5]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.4...openssl-v0.10.5 +[v0.10.4]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.3...openssl-v0.10.4 +[v0.10.3]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.2...openssl-v0.10.3 +[v0.10.2]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.1...openssl-v0.10.2 +[v0.10.1]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.0...openssl-v0.10.1 +[v0.10.0]: https://github.com/sfackler/rust-openssl/compare/v0.9.23...openssl-v0.10.0 +[release tags]: https://github.com/sfackler/rust-openssl/releases diff -Nru cargo-0.33.0/vendor/openssl/examples/mk_certs.rs cargo-0.35.0/vendor/openssl/examples/mk_certs.rs --- cargo-0.33.0/vendor/openssl/examples/mk_certs.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/examples/mk_certs.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,9 +9,11 @@ use openssl::hash::MessageDigest; use openssl::pkey::{PKey, PKeyRef, Private}; use openssl::rsa::Rsa; -use openssl::x509::{X509, X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult}; -use openssl::x509::extension::{AuthorityKeyIdentifier, BasicConstraints, KeyUsage, - SubjectAlternativeName, SubjectKeyIdentifier}; +use openssl::x509::extension::{ + AuthorityKeyIdentifier, BasicConstraints, KeyUsage, SubjectAlternativeName, + SubjectKeyIdentifier, +}; +use openssl::x509::{X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult, X509}; /// Make a CA certificate and private key fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> { @@ -42,11 +44,13 @@ cert_builder.set_not_after(¬_after)?; cert_builder.append_extension(BasicConstraints::new().critical().ca().build()?)?; - cert_builder.append_extension(KeyUsage::new() - .critical() - .key_cert_sign() - .crl_sign() - .build()?)?; + cert_builder.append_extension( + KeyUsage::new() + .critical() + .key_cert_sign() + .crl_sign() + .build()?, + )?; let subject_key_identifier = SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(None, None))?; @@ -104,12 +108,14 @@ cert_builder.append_extension(BasicConstraints::new().build()?)?; - cert_builder.append_extension(KeyUsage::new() - .critical() - .non_repudiation() - .digital_signature() - .key_encipherment() - .build()?)?; + cert_builder.append_extension( + KeyUsage::new() + .critical() + .non_repudiation() + .digital_signature() + .key_encipherment() + .build()?, + )?; let subject_key_identifier = SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(Some(ca_cert), None))?; diff -Nru cargo-0.33.0/vendor/openssl/.pc/disable-vendor.patch/Cargo.toml cargo-0.35.0/vendor/openssl/.pc/disable-vendor.patch/Cargo.toml --- cargo-0.33.0/vendor/openssl/.pc/disable-vendor.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/.pc/disable-vendor.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "openssl" -version = "0.10.16" +version = "0.10.22" authors = ["Steven Fackler "] description = "OpenSSL bindings" readme = "README.md" @@ -36,10 +36,7 @@ version = "0.2" [dependencies.openssl-sys] -version = "0.9.40" -[dev-dependencies.data-encoding] -version = "2.0" - +version = "0.9.45" [dev-dependencies.hex] version = "0.3" diff -Nru cargo-0.33.0/vendor/openssl/src/asn1.rs cargo-0.35.0/vendor/openssl/src/asn1.rs --- cargo-0.33.0/vendor/openssl/src/asn1.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/asn1.rs 2019-05-15 11:26:24.000000000 +0000 @@ -27,13 +27,14 @@ use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_char, c_int, c_long}; +use std::ffi::CString; use std::fmt; use std::ptr; use std::slice; use std::str; use bio::MemBio; -use bn::BigNum; +use bn::{BigNum, BigNumRef}; use error::ErrorStack; use nid::Nid; use string::OpensslString; @@ -105,6 +106,15 @@ } impl Asn1Time { + fn new() -> Result { + ffi::init(); + + unsafe { + let handle = cvt_p(ffi::ASN1_TIME_new())?; + Ok(Asn1Time::from_ptr(handle)) + } + } + fn from_period(period: c_long) -> Result { ffi::init(); @@ -118,6 +128,41 @@ pub fn days_from_now(days: u32) -> Result { Asn1Time::from_period(days as c_long * 60 * 60 * 24) } + + /// Creates a new time corresponding to the specified ASN1 time string. + /// + /// This corresponds to [`ASN1_TIME_set_string`]. + /// + /// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html + pub fn from_str(s: &str) -> Result { + unsafe { + let s = CString::new(s).unwrap(); + + let time = Asn1Time::new()?; + cvt(ffi::ASN1_TIME_set_string(time.as_ptr(), s.as_ptr()))?; + + Ok(time) + } + } + + /// Creates a new time corresponding to the specified X509 time string. + /// + /// This corresponds to [`ASN1_TIME_set_string_X509`]. + /// + /// Requires OpenSSL 1.1.1 or newer. + /// + /// [`ASN1_TIME_set_string_X509`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html + #[cfg(ossl111)] + pub fn from_str_x509(s: &str) -> Result { + unsafe { + let s = CString::new(s).unwrap(); + + let time = Asn1Time::new()?; + cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?; + + Ok(time) + } + } } foreign_type_and_impl_send_sync! { @@ -191,6 +236,19 @@ pub struct Asn1IntegerRef; } +impl Asn1Integer { + /// Converts a bignum to an `Asn1Integer`. + /// + /// Corresponds to [`BN_to_ASN1_INTEGER`]. Also see + /// [`BigNumRef::to_asn1_integer`]. + /// + /// [`BN_to_ASN1_INTEGER`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_to_ASN1_INTEGER.html + /// [`BigNumRef::to_asn1_integer`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer + pub fn from_bn(bn: &BigNumRef) -> Result { + bn.to_asn1_integer() + } +} + impl Asn1IntegerRef { #[allow(missing_docs)] #[deprecated(since = "0.10.6", note = "use to_bn instead")] @@ -306,3 +364,31 @@ } } } + +#[cfg(test)] +mod tests { + use super::*; + + use bn::BigNum; + + /// Tests conversion between BigNum and Asn1Integer. + #[test] + fn bn_cvt() { + fn roundtrip(bn: BigNum) { + let large = Asn1Integer::from_bn(&bn).unwrap(); + assert_eq!(large.to_bn().unwrap(), bn); + } + + roundtrip(BigNum::from_dec_str("1000000000000000000000000000000000").unwrap()); + roundtrip(-BigNum::from_dec_str("1000000000000000000000000000000000").unwrap()); + roundtrip(BigNum::from_u32(1234).unwrap()); + roundtrip(-BigNum::from_u32(1234).unwrap()); + } + + #[test] + fn time_from_str() { + Asn1Time::from_str("99991231235959Z").unwrap(); + #[cfg(ossl111)] + Asn1Time::from_str_x509("99991231235959Z").unwrap(); + } +} diff -Nru cargo-0.33.0/vendor/openssl/src/bn.rs cargo-0.35.0/vendor/openssl/src/bn.rs --- cargo-0.33.0/vendor/openssl/src/bn.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/bn.rs 2019-05-15 11:26:24.000000000 +0000 @@ -120,7 +120,7 @@ /// Dynamically sized large number impelementation /// /// Perform large number mathematics. Create a new BigNum - /// with [`new`]. Perform stanard mathematics on large numbers using + /// with [`new`]. Perform standard mathematics on large numbers using /// methods from [`Dref`] /// /// OpenSSL documenation at [`BN_new`]. @@ -423,7 +423,8 @@ bits.into(), msb.0, odd as c_int, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -439,7 +440,8 @@ bits.into(), msb.0, odd as c_int, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -485,7 +487,8 @@ add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), ptr::null_mut(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -508,7 +511,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -532,7 +536,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -554,7 +559,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -577,7 +583,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -608,7 +615,8 @@ a.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -631,7 +639,8 @@ b.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -654,7 +663,8 @@ b.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -677,7 +687,8 @@ b.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -698,7 +709,8 @@ a.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -719,7 +731,8 @@ a.as_ptr(), p.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -742,7 +755,8 @@ p.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -759,7 +773,8 @@ a.as_ptr(), n.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -780,7 +795,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -803,7 +819,8 @@ checks.into(), ctx.as_ptr(), ptr::null_mut(), - )).map(|r| r != 0) + )) + .map(|r| r != 0) } } @@ -833,7 +850,8 @@ ctx.as_ptr(), do_trial_division as c_int, ptr::null_mut(), - )).map(|r| r != 0) + )) + .map(|r| r != 0) } } @@ -1089,7 +1107,8 @@ n.as_ptr(), n.len() as c_int, ptr::null_mut(), - )).map(|p| BigNum::from_ptr(p)) + )) + .map(|p| BigNum::from_ptr(p)) } } } diff -Nru cargo-0.33.0/vendor/openssl/src/cms.rs cargo-0.35.0/vendor/openssl/src/cms.rs --- cargo-0.33.0/vendor/openssl/src/cms.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/cms.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,7 +14,8 @@ use libc::c_uint; use pkey::{HasPrivate, PKeyRef}; use stack::StackRef; -use x509::{X509, X509Ref}; +use x509::{X509Ref, X509}; +use symm::Cipher; use {cvt, cvt_p}; bitflags! { @@ -122,6 +123,17 @@ } } + from_der! { + /// Deserializes a DER-encoded ContentInfo structure. + /// + /// This corresponds to [`d2i_CMS_ContentInfo`]. + /// + /// [`d2i_CMS_ContentInfo`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509.html + from_der, + CmsContentInfo, + ffi::d2i_CMS_ContentInfo + } + /// Given a signing cert `signcert`, private key `pkey`, a certificate stack `certs`, /// data `data` and flags `flags`, create a CmsContentInfo struct. /// @@ -161,4 +173,67 @@ Ok(CmsContentInfo::from_ptr(cms)) } } + + /// Given a certificate stack `certs`, data `data`, cipher `cipher` and flags `flags`, + /// create a CmsContentInfo struct. + /// + /// OpenSSL documentation at [`CMS_encrypt`] + /// + /// [`CMS_encrypt`]: https://www.openssl.org/docs/manmaster/man3/CMS_encrypt.html + pub fn encrypt( + certs: &StackRef, + data: &[u8], + cipher: Cipher, + flags: CMSOptions, + ) -> Result + { + unsafe { + let data_bio = MemBioSlice::new(data)?; + + let cms = cvt_p(ffi::CMS_encrypt( + certs.as_ptr(), + data_bio.as_ptr(), + cipher.as_ptr(), + flags.bits(), + ))?; + + Ok(CmsContentInfo::from_ptr(cms)) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use stack::Stack; + use x509::X509; + use pkcs12::Pkcs12; + + #[test] + fn cms_encrypt_decrypt() { + // load cert with public key only + let pub_cert_bytes = include_bytes!("../test/cms_pubkey.der"); + let pub_cert = X509::from_der(pub_cert_bytes).expect("failed to load pub cert"); + + // load cert with private key + let priv_cert_bytes = include_bytes!("../test/cms.p12"); + let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert"); + let priv_cert = priv_cert.parse("mypass").expect("failed to parse priv cert"); + + // encrypt cms message using public key cert + let input = String::from("My Message"); + let mut cert_stack = Stack::new().expect("failed to create stack"); + cert_stack.push(pub_cert).expect("failed to add pub cert to stack"); + + let encrypt = CmsContentInfo::encrypt(&cert_stack, &input.as_bytes(), Cipher::des_ede3_cbc(), CMSOptions::empty()) + .expect("failed create encrypted cms"); + let encrypt = encrypt.to_der().expect("failed to create der from cms"); + + // decrypt cms message using private key cert + let decrypt = CmsContentInfo::from_der(&encrypt).expect("failed read cms from der"); + let decrypt = decrypt.decrypt(&priv_cert.pkey, &priv_cert.cert).expect("failed to decrypt cms"); + let decrypt = String::from_utf8(decrypt).expect("failed to create string from cms content"); + + assert_eq!(input, decrypt); + } } diff -Nru cargo-0.33.0/vendor/openssl/src/derive.rs cargo-0.35.0/vendor/openssl/src/derive.rs --- cargo-0.33.0/vendor/openssl/src/derive.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/derive.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,12 +1,12 @@ //! Shared secret derivation. use ffi; +use foreign_types::ForeignTypeRef; use std::marker::PhantomData; use std::ptr; -use foreign_types::ForeignTypeRef; -use {cvt, cvt_p}; use error::ErrorStack; use pkey::{HasPrivate, HasPublic, PKeyRef}; +use {cvt, cvt_p}; /// A type used to derive a shared secret between two keys. pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>); @@ -72,7 +72,8 @@ self.0, buf.as_mut_ptr() as *mut _, &mut len, - )).map(|_| len) + )) + .map(|_| len) } } diff -Nru cargo-0.33.0/vendor/openssl/src/dh.rs cargo-0.35.0/vendor/openssl/src/dh.rs --- cargo-0.33.0/vendor/openssl/src/dh.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/dh.rs 2019-05-15 11:26:24.000000000 +0000 @@ -164,7 +164,8 @@ ).unwrap(); let q = BigNum::from_hex_str( "8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3", - ).unwrap(); + ) + .unwrap(); let dh = Dh::from_params(p, g, q).unwrap(); ctx.set_tmp_dh(&dh).unwrap(); } diff -Nru cargo-0.33.0/vendor/openssl/src/dsa.rs cargo-0.35.0/vendor/openssl/src/dsa.rs --- cargo-0.33.0/vendor/openssl/src/dsa.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/dsa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,8 +9,8 @@ use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use std::fmt; -use std::ptr; use std::mem; +use std::ptr; use bn::{BigNum, BigNumRef}; use error::ErrorStack; @@ -59,6 +59,23 @@ pub struct DsaRef; } +impl Clone for Dsa { + fn clone(&self) -> Dsa { + (**self).to_owned() + } +} + +impl ToOwned for DsaRef { + type Owned = Dsa; + + fn to_owned(&self) -> Dsa { + unsafe { + ffi::DSA_up_ref(self.as_ptr()); + Dsa::from_ptr(self.as_ptr()) + } + } +} + impl DsaRef where T: HasPublic, @@ -321,9 +338,9 @@ mod test { use super::*; use bn::BigNumContext; - use sign::{Signer, Verifier}; use hash::MessageDigest; use pkey::PKey; + use sign::{Signer, Verifier}; #[test] pub fn test_generate() { @@ -390,14 +407,18 @@ BigNumRef::to_owned(q).unwrap(), BigNumRef::to_owned(g).unwrap(), BigNumRef::to_owned(priv_key).unwrap(), - BigNumRef::to_owned(pub_key).unwrap()).unwrap(); + BigNumRef::to_owned(pub_key).unwrap(), + ) + .unwrap(); let priv_key = PKey::from_dsa(priv_key).unwrap(); let pub_key = Dsa::from_public_components( BigNumRef::to_owned(p).unwrap(), BigNumRef::to_owned(q).unwrap(), BigNumRef::to_owned(g).unwrap(), - BigNumRef::to_owned(pub_key).unwrap()).unwrap(); + BigNumRef::to_owned(pub_key).unwrap(), + ) + .unwrap(); let pub_key = PKey::from_dsa(pub_key).unwrap(); let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap(); @@ -408,4 +429,10 @@ verifier.update(TEST_DATA).unwrap(); assert!(verifier.verify(&signature[..]).unwrap()); } + + #[test] + fn clone() { + let key = Dsa::generate(2048).unwrap(); + drop(key.clone()); + } } diff -Nru cargo-0.33.0/vendor/openssl/src/ecdsa.rs cargo-0.35.0/vendor/openssl/src/ecdsa.rs --- cargo-0.33.0/vendor/openssl/src/ecdsa.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ecdsa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -73,7 +73,8 @@ data.len() as c_int, self.as_ptr(), eckey.as_ptr(), - )).map(|x| x == 1) + )) + .map(|x| x == 1) } } @@ -106,21 +107,25 @@ from_der! { /// Decodes a DER-encoded ECDSA signature. /// - /// This corresponds to [`d2i_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_ECDSA_SIG.html + /// This corresponds to [`d2i_ECDSA_SIG`]. + /// + /// [`d2i_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/d2i_ECDSA_SIG.html from_der, EcdsaSig, ffi::d2i_ECDSA_SIG - } + } } impl EcdsaSigRef { to_der! { /// Serializes the ECDSA signature into a DER-encoded ECDSASignature structure. /// - /// This corresponds to [`i2d_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_ECDSA_SIG.html + /// This corresponds to [`i2d_ECDSA_SIG`]. + /// + /// [`i2d_ECDSA_SIG`]: https://www.openssl.org/docs/man1.1.0/crypto/i2d_ECDSA_SIG.html to_der, ffi::i2d_ECDSA_SIG - } + } } cfg_if! { diff -Nru cargo-0.33.0/vendor/openssl/src/ec.rs cargo-0.35.0/vendor/openssl/src/ec.rs --- cargo-0.33.0/vendor/openssl/src/ec.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ec.rs 2019-05-15 11:26:24.000000000 +0000 @@ -163,7 +163,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -192,7 +193,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -220,7 +222,8 @@ self.as_ptr(), order.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -234,6 +237,16 @@ ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0); } } + + /// Returns the name of the curve, if a name is associated. + /// + /// OpenSSL documentation at [`EC_GROUP_get_curve_name`] + /// + /// [`EC_GROUP_get_curve_name`]: https://www.openssl.org/docs/man1.1.0/crypto/EC_GROUP_get_curve_name.html + pub fn curve_name(&self) -> Option { + let nid = unsafe { ffi::EC_GROUP_get_curve_name(self.as_ptr()) }; + if nid > 0 { Some(Nid::from_raw(nid)) } else { None } + } } foreign_type_and_impl_send_sync! { @@ -272,7 +285,8 @@ a.as_ptr(), b.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -296,7 +310,8 @@ q.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -315,7 +330,8 @@ ptr::null(), ptr::null(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -336,7 +352,8 @@ q.as_ptr(), m.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -351,7 +368,8 @@ group.as_ptr(), self.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -437,7 +455,8 @@ x.as_ptr(), y.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -462,7 +481,8 @@ x.as_ptr(), y.as_ptr(), ctx.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } } @@ -688,7 +708,8 @@ cvt(ffi::EC_KEY_set_public_key( key.as_ptr(), public_key.as_ptr(), - )).map(|_| key) + )) + .map(|_| key) }) } } @@ -710,7 +731,8 @@ key.as_ptr(), x.as_ptr(), y.as_ptr(), - )).map(|_| key) + )) + .map(|_| key) }) } } @@ -745,13 +767,15 @@ cvt(ffi::EC_KEY_set_private_key( key.as_ptr(), private_number.as_ptr(), - )).map(|_| key) + )) + .map(|_| key) }) .and_then(|key| { cvt(ffi::EC_KEY_set_public_key( key.as_ptr(), public_key.as_ptr(), - )).map(|_| key) + )) + .map(|_| key) }) } } @@ -803,9 +827,10 @@ #[cfg(test)] mod test { + use hex::FromHex; + use super::*; use bn::{BigNum, BigNumContext}; - use data_encoding::BASE64URL_NOPAD; use nid::Nid; #[test] @@ -889,11 +914,9 @@ #[test] fn key_from_affine_coordinates() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); - let x = BASE64URL_NOPAD - .decode("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes()) + let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e") .unwrap(); - let y = BASE64URL_NOPAD - .decode("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes()) + let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723") .unwrap(); let xbn = BigNum::from_slice(&x).unwrap(); @@ -906,11 +929,9 @@ #[test] fn get_affine_coordinates() { let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); - let x = BASE64URL_NOPAD - .decode("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4".as_bytes()) + let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e") .unwrap(); - let y = BASE64URL_NOPAD - .decode("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM".as_bytes()) + let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723") .unwrap(); let xbn = BigNum::from_slice(&x).unwrap(); diff -Nru cargo-0.33.0/vendor/openssl/src/envelope.rs cargo-0.35.0/vendor/openssl/src/envelope.rs --- cargo-0.33.0/vendor/openssl/src/envelope.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/envelope.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,282 @@ +//! Envelope encryption. +//! +//! # Example +//! +//! ```rust +//! +//! extern crate openssl; +//! +//! use openssl::rsa::Rsa; +//! use openssl::envelope::Seal; +//! use openssl::pkey::PKey; +//! use openssl::symm::Cipher; +//! +//! fn main() { +//! let rsa = Rsa::generate(2048).unwrap(); +//! let key = PKey::from_rsa(rsa).unwrap(); +//! +//! let cipher = Cipher::aes_256_cbc(); +//! let mut seal = Seal::new(cipher, &[key]).unwrap(); +//! +//! let secret = b"My secret message"; +//! let mut encrypted = vec![0; secret.len() + cipher.block_size()]; +//! +//! let mut enc_len = seal.update(secret, &mut encrypted).unwrap(); +//! enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap(); +//! encrypted.truncate(enc_len); +//! } +//! ``` +use error::ErrorStack; +use ffi; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; +use std::cmp; +use std::ptr; +use symm::Cipher; +use {cvt, cvt_p}; + +/// Represents an EVP_Seal context. +pub struct Seal { + ctx: *mut ffi::EVP_CIPHER_CTX, + block_size: usize, + iv: Option>, + enc_keys: Vec>, +} + +impl Seal { + /// Creates a new `Seal`. + pub fn new(cipher: Cipher, pub_keys: &[PKey]) -> Result + where + T: HasPublic, + { + unsafe { + assert!(pub_keys.len() <= c_int::max_value() as usize); + + let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?; + let mut enc_key_ptrs = vec![]; + let mut pub_key_ptrs = vec![]; + let mut enc_keys = vec![]; + for key in pub_keys { + let mut enc_key = vec![0; key.size()]; + let enc_key_ptr = enc_key.as_mut_ptr(); + enc_keys.push(enc_key); + enc_key_ptrs.push(enc_key_ptr); + pub_key_ptrs.push(key.as_ptr()); + } + let mut iv = cipher.iv_len().map(|len| Vec::with_capacity(len)); + let iv_ptr = iv.as_mut().map_or(ptr::null_mut(), |v| v.as_mut_ptr()); + let mut enc_key_lens = vec![0; enc_keys.len()]; + + cvt(ffi::EVP_SealInit( + ctx, + cipher.as_ptr(), + enc_key_ptrs.as_mut_ptr(), + enc_key_lens.as_mut_ptr(), + iv_ptr, + pub_key_ptrs.as_mut_ptr(), + pub_key_ptrs.len() as c_int, + ))?; + + for (buf, len) in enc_keys.iter_mut().zip(&enc_key_lens) { + buf.truncate(*len as usize); + } + + Ok(Seal { + ctx, + block_size: cipher.block_size(), + iv, + enc_keys, + }) + } + } + + /// Returns the initialization vector, if the cipher uses one. + pub fn iv(&self) -> Option<&[u8]> { + self.iv.as_ref().map(|v| &**v) + } + + /// Returns the encrypted keys. + pub fn encrypted_keys(&self) -> &[Vec] { + &self.enc_keys + } + + /// Feeds data from `input` through the cipher, writing encrypted bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Panics + /// + /// Panics if `output.len() < input.len() + block_size` where `block_size` is + /// the block size of the cipher (see `Cipher::block_size`), or if + /// `output.len() > c_int::max_value()`. + pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { + unsafe { + assert!(output.len() >= input.len() + self.block_size); + assert!(output.len() <= c_int::max_value() as usize); + let mut outl = output.len() as c_int; + let inl = input.len() as c_int; + cvt(ffi::EVP_EncryptUpdate( + self.ctx, + output.as_mut_ptr(), + &mut outl, + input.as_ptr(), + inl, + ))?; + Ok(outl as usize) + } + } + + /// Finishes the encryption process, writing any remaining data to `output`. + /// + /// The number of bytes written to `output` is returned. + /// + /// `update` should not be called after this method. + /// + /// # Panics + /// + /// Panics if `output` is less than the cipher's block size. + pub fn finalize(&mut self, output: &mut [u8]) -> Result { + unsafe { + assert!(output.len() >= self.block_size); + let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int; + + cvt(ffi::EVP_SealFinal(self.ctx, output.as_mut_ptr(), &mut outl))?; + + Ok(outl as usize) + } + } +} + +impl Drop for Seal { + fn drop(&mut self) { + unsafe { + ffi::EVP_CIPHER_CTX_free(self.ctx); + } + } +} + +/// Represents an EVP_Open context. +pub struct Open { + ctx: *mut ffi::EVP_CIPHER_CTX, + block_size: usize, +} + +impl Open { + /// Creates a new `Open`. + pub fn new( + cipher: Cipher, + priv_key: &PKeyRef, + iv: Option<&[u8]>, + encrypted_key: &[u8], + ) -> Result + where + T: HasPrivate, + { + unsafe { + assert!(encrypted_key.len() <= c_int::max_value() as usize); + assert!(cipher.iv_len().is_none() || iv.is_some()); + + let ctx = cvt_p(ffi::EVP_CIPHER_CTX_new())?; + cvt(ffi::EVP_OpenInit( + ctx, + cipher.as_ptr(), + encrypted_key.as_ptr(), + encrypted_key.len() as c_int, + iv.map_or(ptr::null(), |v| v.as_ptr()), + priv_key.as_ptr(), + ))?; + Ok(Open { + ctx, + block_size: cipher.block_size(), + }) + } + } + + /// Feeds data from `input` through the cipher, writing decrypted bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Panics + /// + /// Panics if `output.len() < input.len() + block_size` where + /// `block_size` is the block size of the cipher (see `Cipher::block_size`), + /// or if `output.len() > c_int::max_value()`. + pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { + unsafe { + assert!(output.len() >= input.len() + self.block_size); + assert!(output.len() <= c_int::max_value() as usize); + let mut outl = output.len() as c_int; + let inl = input.len() as c_int; + cvt(ffi::EVP_DecryptUpdate( + self.ctx, + output.as_mut_ptr(), + &mut outl, + input.as_ptr(), + inl, + ))?; + Ok(outl as usize) + } + } + + /// Finishes the decryption process, writing any remaining data to `output`. + /// + /// The number of bytes written to `output` is returned. + /// + /// `update` should not be called after this method. + /// + /// # Panics + /// + /// Panics if `output` is less than the cipher's block size. + pub fn finalize(&mut self, output: &mut [u8]) -> Result { + unsafe { + assert!(output.len() >= self.block_size); + let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int; + + cvt(ffi::EVP_OpenFinal(self.ctx, output.as_mut_ptr(), &mut outl))?; + + Ok(outl as usize) + } + } +} + +impl Drop for Open { + fn drop(&mut self) { + unsafe { + ffi::EVP_CIPHER_CTX_free(self.ctx); + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use pkey::PKey; + use symm::Cipher; + + #[test] + fn public_encrypt_private_decrypt() { + let private_pem = include_bytes!("../test/rsa.pem"); + let public_pem = include_bytes!("../test/rsa.pem.pub"); + let private_key = PKey::private_key_from_pem(private_pem).unwrap(); + let public_key = PKey::public_key_from_pem(public_pem).unwrap(); + let cipher = Cipher::aes_256_cbc(); + let secret = b"My secret message"; + + let mut seal = Seal::new(cipher, &[public_key]).unwrap(); + let mut encrypted = vec![0; secret.len() + cipher.block_size()]; + let mut enc_len = seal.update(secret, &mut encrypted).unwrap(); + enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap(); + let iv = seal.iv(); + let encrypted_key = &seal.encrypted_keys()[0]; + + let mut open = Open::new(cipher, &private_key, iv, &encrypted_key).unwrap(); + let mut decrypted = vec![0; enc_len + cipher.block_size()]; + let mut dec_len = open.update(&encrypted[..enc_len], &mut decrypted).unwrap(); + dec_len += open.finalize(&mut decrypted[dec_len..]).unwrap(); + + assert_eq!(&secret[..], &decrypted[..dec_len]); + } +} diff -Nru cargo-0.33.0/vendor/openssl/src/error.rs cargo-0.35.0/vendor/openssl/src/error.rs --- cargo-0.33.0/vendor/openssl/src/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -16,13 +16,13 @@ //! } //! ``` use libc::{c_char, c_int, c_ulong}; -use std::fmt; +use std::borrow::Cow; use std::error; use std::ffi::CStr; +use std::fmt; use std::io; -use std::str; use std::ptr; -use std::borrow::Cow; +use std::str; use ffi; diff -Nru cargo-0.33.0/vendor/openssl/src/hash.rs cargo-0.35.0/vendor/openssl/src/hash.rs --- cargo-0.33.0/vendor/openssl/src/hash.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/hash.rs 2019-05-15 11:26:24.000000000 +0000 @@ -16,7 +16,7 @@ } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq)] pub struct MessageDigest(*const ffi::EVP_MD); impl MessageDigest { @@ -106,6 +106,11 @@ pub fn size(&self) -> usize { unsafe { ffi::EVP_MD_size(self.0) as usize } } + + /// The name of the digest + pub fn type_(&self) -> Nid { + Nid::from_raw(unsafe { ffi::EVP_MD_type(self.0) }) + } } unsafe impl Sync for MessageDigest {} @@ -254,7 +259,7 @@ /// Writes the hash of the data into the supplied buf and resets the XOF hasher. /// The hash will be as long as the buf. #[cfg(ossl111)] - pub fn finish_xof(&mut self, buf: &mut[u8]) -> Result<(), ErrorStack> { + pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> { if self.state == Finalized { self.init()?; } @@ -366,7 +371,7 @@ /// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`. #[cfg(ossl111)] -pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut[u8]) -> Result<(), ErrorStack> { +pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> { let mut h = Hasher::new(t)?; h.update(data)?; h.finish_xof(buf) @@ -388,7 +393,12 @@ fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { let expected = Vec::from_hex(hashtest.1).unwrap(); let mut buf = vec![0; expected.len()]; - hash_xof(hashtype, &Vec::from_hex(hashtest.0).unwrap(), buf.as_mut_slice()).unwrap(); + hash_xof( + hashtype, + &Vec::from_hex(hashtest.0).unwrap(), + buf.as_mut_slice(), + ) + .unwrap(); assert_eq!(buf, expected); } @@ -499,8 +509,9 @@ #[cfg(ossl111)] #[test] fn test_sha3_224() { - let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", - "1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913" + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913", )]; for test in tests.iter() { @@ -511,8 +522,9 @@ #[cfg(ossl111)] #[test] fn test_sha3_256() { - let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", - "b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61" + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61", )]; for test in tests.iter() { @@ -549,8 +561,9 @@ #[cfg(ossl111)] #[test] fn test_shake_128() { - let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", - "49d0697ff508111d8b84f15e46daf135" + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "49d0697ff508111d8b84f15e46daf135", )]; for test in tests.iter() { @@ -561,8 +574,9 @@ #[cfg(ossl111)] #[test] fn test_shake_256() { - let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", - "4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697" + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697", )]; for test in tests.iter() { diff -Nru cargo-0.33.0/vendor/openssl/src/lib.rs cargo-0.35.0/vendor/openssl/src/lib.rs --- cargo-0.33.0/vendor/openssl/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,51 +1,51 @@ //! Bindings to OpenSSL -//! +//! //! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through //! 1.1.1 and LibreSSL versions 2.5 through 2.8 are supported. -//! +//! //! # Building -//! +//! //! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate //! OpenSSL. -//! +//! //! ## Vendored -//! +//! //! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to //! a copy of OpenSSL. The build process requires a C compiler, perl, and make. The OpenSSL version will generally track //! the newest OpenSSL release, and changes to the version are *not* considered breaking changes. -//! +//! //! ```toml //! [dependencies] //! openssl = { version = "0.10", features = ["vendored"] } //! ``` -//! +//! //! The vendored copy will not be configured to automatically find the system's root certificates, but the //! `openssl-probe` crate can be used to do that instead. -//! +//! //! ## Automatic -//! +//! //! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows. //! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation. -//! +//! //! ```not_rust //! # macOS //! $ brew install openssl@1.1 -//! +//! //! # Arch Linux //! $ sudo pacman -S pkg-config openssl -//! +//! //! # Debian and Ubuntu //! $ sudo apt-get install pkg-config libssl-dev -//! +//! //! # Fedora //! $ sudo dnf install pkg-config openssl-devel //! ``` -//! +//! //! ## Manual -//! +//! //! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will //! override the automatic detection logic. -//! +//! //! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and //! `include` subdirectories containing the libraries and headers respectively. //! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and @@ -56,53 +56,53 @@ //! //! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g. //! `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling. -//! +//! //! # Feature Detection -//! +//! //! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the //! functionality available in the version being linked against. This means that methods, constants, and even modules //! will be present when building against one version of OpenSSL but not when building against another! APIs will //! document any version-specific availability restrictions. -//! +//! //! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys` //! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` //! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version: //! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`. -//! +//! //! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile //! against OpenSSL versions that don't support TLSv1.3: -//! +//! //! Cargo.toml: -//! +//! //! ```toml //! [dependencies] //! openssl-sys = "0.9" //! openssl = "0.10" //! ``` -//! +//! //! build.rs: -//! +//! //! ``` //! use std::env; -//! +//! //! fn main() { //! if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") { //! let version = u64::from_str_radix(&v, 16).unwrap(); -//! +//! //! if version >= 0x1_01_01_00_0 { //! println!("cargo:rustc-cfg=openssl111"); //! } //! } //! } //! ``` -//! +//! //! lib.rs: -//! +//! //! ``` //! use openssl::ssl::{SslConnector, SslMethod}; -//! +//! //! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap(); -//! +//! //! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version //! #[cfg(openssl111)] //! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap(); @@ -121,8 +121,6 @@ extern crate openssl_sys as ffi; #[cfg(test)] -extern crate data_encoding; -#[cfg(test)] extern crate hex; #[cfg(test)] extern crate tempdir; @@ -151,6 +149,7 @@ pub mod dsa; pub mod ec; pub mod ecdsa; +pub mod envelope; pub mod error; pub mod ex_data; #[cfg(not(libressl))] diff -Nru cargo-0.33.0/vendor/openssl/src/memcmp.rs cargo-0.35.0/vendor/openssl/src/memcmp.rs --- cargo-0.33.0/vendor/openssl/src/memcmp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/memcmp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -29,8 +29,8 @@ //! assert!(!eq(&a, &b)); //! assert!(!eq(&a, &c)); //! ``` -use libc::size_t; use ffi; +use libc::size_t; /// Returns `true` iff `a` and `b` contain the same bytes. /// diff -Nru cargo-0.33.0/vendor/openssl/src/ocsp.rs cargo-0.35.0/vendor/openssl/src/ocsp.rs --- cargo-0.33.0/vendor/openssl/src/ocsp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ocsp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,16 +1,16 @@ use ffi; use foreign_types::ForeignTypeRef; use libc::{c_int, c_long, c_ulong}; -use std::ptr; use std::mem; +use std::ptr; -use {cvt, cvt_p}; use asn1::Asn1GeneralizedTimeRef; use error::ErrorStack; use hash::MessageDigest; use stack::StackRef; use x509::store::X509StoreRef; -use x509::{X509, X509Ref}; +use x509::{X509Ref, X509}; +use {cvt, cvt_p}; bitflags! { pub struct OcspFlag: c_ulong { @@ -130,7 +130,8 @@ self.next_update.as_ptr(), nsec as c_long, maxsec.map(|n| n as c_long).unwrap_or(-1), - )).map(|_| ()) + )) + .map(|_| ()) } } } @@ -160,7 +161,8 @@ certs.as_ptr(), store.as_ptr(), flags.bits(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -222,7 +224,8 @@ digest.as_ptr(), subject.as_ptr(), issuer.as_ptr(), - )).map(OcspCertId) + )) + .map(OcspCertId) } } } @@ -249,7 +252,8 @@ cvt_p(ffi::OCSP_response_create( status.as_raw(), body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()), - )).map(OcspResponse) + )) + .map(OcspResponse) } } diff -Nru cargo-0.33.0/vendor/openssl/src/pkcs12.rs cargo-0.35.0/vendor/openssl/src/pkcs12.rs --- cargo-0.33.0/vendor/openssl/src/pkcs12.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/pkcs12.rs 2019-05-15 11:26:24.000000000 +0000 @@ -10,7 +10,7 @@ use nid::Nid; use pkey::{HasPrivate, PKey, PKeyRef, Private}; use stack::Stack; -use x509::{X509, X509Ref}; +use x509::{X509Ref, X509}; use {cvt, cvt_p}; foreign_type_and_impl_send_sync! { @@ -196,7 +196,8 @@ self.iter, self.mac_iter, keytype, - )).map(Pkcs12) + )) + .map(Pkcs12) } } } @@ -211,7 +212,7 @@ use pkey::PKey; use rsa::Rsa; use x509::extension::KeyUsage; - use x509::{X509, X509Name}; + use x509::{X509Name, X509}; use super::*; diff -Nru cargo-0.33.0/vendor/openssl/src/pkcs5.rs cargo-0.35.0/vendor/openssl/src/pkcs5.rs --- cargo-0.33.0/vendor/openssl/src/pkcs5.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/pkcs5.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,11 @@ +use ffi; use libc::c_int; use std::ptr; -use ffi; use cvt; +use error::ErrorStack; use hash::MessageDigest; use symm::Cipher; -use error::ErrorStack; #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct KeyIvPair { @@ -59,7 +59,8 @@ ))?; let mut key = vec![0; len as usize]; - let iv_ptr = iv.as_mut() + let iv_ptr = iv + .as_mut() .map(|v| v.as_mut_ptr()) .unwrap_or(ptr::null_mut()); @@ -101,7 +102,8 @@ hash.as_ptr(), key.len() as c_int, key.as_mut_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -131,7 +133,8 @@ maxmem, key.as_mut_ptr() as *mut _, key.len(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -161,7 +164,8 @@ 80000, MessageDigest::sha256(), &mut buf, - ).unwrap(); + ) + .unwrap(); assert_eq!( buf, &[ @@ -198,7 +202,8 @@ 1, MessageDigest::sha512(), &mut buf, - ).unwrap(); + ) + .unwrap(); assert_eq!( &buf[..], &[ @@ -219,7 +224,8 @@ 50, MessageDigest::sha512(), &mut buf, - ).unwrap(); + ) + .unwrap(); assert_eq!( &buf[..], &[ @@ -262,7 +268,8 @@ &data, Some(&salt), 1, - ).unwrap(), + ) + .unwrap(), super::KeyIvPair { key: expected_key, iv: Some(expected_iv), @@ -290,7 +297,8 @@ 1, 0, &mut actual, - ).unwrap(); + ) + .unwrap(); assert_eq!(hex::encode(&actual[..]), expected); } } diff -Nru cargo-0.33.0/vendor/openssl/src/pkcs7.rs cargo-0.35.0/vendor/openssl/src/pkcs7.rs --- cargo-0.33.0/vendor/openssl/src/pkcs7.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/pkcs7.rs 2019-05-15 11:26:24.000000000 +0000 @@ -110,7 +110,8 @@ input_bio.as_ptr(), cipher.as_ptr(), flags.bits, - )).map(Pkcs7) + )) + .map(Pkcs7) } } @@ -142,7 +143,8 @@ certs.as_ptr(), input_bio.as_ptr(), flags.bits, - )).map(Pkcs7) + )) + .map(Pkcs7) } } } @@ -162,7 +164,8 @@ self.as_ptr(), input_bio.as_ptr(), flags.bits, - )).map(|_| output.get_buf().to_owned()) + )) + .map(|_| output.get_buf().to_owned()) } } @@ -206,7 +209,8 @@ cert.as_ptr(), output.as_ptr(), flags.bits, - )).map(|_| output.get_buf().to_owned()) + )) + .map(|_| output.get_buf().to_owned()) } } @@ -244,7 +248,8 @@ indata_bio_ptr, out_bio.as_ptr(), flags.bits, - )).map(|_| ())? + )) + .map(|_| ())? } if let Some(data) = out { @@ -328,7 +333,8 @@ Some(message.as_bytes()), Some(&mut output), flags, - ).expect("should succeed"); + ) + .expect("should succeed"); assert_eq!(message.clone().into_bytes(), output); assert_eq!( diff -Nru cargo-0.33.0/vendor/openssl/src/pkey.rs cargo-0.35.0/vendor/openssl/src/pkey.rs --- cargo-0.33.0/vendor/openssl/src/pkey.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/pkey.rs 2019-05-15 11:26:24.000000000 +0000 @@ -45,21 +45,21 @@ //! } //! ``` -use libc::c_int; -use std::ptr; -use std::mem; -use std::ffi::CString; use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::ffi::CString; +use std::mem; +use std::ptr; -use {cvt, cvt_p}; use bio::MemBioSlice; use dh::Dh; use dsa::Dsa; use ec::EcKey; -use rsa::Rsa; use error::ErrorStack; +use rsa::Rsa; use util::{invoke_passwd_cb, CallbackState}; +use {cvt, cvt_p}; /// A tag type indicating that a key only has parameters. pub enum Params {} @@ -97,22 +97,14 @@ unsafe impl HasParams for Params {} -unsafe impl HasParams for T -where - T: HasPublic, -{ -} +unsafe impl HasParams for T where T: HasPublic {} /// A trait indicating that a key has public components. pub unsafe trait HasPublic {} unsafe impl HasPublic for Public {} -unsafe impl HasPublic for T -where - T: HasPrivate, -{ -} +unsafe impl HasPublic for T where T: HasPrivate {} /// A trait indicating that a key has private components. pub unsafe trait HasPrivate {} @@ -186,6 +178,15 @@ pub fn id(&self) -> Id { unsafe { Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) } } + + /// Returns the maximum size of a signature in bytes. + /// + /// This corresponds to [`EVP_PKEY_size`]. + /// + /// [`EVP_PKEY_size`]: https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_size.html + pub fn size(&self) -> usize { + unsafe { ffi::EVP_PKEY_size(self.as_ptr()) as usize } + } } impl PKeyRef @@ -488,7 +489,8 @@ ptr::null_mut(), Some(invoke_passwd_cb::), &mut cb as *mut _ as *mut _, - )).map(|p| PKey::from_ptr(p)) + )) + .map(|p| PKey::from_ptr(p)) } } @@ -511,7 +513,8 @@ ptr::null_mut(), None, passphrase.as_ptr() as *const _ as *mut _, - )).map(|p| PKey::from_ptr(p)) + )) + .map(|p| PKey::from_ptr(p)) } } } @@ -544,12 +547,12 @@ #[cfg(test)] mod tests { - use symm::Cipher; use dh::Dh; use dsa::Dsa; use ec::EcKey; - use rsa::Rsa; use nid::Nid; + use rsa::Rsa; + use symm::Cipher; use super::*; @@ -557,7 +560,8 @@ fn test_to_password() { let rsa = Rsa::generate(2048).unwrap(); let pkey = PKey::from_rsa(rsa).unwrap(); - let pem = pkey.private_key_to_pem_pkcs8_passphrase(Cipher::aes_128_cbc(), b"foobar") + let pem = pkey + .private_key_to_pem_pkcs8_passphrase(Cipher::aes_128_cbc(), b"foobar") .unwrap(); PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap(); assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); @@ -577,7 +581,8 @@ password_queried = true; password[..6].copy_from_slice(b"mypass"); Ok(6) - }).unwrap(); + }) + .unwrap(); assert!(password_queried); } diff -Nru cargo-0.33.0/vendor/openssl/src/rand.rs cargo-0.35.0/vendor/openssl/src/rand.rs --- cargo-0.33.0/vendor/openssl/src/rand.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/rand.rs 2019-05-15 11:26:24.000000000 +0000 @@ -31,7 +31,7 @@ /// rand_bytes(&mut buf).unwrap(); /// ``` /// -/// [`RAND_bytes`](https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html) +/// [`RAND_bytes`]: https://www.openssl.org/docs/man1.1.0/crypto/RAND_bytes.html pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { unsafe { ffi::init(); diff -Nru cargo-0.33.0/vendor/openssl/src/rsa.rs cargo-0.35.0/vendor/openssl/src/rsa.rs --- cargo-0.33.0/vendor/openssl/src/rsa.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/rsa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -278,6 +278,22 @@ } } } + + /// Validates RSA parameters for correctness + /// + /// This corresponds to [`RSA_check_key`]. + /// + /// [`RSA_check_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_check_key.html + pub fn check_key(&self) -> Result { + unsafe { + let result = ffi::RSA_check_key(self.as_ptr()) as i32; + if result == -1 { + Err(ErrorStack::get()) + } else { + Ok(result == 1) + } + } + } } impl RsaRef @@ -582,11 +598,25 @@ /// Generates a public/private key pair with the specified size. /// /// The public exponent will be 65537. + /// + /// This corresponds to [`RSA_generate_key_ex`]. + /// + /// [`RSA_generate_key_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_generate_key_ex.html pub fn generate(bits: u32) -> Result, ErrorStack> { - ffi::init(); + let e = BigNum::from_u32(ffi::RSA_F4 as u32)?; + Rsa::generate_with_e(bits, &e) + } + + /// Generates a public/private key pair with the specified size and a custom exponent. + /// + /// Unless you have specific needs and know what you're doing, use `Rsa::generate` instead. + /// + /// This corresponds to [`RSA_generate_key_ex`]. + /// + /// [`RSA_generate_key_ex`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_generate_key_ex.html + pub fn generate_with_e(bits: u32, e: &BigNumRef) -> Result, ErrorStack> { unsafe { let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); - let e = BigNum::from_u32(ffi::RSA_F4 as u32)?; cvt(ffi::RSA_generate_key_ex( rsa.0, bits as c_int, @@ -759,7 +789,8 @@ password_queried = true; password[..6].copy_from_slice(b"mypass"); Ok(6) - }).unwrap(); + }) + .unwrap(); assert!(password_queried); } @@ -904,4 +935,10 @@ let key = Rsa::generate(2048).unwrap(); drop(key.clone()); } + + #[test] + fn generate_with_e() { + let e = BigNum::from_u32(0x10001).unwrap(); + Rsa::generate_with_e(2048, &e).unwrap(); + } } diff -Nru cargo-0.33.0/vendor/openssl/src/sha.rs cargo-0.35.0/vendor/openssl/src/sha.rs --- cargo-0.33.0/vendor/openssl/src/sha.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/sha.rs 2019-05-15 11:26:24.000000000 +0000 @@ -16,15 +16,15 @@ //! ```rust //! extern crate openssl; //! extern crate hex; -//! +//! //! use openssl::sha; -//! +//! //! fn main() { //! let mut hasher = sha::Sha256::new(); -//! +//! //! hasher.update(b"Hello, "); //! hasher.update(b"world"); -//! +//! //! let hash = hasher.finish(); //! println!("Hashed \"Hello, world\" to {}", hex::encode(hash)); //! } @@ -45,8 +45,8 @@ //! println!("Hash = {}", hex::encode(hash)); //! } //! ``` -use libc::c_void; use ffi; +use libc::c_void; use std::mem; /// Computes the SHA1 hash of some data. @@ -347,16 +347,18 @@ #[test] fn standalone_384() { let data = b"abc"; - let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ - 7cc2358baeca134c825a7"; + let expected = + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ + 7cc2358baeca134c825a7"; assert_eq!(hex::encode(&sha384(data)[..]), expected); } #[test] fn struct_384() { - let expected = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ - 7cc2358baeca134c825a7"; + let expected = + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ + 7cc2358baeca134c825a7"; let mut hasher = Sha384::new(); hasher.update(b"a"); @@ -367,16 +369,18 @@ #[test] fn standalone_512() { let data = b"abc"; - let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ - fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; + let expected = + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ + fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; assert_eq!(hex::encode(&sha512(data)[..]), expected); } #[test] fn struct_512() { - let expected = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ - fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; + let expected = + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ + fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; let mut hasher = Sha512::new(); hasher.update(b"a"); diff -Nru cargo-0.33.0/vendor/openssl/src/sign.rs cargo-0.35.0/vendor/openssl/src/sign.rs --- cargo-0.33.0/vendor/openssl/src/sign.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/sign.rs 2019-05-15 11:26:24.000000000 +0000 @@ -208,7 +208,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( self.pctx, padding.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -224,7 +225,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( self.pctx, len.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -240,7 +242,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( self.pctx, md.as_ptr() as *mut _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -255,7 +258,8 @@ self.md_ctx, buf.as_ptr() as *const _, buf.len(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -403,7 +407,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( self.pctx, padding.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -419,7 +424,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( self.pctx, len.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -435,7 +441,8 @@ cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( self.pctx, md.as_ptr() as *mut _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -450,7 +457,8 @@ self.md_ctx, buf.as_ptr() as *const _, buf.len(), - )).map(|_| ()) + )) + .map(|_| ()) } } diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/callbacks.rs cargo-0.35.0/vendor/openssl/src/ssl/callbacks.rs --- cargo-0.33.0/vendor/openssl/src/ssl/callbacks.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/callbacks.rs 2019-05-15 11:26:24.000000000 +0000 @@ -23,7 +23,7 @@ #[cfg(any(ossl102, libressl261))] use ssl::AlpnError; #[cfg(ossl111)] -use ssl::{ExtensionContext, ClientHelloResponse}; +use ssl::{ClientHelloResponse, ExtensionContext}; use ssl::{SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, SslSession, SslSessionRef}; #[cfg(ossl111)] use x509::X509Ref; diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/error.rs cargo-0.35.0/vendor/openssl/src/ssl/error.rs --- cargo-0.33.0/vendor/openssl/src/ssl/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -42,7 +42,7 @@ pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL); /// The client hello callback indicated that it needed to be retried. - /// + /// /// Requires OpenSSL 1.1.1 or newer. #[cfg(ossl111)] pub const WANT_CLIENT_HELLO_CB: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_CLIENT_HELLO_CB); diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/mod.rs cargo-0.35.0/vendor/openssl/src/ssl/mod.rs --- cargo-0.33.0/vendor/openssl/src/ssl/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -113,6 +113,26 @@ #[cfg(test)] mod test; +/// Returns the OpenSSL name of a cipher corresponding to an RFC-standard cipher name. +/// +/// If the cipher has no corresponding OpenSSL name, the string `(NONE)` is returned. +/// +/// Requires OpenSSL 1.1.1 or newer. +/// +/// This corresponds to [`OPENSSL_cipher_name`] +/// +/// [`OPENSSL_cipher_name`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html +#[cfg(ossl111)] +pub fn cipher_name(std_name: &str) -> &'static str { + unsafe { + ffi::init(); + + let s = CString::new(std_name).unwrap(); + let ptr = ffi::OPENSSL_cipher_name(s.as_ptr()); + CStr::from_ptr(ptr).to_str().unwrap() + } +} + bitflags! { /// Options controlling the behavior of an `SslContext`. pub struct SslOptions: c_ulong { @@ -830,7 +850,8 @@ self.as_ptr(), file.as_ptr() as *const _, ptr::null(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -868,7 +889,8 @@ self.as_ptr(), sid_ctx.as_ptr(), sid_ctx.len() as c_uint, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -892,7 +914,8 @@ self.as_ptr(), file.as_ptr() as *const _, file_type.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -914,7 +937,8 @@ cvt(ffi::SSL_CTX_use_certificate_chain_file( self.as_ptr(), file.as_ptr() as *const _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -961,7 +985,8 @@ self.as_ptr(), file.as_ptr() as *const _, file_type.as_raw(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -993,7 +1018,8 @@ cvt(ffi::SSL_CTX_set_cipher_list( self.as_ptr(), cipher_list.as_ptr() as *const _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1016,7 +1042,8 @@ cvt(ffi::SSL_CTX_set_ciphersuites( self.as_ptr(), cipher_list.as_ptr() as *const _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1083,7 +1110,8 @@ cvt(ffi::SSL_CTX_set_min_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1103,7 +1131,8 @@ cvt(ffi::SSL_CTX_set_max_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1282,7 +1311,8 @@ cvt( ffi::SSL_CTX_set_tlsext_status_cb(self.as_ptr(), Some(raw_tlsext_status::)) as c_int, - ).map(|_| ()) + ) + .map(|_| ()) } } @@ -1309,10 +1339,7 @@ } } - #[deprecated( - since = "0.10.10", - note = "renamed to `set_psk_client_callback`" - )] + #[deprecated(since = "0.10.10", note = "renamed to `set_psk_client_callback`")] #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] pub fn set_psk_callback(&mut self, callback: F) where @@ -1564,14 +1591,21 @@ parse_cb: ParseFn, ) -> Result<(), ErrorStack> where - AddFn: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) - -> Result, SslAlert> + AddFn: Fn( + &mut SslRef, + ExtensionContext, + Option<(usize, &X509Ref)>, + ) -> Result, SslAlert> + 'static + Sync + Send, T: AsRef<[u8]> + 'static + Sync + Send, - ParseFn: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) - -> Result<(), SslAlert> + ParseFn: Fn( + &mut SslRef, + ExtensionContext, + &[u8], + Option<(usize, &X509Ref)>, + ) -> Result<(), SslAlert> + 'static + Sync + Send, @@ -1617,9 +1651,9 @@ } /// Sets a callback which will be invoked just after the client's hello message is received. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_CTX_set_client_hello_cb`]. /// /// [`SSL_CTX_set_client_hello_cb`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html @@ -1641,6 +1675,17 @@ } } + /// Sets the context's session cache size limit, returning the previous limit. + /// + /// A value of 0 means that the cache size is unbounded. + /// + /// This corresponds to [`SSL_CTX_sess_get_cache_size`]. + /// + /// [`SSL_CTX_sess_get_cache_size`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_sess_set_cache_size.html + pub fn set_session_cache_size(&mut self, size: i32) -> i64 { + unsafe { ffi::SSL_CTX_sess_set_cache_size(self.as_ptr(), size.into()).into() } + } + /// Consumes the builder, returning a new `SslContext`. pub fn build(self) -> SslContext { self.0 @@ -1807,6 +1852,49 @@ pub fn max_early_data(&self) -> u32 { unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) } } + + /// Adds a session to the context's cache. + /// + /// Returns `true` if the session was successfully added to the cache, and `false` if it was already present. + /// + /// This corresponds to [`SSL_CTX_add_session`]. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + /// + /// [`SSL_CTX_add_session`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_remove_session.html + pub unsafe fn add_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_add_session(self.as_ptr(), session.as_ptr()) != 0 + } + + /// Removes a session from the context's cache and marks it as non-resumable. + /// + /// Returns `true` if the session was successfully found and removed, and `false` otherwise. + /// + /// This corresponds to [`SSL_CTX_remove_session`]. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + /// + /// [`SSL_CTX_remove_session`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_remove_session.html + pub unsafe fn remove_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_remove_session(self.as_ptr(), session.as_ptr()) != 0 + } + + /// Returns the context's session cache size limit. + /// + /// A value of 0 means that the cache size is unbounded. + /// + /// This corresponds to [`SSL_CTX_sess_get_cache_size`]. + /// + /// [`SSL_CTX_sess_get_cache_size`]: https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_sess_set_cache_size.html + pub fn session_cache_size(&self) -> i64 { + unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()).into() } + } } /// Information about the state of a cipher. @@ -1866,12 +1954,29 @@ /// /// [`SSL_CIPHER_get_name`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html pub fn name(&self) -> &'static str { - let name = unsafe { + unsafe { let ptr = ffi::SSL_CIPHER_get_name(self.as_ptr()); - CStr::from_ptr(ptr as *const _) - }; + CStr::from_ptr(ptr).to_str().unwrap() + } + } - str::from_utf8(name.to_bytes()).unwrap() + /// Returns the RFC-standard name of the cipher, if one exists. + /// + /// Requires OpenSSL 1.1.1 or newer. + /// + /// This corresponds to [`SSL_CIPHER_standard_name`]. + /// + /// [`SSL_CIPHER_standard_name`]: https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html + #[cfg(ossl111)] + pub fn standard_name(&self) -> Option<&'static str> { + unsafe { + let ptr = ffi::SSL_CIPHER_standard_name(self.as_ptr()); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr).to_str().unwrap()) + } + } } /// Returns the SSL/TLS protocol version that first defined the cipher. @@ -2046,6 +2151,41 @@ unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) } } + /// Returns the time at which the session was established, in seconds since the Unix epoch. + /// + /// This corresponds to [`SSL_SESSION_get_time`]. + /// + /// [`SSL_SESSION_get_time`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + pub fn time(&self) -> i64 { + unsafe { ffi::SSL_SESSION_get_time(self.as_ptr()).into() } + } + + /// Returns the sessions timeout, in seconds. + /// + /// A session older than this time should not be used for session resumption. + /// + /// This corresponds to [`SSL_SESSION_get_timeout`]. + /// + /// [`SSL_SESSION_get_timeout`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + pub fn timeout(&self) -> i64 { + unsafe { ffi::SSL_SESSION_get_timeout(self.as_ptr()).into() } + } + + /// Returns the session's TLS protocol version. + /// + /// Requires OpenSSL 1.1.0 or newer. + /// + /// This corresponds to [`SSL_SESSION_get_protocol_version`]. + /// + /// [`SSL_SESSION_get_protocol_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_time.html + #[cfg(ossl110)] + pub fn protocol_version(&self) -> SslVersion { + unsafe { + let version = ffi::SSL_SESSION_get_protocol_version(self.as_ptr()); + SslVersion(version) + } + } + to_der! { /// Serializes the session into a DER-encoded structure. /// @@ -2753,7 +2893,8 @@ context, contextlen, use_context, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -2783,7 +2924,8 @@ label.len(), context.as_ptr() as *const c_uchar, context.len(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -2861,7 +3003,8 @@ self.as_ptr(), p as *mut c_uchar, response.len() as c_long, - ) as c_int).map(|_| ()) + ) as c_int) + .map(|_| ()) } } @@ -2977,29 +3120,27 @@ } /// Determines if the client's hello message is in the SSLv2 format. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `false` is returned. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_isv2`]. - /// + /// /// [`SSL_client_hello_isv2`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_isv2(&self) -> bool { - unsafe { - ffi::SSL_client_hello_isv2(self.as_ptr()) != 0 - } + unsafe { ffi::SSL_client_hello_isv2(self.as_ptr()) != 0 } } /// Returns the legacy version field of the client's hello message. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_get0_legacy_version`]. - /// + /// /// [`SSL_client_hello_get0_legacy_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_legacy_version(&self) -> Option { @@ -3014,13 +3155,13 @@ } /// Returns the random field of the client's hello message. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `None` is returend. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_get0_random`]. - /// + /// /// [`SSL_client_hello_get0_random`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_random(&self) -> Option<&[u8]> { @@ -3036,13 +3177,13 @@ } /// Returns the session ID field of the client's hello message. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `None` is returend. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_get0_session_id`]. - /// + /// /// [`SSL_client_hello_get0_session_id`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_session_id(&self) -> Option<&[u8]> { @@ -3058,13 +3199,13 @@ } /// Returns the ciphers field of the client's hello message. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `None` is returend. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_get0_ciphers`]. - /// + /// /// [`SSL_client_hello_get0_ciphers`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_ciphers(&self) -> Option<&[u8]> { @@ -3080,13 +3221,13 @@ } /// Returns the compression methods field of the client's hello message. - /// + /// /// This can only be used inside of the client hello callback. Otherwise, `None` is returend. - /// + /// /// Requires OpenSSL 1.1.1 or newer. - /// + /// /// This corresponds to [`SSL_client_hello_get0_compression_methods`]. - /// + /// /// [`SSL_client_hello_get0_compression_methods`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html #[cfg(ossl111)] pub fn client_hello_compression_methods(&self) -> Option<&[u8]> { @@ -3363,13 +3504,13 @@ Ok(n) => return Ok(n), Err(ref e) if e.code() == ErrorCode::ZERO_RETURN => return Ok(0), Err(ref e) if e.code() == ErrorCode::SYSCALL && e.io_error().is_none() => { - return Ok(0) + return Ok(0); } Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {} Err(e) => { return Err(e .into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))) + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))); } } } @@ -3385,7 +3526,7 @@ Err(e) => { return Err(e .into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))) + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))); } } } @@ -3690,9 +3831,14 @@ } cfg_if! { - if #[cfg(ossl110)] { + if #[cfg(any(ossl110, libressl291))] { use ffi::{TLS_method, DTLS_method}; - + } else { + use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method}; + } +} +cfg_if! { + if #[cfg(ossl110)] { unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { ffi::CRYPTO_get_ex_new_index( ffi::CRYPTO_EX_INDEX_SSL_CTX, @@ -3715,8 +3861,6 @@ ) } } else { - use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method}; - unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) } diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/test/mod.rs cargo-0.35.0/vendor/openssl/src/ssl/test/mod.rs --- cargo-0.33.0/vendor/openssl/src/ssl/test/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/test/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1385 @@ +#![allow(unused_imports)] + +use hex; +use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::io::{self, BufReader}; +use std::iter; +use std::mem; +use std::net::UdpSocket; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::path::Path; +use std::process::{Child, ChildStdin, Command, Stdio}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread; +use std::time::Duration; +use tempdir::TempDir; + +use dh::Dh; +use hash::MessageDigest; +use ocsp::{OcspResponse, OcspResponseStatus}; +use pkey::PKey; +use srtp::SrtpProfileId; +use ssl; +use ssl::test::server::Server; +#[cfg(any(ossl110, ossl111, libressl261))] +use ssl::SslVersion; +#[cfg(ossl111)] +use ssl::{ClientHelloResponse, ExtensionContext}; +use ssl::{ + Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor, + SslConnector, SslContext, SslFiletype, SslMethod, SslOptions, SslSessionCacheMode, SslStream, + SslVerifyMode, StatusType, +}; +#[cfg(ossl102)] +use x509::store::X509StoreBuilder; +#[cfg(ossl102)] +use x509::verify::X509CheckFlags; +use x509::{X509Name, X509StoreContext, X509VerifyResult, X509}; + +mod server; + +static ROOT_CERT: &'static [u8] = include_bytes!("../../../test/root-ca.pem"); +static CERT: &'static [u8] = include_bytes!("../../../test/cert.pem"); +static KEY: &'static [u8] = include_bytes!("../../../test/key.pem"); + +#[test] +fn verify_untrusted() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_verify(SslVerifyMode::PEER); + + client.connect_err(); +} + +#[test] +fn verify_trusted() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + + client.connect(); +} + +#[test] +#[cfg(ossl102)] +fn verify_trusted_with_set_cert() { + let server = Server::builder().build(); + + let mut store = X509StoreBuilder::new().unwrap(); + let x509 = X509::from_pem(ROOT_CERT).unwrap(); + store.add_cert(x509).unwrap(); + + let mut client = server.client(); + client.ctx().set_verify(SslVerifyMode::PEER); + client.ctx().set_verify_cert_store(store.build()).unwrap(); + + client.connect(); +} + +#[test] +fn verify_untrusted_callback_override_ok() { + let server = Server::builder().build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); +} + +#[test] +fn verify_untrusted_callback_override_bad() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, _| false); + + client.connect_err(); +} + +#[test] +fn verify_trusted_callback_override_ok() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); +} + +#[test] +fn verify_trusted_callback_override_bad() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, _| false); + + client.connect_err(); +} + +#[test] +fn verify_callback_load_certs() { + let server = Server::builder().build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); +} + +#[test] +fn verify_trusted_get_error_ok() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert_eq!(x509.error(), X509VerifyResult::OK); + true + }); + + client.connect(); +} + +#[test] +fn verify_trusted_get_error_err() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert_ne!(x509.error(), X509VerifyResult::OK); + false + }); + + client.connect_err(); +} + +#[test] +fn verify_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + let expected = "59172d9313e84459bcff27f967e79e6e9217e584"; + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, move |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + let cert = x509.current_cert().unwrap(); + let digest = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!(hex::encode(&digest), expected); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn ssl_verify_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client().build().builder(); + let expected = "59172d9313e84459bcff27f967e79e6e9217e584"; + client + .ssl() + .set_verify_callback(SslVerifyMode::PEER, move |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + let cert = x509.current_cert().unwrap(); + let digest = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!(hex::encode(&digest), expected); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn get_ctx_options() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.options(); +} + +#[test] +fn set_ctx_options() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let opts = ctx.set_options(SslOptions::NO_TICKET); + assert!(opts.contains(SslOptions::NO_TICKET)); +} + +#[test] +fn clear_ctx_options() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_options(SslOptions::ALL); + let opts = ctx.clear_options(SslOptions::ALL); + assert!(!opts.contains(SslOptions::ALL)); +} + +#[test] +fn zero_length_buffers() { + let server = Server::builder().build(); + + let mut s = server.client().connect(); + assert_eq!(s.write(&[]).unwrap(), 0); + assert_eq!(s.read(&mut []).unwrap(), 0); +} + +#[test] +fn peer_certificate() { + let server = Server::builder().build(); + + let s = server.client().connect(); + let cert = s.ssl().peer_certificate().unwrap(); + let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!( + hex::encode(fingerprint), + "59172d9313e84459bcff27f967e79e6e9217e584" + ); +} + +#[test] +fn pending() { + let mut server = Server::builder(); + server.io_cb(|mut s| s.write_all(&[0; 10]).unwrap()); + let server = server.build(); + + let mut s = server.client().connect(); + s.read_exact(&mut [0]).unwrap(); + + assert_eq!(s.ssl().pending(), 9); + assert_eq!(s.read(&mut [0; 10]).unwrap(), 9); +} + +#[test] +fn state() { + let server = Server::builder().build(); + + let s = server.client().connect(); + assert_eq!(s.ssl().state_string(), "SSLOK "); + assert_eq!( + s.ssl().state_string_long(), + "SSL negotiation finished successfully" + ); +} + +/// Tests that when both the client as well as the server use SRTP and their +/// lists of supported protocols have an overlap -- with only ONE protocol +/// being valid for both. +#[test] +#[cfg_attr(libressl291, ignore)] +fn test_connect_with_srtp_ctx() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 60]; + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 60]; + { + let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); + assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); + assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); + } + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .expect("extract"); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf[..], buf2[..]); +} + +/// Tests that when both the client as well as the server use SRTP and their +/// lists of supported protocols have an overlap -- with only ONE protocol +/// being valid for both. +#[test] +#[cfg_attr(libressl291, ignore)] +fn test_connect_with_srtp_ssl() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + let mut profilenames = String::new(); + for profile in ssl.srtp_profiles().unwrap() { + if profilenames.len() > 0 { + profilenames.push(':'); + } + profilenames += profile.name(); + } + assert_eq!( + "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", + profilenames + ); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 60]; + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 60]; + { + let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); + assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); + assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); + } + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .expect("extract"); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf[..], buf2[..]); +} + +/// Tests that when the `SslStream` is created as a server stream, the protocols +/// are correctly advertised to the client. +#[test] +#[cfg(any(ossl102, libressl261))] +fn test_alpn_server_advertise_multiple() { + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) + }); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x08spdy/3.1").unwrap(); + let s = client.connect(); + assert_eq!(s.ssl().selected_alpn_protocol(), Some(&b"spdy/3.1"[..])); +} + +#[test] +#[cfg(any(ossl110))] +fn test_alpn_server_select_none_fatal() { + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client) + .ok_or(ssl::AlpnError::ALERT_FATAL) + }); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + client.connect_err(); +} + +#[test] +#[cfg(any(ossl102, libressl261))] +fn test_alpn_server_select_none() { + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) + }); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + let s = client.connect(); + assert_eq!(None, s.ssl().selected_alpn_protocol()); +} + +#[test] +#[cfg(any(ossl102, libressl261))] +fn test_alpn_server_unilateral() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + let s = client.connect(); + assert_eq!(None, s.ssl().selected_alpn_protocol()); +} + +#[test] +#[should_panic(expected = "blammo")] +fn write_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + } + + impl Write for ExplodingStream { + fn write(&mut self, _: &[u8]) -> io::Result { + panic!("blammo"); + } + + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +#[should_panic(expected = "blammo")] +fn read_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, _: &mut [u8]) -> io::Result { + panic!("blammo"); + } + } + + impl Write for ExplodingStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +#[should_panic(expected = "blammo")] +fn flush_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + } + + impl Write for ExplodingStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + panic!("blammo"); + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +fn refcount_ssl_context() { + let mut ssl = { + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ssl::Ssl::new(&ctx.build()).unwrap() + }; + + { + let new_ctx_a = SslContext::builder(SslMethod::tls()).unwrap().build(); + let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a); + } +} + +#[test] +#[cfg_attr(libressl250, ignore)] +#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] +fn default_verify_paths() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_default_verify_paths().unwrap(); + ctx.set_verify(SslVerifyMode::PEER); + let ctx = ctx.build(); + let s = TcpStream::connect("google.com:443").unwrap(); + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_hostname("google.com").unwrap(); + let mut socket = ssl.connect(s).unwrap(); + + socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); + let mut result = vec![]; + socket.read_to_end(&mut result).unwrap(); + + println!("{}", String::from_utf8_lossy(&result)); + assert!(result.starts_with(b"HTTP/1.0")); + assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); +} + +#[test] +fn add_extra_chain_cert() { + let cert = X509::from_pem(CERT).unwrap(); + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.add_extra_chain_cert(cert).unwrap(); +} + +#[test] +#[cfg(ossl102)] +fn verify_valid_hostname() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + let mut client = client.build().builder(); + client + .ssl() + .param_mut() + .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + client.ssl().param_mut().set_host("foobar.com").unwrap(); + client.connect(); +} + +#[test] +#[cfg(ossl102)] +fn verify_invalid_hostname() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + let mut client = client.build().builder(); + client + .ssl() + .param_mut() + .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + client.ssl().param_mut().set_host("bogus.com").unwrap(); + client.connect_err(); +} + +#[test] +fn connector_valid_hostname() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + let mut s = connector.build().connect("foobar.com", s).unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_invalid_hostname() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + connector.build().connect("bogus.com", s).unwrap_err(); +} + +#[test] +fn connector_invalid_no_hostname_verification() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + let mut s = connector + .build() + .configure() + .unwrap() + .verify_hostname(false) + .connect("bogus.com", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_no_hostname_still_verifies() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); + + let s = server.connect_tcp(); + assert!(connector + .configure() + .unwrap() + .verify_hostname(false) + .connect("fizzbuzz.com", s) + .is_err()); +} + +#[test] +fn connector_no_hostname_can_disable_verify() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_verify(SslVerifyMode::NONE); + let connector = connector.build(); + + let s = server.connect_tcp(); + let mut s = connector + .configure() + .unwrap() + .verify_hostname(false) + .connect("foobar.com", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_client_server_mozilla_intermediate() { + let listener = TcpListener::bind("127.0.0.1:1234").unwrap(); + let port = listener.local_addr().unwrap().port(); + + let t = thread::spawn(move || { + let key = PKey::private_key_from_pem(KEY).unwrap(); + let cert = X509::from_pem(CERT).unwrap(); + let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + acceptor.set_private_key(&key).unwrap(); + acceptor.set_certificate(&cert).unwrap(); + let acceptor = acceptor.build(); + let stream = listener.accept().unwrap().0; + let mut stream = acceptor.accept(stream).unwrap(); + + stream.write_all(b"hello").unwrap(); + }); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + let connector = connector.build(); + + let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); + let mut stream = connector.connect("foobar.com", stream).unwrap(); + + let mut buf = [0; 5]; + stream.read_exact(&mut buf).unwrap(); + assert_eq!(b"hello", &buf); + + t.join().unwrap(); +} + +#[test] +fn connector_client_server_mozilla_modern() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let port = listener.local_addr().unwrap().port(); + + let t = thread::spawn(move || { + let key = PKey::private_key_from_pem(KEY).unwrap(); + let cert = X509::from_pem(CERT).unwrap(); + let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + acceptor.set_private_key(&key).unwrap(); + acceptor.set_certificate(&cert).unwrap(); + let acceptor = acceptor.build(); + let stream = listener.accept().unwrap().0; + let mut stream = acceptor.accept(stream).unwrap(); + + stream.write_all(b"hello").unwrap(); + }); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + let connector = connector.build(); + + let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); + let mut stream = connector.connect("foobar.com", stream).unwrap(); + + let mut buf = [0; 5]; + stream.read_exact(&mut buf).unwrap(); + assert_eq!(b"hello", &buf); + + t.join().unwrap(); +} + +#[test] +fn shutdown() { + let mut server = Server::builder(); + server.io_cb(|mut s| { + assert_eq!(s.read(&mut [0]).unwrap(), 0); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received); + }); + let server = server.build(); + + let mut s = server.client().connect(); + + assert_eq!(s.get_shutdown(), ShutdownState::empty()); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Sent); + assert_eq!(s.get_shutdown(), ShutdownState::SENT); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received); + assert_eq!( + s.get_shutdown(), + ShutdownState::SENT | ShutdownState::RECEIVED + ); +} + +#[test] +fn client_ca_list() { + let names = X509Name::load_client_ca_file("test/root-ca.pem").unwrap(); + assert_eq!(names.len(), 1); + + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_client_ca_list(names); +} + +#[test] +fn cert_store() { + let server = Server::builder().build(); + + let mut client = server.client(); + let cert = X509::from_pem(ROOT_CERT).unwrap(); + client.ctx().cert_store_mut().add_cert(cert).unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + client.connect(); +} + +#[test] +fn tmp_dh_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_tmp_dh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + let dh = include_bytes!("../../../test/dhparams.pem"); + Dh::params_from_pem(dh) + }); + + let server = server.build(); + + let mut client = server.client(); + // TLS 1.3 has no DH suites, so make sure we don't pick that version + #[cfg(ossl111)] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list("EDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(all(ossl101, not(ossl110)))] +fn tmp_ecdh_callback() { + use ec::EcKey; + use nid::Nid; + + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_tmp_ecdh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + EcKey::from_curve_name(Nid::X9_62_PRIME256V1) + }); + + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_cipher_list("ECDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn tmp_dh_callback_ssl() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ssl_cb(|ssl| { + ssl.set_tmp_dh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + let dh = include_bytes!("../../../test/dhparams.pem"); + Dh::params_from_pem(dh) + }); + }); + + let server = server.build(); + + let mut client = server.client(); + // TLS 1.3 has no DH suites, so make sure we don't pick that version + #[cfg(ossl111)] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list("EDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(all(ossl101, not(ossl110)))] +fn tmp_ecdh_callback_ssl() { + use ec::EcKey; + use nid::Nid; + + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ssl_cb(|ssl| { + ssl.set_tmp_ecdh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + EcKey::from_curve_name(Nid::X9_62_PRIME256V1) + }); + }); + + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_cipher_list("ECDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn idle_session() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let ssl = Ssl::new(&ctx).unwrap(); + assert!(ssl.session().is_none()); +} + +#[test] +fn active_session() { + let server = Server::builder().build(); + + let s = server.client().connect(); + + let session = s.ssl().session().unwrap(); + let len = session.master_key_len(); + let mut buf = vec![0; len - 1]; + let copied = session.master_key(&mut buf); + assert_eq!(copied, buf.len()); + let mut buf = vec![0; len + 1]; + let copied = session.master_key(&mut buf); + assert_eq!(copied, len); +} + +#[test] +fn status_callbacks() { + static CALLED_BACK_SERVER: AtomicBool = AtomicBool::new(false); + static CALLED_BACK_CLIENT: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server + .ctx() + .set_status_callback(|ssl| { + CALLED_BACK_SERVER.store(true, Ordering::SeqCst); + let response = OcspResponse::create(OcspResponseStatus::UNAUTHORIZED, None).unwrap(); + let response = response.to_der().unwrap(); + ssl.set_ocsp_status(&response).unwrap(); + Ok(true) + }) + .unwrap(); + + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_status_callback(|ssl| { + CALLED_BACK_CLIENT.store(true, Ordering::SeqCst); + let response = OcspResponse::from_der(ssl.ocsp_status().unwrap()).unwrap(); + assert_eq!(response.status(), OcspResponseStatus::UNAUTHORIZED); + Ok(true) + }) + .unwrap(); + + let mut client = client.build().builder(); + client.ssl().set_status_type(StatusType::OCSP).unwrap(); + + client.connect(); + + assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst)); + assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst)); +} + +#[test] +fn new_session_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_session_id_context(b"foo").unwrap(); + + let server = server.build(); + + let mut client = server.client(); + + client + .ctx() + .set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); + client + .ctx() + .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); + + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn keying_export() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let label = "EXPERIMENTAL test"; + let context = b"my context"; + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 32]; + stream + .ssl() + .export_keying_material(&mut buf, label, Some(context)) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 32]; + stream + .ssl() + .export_keying_material(&mut buf, label, Some(context)) + .unwrap(); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf, buf2); +} + +#[test] +#[cfg(any(ossl110, libressl261))] +fn no_version_overlap() { + let mut server = Server::builder(); + server.ctx().set_min_proto_version(None).unwrap(); + server + .ctx() + .set_max_proto_version(Some(SslVersion::TLS1_1)) + .unwrap(); + #[cfg(any(ossl110g, libressl270))] + assert_eq!(server.ctx().max_proto_version(), Some(SslVersion::TLS1_1)); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_min_proto_version(Some(SslVersion::TLS1_2)) + .unwrap(); + #[cfg(ossl110g)] + assert_eq!(client.ctx().min_proto_version(), Some(SslVersion::TLS1_2)); + client.ctx().set_max_proto_version(None).unwrap(); + + client.connect_err(); +} + +#[test] +#[cfg(ossl111)] +fn custom_extensions() { + static FOUND_EXTENSION: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server + .ctx() + .add_custom_ext( + 12345, + ExtensionContext::CLIENT_HELLO, + |_, _, _| -> Result, _> { unreachable!() }, + |_, _, data, _| { + FOUND_EXTENSION.store(data == b"hello", Ordering::SeqCst); + Ok(()) + }, + ) + .unwrap(); + + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .add_custom_ext( + 12345, + ssl::ExtensionContext::CLIENT_HELLO, + |_, _, _| Ok(Some(b"hello")), + |_, _, _, _| unreachable!(), + ) + .unwrap(); + + client.connect(); + + assert!(FOUND_EXTENSION.load(Ordering::SeqCst)); +} + +fn _check_kinds() { + fn is_send() {} + fn is_sync() {} + + is_send::>(); + is_sync::>(); +} + +#[test] +#[cfg(ossl111)] +fn stateless() { + use super::SslOptions; + + #[derive(Debug)] + struct MemoryStream { + incoming: io::Cursor>, + outgoing: Vec, + } + + impl MemoryStream { + pub fn new() -> Self { + Self { + incoming: io::Cursor::new(Vec::new()), + outgoing: Vec::new(), + } + } + + pub fn extend_incoming(&mut self, data: &[u8]) { + self.incoming.get_mut().extend_from_slice(data); + } + + pub fn take_outgoing(&mut self) -> Outgoing { + Outgoing(&mut self.outgoing) + } + } + + impl Read for MemoryStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let n = self.incoming.read(buf)?; + if self.incoming.position() == self.incoming.get_ref().len() as u64 { + self.incoming.set_position(0); + self.incoming.get_mut().clear(); + } + if n == 0 { + return Err(io::Error::new( + io::ErrorKind::WouldBlock, + "no data available", + )); + } + Ok(n) + } + } + + impl Write for MemoryStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.outgoing.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + + pub struct Outgoing<'a>(&'a mut Vec); + + impl<'a> Drop for Outgoing<'a> { + fn drop(&mut self) { + self.0.clear(); + } + } + + impl<'a> ::std::ops::Deref for Outgoing<'a> { + type Target = [u8]; + fn deref(&self) -> &[u8] { + &self.0 + } + } + + impl<'a> AsRef<[u8]> for Outgoing<'a> { + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + + fn send(from: &mut MemoryStream, to: &mut MemoryStream) { + to.extend_incoming(&from.take_outgoing()); + } + + fn hs( + stream: Result, HandshakeError>, + ) -> Result, MidHandshakeSslStream> { + match stream { + Ok(stream) => Ok(stream), + Err(HandshakeError::WouldBlock(stream)) => Err(stream), + Err(e) => panic!("unexpected error: {:?}", e), + } + } + + // + // Setup + // + + let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap(); + client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT); + let client_stream = Ssl::new(&client_ctx.build()).unwrap(); + + let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap(); + server_ctx + .set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + server_ctx + .set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + const COOKIE: &[u8] = b"chocolate chip"; + server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| { + buf[0..COOKIE.len()].copy_from_slice(COOKIE); + Ok(COOKIE.len()) + }); + server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE); + let mut server_stream = + ssl::SslStreamBuilder::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()); + + // + // Handshake + // + + // Initial ClientHello + let mut client_stream = hs(client_stream.connect(MemoryStream::new())).unwrap_err(); + send(client_stream.get_mut(), server_stream.get_mut()); + // HelloRetryRequest + assert!(!server_stream.stateless().unwrap()); + send(server_stream.get_mut(), client_stream.get_mut()); + // Second ClientHello + let mut client_stream = hs(client_stream.handshake()).unwrap_err(); + send(client_stream.get_mut(), server_stream.get_mut()); + // OldServerHello + assert!(server_stream.stateless().unwrap()); + let mut server_stream = hs(server_stream.accept()).unwrap_err(); + send(server_stream.get_mut(), client_stream.get_mut()); + // Finished + let mut client_stream = hs(client_stream.handshake()).unwrap(); + send(client_stream.get_mut(), server_stream.get_mut()); + hs(server_stream.handshake()).unwrap(); +} + +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +#[test] +fn psk_ciphers() { + const CIPHER: &'static str = "PSK-AES128-CBC-SHA"; + const PSK: &[u8] = b"thisisaverysecurekey"; + const CLIENT_IDENT: &[u8] = b"thisisaclient"; + static CLIENT_CALLED: AtomicBool = AtomicBool::new(false); + static SERVER_CALLED: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_cipher_list(CIPHER).unwrap(); + server.ctx().set_psk_server_callback(|_, identity, psk| { + assert!(identity.unwrap_or(&[]) == CLIENT_IDENT); + psk[..PSK.len()].copy_from_slice(PSK); + SERVER_CALLED.store(true, Ordering::SeqCst); + Ok(PSK.len()) + }); + + let server = server.build(); + + let mut client = server.client(); + // This test relies on TLS 1.2 suites + #[cfg(ossl111)] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list(CIPHER).unwrap(); + client + .ctx() + .set_psk_client_callback(move |_, _, identity, psk| { + identity[..CLIENT_IDENT.len()].copy_from_slice(&CLIENT_IDENT); + identity[CLIENT_IDENT.len()] = 0; + psk[..PSK.len()].copy_from_slice(PSK); + CLIENT_CALLED.store(true, Ordering::SeqCst); + Ok(PSK.len()) + }); + + client.connect(); + + assert!(CLIENT_CALLED.load(Ordering::SeqCst) && SERVER_CALLED.load(Ordering::SeqCst)); +} + +#[test] +fn sni_callback_swapped_ctx() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_servername_callback(|_, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(()) + }); + + let keyed_ctx = mem::replace(server.ctx(), ctx).build(); + server.ssl_cb(move |ssl| ssl.set_ssl_context(&keyed_ctx).unwrap()); + + let server = server.build(); + + server.client().connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(ossl111)] +fn client_hello() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_client_hello_callback(|ssl, _| { + assert!(!ssl.client_hello_isv2()); + assert_eq!(ssl.client_hello_legacy_version(), Some(SslVersion::TLS1_2)); + assert!(ssl.client_hello_random().is_some()); + assert!(ssl.client_hello_session_id().is_some()); + assert!(ssl.client_hello_ciphers().is_some()); + assert!(ssl.client_hello_compression_methods().is_some()); + + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(ClientHelloResponse::SUCCESS) + }); + + let server = server.build(); + server.client().connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(ossl111)] +fn openssl_cipher_name() { + assert_eq!( + super::cipher_name("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"), + "ECDHE-RSA-AES256-SHA384", + ); + + assert_eq!(super::cipher_name("asdf"), "(NONE)"); +} + +#[test] +fn session_cache_size() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_session_cache_size(1234); + let ctx = ctx.build(); + assert_eq!(ctx.session_cache_size(), 1234); +} diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/test/server.rs cargo-0.35.0/vendor/openssl/src/ssl/test/server.rs --- cargo-0.33.0/vendor/openssl/src/ssl/test/server.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/test/server.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,167 @@ +use std::io::{Read, Write}; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::thread::{self, JoinHandle}; + +use ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslRef, SslStream}; + +pub struct Server { + handle: Option>, + addr: SocketAddr, +} + +impl Drop for Server { + fn drop(&mut self) { + if !thread::panicking() { + self.handle.take().unwrap().join().unwrap(); + } + } +} + +impl Server { + pub fn builder() -> Builder { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_certificate_chain_file("test/cert.pem").unwrap(); + ctx.set_private_key_file("test/key.pem", SslFiletype::PEM) + .unwrap(); + + Builder { + ctx, + ssl_cb: Box::new(|_| {}), + io_cb: Box::new(|_| {}), + should_error: false, + } + } + + pub fn client(&self) -> ClientBuilder { + ClientBuilder { + ctx: SslContext::builder(SslMethod::tls()).unwrap(), + addr: self.addr, + } + } + + pub fn connect_tcp(&self) -> TcpStream { + TcpStream::connect(self.addr).unwrap() + } +} + +pub struct Builder { + ctx: SslContextBuilder, + ssl_cb: Box, + io_cb: Box) + Send>, + should_error: bool, +} + +impl Builder { + pub fn ctx(&mut self) -> &mut SslContextBuilder { + &mut self.ctx + } + + pub fn ssl_cb(&mut self, cb: F) + where + F: 'static + FnMut(&mut SslRef) + Send, + { + self.ssl_cb = Box::new(cb); + } + + pub fn io_cb(&mut self, cb: F) + where + F: 'static + FnMut(SslStream) + Send, + { + self.io_cb = Box::new(cb); + } + + pub fn should_error(&mut self) { + self.should_error = true; + } + + pub fn build(self) -> Server { + let ctx = self.ctx.build(); + let socket = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = socket.local_addr().unwrap(); + let mut ssl_cb = self.ssl_cb; + let mut io_cb = self.io_cb; + let should_error = self.should_error; + + let handle = thread::spawn(move || { + let socket = socket.accept().unwrap().0; + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl_cb(&mut ssl); + let r = ssl.accept(socket); + if should_error { + r.unwrap_err(); + } else { + let mut socket = r.unwrap(); + socket.write_all(&[0]).unwrap(); + io_cb(socket); + } + }); + + Server { + handle: Some(handle), + addr, + } + } +} + +pub struct ClientBuilder { + ctx: SslContextBuilder, + addr: SocketAddr, +} + +impl ClientBuilder { + pub fn ctx(&mut self) -> &mut SslContextBuilder { + &mut self.ctx + } + + pub fn build(self) -> Client { + Client { + ctx: self.ctx.build(), + addr: self.addr, + } + } + + pub fn connect(self) -> SslStream { + self.build().builder().connect() + } + + pub fn connect_err(self) { + self.build().builder().connect_err(); + } +} + +pub struct Client { + ctx: SslContext, + addr: SocketAddr, +} + +impl Client { + pub fn builder(&self) -> ClientSslBuilder { + ClientSslBuilder { + ssl: Ssl::new(&self.ctx).unwrap(), + addr: self.addr, + } + } +} + +pub struct ClientSslBuilder { + ssl: Ssl, + addr: SocketAddr, +} + +impl ClientSslBuilder { + pub fn ssl(&mut self) -> &mut SslRef { + &mut self.ssl + } + + pub fn connect(self) -> SslStream { + let socket = TcpStream::connect(self.addr).unwrap(); + let mut s = self.ssl.connect(socket).unwrap(); + s.read_exact(&mut [0]).unwrap(); + s + } + + pub fn connect_err(self) { + let socket = TcpStream::connect(self.addr).unwrap(); + self.ssl.connect(socket).unwrap_err(); + } +} diff -Nru cargo-0.33.0/vendor/openssl/src/ssl/test.rs cargo-0.35.0/vendor/openssl/src/ssl/test.rs --- cargo-0.33.0/vendor/openssl/src/ssl/test.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/ssl/test.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1841 +0,0 @@ -#![allow(unused_imports)] - -use std::env; -use std::fs::File; -use std::io::prelude::*; -use std::io::{self, BufReader}; -use std::iter; -use std::mem; -use std::net::{SocketAddr, TcpListener, TcpStream}; -use std::path::Path; -use std::process::{Child, ChildStdin, Command, Stdio}; -use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT}; -use std::thread; -use std::time::Duration; -use tempdir::TempDir; - -use dh::Dh; -use hash::MessageDigest; -use ocsp::{OcspResponse, OcspResponseStatus}; -use pkey::PKey; -use srtp::SrtpProfileId; -use ssl; -#[cfg(any(ossl110, ossl111, libressl261))] -use ssl::SslVersion; -use ssl::{ - Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor, - SslConnector, SslContext, SslFiletype, SslMethod, SslSessionCacheMode, SslStream, - SslVerifyMode, StatusType, -}; -#[cfg(any(ossl102, ossl110))] -use x509::verify::X509CheckFlags; -use x509::{X509, X509Name, X509StoreContext, X509VerifyResult}; - -use std::net::UdpSocket; - -static ROOT_CERT: &'static [u8] = include_bytes!("../../test/root-ca.pem"); -static CERT: &'static [u8] = include_bytes!("../../test/cert.pem"); -static KEY: &'static [u8] = include_bytes!("../../test/key.pem"); - -fn next_addr() -> SocketAddr { - use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; - static PORT: AtomicUsize = ATOMIC_USIZE_INIT; - let port = 15411 + PORT.fetch_add(1, Ordering::SeqCst); - - format!("127.0.0.1:{}", port).parse().unwrap() -} - -struct Server { - p: Child, - _temp: TempDir, -} - -impl Server { - fn spawn(args: &[&str], input: Option>) -> (Server, SocketAddr) { - let td = TempDir::new("openssl").unwrap(); - let cert = td.path().join("cert.pem"); - let key = td.path().join("key.pem"); - File::create(&cert).unwrap().write_all(CERT).unwrap(); - File::create(&key).unwrap().write_all(KEY).unwrap(); - - let addr = next_addr(); - let mut child = Command::new("openssl") - .arg("s_server") - .arg("-accept") - .arg(addr.port().to_string()) - .args(args) - .arg("-cert") - .arg(&cert) - .arg("-key") - .arg(&key) - .arg("-no_dhe") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .stdin(Stdio::piped()) - .spawn() - .unwrap(); - let stdin = child.stdin.take().unwrap(); - if let Some(mut input) = input { - thread::spawn(move || input(stdin)); - } - ( - Server { - p: child, - _temp: td, - }, - addr, - ) - } - - fn new_tcp(args: &[&str]) -> (Server, TcpStream) { - let (mut server, addr) = Server::spawn(args, None); - for _ in 0..20 { - match TcpStream::connect(&addr) { - Ok(s) => return (server, s), - Err(ref e) if e.kind() == io::ErrorKind::ConnectionRefused => { - if let Some(exit_status) = server.p.try_wait().expect("try_wait") { - panic!("server exited: {}", exit_status); - } - thread::sleep(Duration::from_millis(100)); - } - Err(e) => panic!("wut: {}", e), - } - } - panic!("server never came online"); - } - - fn new() -> (Server, TcpStream) { - Server::new_tcp(&["-www"]) - } - - #[allow(dead_code)] - fn new_alpn() -> (Server, TcpStream) { - Server::new_tcp(&[ - "-www", - "-nextprotoneg", - "http/1.1,spdy/3.1", - "-alpn", - "http/1.1,spdy/3.1", - ]) - } -} - -impl Drop for Server { - fn drop(&mut self) { - let _ = self.p.kill(); - let _ = self.p.wait(); - } -} - -macro_rules! run_test( - ($module:ident, $blk:expr) => ( - #[cfg(test)] - mod $module { - use std::io; - use std::io::prelude::*; - use std::path::Path; - use std::net::UdpSocket; - use std::net::TcpStream; - use ssl; - use ssl::SslMethod; - use ssl::{SslContext, Ssl, SslStream, SslVerifyMode, SslOptions}; - use hash::MessageDigest; - use x509::{X509StoreContext, X509VerifyResult}; - #[cfg(any(ossl102, ossl110))] - use x509::X509; - #[cfg(any(ossl102, ossl110))] - use x509::store::X509StoreBuilder; - use hex::FromHex; - use foreign_types::ForeignTypeRef; - use super::Server; - #[cfg(any(ossl102, ossl110))] - use super::ROOT_CERT; - - #[test] - fn sslv23() { - let (_s, stream) = Server::new(); - $blk(SslMethod::tls(), stream); - } - } - ); -); - -run_test!(new_ctx, |method, _| { - SslContext::builder(method).unwrap(); -}); - -run_test!(verify_untrusted, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => panic!("expected failure"), - Err(err) => println!("error {:?}", err), - } -}); - -run_test!(verify_trusted, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } -}); - -#[cfg(any(ossl102, ossl110))] -run_test!(verify_trusted_with_set_cert, |method, stream| { - let x509 = X509::from_pem(ROOT_CERT).unwrap(); - let mut store = X509StoreBuilder::new().unwrap(); - store.add_cert(x509).unwrap(); - - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - - match ctx.set_verify_cert_store(store.build()) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } -}); - -run_test!(verify_untrusted_callback_override_ok, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, _| true); - - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } -}); - -run_test!(verify_untrusted_callback_override_bad, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, _| false); - - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); -}); - -run_test!(verify_trusted_callback_override_ok, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, _| true); - - match ctx.set_ca_file(&Path::new("test/cert.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } -}); - -run_test!(verify_trusted_callback_override_bad, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, _| false); - - match ctx.set_ca_file(&Path::new("test/cert.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); -}); - -run_test!(verify_callback_load_certs, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, x509_ctx| { - assert!(x509_ctx.current_cert().is_some()); - true - }); - - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_ok()); -}); - -run_test!(verify_trusted_get_error_ok, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, x509_ctx| { - assert!(x509_ctx.error() == X509VerifyResult::OK); - true - }); - - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_ok()); -}); - -run_test!(verify_trusted_get_error_err, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, |_, x509_ctx| { - assert_ne!(x509_ctx.error(), X509VerifyResult::OK); - false - }); - - assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); -}); - -run_test!(verify_callback_data, |method, stream| { - let mut ctx = SslContext::builder(method).unwrap(); - - // Node id was generated as SHA256 hash of certificate "test/cert.pem" - // in DER format. - // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 - // Please update if "test/cert.pem" will ever change - let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; - let node_id = Vec::from_hex(node_hash_str).unwrap(); - ctx.set_verify_callback(SslVerifyMode::PEER, move |_preverify_ok, x509_ctx| { - let cert = x509_ctx.current_cert(); - match cert { - None => false, - Some(cert) => { - let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); - node_id == &*fingerprint - } - } - }); - ctx.set_verify_depth(1); - - match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } -}); - -run_test!(ssl_verify_callback, |method, stream| { - use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; - - static CHECKED: AtomicUsize = ATOMIC_USIZE_INIT; - - let ctx = SslContext::builder(method).unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - - let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; - let node_id = Vec::from_hex(node_hash_str).unwrap(); - ssl.set_verify_callback(SslVerifyMode::PEER, move |_, x509| { - CHECKED.store(1, Ordering::SeqCst); - match x509.current_cert() { - None => false, - Some(cert) => { - let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); - node_id == &*fingerprint - } - } - }); - - match ssl.connect(stream) { - Ok(_) => (), - Err(err) => panic!("Expected success, got {:?}", err), - } - - assert_eq!(CHECKED.load(Ordering::SeqCst), 1); -}); - -// Make sure every write call translates to a write call to the underlying socket. -#[test] -fn test_write_hits_stream() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let stream = TcpStream::connect(addr).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); - - stream.write_all(b"hello").unwrap(); - stream - }); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let stream = listener.accept().unwrap().0; - let mut stream = Ssl::new(&ctx.build()).unwrap().accept(stream).unwrap(); - - let mut buf = [0; 5]; - assert_eq!(5, stream.read(&mut buf).unwrap()); - assert_eq!(&b"hello"[..], &buf[..]); - guard.join().unwrap(); -} - -#[test] -fn test_set_certificate_and_private_key() { - let key = include_bytes!("../../test/key.pem"); - let key = PKey::private_key_from_pem(key).unwrap(); - let cert = include_bytes!("../../test/cert.pem"); - let cert = X509::from_pem(cert).unwrap(); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_private_key(&key).unwrap(); - ctx.set_certificate(&cert).unwrap(); - - assert!(ctx.check_private_key().is_ok()); -} - -run_test!(get_ctx_options, |method, _| { - let ctx = SslContext::builder(method).unwrap(); - ctx.options(); -}); - -run_test!(set_ctx_options, |method, _| { - let mut ctx = SslContext::builder(method).unwrap(); - let opts = ctx.set_options(SslOptions::NO_TICKET); - assert!(opts.contains(SslOptions::NO_TICKET)); -}); - -run_test!(clear_ctx_options, |method, _| { - let mut ctx = SslContext::builder(method).unwrap(); - ctx.set_options(SslOptions::ALL); - let opts = ctx.clear_options(SslOptions::ALL); - assert!(!opts.contains(SslOptions::ALL)); -}); - -#[test] -fn test_write() { - let (_s, stream) = Server::new(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); - stream.write_all("hello".as_bytes()).unwrap(); - stream.flush().unwrap(); - stream.write_all(" there".as_bytes()).unwrap(); - stream.flush().unwrap(); -} - -#[test] -fn zero_length_buffers() { - let (_s, stream) = Server::new(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); - - assert_eq!(stream.write(b"").unwrap(), 0); - assert_eq!(stream.read(&mut []).unwrap(), 0); -} - -run_test!(get_peer_certificate, |method, stream| { - let ctx = SslContext::builder(method).unwrap(); - let stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); - let cert = stream.ssl().peer_certificate().unwrap(); - let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); - let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; - let node_id = Vec::from_hex(node_hash_str).unwrap(); - assert_eq!(node_id, &*fingerprint) -}); - -#[test] -fn test_read() { - let (_s, tcp) = Server::new(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap(); - stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); - stream.flush().unwrap(); - io::copy(&mut stream, &mut io::sink()) - .ok() - .expect("read error"); -} - -#[test] -fn test_pending() { - let (_s, tcp) = Server::new(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap(); - stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap(); - stream.flush().unwrap(); - - // wait for the response and read first byte... - let mut buf = [0u8; 16 * 1024]; - stream.read(&mut buf[..1]).unwrap(); - - let pending = stream.ssl().pending(); - let len = stream.read(&mut buf[1..]).unwrap(); - - assert_eq!(pending, len); - - stream.read(&mut buf[..1]).unwrap(); - - let pending = stream.ssl().pending(); - let len = stream.read(&mut buf[1..]).unwrap(); - assert_eq!(pending, len); -} - -#[test] -fn test_state() { - let (_s, tcp) = Server::new(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let stream = Ssl::new(&ctx.build()).unwrap().connect(tcp).unwrap(); - assert_eq!(stream.ssl().state_string(), "SSLOK "); - assert_eq!( - stream.ssl().state_string_long(), - "SSL negotiation finished successfully" - ); -} - -/// Tests that connecting with the client using ALPN, but the server not does not -/// break the existing connection behavior. -#[test] -#[cfg(any(ossl102, libressl261))] -fn test_connect_with_unilateral_alpn() { - let (_s, stream) = Server::new(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x08http/1.1\x08spdy/3.1").unwrap(); - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(stream) => stream, - Err(err) => panic!("Expected success, got {:?}", err), - }; - // Since the socket to which we connected is not configured to use ALPN, - // there should be no selected protocol... - assert!(stream.ssl().selected_alpn_protocol().is_none()); -} - -/// Tests that when both the client as well as the server use ALPN and their -/// lists of supported protocols have an overlap, the correct protocol is chosen. -#[test] -#[cfg(any(ossl102, libressl261))] -fn test_connect_with_alpn_successful_multiple_matching() { - let (_s, stream) = Server::new_alpn(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x08http/1.1\x08spdy/3.1").unwrap(); - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(stream) => stream, - Err(err) => panic!("Expected success, got {:?}", err), - }; - // The server prefers "http/1.1", so that is chosen, even though the client - // would prefer "spdy/3.1" - assert_eq!(b"http/1.1", stream.ssl().selected_alpn_protocol().unwrap()); -} - -/// Tests that when both the client as well as the server use ALPN and their -/// lists of supported protocols have an overlap -- with only ONE protocol -/// being valid for both. -#[test] -#[cfg(any(ossl102, libressl261))] -fn test_connect_with_alpn_successful_single_match() { - let (_s, stream) = Server::new_alpn(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x08spdy/3.1").unwrap(); - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - let stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(stream) => stream, - Err(err) => panic!("Expected success, got {:?}", err), - }; - // The client now only supports one of the server's protocols, so that one - // is used. - assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); -} - -/// Tests that when both the client as well as the server use SRTP and their -/// lists of supported protocols have an overlap -- with only ONE protocol -/// being valid for both. -#[test] -fn test_connect_with_srtp_ctx() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); - ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") - .unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - - let mut buf = [0; 60]; - stream - .ssl() - .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) - .unwrap(); - - stream.write_all(&[0]).unwrap(); - - buf - }); - - let stream = TcpStream::connect(addr).unwrap(); - let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); - ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") - .unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - - let mut buf = [1; 60]; - { - let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); - assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); - assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); - } - stream - .ssl() - .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) - .expect("extract"); - - stream.read_exact(&mut [0]).unwrap(); - - let buf2 = guard.join().unwrap(); - - assert_eq!(buf[..], buf2[..]); -} - -/// Tests that when both the client as well as the server use SRTP and their -/// lists of supported protocols have an overlap -- with only ONE protocol -/// being valid for both. -#[test] -fn test_connect_with_srtp_ssl() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") - .unwrap(); - let mut profilenames = String::new(); - for profile in ssl.srtp_profiles().unwrap() { - if profilenames.len() > 0 { - profilenames.push(':'); - } - profilenames += profile.name(); - } - assert_eq!( - "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", - profilenames - ); - let mut stream = ssl.accept(stream).unwrap(); - - let mut buf = [0; 60]; - stream - .ssl() - .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) - .unwrap(); - - stream.write_all(&[0]).unwrap(); - - buf - }); - - let stream = TcpStream::connect(addr).unwrap(); - let ctx = SslContext::builder(SslMethod::dtls()).unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") - .unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - - let mut buf = [1; 60]; - { - let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); - assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); - assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); - } - stream - .ssl() - .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) - .expect("extract"); - - stream.read_exact(&mut [0]).unwrap(); - - let buf2 = guard.join().unwrap(); - - assert_eq!(buf[..], buf2[..]); -} - -/// Tests that when the `SslStream` is created as a server stream, the protocols -/// are correctly advertised to the client. -#[test] -#[cfg(any(ossl102, libressl261))] -fn test_alpn_server_advertise_multiple() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let localhost = listener.local_addr().unwrap(); - // We create a different context instance for the server... - let listener_ctx = { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_alpn_select_callback(|_, client| { - ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) - }); - assert!( - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .is_ok() - ); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.build() - }; - // Have the listener wait on the connection in a different thread. - let guard = thread::spawn(move || { - let (stream, _) = listener.accept().unwrap(); - let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x08spdy/3.1").unwrap(); - match ctx.set_ca_file(&Path::new("test/root-ca.pem")) { - Ok(_) => {} - Err(err) => panic!("Unexpected error {:?}", err), - } - // Now connect to the socket and make sure the protocol negotiation works... - let stream = TcpStream::connect(localhost).unwrap(); - let mut stream = match Ssl::new(&ctx.build()).unwrap().connect(stream) { - Ok(stream) => stream, - Err(err) => panic!("Expected success, got {:?}", err), - }; - // SPDY is selected since that's the only thing the client supports. - assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); - let mut buf = [0]; - stream.read_exact(&mut buf).unwrap(); - - guard.join().unwrap(); -} - -#[test] -#[cfg(any(ossl110))] -fn test_alpn_server_select_none_fatal() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let localhost = listener.local_addr().unwrap(); - // We create a different context instance for the server... - let listener_ctx = { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_alpn_select_callback(|_, client| { - ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client) - .ok_or(ssl::AlpnError::ALERT_FATAL) - }); - assert!( - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .is_ok() - ); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.build() - }; - // Have the listener wait on the connection in a different thread. - thread::spawn(move || { - let (stream, _) = listener.accept().unwrap(); - Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap_err(); - }); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x06http/2").unwrap(); - ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap(); - let stream = TcpStream::connect(localhost).unwrap(); - Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap_err(); -} - -#[test] -#[cfg(any(ossl102, libressl261))] -fn test_alpn_server_select_none() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let localhost = listener.local_addr().unwrap(); - // We create a different context instance for the server... - let listener_ctx = { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_alpn_select_callback(|_, client| { - ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) - }); - assert!( - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .is_ok() - ); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.build() - }; - // Have the listener wait on the connection in a different thread. - let guard = thread::spawn(move || { - let (stream, _) = listener.accept().unwrap(); - let mut stream = Ssl::new(&listener_ctx).unwrap().accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - ctx.set_alpn_protos(b"\x06http/2").unwrap(); - ctx.set_ca_file(&Path::new("test/root-ca.pem")).unwrap(); - // Now connect to the socket and make sure the protocol negotiation works... - let stream = TcpStream::connect(localhost).unwrap(); - let mut stream = Ssl::new(&ctx.build()).unwrap().connect(stream).unwrap(); - - // Since the protocols from the server and client don't overlap at all, no protocol is selected - assert_eq!(None, stream.ssl().selected_alpn_protocol()); - - let mut buf = [0]; - stream.read_exact(&mut buf).unwrap(); - - guard.join().unwrap(); -} - -#[test] -#[should_panic(expected = "blammo")] -fn write_panic() { - struct ExplodingStream(TcpStream); - - impl Read for ExplodingStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - } - - impl Write for ExplodingStream { - fn write(&mut self, _: &[u8]) -> io::Result { - panic!("blammo"); - } - - fn flush(&mut self) -> io::Result<()> { - self.0.flush() - } - } - - let (_s, stream) = Server::new(); - let stream = ExplodingStream(stream); - - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); -} - -#[test] -#[should_panic(expected = "blammo")] -fn read_panic() { - struct ExplodingStream(TcpStream); - - impl Read for ExplodingStream { - fn read(&mut self, _: &mut [u8]) -> io::Result { - panic!("blammo"); - } - } - - impl Write for ExplodingStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.0.flush() - } - } - - let (_s, stream) = Server::new(); - let stream = ExplodingStream(stream); - - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); -} - -#[test] -#[should_panic(expected = "blammo")] -fn flush_panic() { - struct ExplodingStream(TcpStream); - - impl Read for ExplodingStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) - } - } - - impl Write for ExplodingStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - panic!("blammo"); - } - } - - let (_s, stream) = Server::new(); - let stream = ExplodingStream(stream); - - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let mut stream = Ssl::new(&ctx.build()) - .unwrap() - .connect(stream) - .ok() - .unwrap(); - let _ = stream.flush(); -} - -#[test] -fn refcount_ssl_context() { - let mut ssl = { - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ssl::Ssl::new(&ctx.build()).unwrap() - }; - - { - let new_ctx_a = SslContext::builder(SslMethod::tls()).unwrap().build(); - let _new_ctx_b = ssl.set_ssl_context(&new_ctx_a); - } -} - -#[test] -#[cfg_attr(libressl250, ignore)] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn default_verify_paths() { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_default_verify_paths().unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - let ctx = ctx.build(); - let s = TcpStream::connect("google.com:443").unwrap(); - let mut ssl = Ssl::new(&ctx).unwrap(); - ssl.set_hostname("google.com").unwrap(); - let mut socket = ssl.connect(s).unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); -} - -#[test] -fn add_extra_chain_cert() { - let cert = include_bytes!("../../test/cert.pem"); - let cert = X509::from_pem(cert).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.add_extra_chain_cert(cert).unwrap(); -} - -#[test] -#[cfg(any(ossl102, ossl110))] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn verify_valid_hostname() { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_default_verify_paths().unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.param_mut() - .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); - ssl.param_mut().set_host("google.com").unwrap(); - ssl.set_hostname("google.com").unwrap(); - - let s = TcpStream::connect("google.com:443").unwrap(); - let mut socket = ssl.connect(s).unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); -} - -#[test] -#[cfg(any(ossl102, ossl110))] -fn verify_invalid_hostname() { - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_default_verify_paths().unwrap(); - ctx.set_verify(SslVerifyMode::PEER); - - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.param_mut() - .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); - ssl.param_mut().set_host("foobar.com").unwrap(); - - let s = TcpStream::connect("google.com:443").unwrap(); - assert!(ssl.connect(s).is_err()); -} - -#[test] -#[cfg_attr(libressl250, ignore)] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn connector_valid_hostname() { - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - - let s = TcpStream::connect("google.com:443").unwrap(); - let mut socket = connector.connect("google.com", s).unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); -} - -#[test] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn connector_invalid_hostname() { - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - - let s = TcpStream::connect("google.com:443").unwrap(); - assert!(connector.connect("foobar.com", s).is_err()); -} - -#[test] -#[cfg_attr(libressl250, ignore)] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn connector_invalid_no_hostname_verification() { - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - - let s = TcpStream::connect("google.com:443").unwrap(); - connector - .configure() - .unwrap() - .verify_hostname(false) - .connect("foobar.com", s) - .unwrap(); -} - -#[test] -fn connector_no_hostname_still_verifies() { - let (_s, tcp) = Server::new(); - - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - - assert!( - connector - .configure() - .unwrap() - .verify_hostname(false) - .connect("fizzbuzz.com", tcp) - .is_err() - ); -} - -#[test] -fn connector_no_hostname_can_disable_verify() { - let (_s, tcp) = Server::new(); - - let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); - connector.set_verify(SslVerifyMode::NONE); - let connector = connector.build(); - - connector - .configure() - .unwrap() - .verify_hostname(false) - .connect("foobar.com", tcp) - .unwrap(); -} - -#[test] -fn connector_client_server_mozilla_intermediate() { - let listener = TcpListener::bind("127.0.0.1:1234").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let t = thread::spawn(move || { - let key = PKey::private_key_from_pem(KEY).unwrap(); - let cert = X509::from_pem(CERT).unwrap(); - let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - acceptor.set_private_key(&key).unwrap(); - acceptor.set_certificate(&cert).unwrap(); - let acceptor = acceptor.build(); - let stream = listener.accept().unwrap().0; - let mut stream = acceptor.accept(stream).unwrap(); - - stream.write_all(b"hello").unwrap(); - }); - - let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); - connector.set_ca_file("test/root-ca.pem").unwrap(); - let connector = connector.build(); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut stream = connector.connect("foobar.com", stream).unwrap(); - - let mut buf = [0; 5]; - stream.read_exact(&mut buf).unwrap(); - assert_eq!(b"hello", &buf); - - t.join().unwrap(); -} - -#[test] -fn connector_client_server_mozilla_modern() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let t = thread::spawn(move || { - let key = PKey::private_key_from_pem(KEY).unwrap(); - let cert = X509::from_pem(CERT).unwrap(); - let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - acceptor.set_private_key(&key).unwrap(); - acceptor.set_certificate(&cert).unwrap(); - let acceptor = acceptor.build(); - let stream = listener.accept().unwrap().0; - let mut stream = acceptor.accept(stream).unwrap(); - - stream.write_all(b"hello").unwrap(); - }); - - let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); - connector.set_ca_file("test/root-ca.pem").unwrap(); - let connector = connector.build(); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut stream = connector.connect("foobar.com", stream).unwrap(); - - let mut buf = [0; 5]; - stream.read_exact(&mut buf).unwrap(); - assert_eq!(b"hello", &buf); - - t.join().unwrap(); -} - -#[test] -fn shutdown() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - - stream.write_all(b"hello").unwrap(); - let mut buf = [0; 1]; - assert_eq!(stream.read(&mut buf).unwrap(), 0); - assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - - let mut buf = [0; 5]; - stream.read_exact(&mut buf).unwrap(); - assert_eq!(b"hello", &buf); - - assert_eq!(stream.get_shutdown(), ShutdownState::empty()); - assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Sent); - assert_eq!(stream.get_shutdown(), ShutdownState::SENT); - assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received); - assert_eq!( - stream.get_shutdown(), - ShutdownState::SENT | ShutdownState::RECEIVED - ); - - guard.join().unwrap(); -} - -#[test] -fn client_ca_list() { - let names = X509Name::load_client_ca_file("test/root-ca.pem").unwrap(); - assert_eq!(names.len(), 1); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_client_ca_list(names); -} - -#[test] -fn cert_store() { - let (_s, tcp) = Server::new(); - - let cert = X509::from_pem(ROOT_CERT).unwrap(); - - let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap(); - ctx.cert_store_mut().add_cert(cert).unwrap(); - let ctx = ctx.build(); - - ctx.connect("foobar.com", tcp).unwrap(); -} - -#[test] -fn tmp_dh_callback() { - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_tmp_dh_callback(|_, _, _| { - CALLED_BACK.store(true, Ordering::SeqCst); - let dh = include_bytes!("../../test/dhparams.pem"); - Dh::params_from_pem(dh) - }); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - // TLS 1.3 has no DH suites, so make sure we don't pick that version - #[cfg(ossl111)] - ctx.set_options(super::SslOptions::NO_TLSV1_3); - ctx.set_cipher_list("EDH").unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -#[cfg(all(ossl101, not(ossl110)))] -fn tmp_ecdh_callback() { - use ec::EcKey; - use nid::Nid; - - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_tmp_ecdh_callback(|_, _, _| { - CALLED_BACK.store(true, Ordering::SeqCst); - EcKey::from_curve_name(Nid::X9_62_PRIME256V1) - }); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_cipher_list("ECDH").unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -fn tmp_dh_callback_ssl() { - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.set_tmp_dh_callback(|_, _, _| { - CALLED_BACK.store(true, Ordering::SeqCst); - let dh = include_bytes!("../../test/dhparams.pem"); - Dh::params_from_pem(dh) - }); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - // TLS 1.3 has no DH suites, so make sure we don't pick that version - #[cfg(ossl111)] - ctx.set_options(super::SslOptions::NO_TLSV1_3); - ctx.set_cipher_list("EDH").unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -#[cfg(all(ossl101, not(ossl110)))] -fn tmp_ecdh_callback_ssl() { - use ec::EcKey; - use nid::Nid; - - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.set_tmp_ecdh_callback(|_, _, _| { - CALLED_BACK.store(true, Ordering::SeqCst); - EcKey::from_curve_name(Nid::X9_62_PRIME256V1) - }); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_cipher_list("ECDH").unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -fn idle_session() { - let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); - let ssl = Ssl::new(&ctx).unwrap(); - assert!(ssl.session().is_none()); -} - -#[test] -#[cfg_attr(libressl250, ignore)] -#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] -fn active_session() { - let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); - - let s = TcpStream::connect("google.com:443").unwrap(); - let socket = connector.connect("google.com", s).unwrap(); - let session = socket.ssl().session().unwrap(); - let len = session.master_key_len(); - let mut buf = vec![0; len - 1]; - let copied = session.master_key(&mut buf); - assert_eq!(copied, buf.len()); - let mut buf = vec![0; len + 1]; - let copied = session.master_key(&mut buf); - assert_eq!(copied, len); -} - -#[test] -fn status_callbacks() { - static CALLED_BACK_SERVER: AtomicBool = ATOMIC_BOOL_INIT; - static CALLED_BACK_CLIENT: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:12345").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_status_callback(|ssl| { - CALLED_BACK_SERVER.store(true, Ordering::SeqCst); - let response = OcspResponse::create(OcspResponseStatus::UNAUTHORIZED, None).unwrap(); - let response = response.to_der().unwrap(); - ssl.set_ocsp_status(&response).unwrap(); - Ok(true) - }).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_status_callback(|ssl| { - CALLED_BACK_CLIENT.store(true, Ordering::SeqCst); - let response = OcspResponse::from_der(ssl.ocsp_status().unwrap()).unwrap(); - assert_eq!(response.status(), OcspResponseStatus::UNAUTHORIZED); - Ok(true) - }).unwrap(); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.set_status_type(StatusType::OCSP).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - let mut buf = [0]; - stream.read_exact(&mut buf).unwrap(); - - assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst)); - assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -fn new_session_callback() { - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_session_id_context(b"foo").unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); - ctx.set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -fn keying_export() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let label = "EXPERIMENTAL test"; - let context = b"my context"; - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - - let mut buf = [0; 32]; - stream - .ssl() - .export_keying_material(&mut buf, label, Some(context)) - .unwrap(); - - stream.write_all(&[0]).unwrap(); - - buf - }); - - let stream = TcpStream::connect(addr).unwrap(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - - let mut buf = [1; 32]; - stream - .ssl() - .export_keying_material(&mut buf, label, Some(context)) - .unwrap(); - - stream.read_exact(&mut [0]).unwrap(); - - let buf2 = guard.join().unwrap(); - - assert_eq!(buf, buf2); -} - -#[test] -#[cfg(any(ossl110, libressl261))] -fn no_version_overlap() { - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_max_proto_version(Some(SslVersion::TLS1_1)).unwrap(); - #[cfg(ossl110g)] - assert_eq!(ctx.min_proto_version(), None); - #[cfg(any(ossl110g, libressl270))] - assert_eq!(ctx.max_proto_version(), Some(SslVersion::TLS1_1)); - let ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.accept(stream).unwrap_err(); - }); - - let stream = TcpStream::connect(addr).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap(); - #[cfg(any(ossl110g, libressl270))] - assert_eq!(ctx.min_proto_version(), Some(SslVersion::TLS1_2)); - #[cfg(ossl110g)] - assert_eq!(ctx.max_proto_version(), None); - let ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.connect(stream).unwrap_err(); - - guard.join().unwrap(); -} - -#[test] -#[cfg(ossl111)] -fn custom_extensions() { - static FOUND_EXTENSION: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.add_custom_ext( - 12345, - ssl::ExtensionContext::CLIENT_HELLO, - |_, _, _| -> Result, _> { unreachable!() }, - |_, _, data, _| { - FOUND_EXTENSION.store(data == b"hello", Ordering::SeqCst); - Ok(()) - }, - ).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(addr).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.add_custom_ext( - 12345, - ssl::ExtensionContext::CLIENT_HELLO, - |_, _, _| Ok(Some(b"hello")), - |_, _, _, _| unreachable!(), - ).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - guard.join().unwrap(); - assert!(FOUND_EXTENSION.load(Ordering::SeqCst)); -} - -fn _check_kinds() { - fn is_send() {} - fn is_sync() {} - - is_send::>(); - is_sync::>(); -} - -#[test] -#[cfg(ossl111)] -fn stateless() { - use super::SslOptions; - - #[derive(Debug)] - struct MemoryStream { - incoming: io::Cursor>, - outgoing: Vec, - } - - impl MemoryStream { - pub fn new() -> Self { - Self { - incoming: io::Cursor::new(Vec::new()), - outgoing: Vec::new(), - } - } - - pub fn extend_incoming(&mut self, data: &[u8]) { - self.incoming.get_mut().extend_from_slice(data); - } - - pub fn take_outgoing(&mut self) -> Outgoing { - Outgoing(&mut self.outgoing) - } - } - - impl Read for MemoryStream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let n = self.incoming.read(buf)?; - if self.incoming.position() == self.incoming.get_ref().len() as u64 { - self.incoming.set_position(0); - self.incoming.get_mut().clear(); - } - if n == 0 { - return Err(io::Error::new( - io::ErrorKind::WouldBlock, - "no data available", - )); - } - Ok(n) - } - } - - impl Write for MemoryStream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.outgoing.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } - } - - pub struct Outgoing<'a>(&'a mut Vec); - - impl<'a> Drop for Outgoing<'a> { - fn drop(&mut self) { - self.0.clear(); - } - } - - impl<'a> ::std::ops::Deref for Outgoing<'a> { - type Target = [u8]; - fn deref(&self) -> &[u8] { - &self.0 - } - } - - impl<'a> AsRef<[u8]> for Outgoing<'a> { - fn as_ref(&self) -> &[u8] { - &self.0 - } - } - - fn send(from: &mut MemoryStream, to: &mut MemoryStream) { - to.extend_incoming(&from.take_outgoing()); - } - - fn hs( - stream: Result, HandshakeError>, - ) -> Result, MidHandshakeSslStream> { - match stream { - Ok(stream) => Ok(stream), - Err(HandshakeError::WouldBlock(stream)) => Err(stream), - Err(e) => panic!("unexpected error: {:?}", e), - } - } - - // - // Setup - // - - let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap(); - client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT); - let client_stream = Ssl::new(&client_ctx.build()).unwrap(); - - let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap(); - server_ctx - .set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - server_ctx - .set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - const COOKIE: &[u8] = b"chocolate chip"; - server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| { - buf[0..COOKIE.len()].copy_from_slice(COOKIE); - Ok(COOKIE.len()) - }); - server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE); - let mut server_stream = - ssl::SslStreamBuilder::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()); - - // - // Handshake - // - - // Initial ClientHello - let mut client_stream = hs(client_stream.connect(MemoryStream::new())).unwrap_err(); - send(client_stream.get_mut(), server_stream.get_mut()); - // HelloRetryRequest - assert!(!server_stream.stateless().unwrap()); - send(server_stream.get_mut(), client_stream.get_mut()); - // Second ClientHello - let mut client_stream = hs(client_stream.handshake()).unwrap_err(); - send(client_stream.get_mut(), server_stream.get_mut()); - // ServerHello - assert!(server_stream.stateless().unwrap()); - let mut server_stream = hs(server_stream.accept()).unwrap_err(); - send(server_stream.get_mut(), client_stream.get_mut()); - // Finished - let mut client_stream = hs(client_stream.handshake()).unwrap(); - send(client_stream.get_mut(), server_stream.get_mut()); - hs(server_stream.handshake()).unwrap(); -} - -#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] -#[test] -fn psk_ciphers() { - const CIPHER: &'static str = "PSK-AES128-CBC-SHA"; - const PSK: &[u8] = b"thisisaverysecurekey"; - const CLIENT_IDENT: &[u8] = b"thisisaclient"; - static CLIENT_CALLED: AtomicBool = ATOMIC_BOOL_INIT; - static SERVER_CALLED: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_cipher_list(CIPHER).unwrap(); - ctx.set_psk_server_callback(move |_, identity, psk| { - assert!(identity.unwrap_or(&[]) == CLIENT_IDENT); - psk[..PSK.len()].copy_from_slice(&PSK); - SERVER_CALLED.store(true, Ordering::SeqCst); - Ok(PSK.len()) - }); - let ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.accept(stream).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - // TLS 1.3 has no DH suites, and openssl isn't happy if the max version has no suites :( - #[cfg(ossl111)] - { - ctx.set_options(super::SslOptions { - bits: ::ffi::SSL_OP_NO_TLSv1_3, - }); - } - ctx.set_cipher_list(CIPHER).unwrap(); - ctx.set_psk_client_callback(move |_, _, identity, psk| { - identity[..CLIENT_IDENT.len()].copy_from_slice(&CLIENT_IDENT); - identity[CLIENT_IDENT.len()] = 0; - psk[..PSK.len()].copy_from_slice(&PSK); - CLIENT_CALLED.store(true, Ordering::SeqCst); - Ok(PSK.len()) - }); - let ssl = Ssl::new(&ctx.build()).unwrap(); - ssl.connect(stream).unwrap(); - - assert!(CLIENT_CALLED.load(Ordering::SeqCst) && SERVER_CALLED.load(Ordering::SeqCst)); -} - -#[test] -fn sni_callback_swapped_ctx() { - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_servername_callback(|_, _| { - CALLED_BACK.store(true, Ordering::SeqCst); - Ok(()) - }); - let mut ssl = Ssl::new(&ctx.build()).unwrap(); - - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ssl.set_ssl_context(&ctx.build()).unwrap(); - - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&[0]).unwrap(); - }); - - let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} - -#[test] -#[cfg(ossl111)] -fn client_hello() { - use ssl::ClientHelloResponse; - - static CALLED_BACK: AtomicBool = ATOMIC_BOOL_INIT; - - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let addr = listener.local_addr().unwrap(); - - let guard = thread::spawn(move || { - let stream = listener.accept().unwrap().0; - let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); - ctx.set_certificate_file(&Path::new("test/cert.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_private_key_file(&Path::new("test/key.pem"), SslFiletype::PEM) - .unwrap(); - ctx.set_client_hello_callback(|ssl, _| { - assert!(!ssl.client_hello_isv2()); - assert_eq!(ssl.client_hello_legacy_version(), Some(SslVersion::TLS1_2)); - assert!(ssl.client_hello_random().is_some()); - assert!(ssl.client_hello_session_id().is_some()); - assert!(ssl.client_hello_ciphers().is_some()); - assert!(ssl.client_hello_compression_methods().is_some()); - - CALLED_BACK.store(true, Ordering::SeqCst); - Ok(ClientHelloResponse::SUCCESS) - }); - - let ssl = Ssl::new(&ctx.build()).unwrap(); - let mut stream = ssl.accept(stream).unwrap(); - stream.write_all(&mut [0]).unwrap(); - }); - - let stream = TcpStream::connect(addr).unwrap(); - let ctx = SslContext::builder(SslMethod::tls()).unwrap(); - let ssl = Ssl::new(&ctx.build()).unwrap(); - - let mut stream = ssl.connect(stream).unwrap(); - stream.read_exact(&mut [0]).unwrap(); - - assert!(CALLED_BACK.load(Ordering::SeqCst)); - - guard.join().unwrap(); -} diff -Nru cargo-0.33.0/vendor/openssl/src/string.rs cargo-0.35.0/vendor/openssl/src/string.rs --- cargo-0.33.0/vendor/openssl/src/string.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/string.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,9 @@ use ffi; use foreign_types::ForeignTypeRef; use libc::{c_char, c_void}; -use std::fmt; +use std::convert::AsRef; use std::ffi::CStr; +use std::fmt; use std::ops::Deref; use std::str; @@ -32,6 +33,18 @@ type StackType = ffi::stack_st_OPENSSL_STRING; } +impl AsRef for OpensslString { + fn as_ref(&self) -> &str { + &**self + } +} + +impl AsRef<[u8]> for OpensslString { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + impl Deref for OpensslStringRef { type Target = str; @@ -43,6 +56,18 @@ } } +impl AsRef for OpensslStringRef { + fn as_ref(&self) -> &str { + &*self + } +} + +impl AsRef<[u8]> for OpensslStringRef { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + impl fmt::Display for OpensslStringRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&**self, f) diff -Nru cargo-0.33.0/vendor/openssl/src/symm.rs cargo-0.35.0/vendor/openssl/src/symm.rs --- cargo-0.33.0/vendor/openssl/src/symm.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/symm.rs 2019-05-15 11:26:24.000000000 +0000 @@ -194,6 +194,10 @@ unsafe { Cipher(ffi::EVP_des_ede3_cbc()) } } + pub fn des_ede3_cfb64() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) } + } + pub fn rc4() -> Cipher { unsafe { Cipher(ffi::EVP_rc4()) } } @@ -418,7 +422,8 @@ ffi::EVP_CTRL_GCM_SET_TAG, tag.len() as c_int, tag.as_ptr() as *mut _, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -435,7 +440,8 @@ ffi::EVP_CTRL_GCM_SET_TAG, tag_len as c_int, ptr::null_mut(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -453,7 +459,8 @@ &mut len, ptr::null_mut(), data_len as c_int, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -472,7 +479,8 @@ &mut len, input.as_ptr(), input.len() as c_int, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -484,12 +492,16 @@ /// /// # Panics /// - /// Panics if `output.len() < input.len() + block_size` where - /// `block_size` is the block size of the cipher (see `Cipher::block_size`), - /// or if `output.len() > c_int::max_value()`. + /// Panics for stream ciphers if `output.len() < input.len()`. + /// + /// Panics for block ciphers if `output.len() < input.len() + block_size`, + /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). + /// + /// Panics if `output.len() > c_int::max_value()`. pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { unsafe { - assert!(output.len() >= input.len() + self.block_size); + let block_size = if self.block_size > 1 { self.block_size } else { 0 }; + assert!(output.len() >= input.len() + block_size); assert!(output.len() <= c_int::max_value() as usize); let mut outl = output.len() as c_int; let inl = input.len() as c_int; @@ -515,10 +527,11 @@ /// /// # Panics /// - /// Panics if `output` is less than the cipher's block size. + /// Panics for block ciphers if `output.len() < block_size`, + /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). pub fn finalize(&mut self, output: &mut [u8]) -> Result { unsafe { - assert!(output.len() >= self.block_size); + if self.block_size > 1 { assert!(output.len() >= self.block_size); } let mut outl = cmp::min(output.len(), c_int::max_value() as usize) as c_int; cvt(ffi::EVP_CipherFinal( @@ -547,7 +560,8 @@ ffi::EVP_CTRL_GCM_GET_TAG, tag.len() as c_int, tag.as_mut_ptr() as *mut _, - )).map(|_| ()) + )) + .map(|_| ()) } } } @@ -744,6 +758,22 @@ use super::*; use hex::{self, FromHex}; + #[test] + fn test_stream_cipher_output() { + let key = [0u8; 16]; + let iv = [0u8; 16]; + let mut c = super::Crypter::new( + super::Cipher::aes_128_ctr(), + super::Mode::Encrypt, + &key, + Some(&iv), + ).unwrap(); + + assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15); + assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1); + assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0); + } + // Test vectors from FIPS-197: // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf #[test] @@ -766,7 +796,8 @@ super::Mode::Encrypt, &k0, None, - ).unwrap(); + ) + .unwrap(); c.pad(false); let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()]; let count = c.update(&p0, &mut r0).unwrap(); @@ -779,7 +810,8 @@ super::Mode::Decrypt, &k0, None, - ).unwrap(); + ) + .unwrap(); c.pad(false); let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()]; let count = c.update(&r0, &mut p1).unwrap(); @@ -808,7 +840,8 @@ super::Mode::Decrypt, &data, Some(&iv), - ).unwrap(); + ) + .unwrap(); cr.pad(false); let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()]; let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap(); @@ -1056,6 +1089,16 @@ } #[test] + fn test_des_ede3_cfb64() { + let pt = "2b1773784b5889dc788477367daa98ad"; + let ct = "6f2867cfefda048a4046ef7e556c7132"; + let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; + let iv = "0001020304050607"; + + cipher_test(super::Cipher::des_ede3_cfb64(), pt, ct, key, iv); + } + + #[test] fn test_aes128_gcm() { let key = "0e00c76561d2bd9b40c3c15427e2b08f"; let iv = "492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e7\ @@ -1080,7 +1123,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, - ).unwrap(); + ) + .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); @@ -1091,7 +1135,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), - ).unwrap(); + ) + .unwrap(); assert_eq!(pt, hex::encode(out)); } @@ -1113,7 +1158,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, - ).unwrap(); + ) + .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); @@ -1125,7 +1171,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), - ).unwrap(); + ) + .unwrap(); assert_eq!(pt, hex::encode(out)); } @@ -1167,7 +1214,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, - ).unwrap(); + ) + .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); @@ -1179,7 +1227,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), - ).unwrap(); + ) + .unwrap(); assert_eq!(pt, hex::encode(out)); } @@ -1242,7 +1291,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, - ).unwrap(); + ) + .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); @@ -1253,7 +1303,8 @@ &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), - ).unwrap(); + ) + .unwrap(); assert_eq!(pt, hex::encode(out)); } } diff -Nru cargo-0.33.0/vendor/openssl/src/version.rs cargo-0.35.0/vendor/openssl/src/version.rs --- cargo-0.33.0/vendor/openssl/src/version.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/version.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,7 +14,7 @@ use std::ffi::CStr; cfg_if! { - if #[cfg(ossl110)] { + if #[cfg(any(ossl110, libressl271))] { use ffi::{ OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR, OpenSSL_version_num, OpenSSL_version, diff -Nru cargo-0.33.0/vendor/openssl/src/x509/extension.rs cargo-0.35.0/vendor/openssl/src/x509/extension.rs --- cargo-0.33.0/vendor/openssl/src/x509/extension.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/x509/extension.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,4 @@ -//! Add extensions to an `X509` certificate or certificate request. +//! Add extensions to an `X509` certificate or certificate request. //! //! The extensions defined for X.509 v3 certificates provide methods for //! associating additional attributes with users or public keys and for @@ -11,11 +11,11 @@ //! extern crate openssl; //! //! use openssl::x509::extension::BasicConstraints; -//! use openssl::x509::X509Extension; +//! use openssl::x509::X509Extension; //! //! fn main() { //! let mut bc = BasicConstraints::new(); -//! let bc = bc.critical().ca().pathlen(1); +//! let bc = bc.critical().ca().pathlen(1); //! //! let extension: X509Extension = bc.build().unwrap(); //! } diff -Nru cargo-0.33.0/vendor/openssl/src/x509/mod.rs cargo-0.35.0/vendor/openssl/src/x509/mod.rs --- cargo-0.33.0/vendor/openssl/src/x509/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/x509/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -255,7 +255,8 @@ cvt(ffi::X509_set_serialNumber( self.0.as_ptr(), serial_number.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -265,7 +266,8 @@ cvt(ffi::X509_set_issuer_name( self.0.as_ptr(), issuer_name.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -292,7 +294,8 @@ cvt(ffi::X509_set_subject_name( self.0.as_ptr(), subject_name.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -528,6 +531,23 @@ } } + /// Check if the certificate is signed using the given public key. + /// + /// Only the signature is checked: no other checks (such as certificate chain validity) + /// are performed. + /// + /// Returns `true` if verification succeeds. + /// + /// This corresponds to [`X509_verify"]. + /// + /// [`X509_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_verify.html + pub fn verify(&self, key: &PKeyRef) -> Result + where + T: HasPublic, + { + unsafe { cvt_n(ffi::X509_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } + } + /// Returns this certificate's serial number. /// /// This corresponds to [`X509_get_serialNumber`]. @@ -756,7 +776,8 @@ value.len() as c_int, -1, 0, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -776,7 +797,8 @@ value.len() as c_int, -1, 0, - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -830,7 +852,7 @@ X509NameEntries { name: self, nid: None, - loc: -1 + loc: -1, } } } @@ -945,7 +967,8 @@ cvt(ffi::X509_REQ_set_subject_name( self.0.as_ptr(), subject_name.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -994,7 +1017,8 @@ cvt(ffi::X509_REQ_add_extensions( self.0.as_ptr(), extensions.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1012,7 +1036,8 @@ self.0.as_ptr(), key.as_ptr(), hash.as_ptr(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -1120,6 +1145,20 @@ } } + /// Check if the certificate request is signed using the given public key. + /// + /// Returns `true` if verification succeeds. + /// + /// This corresponds to [`X509_REQ_verify"]. + /// + /// [`X509_REQ_verify`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_verify.html + pub fn verify(&self, key: &PKeyRef) -> Result + where + T: HasPublic, + { + unsafe { cvt_n(ffi::X509_REQ_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } + } + /// Returns the extensions of the certificate request. /// /// This corresponds to [`X509_REQ_get_extensions"] diff -Nru cargo-0.33.0/vendor/openssl/src/x509/tests.rs cargo-0.35.0/vendor/openssl/src/x509/tests.rs --- cargo-0.33.0/vendor/openssl/src/x509/tests.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/x509/tests.rs 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ SubjectKeyIdentifier, }; use x509::store::X509StoreBuilder; -use x509::{X509, X509Name, X509Req, X509StoreContext, X509VerifyResult}; +use x509::{X509Name, X509Req, X509StoreContext, X509VerifyResult, X509}; fn pkey() -> PKey { let rsa = Rsa::generate(2048).unwrap(); @@ -87,7 +87,10 @@ let mut all_entries = subject.entries(); let email = all_entries.next().unwrap(); - assert_eq!(email.object().nid().as_raw(), Nid::PKCS9_EMAILADDRESS.as_raw()); + assert_eq!( + email.object().nid().as_raw(), + Nid::PKCS9_EMAILADDRESS.as_raw() + ); assert_eq!(email.data().as_slice(), b"test@example.com"); let cn = all_entries.next().unwrap(); @@ -222,6 +225,7 @@ let x509 = builder.build(); assert!(pkey.public_eq(&x509.public_key().unwrap())); + assert!(x509.verify(&pkey).unwrap()); let cn = x509 .subject_name() @@ -265,6 +269,7 @@ let req = builder.build(); assert!(req.public_key().unwrap().public_eq(&pkey)); assert_eq!(req.extensions().unwrap().len(), extensions.len()); + assert!(req.verify(&pkey).unwrap()); } #[test] @@ -334,16 +339,12 @@ let store = store_bldr.build(); let mut context = X509StoreContext::new().unwrap(); - assert!( - context - .init(&store, &cert, &chain, |c| c.verify_cert()) - .unwrap() - ); - assert!( - context - .init(&store, &cert, &chain, |c| c.verify_cert()) - .unwrap() - ); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); } #[test] diff -Nru cargo-0.33.0/vendor/openssl/src/x509/verify.rs cargo-0.35.0/vendor/openssl/src/x509/verify.rs --- cargo-0.33.0/vendor/openssl/src/x509/verify.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl/src/x509/verify.rs 2019-05-15 11:26:24.000000000 +0000 @@ -56,7 +56,8 @@ self.as_ptr(), host.as_ptr() as *const _, host.len(), - )).map(|_| ()) + )) + .map(|_| ()) } } @@ -82,7 +83,8 @@ self.as_ptr(), buf.as_ptr() as *const _, len, - )).map(|_| ()) + )) + .map(|_| ()) } } } Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/openssl/test/cms.p12 and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/openssl/test/cms.p12 differ Binary files /tmp/tmpAnriHn/_z9DeFhKdL/cargo-0.33.0/vendor/openssl/test/cms_pubkey.der and /tmp/tmpAnriHn/Fsvo1M_byf/cargo-0.35.0/vendor/openssl/test/cms_pubkey.der differ diff -Nru cargo-0.33.0/vendor/openssl-sys/build/cfgs.rs cargo-0.35.0/vendor/openssl-sys/build/cfgs.rs --- cargo-0.33.0/vendor/openssl-sys/build/cfgs.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/build/cfgs.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,6 +13,9 @@ if libressl_version >= 0x2_07_00_00_0 { cfgs.push("libressl270"); } + if libressl_version >= 0x2_07_01_00_0 { + cfgs.push("libressl271"); + } if libressl_version >= 0x2_07_03_00_0 { cfgs.push("libressl273"); } @@ -22,6 +25,9 @@ if libressl_version >= 0x2_08_01_00_0 { cfgs.push("libressl281"); } + if libressl_version >= 0x2_09_01_00_0 { + cfgs.push("libressl291"); + } } else { let openssl_version = openssl_version.unwrap(); @@ -49,6 +55,9 @@ if openssl_version >= 0x1_01_01_00_0 { cfgs.push("ossl111"); } + if openssl_version >= 0x1_01_01_02_0 { + cfgs.push("ossl111b"); + } } cfgs diff -Nru cargo-0.33.0/vendor/openssl-sys/build/expando.c cargo-0.35.0/vendor/openssl-sys/build/expando.c --- cargo-0.33.0/vendor/openssl-sys/build/expando.c 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/build/expando.c 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,67 @@ +#include +#include + +#define VERSION2(n, v) RUST_VERSION_##n##_##v +#define VERSION(n, v) VERSION2(n, v) + +#ifdef LIBRESSL_VERSION_NUMBER +VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER) +#else +VERSION(OPENSSL, OPENSSL_VERSION_NUMBER) +#endif + +#ifdef OPENSSL_NO_BUF_FREELISTS +RUST_CONF_OPENSSL_NO_BUF_FREELISTS +#endif + +#ifdef OPENSSL_NO_COMP +RUST_CONF_OPENSSL_NO_COMP +#endif + +#ifdef OPENSSL_NO_EC +RUST_CONF_OPENSSL_NO_EC +#endif + +#ifdef OPENSSL_NO_EC2M +RUST_CONF_OPENSSL_NO_EC2M +#endif + +#ifdef OPENSSL_NO_ENGINE +RUST_CONF_OPENSSL_NO_ENGINE +#endif + +#ifdef OPENSSL_NO_KRB5 +RUST_CONF_OPENSSL_NO_KRB5 +#endif + +#ifdef OPENSSL_NO_NEXTPROTONEG +RUST_CONF_OPENSSL_NO_NEXTPROTONEG +#endif + +#ifdef OPENSSL_NO_PSK +RUST_CONF_OPENSSL_NO_PSK +#endif + +#ifdef OPENSSL_NO_RFC3779 +RUST_CONF_OPENSSL_NO_RFC3779 +#endif + +#ifdef OPENSSL_NO_SHA +RUST_CONF_OPENSSL_NO_SHA +#endif + +#ifdef OPENSSL_NO_SRP +RUST_CONF_OPENSSL_NO_SRP +#endif + +#ifdef OPENSSL_NO_SSL3_METHOD +RUST_CONF_OPENSSL_NO_SSL3_METHOD +#endif + +#ifdef OPENSSL_NO_TLSEXT +RUST_CONF_OPENSSL_NO_TLSEXT +#endif + +#ifdef OPENSSL_NO_STDIO +RUST_CONF_OPENSSL_NO_STDIO +#endif diff -Nru cargo-0.33.0/vendor/openssl-sys/build/find_normal.rs cargo-0.35.0/vendor/openssl-sys/build/find_normal.rs --- cargo-0.33.0/vendor/openssl-sys/build/find_normal.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/build/find_normal.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,251 @@ +use pkg_config; +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::process::{self, Command}; + +use super::env; + +pub fn get_openssl(target: &str) -> (PathBuf, PathBuf) { + let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from); + let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from); + + if lib_dir.is_none() || include_dir.is_none() { + let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target)); + let openssl_dir = Path::new(&openssl_dir); + let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib")); + let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include")); + (lib_dir, include_dir) + } else { + (lib_dir.unwrap(), include_dir.unwrap()) + } +} + +fn find_openssl_dir(target: &str) -> OsString { + let host = env::var("HOST").unwrap(); + + if host == target && target.contains("apple-darwin") { + // Check up default Homebrew installation location first + // for quick resolution if possible. + let homebrew = Path::new("/usr/local/opt/openssl@1.1"); + if homebrew.exists() { + return homebrew.to_path_buf().into(); + } + let homebrew = Path::new("/usr/local/opt/openssl"); + if homebrew.exists() { + return homebrew.to_path_buf().into(); + } + // Calling `brew --prefix ` command usually slow and + // takes seconds, and will be used only as a last resort. + let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]); + if let Some(ref output) = output { + let homebrew = Path::new(&output); + if homebrew.exists() { + return homebrew.to_path_buf().into(); + } + } + let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]); + if let Some(ref output) = output { + let homebrew = Path::new(&output); + if homebrew.exists() { + return homebrew.to_path_buf().into(); + } + } + } + + try_pkg_config(); + try_vcpkg(); + + // FreeBSD ships with OpenSSL but doesn't include a pkg-config file :( + if host == target && target.contains("freebsd") { + return OsString::from("/usr"); + } + + let mut msg = format!( + " + +Could not find directory of OpenSSL installation, and this `-sys` crate cannot +proceed without this knowledge. If OpenSSL is installed and this crate had +trouble finding it, you can set the `OPENSSL_DIR` environment variable for the +compilation process. + +Make sure you also have the development packages of openssl installed. +For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. + +If you're in a situation where you think the directory *should* be found +automatically, please open a bug at https://github.com/sfackler/rust-openssl +and include information about your system as well as this message. + +$HOST = {} +$TARGET = {} +openssl-sys = {} + +", + host, + target, + env!("CARGO_PKG_VERSION") + ); + + if host.contains("apple-darwin") && target.contains("apple-darwin") { + let system = Path::new("/usr/lib/libssl.0.9.8.dylib"); + if system.exists() { + msg.push_str(&format!( + " + +It looks like you're compiling on macOS, where the system contains a version of +OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8. + +As a consumer of this crate, you can fix this error by using Homebrew to +install the `openssl` package, or as a maintainer you can use the openssl-sys +0.7 crate for support with OpenSSL 0.9.8. + +Unfortunately though the compile cannot continue, so aborting. + +" + )); + } + } + + if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") { + if Command::new("pkg-config").output().is_err() { + msg.push_str(&format!( + " +It looks like you're compiling on Linux and also targeting Linux. Currently this +requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` +could not be found. If you have OpenSSL installed you can likely fix this by +installing `pkg-config`. + +" + )); + } + } + + if host.contains("windows") && target.contains("windows-gnu") { + msg.push_str(&format!( + " +It looks like you're compiling for MinGW but you may not have either OpenSSL or +pkg-config installed. You can install these two dependencies with: + +pacman -S openssl-devel pkg-config + +and try building this crate again. + +" + )); + } + + if host.contains("windows") && target.contains("windows-msvc") { + msg.push_str(&format!( + " +It looks like you're compiling for MSVC but we couldn't detect an OpenSSL +installation. If there isn't one installed then you can try the rust-openssl +README for more information about how to download precompiled binaries of +OpenSSL: + +https://github.com/sfackler/rust-openssl#windows + +" + )); + } + + panic!(msg); +} + +/// Attempt to find OpenSSL through pkg-config. +/// +/// Note that if this succeeds then the function does not return as pkg-config +/// typically tells us all the information that we need. +fn try_pkg_config() { + let target = env::var("TARGET").unwrap(); + let host = env::var("HOST").unwrap(); + + // If we're going to windows-gnu we can use pkg-config, but only so long as + // we're coming from a windows host. + // + // Otherwise if we're going to windows we probably can't use pkg-config. + if target.contains("windows-gnu") && host.contains("windows") { + env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); + } else if target.contains("windows") { + return; + } + + let lib = match pkg_config::Config::new() + .print_system_libs(false) + .find("openssl") + { + Ok(lib) => lib, + Err(e) => { + println!("run pkg_config fail: {:?}", e); + return; + } + }; + + super::validate_headers(&lib.include_paths); + + for include in lib.include_paths.iter() { + println!("cargo:include={}", include.display()); + } + + process::exit(0); +} + +/// Attempt to find OpenSSL through vcpkg. +/// +/// Note that if this succeeds then the function does not return as vcpkg +/// should emit all of the cargo metadata that we need. +#[cfg(target_env = "msvc")] +fn try_vcpkg() { + use vcpkg; + + // vcpkg will not emit any metadata if it can not find libraries + // appropriate for the target triple with the desired linkage. + + let mut lib = vcpkg::Config::new() + .emit_includes(true) + .lib_name("libcrypto") + .lib_name("libssl") + .probe("openssl"); + + if let Err(e) = lib { + println!( + "note: vcpkg did not find openssl as libcrypto and libssl: {}", + e + ); + lib = vcpkg::Config::new() + .emit_includes(true) + .lib_name("libeay32") + .lib_name("ssleay32") + .probe("openssl"); + } + if let Err(e) = lib { + println!( + "note: vcpkg did not find openssl as ssleay32 and libeay32: {}", + e + ); + return; + } + + let lib = lib.unwrap(); + super::validate_headers(&lib.include_paths); + + println!("cargo:rustc-link-lib=user32"); + println!("cargo:rustc-link-lib=gdi32"); + println!("cargo:rustc-link-lib=crypt32"); + + process::exit(0); +} + +#[cfg(not(target_env = "msvc"))] +fn try_vcpkg() {} + +fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option { + let out = Command::new(cmd).args(args).output(); + if let Ok(ref r1) = out { + if r1.status.success() { + let r2 = String::from_utf8(r1.stdout.clone()); + if let Ok(r3) = r2 { + return Some(r3.trim().to_string()); + } + } + } + return None; +} diff -Nru cargo-0.33.0/vendor/openssl-sys/build/find_vendored.rs cargo-0.35.0/vendor/openssl-sys/build/find_vendored.rs --- cargo-0.33.0/vendor/openssl-sys/build/find_vendored.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/build/find_vendored.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,11 @@ +use openssl_src; +use std::path::PathBuf; + +pub fn get_openssl(_target: &str) -> (PathBuf, PathBuf) { + let artifacts = openssl_src::Build::new().build(); + println!("cargo:vendored=1"); + ( + artifacts.lib_dir().to_path_buf(), + artifacts.include_dir().to_path_buf(), + ) +} diff -Nru cargo-0.33.0/vendor/openssl-sys/build/main.rs cargo-0.35.0/vendor/openssl-sys/build/main.rs --- cargo-0.33.0/vendor/openssl-sys/build/main.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/build/main.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,35 +2,20 @@ #[cfg(feature = "vendored")] extern crate openssl_src; extern crate pkg_config; +extern crate autocfg; #[cfg(target_env = "msvc")] extern crate vcpkg; use std::collections::HashSet; use std::env; use std::ffi::OsString; -use std::fs::File; -use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; mod cfgs; -// The set of `OPENSSL_NO_`s that we care about. -const DEFINES: &'static [&'static str] = &[ - "OPENSSL_NO_BUF_FREELISTS", - "OPENSSL_NO_COMP", - "OPENSSL_NO_EC", - "OPENSSL_NO_EC2M", - "OPENSSL_NO_ENGINE", - "OPENSSL_NO_KRB5", - "OPENSSL_NO_NEXTPROTONEG", - "OPENSSL_NO_PSK", - "OPENSSL_NO_RFC3779", - "OPENSSL_NO_SHA", - "OPENSSL_NO_SRP", - "OPENSSL_NO_SSL3_METHOD", - "OPENSSL_NO_TLSEXT", - "OPENSSL_NO_STDIO", -]; +#[cfg_attr(feature = "vendored", path = "find_vendored.rs")] +#[cfg_attr(not(feature = "vendored"), path = "find_normal.rs")] +mod find; enum Version { Openssl11x, @@ -38,23 +23,30 @@ Libressl, } -fn env(name: &str) -> Option { - let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_"); - let prefixed = format!("{}_{}", prefix, name); - println!("cargo:rerun-if-env-changed={}", prefixed); +fn env_inner(name: &str) -> Option { + let var = env::var_os(name); + println!("cargo:rerun-if-env-changed={}", name); - if let Some(var) = env::var_os(&prefixed) { - return Some(var); + match var { + Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), + None => println!("{} unset", name), } - println!("cargo:rerun-if-env-changed={}", name); - env::var_os(name) + var +} + +fn env(name: &str) -> Option { + let prefix = env::var("TARGET").unwrap().to_uppercase().replace("-", "_"); + let prefixed = format!("{}_{}", prefix, name); + env_inner(&prefixed).or_else(|| env_inner(name)) } fn main() { + check_rustc_versions(); + let target = env::var("TARGET").unwrap(); - let (lib_dir, include_dir) = imp::get_openssl(&target); + let (lib_dir, include_dir) = find::get_openssl(&target); if !Path::new(&lib_dir).exists() { panic!( @@ -101,272 +93,11 @@ } } -#[cfg(feature = "vendored")] -mod imp { - use openssl_src; - use std::path::PathBuf; - - pub fn get_openssl(_target: &str) -> (PathBuf, PathBuf) { - let artifacts = openssl_src::Build::new().build(); - ( - artifacts.lib_dir().to_path_buf(), - artifacts.include_dir().to_path_buf(), - ) - } -} +fn check_rustc_versions() { + let cfg = autocfg::new(); -#[cfg(not(feature = "vendored"))] -mod imp { - use pkg_config; - use std::ffi::OsString; - use std::path::{Path, PathBuf}; - use std::process::{self, Command}; - - use super::env; - - pub fn get_openssl(target: &str) -> (PathBuf, PathBuf) { - let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from); - let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from); - - if lib_dir.is_none() || include_dir.is_none() { - let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(&target)); - let openssl_dir = Path::new(&openssl_dir); - let lib_dir = lib_dir.unwrap_or_else(|| openssl_dir.join("lib")); - let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include")); - (lib_dir, include_dir) - } else { - (lib_dir.unwrap(), include_dir.unwrap()) - } - } - - fn find_openssl_dir(target: &str) -> OsString { - let host = env::var("HOST").unwrap(); - - if host == target && target.contains("apple-darwin") { - // Check up default Homebrew installation location first - // for quick resolution if possible. - let homebrew = Path::new("/usr/local/opt/openssl@1.1"); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - let homebrew = Path::new("/usr/local/opt/openssl"); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - // Calling `brew --prefix ` command usually slow and - // takes seconds, and will be used only as a last resort. - let output = execute_command_and_get_output("brew", &["--prefix", "openssl@1.1"]); - if let Some(ref output) = output { - let homebrew = Path::new(&output); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - } - let output = execute_command_and_get_output("brew", &["--prefix", "openssl"]); - if let Some(ref output) = output { - let homebrew = Path::new(&output); - if homebrew.exists() { - return homebrew.to_path_buf().into(); - } - } - } - - try_pkg_config(); - try_vcpkg(); - - // FreeBSD ships with OpenSSL but doesn't include a pkg-config file :( - if host == target && target.contains("freebsd") { - return OsString::from("/usr"); - } - - let mut msg = format!( - " - -Could not find directory of OpenSSL installation, and this `-sys` crate cannot -proceed without this knowledge. If OpenSSL is installed and this crate had -trouble finding it, you can set the `OPENSSL_DIR` environment variable for the -compilation process. - -Make sure you also have the development packages of openssl installed. -For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. - -If you're in a situation where you think the directory *should* be found -automatically, please open a bug at https://github.com/sfackler/rust-openssl -and include information about your system as well as this message. - - $HOST = {} - $TARGET = {} - openssl-sys = {} - -", - host, - target, - env!("CARGO_PKG_VERSION") - ); - - if host.contains("apple-darwin") && target.contains("apple-darwin") { - let system = Path::new("/usr/lib/libssl.0.9.8.dylib"); - if system.exists() { - msg.push_str(&format!( - " - -It looks like you're compiling on macOS, where the system contains a version of -OpenSSL 0.9.8. This crate no longer supports OpenSSL 0.9.8. - -As a consumer of this crate, you can fix this error by using Homebrew to -install the `openssl` package, or as a maintainer you can use the openssl-sys -0.7 crate for support with OpenSSL 0.9.8. - -Unfortunately though the compile cannot continue, so aborting. - -" - )); - } - } - - if host.contains("unknown-linux") && target.contains("unknown-linux-gnu") { - if Command::new("pkg-config").output().is_err() { - msg.push_str(&format!( - " -It looks like you're compiling on Linux and also targeting Linux. Currently this -requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` -could not be found. If you have OpenSSL installed you can likely fix this by -installing `pkg-config`. - -" - )); - } - } - - if host.contains("windows") && target.contains("windows-gnu") { - msg.push_str(&format!( - " -It looks like you're compiling for MinGW but you may not have either OpenSSL or -pkg-config installed. You can install these two dependencies with: - - pacman -S openssl-devel pkg-config - -and try building this crate again. - -" - )); - } - - if host.contains("windows") && target.contains("windows-msvc") { - msg.push_str(&format!( - " -It looks like you're compiling for MSVC but we couldn't detect an OpenSSL -installation. If there isn't one installed then you can try the rust-openssl -README for more information about how to download precompiled binaries of -OpenSSL: - - https://github.com/sfackler/rust-openssl#windows - -" - )); - } - - panic!(msg); - } - - /// Attempt to find OpenSSL through pkg-config. - /// - /// Note that if this succeeds then the function does not return as pkg-config - /// typically tells us all the information that we need. - fn try_pkg_config() { - let target = env::var("TARGET").unwrap(); - let host = env::var("HOST").unwrap(); - - // If we're going to windows-gnu we can use pkg-config, but only so long as - // we're coming from a windows host. - // - // Otherwise if we're going to windows we probably can't use pkg-config. - if target.contains("windows-gnu") && host.contains("windows") { - env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); - } else if target.contains("windows") { - return; - } - - let lib = match pkg_config::Config::new() - .print_system_libs(false) - .find("openssl") - { - Ok(lib) => lib, - Err(e) => { - println!("run pkg_config fail: {:?}", e); - return; - } - }; - - super::validate_headers(&lib.include_paths); - - for include in lib.include_paths.iter() { - println!("cargo:include={}", include.display()); - } - - process::exit(0); - } - - /// Attempt to find OpenSSL through vcpkg. - /// - /// Note that if this succeeds then the function does not return as vcpkg - /// should emit all of the cargo metadata that we need. - #[cfg(target_env = "msvc")] - fn try_vcpkg() { - use vcpkg; - - // vcpkg will not emit any metadata if it can not find libraries - // appropriate for the target triple with the desired linkage. - - let mut lib = vcpkg::Config::new() - .emit_includes(true) - .lib_name("libcrypto") - .lib_name("libssl") - .probe("openssl"); - - if let Err(e) = lib { - println!( - "note: vcpkg did not find openssl as libcrypto and libssl : {:?}", - e - ); - lib = vcpkg::Config::new() - .emit_includes(true) - .lib_name("libeay32") - .lib_name("ssleay32") - .probe("openssl"); - } - if let Err(e) = lib { - println!( - "note: vcpkg did not find openssl as ssleay32 and libeay32: {:?}", - e - ); - return; - } - - let lib = lib.unwrap(); - super::validate_headers(&lib.include_paths); - - println!("cargo:rustc-link-lib=user32"); - println!("cargo:rustc-link-lib=gdi32"); - println!("cargo:rustc-link-lib=crypt32"); - - process::exit(0); - } - - #[cfg(not(target_env = "msvc"))] - fn try_vcpkg() {} - - fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option { - let out = Command::new(cmd).args(args).output(); - if let Ok(ref r1) = out { - if r1.status.success() { - let r2 = String::from_utf8(r1.stdout.clone()); - if let Ok(r3) = r2 { - return Some(r3.trim().to_string()); - } - } - } - return None; + if cfg.probe_rustc_version(1, 31) { + println!("cargo:rustc-cfg=const_fn"); } } @@ -385,48 +116,11 @@ // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can // account for compile differences and such. - let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - path.push("expando.c"); - let mut file = BufWriter::new(File::create(&path).unwrap()); - - write!( - file, - "\ -#include -#include - -#define VERSION2(n, v) RUST_VERSION_ ## n ## _ ## v -#define VERSION(n, v) VERSION2(n, v) - -VERSION(OPENSSL, OPENSSL_VERSION_NUMBER) - -#ifdef LIBRESSL_VERSION_NUMBER -VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER) -#endif -" - ).unwrap(); - - for define in DEFINES { - write!( - file, - "\ -#ifdef {define} -RUST_CONF_{define} -#endif -", - define = define - ).unwrap(); - } - - file.flush().unwrap(); - drop(file); - let mut gcc = cc::Build::new(); for include_dir in include_dirs { gcc.include(include_dir); } - // https://github.com/alexcrichton/gcc-rs/issues/133 - let expanded = match gcc.file(&path).try_expand() { + let expanded = match gcc.file("build/expando.c").try_expand() { Ok(expanded) => expanded, Err(e) => { panic!( @@ -505,6 +199,7 @@ (8, 1) => ('8', '1'), (8, _) => ('8', 'x'), (9, 0) => ('9', '0'), + (9, _) => ('9', 'x'), _ => version_error(), }; @@ -545,7 +240,7 @@ " This crate is only compatible with OpenSSL 1.0.1 through 1.1.1, or LibreSSL 2.5 -through 2.9.0, but a different version of OpenSSL was found. The build is now aborting +through 2.9.x, but a different version of OpenSSL was found. The build is now aborting due to this version mismatch. " @@ -553,6 +248,7 @@ } // parses a string that looks like "0x100020cfL" +#[allow(deprecated)] // trim_right_matches is now trim_end_matches fn parse_version(version: &str) -> u64 { // cut off the 0x prefix assert!(version.starts_with("0x")); diff -Nru cargo-0.33.0/vendor/openssl-sys/.cargo-checksum.json cargo-0.35.0/vendor/openssl-sys/.cargo-checksum.json --- cargo-0.33.0/vendor/openssl-sys/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6"} \ No newline at end of file +{"files":{},"package":"05636e06b4f8762d4b81d24a351f3966f38bd25ccbcfd235606c91fdb82cc60f"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/openssl-sys/Cargo.toml cargo-0.35.0/vendor/openssl-sys/Cargo.toml --- cargo-0.33.0/vendor/openssl-sys/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "openssl-sys" -version = "0.9.40" +version = "0.9.46" authors = ["Alex Crichton ", "Steven Fackler "] build = "build/main.rs" links = "openssl" @@ -25,6 +25,9 @@ openssl = "1.0.1" [dependencies.libc] version = "0.2" +[build-dependencies.autocfg] +version = "0.1.2" + [build-dependencies.cc] version = "1.0" diff -Nru cargo-0.33.0/vendor/openssl-sys/CHANGELOG.md cargo-0.35.0/vendor/openssl-sys/CHANGELOG.md --- cargo-0.33.0/vendor/openssl-sys/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,41 @@ +# Change Log + +## [Unreleased] + +## [v0.9.46] - 2019-05-08 + +### Added + +* Added support for the LibreSSL 2.9.x series. + +## [v0.9.45] - 2019-05-03 + +### Fixed + +* Reverted a change to windows-gnu library names that caused regressions. + +## [v0.9.44] - 2019-04-30 + +### Added + +* The `DEP_OPENSSL_VENDORED` environment variable tells downstream build scripts if the vendored feature was enabled. +* Added `EVP_SealInit`, `EVP_SealFinal`, `EVP_EncryptUpdate`, `EVP_OpenInit`, `EVP_OpenFinal`, and `EVP_DecryptUpdate`. +* Added `EVP_PKEY_size`. + +### Fixed + +* Fixed library names when targeting windows-gnu and pkg-config fails. + +## [v0.9.43] - 2019-03-20 + +### Added + +* Added `d2i_CMS_ContentInfo` and `CMS_encrypt`. +* Added `X509_verify` and `X509_REQ_verify`. +* Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`. + +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.46...master +[v0.9.46]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.45...openssl-sys-v0.9.46 +[v0.9.45]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.44...openssl-sys-v0.9.45 +[v0.9.44]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.43...openssl-sys-v0.9.44 +[v0.9.43]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.42...openssl-sys-v0.9.43 diff -Nru cargo-0.33.0/vendor/openssl-sys/.pc/disable-vendor.patch/Cargo.toml cargo-0.35.0/vendor/openssl-sys/.pc/disable-vendor.patch/Cargo.toml --- cargo-0.33.0/vendor/openssl-sys/.pc/disable-vendor.patch/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/.pc/disable-vendor.patch/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "openssl-sys" -version = "0.9.40" +version = "0.9.46" authors = ["Alex Crichton ", "Steven Fackler "] build = "build/main.rs" links = "openssl" @@ -25,6 +25,9 @@ openssl = "1.0.1" [dependencies.libc] version = "0.2" +[build-dependencies.autocfg] +version = "0.1.2" + [build-dependencies.cc] version = "1.0" diff -Nru cargo-0.33.0/vendor/openssl-sys/src/asn1.rs cargo-0.35.0/vendor/openssl-sys/src/asn1.rs --- cargo-0.33.0/vendor/openssl-sys/src/asn1.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/asn1.rs 2019-05-15 11:26:24.000000000 +0000 @@ -38,6 +38,7 @@ pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME); pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int; + pub fn ASN1_TIME_new() -> *mut ASN1_TIME; pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int; @@ -46,6 +47,10 @@ pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER; pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM; + + pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int; + #[cfg(ossl111)] + pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int; } cfg_if! { diff -Nru cargo-0.33.0/vendor/openssl-sys/src/cms.rs cargo-0.35.0/vendor/openssl-sys/src/cms.rs --- cargo-0.33.0/vendor/openssl-sys/src/cms.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/cms.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,4 +1,5 @@ use libc::*; +use *; pub enum CMS_ContentInfo {} @@ -7,6 +8,9 @@ pub fn CMS_ContentInfo_free(cms: *mut ::CMS_ContentInfo); #[cfg(ossl101)] pub fn i2d_CMS_ContentInfo(a: *mut ::CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int; + + #[cfg(ossl101)] + pub fn d2i_CMS_ContentInfo(a: *mut *mut ::CMS_ContentInfo, pp: *mut *const c_uchar, length: c_long) -> *mut ::CMS_ContentInfo; } #[cfg(ossl101)] @@ -68,6 +72,14 @@ ) -> *mut ::CMS_ContentInfo; #[cfg(ossl101)] + pub fn CMS_encrypt( + certs: *mut stack_st_X509, + data: *mut ::BIO, + cipher: *const EVP_CIPHER, + flags: c_uint + ) -> *mut ::CMS_ContentInfo; + + #[cfg(ossl101)] pub fn CMS_decrypt( cms: *mut ::CMS_ContentInfo, pkey: *mut ::EVP_PKEY, diff -Nru cargo-0.33.0/vendor/openssl-sys/src/crypto.rs cargo-0.35.0/vendor/openssl-sys/src/crypto.rs --- cargo-0.33.0/vendor/openssl-sys/src/crypto.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/crypto.rs 2019-05-15 11:26:24.000000000 +0000 @@ -15,7 +15,13 @@ if #[cfg(ossl110)] { pub const CRYPTO_EX_INDEX_SSL: c_int = 0; pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1; - + } else if #[cfg(libressl)] { + pub const CRYPTO_EX_INDEX_SSL: c_int = 1; + pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 2; + } +} +cfg_if! { + if #[cfg(any(ossl110, libressl271))] { extern "C" { pub fn OpenSSL_version_num() -> c_ulong; pub fn OpenSSL_version(key: c_int) -> *const c_char; @@ -64,7 +70,7 @@ argp: *mut c_void, ); extern "C" { - #[cfg(ossl110)] + #[cfg(any(ossl110, libressl))] pub fn CRYPTO_get_ex_new_index( class_index: c_int, argl: c_long, diff -Nru cargo-0.33.0/vendor/openssl-sys/src/dh.rs cargo-0.35.0/vendor/openssl-sys/src/dh.rs --- cargo-0.33.0/vendor/openssl-sys/src/dh.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/dh.rs 2019-05-15 11:26:24.000000000 +0000 @@ -15,10 +15,5 @@ pub fn DH_get_2048_256() -> *mut DH; #[cfg(any(ossl110, libressl273))] - pub fn DH_set0_pqg( - dh: *mut DH, - p: *mut BIGNUM, - q: *mut BIGNUM, - g: *mut BIGNUM, - ) -> c_int; + pub fn DH_set0_pqg(dh: *mut DH, p: *mut BIGNUM, q: *mut BIGNUM, g: *mut BIGNUM) -> c_int; } diff -Nru cargo-0.33.0/vendor/openssl-sys/src/dsa.rs cargo-0.35.0/vendor/openssl-sys/src/dsa.rs --- cargo-0.33.0/vendor/openssl-sys/src/dsa.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/dsa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,6 +5,7 @@ extern "C" { pub fn DSA_new() -> *mut DSA; pub fn DSA_free(dsa: *mut DSA); + pub fn DSA_up_ref(dsa: *mut DSA) -> c_int; pub fn DSA_size(dsa: *const DSA) -> c_int; pub fn DSA_sign( dummy: c_int, @@ -49,18 +50,9 @@ q: *mut *const BIGNUM, ); #[cfg(any(ossl110, libressl273))] - pub fn DSA_set0_pqg( - d: *mut DSA, - p: *mut BIGNUM, - q: *mut BIGNUM, - q: *mut BIGNUM, - ) -> c_int; + pub fn DSA_set0_pqg(d: *mut DSA, p: *mut BIGNUM, q: *mut BIGNUM, q: *mut BIGNUM) -> c_int; #[cfg(any(ossl110, libressl273))] - pub fn DSA_get0_key( - d: *const DSA, - pub_key: *mut *const BIGNUM, - priv_key: *mut *const BIGNUM, - ); + pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); #[cfg(any(ossl110, libressl273))] pub fn DSA_set0_key(d: *mut DSA, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int; } diff -Nru cargo-0.33.0/vendor/openssl-sys/src/ec.rs cargo-0.35.0/vendor/openssl-sys/src/ec.rs --- cargo-0.33.0/vendor/openssl-sys/src/ec.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/ec.rs 2019-05-15 11:26:24.000000000 +0000 @@ -30,6 +30,8 @@ ctx: *mut BN_CTX, ) -> c_int; + pub fn EC_GROUP_get_curve_name(group: *const EC_GROUP) -> c_int; + pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int); pub fn EC_GROUP_get_curve_GFp( diff -Nru cargo-0.33.0/vendor/openssl-sys/src/err.rs cargo-0.35.0/vendor/openssl-sys/src/err.rs --- cargo-0.33.0/vendor/openssl-sys/src/err.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/err.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,16 +5,24 @@ pub const ERR_LIB_PEM: c_int = 9; -pub fn ERR_GET_LIB(l: c_ulong) -> c_int { - ((l >> 24) & 0x0FF) as c_int -} +const_fn! { + pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong { + ((l as c_ulong & 0x0FF) << 24) | + ((f as c_ulong & 0xFFF) << 12) | + ((r as c_ulong & 0xFFF)) + } -pub fn ERR_GET_FUNC(l: c_ulong) -> c_int { - ((l >> 12) & 0xFFF) as c_int -} + pub const fn ERR_GET_LIB(l: c_ulong) -> c_int { + ((l >> 24) & 0x0FF) as c_int + } + + pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int { + ((l >> 12) & 0xFFF) as c_int + } -pub fn ERR_GET_REASON(l: c_ulong) -> c_int { - (l & 0xFFF) as c_int + pub const fn ERR_GET_REASON(l: c_ulong) -> c_int { + (l & 0xFFF) as c_int + } } #[repr(C)] diff -Nru cargo-0.33.0/vendor/openssl-sys/src/evp.rs cargo-0.35.0/vendor/openssl-sys/src/evp.rs --- cargo-0.33.0/vendor/openssl-sys/src/evp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/evp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -23,12 +23,10 @@ extern "C" { pub fn EVP_MD_size(md: *const EVP_MD) -> c_int; + pub fn EVP_MD_type(md: *const EVP_MD) -> c_int; - #[cfg(any(ossl110, libressl273))] pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int; - #[cfg(any(ossl110, libressl273))] pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int; - #[cfg(any(ossl110, libressl273))] pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int; } @@ -110,6 +108,50 @@ e: *mut ENGINE, pkey: *mut EVP_PKEY, ) -> c_int; + pub fn EVP_SealInit( + ctx: *mut EVP_CIPHER_CTX, + type_: *const EVP_CIPHER, + ek: *mut *mut c_uchar, + ekl: *mut c_int, + iv: *mut c_uchar, + pubk: *mut *mut EVP_PKEY, + npubk: c_int, + ) -> c_int; + pub fn EVP_SealFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int; + pub fn EVP_EncryptUpdate( + ctx: *mut EVP_CIPHER_CTX, + out: *mut c_uchar, + outl: *mut c_int, + in_: *const u8, + inl: c_int, + ) -> c_int; + pub fn EVP_OpenInit( + ctx: *mut EVP_CIPHER_CTX, + type_: *const EVP_CIPHER, + ek: *const c_uchar, + ekl: c_int, + iv: *const c_uchar, + priv_: *mut EVP_PKEY, + ) -> c_int; + pub fn EVP_OpenFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int; + pub fn EVP_DecryptUpdate( + ctx: *mut EVP_CIPHER_CTX, + out: *mut c_uchar, + outl: *mut c_int, + in_: *const u8, + inl: c_int, + ) -> c_int; +} +cfg_if! { + if #[cfg(any(ossl111b, libressl280))] { + extern "C" { + pub fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int; + } + } else { + extern "C" { + pub fn EVP_PKEY_size(pkey: *mut EVP_PKEY) -> c_int; + } + } } cfg_if! { if #[cfg(any(ossl102, libressl280))] { @@ -166,6 +208,7 @@ pub fn EVP_des_ecb() -> *const EVP_CIPHER; pub fn EVP_des_ede3() -> *const EVP_CIPHER; pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER; pub fn EVP_des_cbc() -> *const EVP_CIPHER; pub fn EVP_rc4() -> *const EVP_CIPHER; pub fn EVP_bf_ecb() -> *const EVP_CIPHER; diff -Nru cargo-0.33.0/vendor/openssl-sys/src/lib.rs cargo-0.35.0/vendor/openssl-sys/src/lib.rs --- cargo-0.33.0/vendor/openssl-sys/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,8 +25,8 @@ pub use ocsp::*; pub use ossl_typ::*; pub use pem::*; -pub use pkcs7::*; pub use pkcs12::*; +pub use pkcs7::*; pub use rand::*; pub use rsa::*; pub use safestack::*; @@ -62,8 +62,8 @@ mod ocsp; mod ossl_typ; mod pem; -mod pkcs7; mod pkcs12; +mod pkcs7; mod rand; mod rsa; mod safestack; @@ -78,9 +78,12 @@ mod x509v3; // FIXME remove -pub type PasswordCallback = - unsafe extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) - -> c_int; +pub type PasswordCallback = unsafe extern "C" fn( + buf: *mut c_char, + size: c_int, + rwflag: c_int, + user_data: *mut c_void, +) -> c_int; #[cfg(ossl110)] pub fn init() { diff -Nru cargo-0.33.0/vendor/openssl-sys/src/macros.rs cargo-0.35.0/vendor/openssl-sys/src/macros.rs --- cargo-0.33.0/vendor/openssl-sys/src/macros.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/macros.rs 2019-05-15 11:26:24.000000000 +0000 @@ -65,5 +65,23 @@ } } } + }; +} + +#[cfg(const_fn)] +macro_rules! const_fn { + ($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => { + $( + pub const fn $name($($arg: $t),*) -> $ret $b + )* + } +} + +#[cfg(not(const_fn))] +macro_rules! const_fn { + ($(pub const fn $name:ident($($arg:ident: $t:ty),*) -> $ret:ty $b:block)*) => { + $( + pub fn $name($($arg: $t),*) -> $ret $b + )* } } diff -Nru cargo-0.33.0/vendor/openssl-sys/src/ossl_typ.rs cargo-0.35.0/vendor/openssl-sys/src/ossl_typ.rs --- cargo-0.33.0/vendor/openssl-sys/src/ossl_typ.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/ossl_typ.rs 2019-05-15 11:26:24.000000000 +0000 @@ -346,7 +346,7 @@ cfg_if! { if #[cfg(any(ossl110, libressl280))] { - pub enum X509_VERIFY_PARAM {} + pub enum X509_VERIFY_PARAM {} } else if #[cfg(libressl251)] { #[repr(C)] pub struct X509_VERIFY_PARAM { @@ -947,6 +947,7 @@ } #[repr(C)] + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] pub struct SRP_CTX { SRP_cb_arg: *mut c_void, TLS_ext_srp_username_callback: *mut c_void, diff -Nru cargo-0.33.0/vendor/openssl-sys/src/pem.rs cargo-0.35.0/vendor/openssl-sys/src/pem.rs --- cargo-0.33.0/vendor/openssl-sys/src/pem.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/pem.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,9 +2,14 @@ use *; -pub type pem_password_cb = - Option c_int>; +pub type pem_password_cb = Option< + unsafe extern "C" fn( + buf: *mut c_char, + size: c_int, + rwflag: c_int, + user_data: *mut c_void, + ) -> c_int, +>; extern "C" { pub fn PEM_read_bio_X509( diff -Nru cargo-0.33.0/vendor/openssl-sys/src/rsa.rs cargo-0.35.0/vendor/openssl-sys/src/rsa.rs --- cargo-0.33.0/vendor/openssl-sys/src/rsa.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/rsa.rs 2019-05-15 11:26:24.000000000 +0000 @@ -143,6 +143,7 @@ k: *mut RSA, pad: c_int, ) -> c_int; + pub fn RSA_check_key(r: *const ::RSA) -> c_int; pub fn RSA_free(rsa: *mut RSA); pub fn RSA_up_ref(rsa: *mut RSA) -> c_int; diff -Nru cargo-0.33.0/vendor/openssl-sys/src/ssl.rs cargo-0.35.0/vendor/openssl-sys/src/ssl.rs --- cargo-0.33.0/vendor/openssl-sys/src/ssl.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/ssl.rs 2019-05-15 11:26:24.000000000 +0000 @@ -526,16 +526,22 @@ pub fn SSL_CTX_set_stateless_cookie_generate_cb( s: *mut SSL_CTX, cb: Option< - unsafe extern "C" fn(ssl: *mut SSL, cookie: *mut c_uchar, cookie_len: *mut size_t) - -> c_int, + unsafe extern "C" fn( + ssl: *mut SSL, + cookie: *mut c_uchar, + cookie_len: *mut size_t, + ) -> c_int, >, ); #[cfg(ossl111)] pub fn SSL_CTX_set_stateless_cookie_verify_cb( s: *mut SSL_CTX, cb: Option< - unsafe extern "C" fn(ssl: *mut SSL, cookie: *const c_uchar, cookie_len: size_t) - -> c_int, + unsafe extern "C" fn( + ssl: *mut SSL, + cookie: *const c_uchar, + cookie_len: size_t, + ) -> c_int, >, ); @@ -609,8 +615,14 @@ pub fn SSL_CTX_set_psk_client_callback( ssl: *mut SSL_CTX, psk_client_cb: Option< - extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint) - -> c_uint, + extern "C" fn( + *mut SSL, + *const c_char, + *mut c_char, + c_uint, + *mut c_uchar, + c_uint, + ) -> c_uint, >, ); pub fn SSL_CTX_set_psk_server_callback( @@ -685,6 +697,8 @@ pub const SSL_CTRL_OPTIONS: c_int = 32; pub const SSL_CTRL_MODE: c_int = 33; pub const SSL_CTRL_SET_READ_AHEAD: c_int = 41; +pub const SSL_CTRL_SET_SESS_CACHE_SIZE: c_int = 42; +pub const SSL_CTRL_GET_SESS_CACHE_SIZE: c_int = 43; pub const SSL_CTRL_SET_SESS_CACHE_MODE: c_int = 44; pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: c_int = 53; pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: c_int = 54; @@ -864,6 +878,10 @@ #[cfg(ossl111)] pub fn SSL_CIPHER_get_handshake_digest(cipher: *const ::SSL_CIPHER) -> *const ::EVP_MD; pub fn SSL_CIPHER_get_name(cipher: *const SSL_CIPHER) -> *const c_char; + #[cfg(ossl111)] + pub fn SSL_CIPHER_standard_name(cipher: *const SSL_CIPHER) -> *const c_char; + #[cfg(ossl111)] + pub fn OPENSSL_cipher_name(rfc_name: *const c_char) -> *const c_char; pub fn SSL_pending(ssl: *const SSL) -> c_int; pub fn SSL_set_bio(ssl: *mut SSL, rbio: *mut BIO, wbio: *mut BIO); @@ -903,6 +921,11 @@ pub fn SSL_state_string(ssl: *const SSL) -> *const c_char; pub fn SSL_state_string_long(ssl: *const SSL) -> *const c_char; + pub fn SSL_SESSION_get_time(s: *const SSL_SESSION) -> c_long; + pub fn SSL_SESSION_get_timeout(s: *const SSL_SESSION) -> c_long; + #[cfg(ossl110)] + pub fn SSL_SESSION_get_protocol_version(s: *const SSL_SESSION) -> c_int; + #[cfg(ossl111)] pub fn SSL_SESSION_set_max_early_data(ctx: *mut SSL_SESSION, max_early_data: u32) -> c_int; #[cfg(ossl111)] @@ -914,6 +937,8 @@ pub fn SSL_SESSION_free(s: *mut SSL_SESSION); pub fn i2d_SSL_SESSION(s: *mut SSL_SESSION, pp: *mut *mut c_uchar) -> c_int; pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_add_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_remove_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; pub fn d2i_SSL_SESSION( a: *mut *mut SSL_SESSION, pp: *mut *const c_uchar, @@ -1032,7 +1057,7 @@ } cfg_if! { - if #[cfg(ossl110)] { + if #[cfg(any(ossl110, libressl291))] { extern "C" { pub fn TLS_method() -> *const SSL_METHOD; @@ -1074,9 +1099,21 @@ CAfile: *const c_char, CApath: *const c_char, ) -> c_int; +} - pub fn SSL_get_ssl_method(ssl: *mut SSL) -> *const SSL_METHOD; +cfg_if! { + if #[cfg(ossl111b)] { + extern "C" { + pub fn SSL_get_ssl_method(ssl: *const SSL) -> *const SSL_METHOD; + } + } else { + extern "C" { + pub fn SSL_get_ssl_method(ssl: *mut SSL) -> *const SSL_METHOD; + } + } +} +extern "C" { pub fn SSL_set_connect_state(s: *mut SSL); pub fn SSL_set_accept_state(s: *mut SSL); @@ -1189,6 +1226,14 @@ pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int; } +pub unsafe fn SSL_CTX_sess_set_cache_size(ctx: *mut SSL_CTX, t: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_SIZE, t, ptr::null_mut()) +} + +pub unsafe fn SSL_CTX_sess_get_cache_size(ctx: *mut SSL_CTX) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_SESS_CACHE_SIZE, 0, ptr::null_mut()) +} + pub unsafe fn SSL_CTX_set_session_cache_mode(ctx: *mut SSL_CTX, m: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_MODE, m, ptr::null_mut()) } @@ -1212,15 +1257,21 @@ #[cfg(not(ossl110))] pub fn SSL_CTX_set_tmp_ecdh_callback( ctx: *mut ::SSL_CTX, - ecdh: unsafe extern "C" fn(ssl: *mut ::SSL, is_export: c_int, keylength: c_int) - -> *mut ::EC_KEY, + ecdh: unsafe extern "C" fn( + ssl: *mut ::SSL, + is_export: c_int, + keylength: c_int, + ) -> *mut ::EC_KEY, ); // FIXME should take an option #[cfg(not(ossl110))] pub fn SSL_set_tmp_ecdh_callback( ssl: *mut SSL, - ecdh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) - -> *mut EC_KEY, + ecdh: unsafe extern "C" fn( + ssl: *mut SSL, + is_export: c_int, + keylength: c_int, + ) -> *mut EC_KEY, ); } @@ -1228,11 +1279,25 @@ if #[cfg(libressl)] { extern "C" { pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const libc::c_void; + } + } else if #[cfg(osslconf = "OPENSSL_NO_COMP")] { + } else if #[cfg(ossl111b)] { + extern "C" { + pub fn SSL_get_current_compression(ssl: *const SSL) -> *const COMP_METHOD; + } + } else { + extern "C" { + pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const COMP_METHOD; + } + } +} +cfg_if! { + if #[cfg(libressl)] { + extern "C" { pub fn SSL_COMP_get_name(comp: *const libc::c_void) -> *const c_char; } } else if #[cfg(not(osslconf = "OPENSSL_NO_COMP"))] { extern "C" { - pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const COMP_METHOD; pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char; } } diff -Nru cargo-0.33.0/vendor/openssl-sys/src/tls1.rs cargo-0.35.0/vendor/openssl-sys/src/tls1.rs --- cargo-0.33.0/vendor/openssl-sys/src/tls1.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/tls1.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,6 @@ use libc::*; -use std::ptr; use std::mem; +use std::ptr; use *; diff -Nru cargo-0.33.0/vendor/openssl-sys/src/x509.rs cargo-0.35.0/vendor/openssl-sys/src/x509.rs --- cargo-0.33.0/vendor/openssl-sys/src/x509.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/x509.rs 2019-05-15 11:26:24.000000000 +0000 @@ -241,6 +241,7 @@ pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int; + pub fn X509_REQ_verify(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int; #[cfg(any(ossl110, libressl273))] pub fn X509_getm_notBefore(x: *const X509) -> *mut ASN1_TIME; #[cfg(any(ossl110, libressl273))] diff -Nru cargo-0.33.0/vendor/openssl-sys/src/x509v3.rs cargo-0.35.0/vendor/openssl-sys/src/x509v3.rs --- cargo-0.33.0/vendor/openssl-sys/src/x509v3.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/openssl-sys/src/x509v3.rs 2019-05-15 11:26:24.000000000 +0000 @@ -76,6 +76,7 @@ extern "C" { pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> c_int; + pub fn X509_verify(req: *mut X509, pkey: *mut EVP_PKEY) -> c_int; pub fn X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF); diff -Nru cargo-0.33.0/vendor/pretty_env_logger/.cargo-checksum.json cargo-0.35.0/vendor/pretty_env_logger/.cargo-checksum.json --- cargo-0.33.0/vendor/pretty_env_logger/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/pretty_env_logger/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28"} \ No newline at end of file +{"files":{},"package":"df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/pretty_env_logger/Cargo.toml cargo-0.35.0/vendor/pretty_env_logger/Cargo.toml --- cargo-0.33.0/vendor/pretty_env_logger/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/pretty_env_logger/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "pretty_env_logger" -version = "0.2.5" +version = "0.3.0" authors = ["Sean McArthur "] include = ["Cargo.toml", "LICENSE-APACHE", "LICENSE-MIT", "src/**/*"] description = "a visually pretty env_logger" @@ -21,14 +21,11 @@ categories = ["development-tools::debugging"] license = "MIT/Apache-2.0" repository = "https://github.com/seanmonstar/pretty-env-logger" -[dependencies.ansi_term] -version = "0.11" - [dependencies.chrono] version = "0.4.4" [dependencies.env_logger] -version = "0.5" +version = "0.6" [dependencies.log] version = "0.4" diff -Nru cargo-0.33.0/vendor/pretty_env_logger/src/lib.rs cargo-0.35.0/vendor/pretty_env_logger/src/lib.rs --- cargo-0.33.0/vendor/pretty_env_logger/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/pretty_env_logger/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -21,30 +21,23 @@ //! } //! ``` -extern crate ansi_term; extern crate env_logger; extern crate log; extern crate chrono; -use std::fmt; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use chrono::Local; -use ansi_term::{Color, Style}; -use env_logger::Builder; +use env_logger::{fmt::{Color, Style, StyledValue}, Builder}; use log::Level; -struct ColorLevel(Level); - -impl fmt::Display for ColorLevel { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - Level::Trace => Color::Purple.paint("TRACE"), - Level::Debug => Color::Blue.paint("DEBUG"), - Level::Info => Color::Green.paint("INFO "), - Level::Warn => Color::Yellow.paint("WARN "), - Level::Error => Color::Red.paint("ERROR") - }.fmt(f) +fn colored_level<'a>(style: &'a mut Style, level: Level) -> StyledValue<'a, &'static str> { + match level { + Level::Trace => style.set_color(Color::Magenta).value("TRACE"), + Level::Debug => style.set_color(Color::Blue).value("DEBUG"), + Level::Info => style.set_color(Color::Green).value("INFO "), + Level::Warn => style.set_color(Color::Yellow).value("WARN "), + Level::Error => style.set_color(Color::Red).value("ERROR"), } } @@ -127,7 +120,7 @@ /// /// This function fails to set the global logger if one has already been set. pub fn try_init_custom_env(environment_variable_name: &str) -> Result<(), log::SetLoggerError> { - let mut builder = formatted_builder()?; + let mut builder = formatted_builder(); if let Ok(s) = ::std::env::var(environment_variable_name) { builder.parse(&s); @@ -157,10 +150,10 @@ /// Returns a `env_logger::Builder` for further customization. /// -/// This method will return a colored and formatted) `env_logger::Builder` +/// This method will return a colored and formatted `env_logger::Builder` /// for further customization. Refer to env_logger::Build crate documentation /// for further details and usage. -pub fn formatted_builder() -> Result { +pub fn formatted_builder() -> Builder { let mut builder = Builder::new(); builder.format(|f, record| { @@ -171,18 +164,27 @@ MAX_MODULE_WIDTH.store(target.len(), Ordering::Relaxed); max_width = target.len(); } - writeln!(f, " {} {} > {}", - ColorLevel(record.level()), - Style::new().bold().paint(format!("{: {}", + level, + target, + record.args(), + ) }); - Ok(builder) + builder } /// Returns a `env_logger::Builder` for further customization. /// -/// This method will return a colored and time formatted) `env_logger::Builder` +/// This method will return a colored and time formatted `env_logger::Builder` /// for further customization. Refer to env_logger::Build crate documentation /// for further details and usage. pub fn formatted_timed_builder() -> Builder { @@ -196,11 +198,19 @@ MAX_MODULE_WIDTH.store(target.len(), Ordering::Relaxed); max_width = target.len(); } - writeln!(f, " {} {} {} > {}", - Local::now().format("%Y-%m-%d %H:%M:%S"), - ColorLevel(record.level()), - Style::new().bold().paint(format!("{: {}", + Local::now().format("%Y-%m-%d %H:%M:%S"), + level, + target, + record.args(), + ) }); builder diff -Nru cargo-0.33.0/vendor/proc-macro2/build.rs cargo-0.35.0/vendor/proc-macro2/build.rs --- cargo-0.33.0/vendor/proc-macro2/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -23,10 +23,11 @@ // were added one version later than the rest of the proc_macro token API. // Enabled on rustc 1.29 only. // -// "nightly" -// Enable the Span::unwrap method. This is to support proc_macro_span and -// proc_macro_diagnostic use on the nightly channel without requiring the -// semver exemption opt-in. Enabled when building with nightly. +// "proc_macro_span" +// Enable non-dummy behavior of Span::start and Span::end methods which +// requires an unstable compiler feature. Enabled when building with +// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable +// features. // // "super_unstable" // Implement the semver exempt API in terms of the nightly-only proc_macro @@ -81,8 +82,8 @@ println!("cargo:rustc-cfg=slow_extend"); } - if version.nightly { - println!("cargo:rustc-cfg=nightly"); + if version.nightly && feature_allowed("proc_macro_span") { + println!("cargo:rustc-cfg=proc_macro_span"); } if semver_exempt && version.nightly { @@ -131,3 +132,26 @@ nightly: nightly, }) } + +fn feature_allowed(feature: &str) -> bool { + // Recognized formats: + // + // -Z allow-features=feature1,feature2 + // + // -Zallow-features=feature1,feature2 + + if let Some(rustflags) = env::var_os("RUSTFLAGS") { + for mut flag in rustflags.to_string_lossy().split(' ') { + if flag.starts_with("-Z") { + flag = &flag["-Z".len()..]; + } + if flag.starts_with("allow-features=") { + flag = &flag["allow-features=".len()..]; + return flag.split(',').any(|allowed| allowed == feature); + } + } + } + + // No allow-features= flag, allowed by default. + true +} diff -Nru cargo-0.33.0/vendor/proc-macro2/.cargo-checksum.json cargo-0.35.0/vendor/proc-macro2/.cargo-checksum.json --- cargo-0.33.0/vendor/proc-macro2/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"} \ No newline at end of file +{"files":{},"package":"cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/proc-macro2/Cargo.toml cargo-0.35.0/vendor/proc-macro2/Cargo.toml --- cargo-0.33.0/vendor/proc-macro2/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "proc-macro2" -version = "0.4.27" +version = "0.4.30" authors = ["Alex Crichton "] build = "build.rs" description = "A stable implementation of the upcoming new `proc_macro` API. Comes with an\noption, off by default, to also reimplement itself in terms of the upstream\nunstable API.\n" diff -Nru cargo-0.33.0/vendor/proc-macro2/README.md cargo-0.35.0/vendor/proc-macro2/README.md --- cargo-0.33.0/vendor/proc-macro2/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -96,5 +96,5 @@ ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff -Nru cargo-0.33.0/vendor/proc-macro2/src/fallback.rs cargo-0.35.0/vendor/proc-macro2/src/fallback.rs --- cargo-0.33.0/vendor/proc-macro2/src/fallback.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/src/fallback.rs 2019-05-15 11:26:24.000000000 +0000 @@ -35,8 +35,8 @@ #[cfg(span_locations)] fn get_cursor(src: &str) -> Cursor { - // Create a dummy file & add it to the codemap - CODEMAP.with(|cm| { + // Create a dummy file & add it to the source map + SOURCE_MAP.with(|cm| { let mut cm = cm.borrow_mut(); let name = format!("", cm.files.len()); let span = cm.add_file(&name, src); @@ -56,7 +56,7 @@ type Err = LexError; fn from_str(src: &str) -> Result { - // Create a dummy file & add it to the codemap + // Create a dummy file & add it to the source map let cursor = get_cursor(src); match token_stream(cursor) { @@ -225,7 +225,7 @@ #[cfg(span_locations)] thread_local! { - static CODEMAP: RefCell = RefCell::new(Codemap { + static SOURCE_MAP: RefCell = RefCell::new(SourceMap { // NOTE: We start with a single dummy file which all call_site() and // def_site() spans reference. files: vec![{ @@ -295,12 +295,12 @@ } #[cfg(span_locations)] -struct Codemap { +struct SourceMap { files: Vec, } #[cfg(span_locations)] -impl Codemap { +impl SourceMap { fn next_start_pos(&self) -> u32 { // Add 1 so there's always space between files. // @@ -384,7 +384,7 @@ #[cfg(procmacro2_semver_exempt)] pub fn source_file(&self) -> SourceFile { - CODEMAP.with(|cm| { + SOURCE_MAP.with(|cm| { let cm = cm.borrow(); let fi = cm.fileinfo(*self); SourceFile { @@ -395,7 +395,7 @@ #[cfg(span_locations)] pub fn start(&self) -> LineColumn { - CODEMAP.with(|cm| { + SOURCE_MAP.with(|cm| { let cm = cm.borrow(); let fi = cm.fileinfo(*self); fi.offset_line_column(self.lo as usize) @@ -404,7 +404,7 @@ #[cfg(span_locations)] pub fn end(&self) -> LineColumn { - CODEMAP.with(|cm| { + SOURCE_MAP.with(|cm| { let cm = cm.borrow(); let fi = cm.fileinfo(*self); fi.offset_line_column(self.hi as usize) @@ -413,7 +413,7 @@ #[cfg(procmacro2_semver_exempt)] pub fn join(&self, other: Span) -> Option { - CODEMAP.with(|cm| { + SOURCE_MAP.with(|cm| { let cm = cm.borrow(); // If `other` is not within the same FileInfo as us, return None. if !cm.fileinfo(*self).span_within(other) { @@ -523,7 +523,7 @@ impl Ident { fn _new(string: &str, raw: bool, span: Span) -> Ident { - validate_term(string); + validate_ident(string); Ident { sym: string.to_owned(), @@ -566,7 +566,7 @@ || (c > '\x7f' && UnicodeXID::is_xid_continue(c)) } -fn validate_term(string: &str) { +fn validate_ident(string: &str) { let validate = string; if validate.is_empty() { panic!("Ident is not allowed to be empty; use Option"); @@ -734,17 +734,31 @@ } pub fn string(t: &str) -> Literal { - let mut s = t - .chars() - .flat_map(|c| c.escape_default()) - .collect::(); - s.push('"'); - s.insert(0, '"'); - Literal::_new(s) + let mut text = String::with_capacity(t.len() + 2); + text.push('"'); + for c in t.chars() { + if c == '\'' { + // escape_default turns this into "\'" which is unnecessary. + text.push(c); + } else { + text.extend(c.escape_default()); + } + } + text.push('"'); + Literal::_new(text) } pub fn character(t: char) -> Literal { - Literal::_new(format!("'{}'", t.escape_default().collect::())) + let mut text = String::new(); + text.push('\''); + if t == '"' { + // escape_default turns this into '\"' which is unnecessary. + text.push(t); + } else { + text.extend(t.escape_default()); + } + text.push('\''); + Literal::_new(text) } pub fn byte_string(bytes: &[u8]) -> Literal { diff -Nru cargo-0.33.0/vendor/proc-macro2/src/lib.rs cargo-0.35.0/vendor/proc-macro2/src/lib.rs --- cargo-0.33.0/vendor/proc-macro2/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -79,8 +79,8 @@ //! Semver exempt methods are marked as such in the proc-macro2 documentation. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.27")] -#![cfg_attr(nightly, feature(proc_macro_span))] +#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.30")] +#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] #![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))] #[cfg(use_proc_macro)] @@ -301,6 +301,7 @@ /// /// This type is semver exempt and not exposed by default. #[cfg(span_locations)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct LineColumn { /// The 1-indexed line in the source file on which the span starts or ends /// (inclusive). @@ -853,7 +854,12 @@ /// # Panics /// /// Panics if the input string is neither a keyword nor a legal variable - /// name. + /// name. If you are not sure whether the string contains an identifier and + /// need to handle an error case, use + /// syn::parse_str::<Ident> + /// rather than `Ident::new`. pub fn new(string: &str, span: Span) -> Ident { Ident::_new(imp::Ident::new(string, span.inner)) } @@ -1116,6 +1122,7 @@ /// /// The iteration is "shallow", e.g. the iterator doesn't recurse into /// delimited groups, and returns whole groups as token trees. + #[derive(Clone)] pub struct IntoIter { inner: imp::TokenTreeIter, _marker: marker::PhantomData>, diff -Nru cargo-0.33.0/vendor/proc-macro2/src/wrapper.rs cargo-0.35.0/vendor/proc-macro2/src/wrapper.rs --- cargo-0.33.0/vendor/proc-macro2/src/wrapper.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/src/wrapper.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,6 +25,7 @@ use std::sync::atomic::*; use std::sync::Once; + #[allow(deprecated)] static WORKS: AtomicUsize = ATOMIC_USIZE_INIT; static INIT: Once = Once::new(); @@ -317,6 +318,7 @@ } } +#[derive(Clone)] pub enum TokenTreeIter { Compiler(proc_macro::token_stream::IntoIter), Fallback(fallback::TokenTreeIter), @@ -477,12 +479,12 @@ #[cfg(any(super_unstable, feature = "span-locations"))] pub fn start(&self) -> LineColumn { match self { - #[cfg(nightly)] + #[cfg(proc_macro_span)] Span::Compiler(s) => { let proc_macro::LineColumn { line, column } = s.start(); LineColumn { line, column } } - #[cfg(not(nightly))] + #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => { let fallback::LineColumn { line, column } = s.start(); @@ -494,12 +496,12 @@ #[cfg(any(super_unstable, feature = "span-locations"))] pub fn end(&self) -> LineColumn { match self { - #[cfg(nightly)] + #[cfg(proc_macro_span)] Span::Compiler(s) => { let proc_macro::LineColumn { line, column } = s.end(); LineColumn { line, column } } - #[cfg(not(nightly))] + #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => { let fallback::LineColumn { line, column } = s.end(); diff -Nru cargo-0.33.0/vendor/proc-macro2/tests/test.rs cargo-0.35.0/vendor/proc-macro2/tests/test.rs --- cargo-0.33.0/vendor/proc-macro2/tests/test.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/proc-macro2/tests/test.rs 2019-05-15 11:26:24.000000000 +0000 @@ -5,7 +5,7 @@ use proc_macro2::{Ident, Literal, Spacing, Span, TokenStream, TokenTree}; #[test] -fn terms() { +fn idents() { assert_eq!( Ident::new("String", Span::call_site()).to_string(), "String" @@ -16,7 +16,7 @@ #[test] #[cfg(procmacro2_semver_exempt)] -fn raw_terms() { +fn raw_idents() { assert_eq!( Ident::new_raw("String", Span::call_site()).to_string(), "r#String" @@ -27,37 +27,37 @@ #[test] #[should_panic(expected = "Ident is not allowed to be empty; use Option")] -fn term_empty() { +fn ident_empty() { Ident::new("", Span::call_site()); } #[test] #[should_panic(expected = "Ident cannot be a number; use Literal instead")] -fn term_number() { +fn ident_number() { Ident::new("255", Span::call_site()); } #[test] #[should_panic(expected = "\"a#\" is not a valid Ident")] -fn term_invalid() { +fn ident_invalid() { Ident::new("a#", Span::call_site()); } #[test] #[should_panic(expected = "not a valid Ident")] -fn raw_term_empty() { +fn raw_ident_empty() { Ident::new("r#", Span::call_site()); } #[test] #[should_panic(expected = "not a valid Ident")] -fn raw_term_number() { +fn raw_ident_number() { Ident::new("r#255", Span::call_site()); } #[test] #[should_panic(expected = "\"r#a#\" is not a valid Ident")] -fn raw_term_invalid() { +fn raw_ident_invalid() { Ident::new("r#a#", Span::call_site()); } @@ -80,9 +80,21 @@ } #[test] -fn literals() { +fn literal_string() { assert_eq!(Literal::string("foo").to_string(), "\"foo\""); assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); + assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); +} + +#[test] +fn literal_character() { + assert_eq!(Literal::character('x').to_string(), "'x'"); + assert_eq!(Literal::character('\'').to_string(), "'\\''"); + assert_eq!(Literal::character('"').to_string(), "'\"'"); +} + +#[test] +fn literal_float() { assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0"); } @@ -339,6 +351,27 @@ delimiter: Bracket, stream: TokenStream [ Ident { + sym: a, + }, + Punct { + op: '+', + spacing: Alone, + }, + Literal { + lit: 1, + }, + ], + }, +]\ + "; + + #[cfg(not(procmacro2_semver_exempt))] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { sym: a }, Punct { @@ -361,6 +394,31 @@ stream: TokenStream [ Ident { sym: a, + span: bytes(2..3), + }, + Punct { + op: '+', + spacing: Alone, + span: bytes(4..5), + }, + Literal { + lit: 1, + span: bytes(6..7), + }, + ], + span: bytes(1..8), + }, +]\ + "; + + #[cfg(procmacro2_semver_exempt)] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, span: bytes(2..3) }, Punct { @@ -378,7 +436,12 @@ ]\ "; - assert_eq!(expected, format!("{:#?}", tts)); + let actual = format!("{:#?}", tts); + if actual.ends_with(",\n]") { + assert_eq!(expected, actual); + } else { + assert_eq!(expected_before_trailing_commas, actual); + } } #[test] diff -Nru cargo-0.33.0/vendor/quote/.cargo-checksum.json cargo-0.35.0/vendor/quote/.cargo-checksum.json --- cargo-0.33.0/vendor/quote/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/quote/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"} \ No newline at end of file +{"files":{},"package":"faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/quote/Cargo.toml cargo-0.35.0/vendor/quote/Cargo.toml --- cargo-0.33.0/vendor/quote/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/quote/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "quote" -version = "0.6.11" +version = "0.6.12" authors = ["David Tolnay "] include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] description = "Quasi-quoting macro quote!(...)" diff -Nru cargo-0.33.0/vendor/quote/src/lib.rs cargo-0.35.0/vendor/quote/src/lib.rs --- cargo-0.33.0/vendor/quote/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/quote/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -81,7 +81,7 @@ //! An even higher limit may be necessary for especially large invocations. // Quote types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/quote/0.6.11")] +#![doc(html_root_url = "https://docs.rs/quote/0.6.12")] #[cfg(all( not(all(target_arch = "wasm32", target_os = "unknown")), @@ -98,130 +98,8 @@ // Not public API. #[doc(hidden)] -pub mod __rt { - use ext::TokenStreamExt; - pub use proc_macro2::*; - - fn is_ident_start(c: u8) -> bool { - (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_' - } - - fn is_ident_continue(c: u8) -> bool { - (b'a' <= c && c <= b'z') - || (b'A' <= c && c <= b'Z') - || c == b'_' - || (b'0' <= c && c <= b'9') - } - - fn is_ident(token: &str) -> bool { - if token.bytes().all(|digit| digit >= b'0' && digit <= b'9') { - return false; - } - - let mut bytes = token.bytes(); - let first = bytes.next().unwrap(); - if !is_ident_start(first) { - return false; - } - for ch in bytes { - if !is_ident_continue(ch) { - return false; - } - } - true - } - - pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) { - if is_ident(s) { - // Fast path, since idents are the most common token. - tokens.append(Ident::new(s, span)); - } else { - let s: TokenStream = s.parse().expect("invalid token stream"); - tokens.extend(s.into_iter().map(|mut t| { - t.set_span(span); - t - })); - } - } - - macro_rules! push_punct { - ($name:ident $char1:tt) => { - pub fn $name(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; - ($name:ident $char1:tt $char2:tt) => { - pub fn $name(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char2, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; - ($name:ident $char1:tt $char2:tt $char3:tt) => { - pub fn $name(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char2, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char3, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; - } - - push_punct!(push_add '+'); - push_punct!(push_add_eq '+' '='); - push_punct!(push_and '&'); - push_punct!(push_and_and '&' '&'); - push_punct!(push_and_eq '&' '='); - push_punct!(push_at '@'); - push_punct!(push_bang '!'); - push_punct!(push_caret '^'); - push_punct!(push_caret_eq '^' '='); - push_punct!(push_colon ':'); - push_punct!(push_colon2 ':' ':'); - push_punct!(push_comma ','); - push_punct!(push_div '/'); - push_punct!(push_div_eq '/' '='); - push_punct!(push_dot '.'); - push_punct!(push_dot2 '.' '.'); - push_punct!(push_dot3 '.' '.' '.'); - push_punct!(push_dot_dot_eq '.' '.' '='); - push_punct!(push_eq '='); - push_punct!(push_eq_eq '=' '='); - push_punct!(push_ge '>' '='); - push_punct!(push_gt '>'); - push_punct!(push_le '<' '='); - push_punct!(push_lt '<'); - push_punct!(push_mul_eq '*' '='); - push_punct!(push_ne '!' '='); - push_punct!(push_or '|'); - push_punct!(push_or_eq '|' '='); - push_punct!(push_or_or '|' '|'); - push_punct!(push_pound '#'); - push_punct!(push_question '?'); - push_punct!(push_rarrow '-' '>'); - push_punct!(push_larrow '<' '-'); - push_punct!(push_rem '%'); - push_punct!(push_rem_eq '%' '='); - push_punct!(push_fat_arrow '=' '>'); - push_punct!(push_semi ';'); - push_punct!(push_shl '<' '<'); - push_punct!(push_shl_eq '<' '<' '='); - push_punct!(push_shr '>' '>'); - push_punct!(push_shr_eq '>' '>' '='); - push_punct!(push_star '*'); - push_punct!(push_sub '-'); - push_punct!(push_sub_eq '-' '='); -} +#[path = "runtime.rs"] +pub mod __rt; /// The whole point. /// @@ -254,6 +132,20 @@ /// - `#( struct #var; )*` — the repetition can contain other tokens /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations /// +/// There are two limitations around interpolations in a repetition: +/// +/// - Every interpolation inside of a repetition must be a distinct variable. +/// That is, `#(#a #a)*` is not allowed. Work around this by collecting `a` +/// into a vector and taking references `a1 = &a` and `a2 = &a` which you use +/// inside the repetition: `#(#a1 #a2)*`. Where possible, use meaningful names +/// that indicate the distinct role of each copy. +/// +/// - Every interpolation inside of a repetition must be iterable. If we have +/// `vec` which is a vector and `ident` which is a single identifier, +/// `#(#ident #vec)*` is not allowed. Work around this by using +/// `std::iter::repeat(ident)` to produce an iterable that can be used from +/// within the repetition. +/// /// # Hygiene /// /// Any interpolated tokens preserve the `Span` information provided by their @@ -441,7 +333,9 @@ /// ``` #[macro_export(local_inner_macros)] macro_rules! quote { - ($($tt:tt)*) => (quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*)); + ($($tt:tt)*) => { + quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*) + }; } /// Same as `quote!`, but applies a given span to all tokens originating within @@ -539,14 +433,12 @@ /// named `Sync` that is implemented for their type. #[macro_export(local_inner_macros)] macro_rules! quote_spanned { - ($span:expr=> $($tt:tt)*) => { - { - let mut _s = $crate::__rt::TokenStream::new(); - let _span = $span; - quote_each_token!(_s _span $($tt)*); - _s - } - }; + ($span:expr=> $($tt:tt)*) => {{ + let mut _s = $crate::__rt::TokenStream::new(); + let _span = $span; + quote_each_token!(_s _span $($tt)*); + _s + }}; } // Extract the names of all #metavariables and pass them to the $finish macro. diff -Nru cargo-0.33.0/vendor/quote/src/runtime.rs cargo-0.35.0/vendor/quote/src/runtime.rs --- cargo-0.33.0/vendor/quote/src/runtime.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/quote/src/runtime.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,119 @@ +use ext::TokenStreamExt; +pub use proc_macro2::*; + +fn is_ident_start(c: u8) -> bool { + (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_' +} + +fn is_ident_continue(c: u8) -> bool { + (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_' || (b'0' <= c && c <= b'9') +} + +fn is_ident(token: &str) -> bool { + if token.bytes().all(|digit| digit >= b'0' && digit <= b'9') { + return false; + } + + let mut bytes = token.bytes(); + let first = bytes.next().unwrap(); + if !is_ident_start(first) { + return false; + } + for ch in bytes { + if !is_ident_continue(ch) { + return false; + } + } + true +} + +pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) { + if is_ident(s) { + // Fast path, since idents are the most common token. + tokens.append(Ident::new(s, span)); + } else { + let s: TokenStream = s.parse().expect("invalid token stream"); + tokens.extend(s.into_iter().map(|mut t| { + t.set_span(span); + t + })); + } +} + +macro_rules! push_punct { + ($name:ident $char1:tt) => { + pub fn $name(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $char1:tt $char2:tt) => { + pub fn $name(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $char1:tt $char2:tt $char3:tt) => { + pub fn $name(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char3, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; +} + +push_punct!(push_add '+'); +push_punct!(push_add_eq '+' '='); +push_punct!(push_and '&'); +push_punct!(push_and_and '&' '&'); +push_punct!(push_and_eq '&' '='); +push_punct!(push_at '@'); +push_punct!(push_bang '!'); +push_punct!(push_caret '^'); +push_punct!(push_caret_eq '^' '='); +push_punct!(push_colon ':'); +push_punct!(push_colon2 ':' ':'); +push_punct!(push_comma ','); +push_punct!(push_div '/'); +push_punct!(push_div_eq '/' '='); +push_punct!(push_dot '.'); +push_punct!(push_dot2 '.' '.'); +push_punct!(push_dot3 '.' '.' '.'); +push_punct!(push_dot_dot_eq '.' '.' '='); +push_punct!(push_eq '='); +push_punct!(push_eq_eq '=' '='); +push_punct!(push_ge '>' '='); +push_punct!(push_gt '>'); +push_punct!(push_le '<' '='); +push_punct!(push_lt '<'); +push_punct!(push_mul_eq '*' '='); +push_punct!(push_ne '!' '='); +push_punct!(push_or '|'); +push_punct!(push_or_eq '|' '='); +push_punct!(push_or_or '|' '|'); +push_punct!(push_pound '#'); +push_punct!(push_question '?'); +push_punct!(push_rarrow '-' '>'); +push_punct!(push_larrow '<' '-'); +push_punct!(push_rem '%'); +push_punct!(push_rem_eq '%' '='); +push_punct!(push_fat_arrow '=' '>'); +push_punct!(push_semi ';'); +push_punct!(push_shl '<' '<'); +push_punct!(push_shl_eq '<' '<' '='); +push_punct!(push_shr '>' '>'); +push_punct!(push_shr_eq '>' '>' '='); +push_punct!(push_star '*'); +push_punct!(push_sub '-'); +push_punct!(push_sub_eq '-' '='); diff -Nru cargo-0.33.0/vendor/quote/src/to_tokens.rs cargo-0.35.0/vendor/quote/src/to_tokens.rs --- cargo-0.33.0/vendor/quote/src/to_tokens.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/quote/src/to_tokens.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::iter; +use std::rc::Rc; use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree}; @@ -89,6 +90,12 @@ fn to_tokens(&self, tokens: &mut TokenStream) { (**self).to_tokens(tokens); } +} + +impl ToTokens for Rc { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } } impl ToTokens for Option { diff -Nru cargo-0.33.0/vendor/rand_jitter/.cargo-checksum.json cargo-0.35.0/vendor/rand_jitter/.cargo-checksum.json --- cargo-0.33.0/vendor/rand_jitter/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"080723c6145e37503a2224f801f252e14ac5531cb450f4502698542d188cb3c0"} \ No newline at end of file +{"files":{},"package":"1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rand_jitter/Cargo.toml cargo-0.35.0/vendor/rand_jitter/Cargo.toml --- cargo-0.33.0/vendor/rand_jitter/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,13 +12,13 @@ [package] name = "rand_jitter" -version = "0.1.2" +version = "0.1.4" authors = ["The Rand Project Developers"] description = "Random number generator based on timing jitter" documentation = "https://docs.rs/rand_jitter" readme = "README.md" keywords = ["random", "rng", "os"] -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/rust-random/rand" [dependencies.log] version = "0.4" @@ -31,6 +31,7 @@ std = ["rand_core/std"] [target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.libc] version = "0.2" +default_features = false [target."cfg(target_os = \"windows\")".dependencies.winapi] version = "0.3" features = ["profileapi"] diff -Nru cargo-0.33.0/vendor/rand_jitter/CHANGELOG.md cargo-0.35.0/vendor/rand_jitter/CHANGELOG.md --- cargo-0.33.0/vendor/rand_jitter/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -4,6 +4,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.4] - 2019-05-02 +- Change error conversion code to partially fix #738 + +## [0.1.3] - 2019-02-05 +- Use libc in `no_std` mode to fix #723 + ## [0.1.2] - 2019-01-31 - Fix for older rustc compilers on Windows (#722) diff -Nru cargo-0.33.0/vendor/rand_jitter/README.md cargo-0.35.0/vendor/rand_jitter/README.md --- cargo-0.33.0/vendor/rand_jitter/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,11 @@ # rand_jitter [![Build Status](https://travis-ci.org/rust-random/rand.svg?branch=master)](https://travis-ci.org/rust-random/rand) [![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/rand?svg=true)](https://ci.appveyor.com/project/rust-random/rand) -[![Latest version](https://img.shields.io/crates/v/rand_os.svg)](https://crates.io/crates/rand_jitter) +[![Latest version](https://img.shields.io/crates/v/rand_jitter.svg)](https://crates.io/crates/rand_jitter) [![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) [![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_jitter) -[![API](https://docs.rs/rand_os/badge.svg)](https://docs.rs/rand_jitter) -[![Minimum rustc version](https://img.shields.io/badge/rustc-1.22+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) +[![API](https://docs.rs/rand_jitter/badge.svg)](https://docs.rs/rand_jitter) +[![Minimum rustc version](https://img.shields.io/badge/rustc-1.32+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) Non-physical true random number generator based on timing jitter. diff -Nru cargo-0.33.0/vendor/rand_jitter/src/error.rs cargo-0.35.0/vendor/rand_jitter/src/error.rs --- cargo-0.33.0/vendor/rand_jitter/src/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -59,8 +59,12 @@ fn from(err: TimerError) -> Error { // Timer check is already quite permissive of failures so we don't // expect false-positive failures, i.e. any error is irrecoverable. - Error::with_cause(ErrorKind::Unavailable, - "timer jitter failed basic quality tests", err) + #[cfg(feature = "std")] { + Error::with_cause(ErrorKind::Unavailable, "timer jitter failed basic quality tests", err) + } + #[cfg(not(feature = "std"))] { + Error::new(ErrorKind::Unavailable, "timer jitter failed basic quality tests") + } } } diff -Nru cargo-0.33.0/vendor/rand_jitter/src/lib.rs cargo-0.35.0/vendor/rand_jitter/src/lib.rs --- cargo-0.33.0/vendor/rand_jitter/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_jitter/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -75,7 +75,10 @@ use core::{fmt, mem, ptr}; #[cfg(feature = "std")] -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use std::sync::atomic::{AtomicUsize, Ordering}; +#[cfg(feature = "std")] +#[allow(deprecated)] // Required for compatibility with Rust < 1.24. +use std::sync::atomic::ATOMIC_USIZE_INIT; const MEMORY_BLOCKS: usize = 64; const MEMORY_BLOCKSIZE: usize = 32; @@ -167,6 +170,7 @@ // Initialise to zero; must be positive #[cfg(all(feature = "std", not(target_arch = "wasm32")))] +#[allow(deprecated)] static JITTER_ROUNDS: AtomicUsize = ATOMIC_USIZE_INIT; impl JitterRng { @@ -503,7 +507,7 @@ /// Basic quality tests on the timer, by measuring CPU timing jitter a few /// hundred times. /// - /// If succesful, this will return the estimated number of rounds necessary + /// If successful, this will return the estimated number of rounds necessary /// to collect 64 bits of entropy. Otherwise a [`TimerError`] with the cause /// of the failure will be returned. pub fn test_timer(&mut self) -> Result { diff -Nru cargo-0.33.0/vendor/rand_os/.cargo-checksum.json cargo-0.35.0/vendor/rand_os/.cargo-checksum.json --- cargo-0.33.0/vendor/rand_os/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d"} \ No newline at end of file +{"files":{},"package":"7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rand_os/Cargo.toml cargo-0.35.0/vendor/rand_os/Cargo.toml --- cargo-0.33.0/vendor/rand_os/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "rand_os" -version = "0.1.2" +version = "0.1.3" authors = ["The Rand Project Developers"] description = "OS backed Random Number Generator" homepage = "https://crates.io/crates/rand_os" diff -Nru cargo-0.33.0/vendor/rand_os/CHANGELOG.md cargo-0.35.0/vendor/rand_os/CHANGELOG.md --- cargo-0.33.0/vendor/rand_os/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.3] - 2019-03-05 +### Changes +- Fix support for Illumos (#730) +- Fix deprecation warnings from atomic init (#739) + ## [0.1.2] - 2019-01-28 ### Changes - Fuchsia: Replaced fuchsia-zircon with fuchsia-cprng diff -Nru cargo-0.33.0/vendor/rand_os/src/lib.rs cargo-0.35.0/vendor/rand_os/src/lib.rs --- cargo-0.33.0/vendor/rand_os/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -283,7 +283,8 @@ #[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd", target_os = "dragonfly", target_os = "solaris", target_os = "redox", - target_os = "haiku", target_os = "emscripten"))] + target_os = "haiku", target_os = "emscripten", + target_os = "illumos"))] mod random_device; macro_rules! mod_use { @@ -309,7 +310,7 @@ mod_use!(cfg(target_os = "netbsd"), netbsd); mod_use!(cfg(target_os = "openbsd"), openbsd_bitrig); mod_use!(cfg(target_os = "redox"), redox); -mod_use!(cfg(target_os = "solaris"), solaris); +mod_use!(cfg(any(target_os = "solaris", target_os = "illumos")), solarish); mod_use!(cfg(windows), windows); mod_use!(cfg(target_env = "sgx"), sgx); @@ -376,6 +377,7 @@ target_os = "openbsd", target_os = "redox", target_os = "solaris", + target_os = "illumos", windows, target_arch = "wasm32", target_env = "sgx" diff -Nru cargo-0.33.0/vendor/rand_os/src/linux_android.rs cargo-0.35.0/vendor/rand_os/src/linux_android.rs --- cargo-0.33.0/vendor/rand_os/src/linux_android.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/src/linux_android.rs 2019-05-15 11:26:24.000000000 +0000 @@ -18,7 +18,9 @@ use std::io::Read; use std::fs::{File, OpenOptions}; use std::os::unix::fs::OpenOptionsExt; -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; +use std::sync::atomic::{AtomicBool, Ordering}; +#[allow(deprecated)] // Required for compatibility with Rust < 1.24. +use std::sync::atomic::ATOMIC_BOOL_INIT; use std::sync::{Once, ONCE_INIT}; #[derive(Clone, Debug)] @@ -53,6 +55,7 @@ fn test_initialized(&mut self, dest: &mut [u8], blocking: bool) -> Result { + #[allow(deprecated)] static OS_RNG_INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; if !self.initialized { self.initialized = OS_RNG_INITIALIZED.load(Ordering::Relaxed); @@ -160,6 +163,7 @@ fn is_getrandom_available() -> bool { static CHECKER: Once = ONCE_INIT; + #[allow(deprecated)] static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT; if NR_GETRANDOM == 0 { return false }; diff -Nru cargo-0.33.0/vendor/rand_os/src/netbsd.rs cargo-0.35.0/vendor/rand_os/src/netbsd.rs --- cargo-0.33.0/vendor/rand_os/src/netbsd.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/src/netbsd.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,7 +14,9 @@ use std::fs::File; use std::io::Read; -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; +use std::sync::atomic::{AtomicBool, Ordering}; +#[allow(deprecated)] // Required for compatibility with Rust < 1.24. +use std::sync::atomic::ATOMIC_BOOL_INIT; #[derive(Clone, Debug)] pub struct OsRng { initialized: bool } @@ -34,6 +36,7 @@ fn test_initialized(&mut self, dest: &mut [u8], _blocking: bool) -> Result { + #[allow(deprecated)] static OS_RNG_INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; if !self.initialized { self.initialized = OS_RNG_INITIALIZED.load(Ordering::Relaxed); diff -Nru cargo-0.33.0/vendor/rand_os/src/solarish.rs cargo-0.35.0/vendor/rand_os/src/solarish.rs --- cargo-0.33.0/vendor/rand_os/src/solarish.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/src/solarish.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,195 @@ +// Copyright 2018 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementation for the Solaris family +//! +//! Read from `/dev/random`, with chunks of limited size (1040 bytes). +//! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A. +//! `/dev/urandom` uses the FIPS 186-2 algorithm, which is considered less +//! secure. We choose to read from `/dev/random`. +//! +//! Since Solaris 11.3 the `getrandom` syscall is available. To make sure we can +//! compile on both Solaris and on OpenSolaris derivatives, that do not have the +//! function, we do a direct syscall instead of calling a library function. +//! +//! We have no way to differentiate between Solaris, illumos, SmartOS, etc. +extern crate libc; + +use rand_core::{Error, ErrorKind}; +use super::random_device; +use super::OsRngImpl; + +use std::io; +use std::io::Read; +use std::fs::{File, OpenOptions}; +use std::os::unix::fs::OpenOptionsExt; +use std::sync::atomic::{AtomicBool, Ordering, AtomicUsize}; +#[allow(deprecated)] // Required for compatibility with Rust < 1.24. +use std::sync::atomic::ATOMIC_BOOL_INIT; +use std::cmp; +use std::mem; + +#[derive(Clone, Debug)] +pub struct OsRng { + method: OsRngMethod, + initialized: bool, +} + +#[derive(Clone, Debug)] +enum OsRngMethod { + GetRandom, + RandomDevice, +} + +impl OsRngImpl for OsRng { + fn new() -> Result { + if is_getrandom_available() { + return Ok(OsRng { method: OsRngMethod::GetRandom, + initialized: false }); + } + let open = |p| OpenOptions::new() + .read(true) + .custom_flags(libc::O_NONBLOCK) + .open(p); + random_device::open("/dev/random", &open)?; + Ok(OsRng { method: OsRngMethod::RandomDevice, initialized: false }) + } + + fn fill_chunk(&mut self, dest: &mut [u8]) -> Result<(), Error> { + match self.method { + OsRngMethod::GetRandom => getrandom_try_fill(dest, false), + OsRngMethod::RandomDevice => random_device::read(dest), + } + } + + fn test_initialized(&mut self, dest: &mut [u8], blocking: bool) + -> Result + { + #[allow(deprecated)] + static OS_RNG_INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; + if !self.initialized { + self.initialized = OS_RNG_INITIALIZED.load(Ordering::Relaxed); + } + if self.initialized { return Ok(0); } + + let chunk_len = cmp::min(1024, dest.len()); + let dest = &mut dest[..chunk_len]; + + match self.method { + OsRngMethod::GetRandom => getrandom_try_fill(dest, blocking)?, + OsRngMethod::RandomDevice => { + if blocking { + info!("OsRng: testing random device /dev/random"); + // We already have a non-blocking handle, but now need a + // blocking one. Not much choice except opening it twice + let mut file = File::open("/dev/random") + .map_err(random_device::map_err)?; + file.read(dest).map_err(random_device::map_err)?; + } else { + self.fill_chunk(dest)?; + } + } + }; + OS_RNG_INITIALIZED.store(true, Ordering::Relaxed); + self.initialized = true; + Ok(chunk_len) + } + + fn max_chunk_size(&self) -> usize { + // This is the largest size that's guaranteed to not block across + // all the Solarish platforms, though some may allow for larger + // sizes. + 256 + } + + fn method_str(&self) -> &'static str { + match self.method { + OsRngMethod::GetRandom => "getrandom", + OsRngMethod::RandomDevice => "/dev/random", + } + } +} + +#[cfg(target_os = "illumos")] +type GetRandomFn = unsafe extern fn(*mut u8, libc::size_t, libc::c_uint) + -> libc::ssize_t; +#[cfg(target_os = "solaris")] +type GetRandomFn = unsafe extern fn(*mut u8, libc::size_t, libc::c_uint) + -> libc::c_int; + +// Use dlsym to determine if getrandom(2) is present in libc. On Solarish +// systems, the syscall interface is not stable and can change between +// updates. Even worse, issuing unsupported syscalls will cause the system +// to generate a SIGSYS signal (usually terminating the program). +// Instead the stable APIs are exposed via libc. Cache the result of the +// lookup for future calls. This is loosely modeled after the +// libstd::sys::unix::weak macro which unfortunately is not exported. +fn fetch() -> Option { + static FPTR: AtomicUsize = AtomicUsize::new(1); + + if FPTR.load(Ordering::SeqCst) == 1 { + let name = "getrandom\0"; + let addr = unsafe { + libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr() as *const _) as usize + }; + FPTR.store(addr, Ordering::SeqCst); + } + + let ptr = FPTR.load(Ordering::SeqCst); + unsafe { + mem::transmute::>(ptr) + } +} + +fn getrandom(buf: &mut [u8], blocking: bool) -> libc::ssize_t { + const GRND_NONBLOCK: libc::c_uint = 0x0001; + const GRND_RANDOM: libc::c_uint = 0x0002; + + if let Some(rand) = fetch() { + let flag = if blocking { 0 } else { GRND_NONBLOCK } | GRND_RANDOM; + unsafe { + rand(buf.as_mut_ptr(), buf.len(), flag) as libc::ssize_t + } + } else { + -1 + } +} + +fn getrandom_try_fill(dest: &mut [u8], blocking: bool) -> Result<(), Error> { + let result = getrandom(dest, blocking); + if result == -1 || result == 0 { + let err = io::Error::last_os_error(); + let kind = err.kind(); + if kind == io::ErrorKind::WouldBlock { + return Err(Error::with_cause( + ErrorKind::NotReady, + "getrandom not ready", + err, + )); + } else { + return Err(Error::with_cause( + ErrorKind::Unavailable, + "unexpected getrandom error", + err, + )); + } + } else if result != dest.len() as libc::ssize_t { + return Err(Error::new(ErrorKind::Unavailable, + "unexpected getrandom error")); + } + Ok(()) +} + +fn is_getrandom_available() -> bool { + let available = match fetch() { + Some(_) => true, + None => false, + }; + info!("OsRng: using {}", if available { "getrandom" } else { "/dev/random" }); + available +} diff -Nru cargo-0.33.0/vendor/rand_os/src/solaris.rs cargo-0.35.0/vendor/rand_os/src/solaris.rs --- cargo-0.33.0/vendor/rand_os/src/solaris.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_os/src/solaris.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -// Copyright 2018 Developers of the Rand project. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementation for the Solaris family -//! -//! Read from `/dev/random`, with chunks of limited size (1040 bytes). -//! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A. -//! `/dev/urandom` uses the FIPS 186-2 algorithm, which is considered less -//! secure. We choose to read from `/dev/random`. -//! -//! Since Solaris 11.3 the `getrandom` syscall is available. To make sure we can -//! compile on both Solaris and on OpenSolaris derivatives, that do not have the -//! function, we do a direct syscall instead of calling a library function. -//! -//! We have no way to differentiate between Solaris, illumos, SmartOS, etc. -extern crate libc; - -use rand_core::{Error, ErrorKind}; -use super::random_device; -use super::OsRngImpl; - -use std::io; -use std::io::Read; -use std::fs::{File, OpenOptions}; -use std::os::unix::fs::OpenOptionsExt; -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; -use std::cmp; - -#[derive(Clone, Debug)] -pub struct OsRng { - method: OsRngMethod, - initialized: bool, -} - -#[derive(Clone, Debug)] -enum OsRngMethod { - GetRandom, - RandomDevice, -} - -impl OsRngImpl for OsRng { - fn new() -> Result { - if is_getrandom_available() { - return Ok(OsRng { method: OsRngMethod::GetRandom, - initialized: false }); - } - let open = |p| OpenOptions::new() - .read(true) - .custom_flags(libc::O_NONBLOCK) - .open(p); - random_device::open("/dev/random", &open)?; - Ok(OsRng { method: OsRngMethod::RandomDevice, initialized: false }) - } - - fn fill_chunk(&mut self, dest: &mut [u8]) -> Result<(), Error> { - match self.method { - OsRngMethod::GetRandom => getrandom_try_fill(dest, false), - OsRngMethod::RandomDevice => random_device::read(dest), - } - } - - fn test_initialized(&mut self, dest: &mut [u8], blocking: bool) - -> Result - { - static OS_RNG_INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; - if !self.initialized { - self.initialized = OS_RNG_INITIALIZED.load(Ordering::Relaxed); - } - if self.initialized { return Ok(0); } - - let chunk_len = cmp::min(1024, dest.len()); - let dest = &mut dest[..chunk_len]; - - match self.method { - OsRngMethod::GetRandom => getrandom_try_fill(dest, blocking)?, - OsRngMethod::RandomDevice => { - if blocking { - info!("OsRng: testing random device /dev/random"); - // We already have a non-blocking handle, but now need a - // blocking one. Not much choice except opening it twice - let mut file = File::open("/dev/random") - .map_err(random_device::map_err)?; - file.read(dest).map_err(random_device::map_err)?; - } else { - self.fill_chunk(dest)?; - } - } - }; - OS_RNG_INITIALIZED.store(true, Ordering::Relaxed); - self.initialized = true; - Ok(chunk_len) - } - - fn max_chunk_size(&self) -> usize { - // The documentation says 1024 is the maximum for getrandom, but - // 1040 for /dev/random. - 1024 - } - - fn method_str(&self) -> &'static str { - match self.method { - OsRngMethod::GetRandom => "getrandom", - OsRngMethod::RandomDevice => "/dev/random", - } - } -} - -fn getrandom(buf: &mut [u8], blocking: bool) -> libc::c_long { - extern "C" { - fn syscall(number: libc::c_long, ...) -> libc::c_long; - } - - const SYS_GETRANDOM: libc::c_long = 143; - const GRND_NONBLOCK: libc::c_uint = 0x0001; - const GRND_RANDOM: libc::c_uint = 0x0002; - - unsafe { - syscall(SYS_GETRANDOM, buf.as_mut_ptr(), buf.len(), - if blocking { 0 } else { GRND_NONBLOCK } | GRND_RANDOM) - } -} - -fn getrandom_try_fill(dest: &mut [u8], blocking: bool) -> Result<(), Error> { - let result = getrandom(dest, blocking); - if result == -1 || result == 0 { - let err = io::Error::last_os_error(); - let kind = err.kind(); - if kind == io::ErrorKind::WouldBlock { - return Err(Error::with_cause( - ErrorKind::NotReady, - "getrandom not ready", - err, - )); - } else { - return Err(Error::with_cause( - ErrorKind::Unavailable, - "unexpected getrandom error", - err, - )); - } - } else if result != dest.len() as i64 { - return Err(Error::new(ErrorKind::Unavailable, - "unexpected getrandom error")); - } - Ok(()) -} - -fn is_getrandom_available() -> bool { - use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; - use std::sync::{Once, ONCE_INIT}; - - static CHECKER: Once = ONCE_INIT; - static AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT; - - CHECKER.call_once(|| { - debug!("OsRng: testing getrandom"); - let mut buf: [u8; 0] = []; - let result = getrandom(&mut buf, false); - let available = if result == -1 { - let err = io::Error::last_os_error().raw_os_error(); - err != Some(libc::ENOSYS) - } else { - true - }; - AVAILABLE.store(available, Ordering::Relaxed); - info!("OsRng: using {}", if available { "getrandom" } else { "/dev/random" }); - }); - - AVAILABLE.load(Ordering::Relaxed) -} diff -Nru cargo-0.33.0/vendor/rand_pcg/build.rs cargo-0.35.0/vendor/rand_pcg/build.rs --- cargo-0.33.0/vendor/rand_pcg/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,7 @@ -extern crate rustc_version; -use rustc_version::{version, Version}; +extern crate autocfg; fn main() { - if version().unwrap() >= Version::parse("1.26.0").unwrap() { - println!("cargo:rustc-cfg=rust_1_26"); - } + println!("cargo:rerun-if-changed=build.rs"); + let ac = autocfg::new(); + ac.emit_rustc_version(1, 26); } diff -Nru cargo-0.33.0/vendor/rand_pcg/.cargo-checksum.json cargo-0.35.0/vendor/rand_pcg/.cargo-checksum.json --- cargo-0.33.0/vendor/rand_pcg/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05"} \ No newline at end of file +{"files":{},"package":"abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rand_pcg/Cargo.toml cargo-0.35.0/vendor/rand_pcg/Cargo.toml --- cargo-0.33.0/vendor/rand_pcg/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,24 +12,19 @@ [package] name = "rand_pcg" -version = "0.1.1" +version = "0.1.2" authors = ["The Rand Project Developers"] build = "build.rs" description = "Selected PCG random number generators\n" homepage = "https://crates.io/crates/rand_pcg" -documentation = "https://docs.rs/rand_pcg" +documentation = "https://rust-random.github.io/rand/rand_pcg" readme = "README.md" keywords = ["random", "rng", "pcg"] categories = ["algorithms", "no-std"] license = "MIT/Apache-2.0" -repository = "https://github.com/rust-random/small-rngs" -[dependencies.bincode] -version = "1" -optional = true - +repository = "https://github.com/rust-random/rand" [dependencies.rand_core] -version = "0.3" -default-features = false +version = "0.4" [dependencies.serde] version = "1" @@ -38,13 +33,15 @@ [dependencies.serde_derive] version = "^1.0.38" optional = true -[build-dependencies.rustc_version] -version = "0.2" +[dev-dependencies.bincode] +version = "1.1.2" +[build-dependencies.autocfg] +version = "0.1" [features] -serde1 = ["serde", "serde_derive", "bincode/i128"] +serde1 = ["serde", "serde_derive"] [badges.appveyor] -repository = "rust-random/small-rngs" +repository = "rust-random/rand" [badges.travis-ci] -repository = "rust-random/small-rngs" +repository = "rust-random/rand" diff -Nru cargo-0.33.0/vendor/rand_pcg/CHANGELOG.md cargo-0.35.0/vendor/rand_pcg/CHANGELOG.md --- cargo-0.33.0/vendor/rand_pcg/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -4,6 +4,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.2] - 2019-02-23 +- require `bincode` 1.1.2 for i128 auto-detection +- make `bincode` a dev-dependency again #663 +- clean up tests and Serde support + ## [0.1.1] - 2018-10-04 - make `bincode` an explicit dependency when using Serde diff -Nru cargo-0.33.0/vendor/rand_pcg/README.md cargo-0.35.0/vendor/rand_pcg/README.md --- cargo-0.33.0/vendor/rand_pcg/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,11 +1,12 @@ # rand_pcg -[![Build Status](https://travis-ci.org/rust-random/small-rngs.svg?branch=master)](https://travis-ci.org/rust-random/small-rngs) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/small-rngs?svg=true)](https://ci.appveyor.com/project/rust-random/small-rngs) +[![Build Status](https://travis-ci.org/rust-random/rand.svg?branch=master)](https://travis-ci.org/rust-random/rand) +[![Build Status](https://ci.appveyor.com/api/projects/status/github/rust-random/rand?svg=true)](https://ci.appveyor.com/project/rust-random/rand) [![Latest version](https://img.shields.io/crates/v/rand_pcg.svg)](https://crates.io/crates/rand_pcg) -[![Documentation](https://docs.rs/rand_pcg/badge.svg)](https://docs.rs/rand_pcg) -[![Minimum rustc version](https://img.shields.io/badge/rustc-1.22+-yellow.svg)](https://github.com/rust-random/rand#rust-version-requirements) -[![License](https://img.shields.io/crates/l/rand_pcg.svg)](https://github.com/rust-random/small-rngs/tree/master/rand_pcg#license) +[[![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/) +[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_pcg) +[![API](https://docs.rs/rand_pcg/badge.svg)](https://docs.rs/rand_pcg) +[![Minimum rustc version](https://img.shields.io/badge/rustc-1.22+-lightgray.svg)](https://github.com/rust-random/rand#rust-version-requirements) Implements a selection of PCG random number generators. @@ -19,22 +20,20 @@ This crate depends on [rand_core](https://crates.io/crates/rand_core) and is part of the [Rand project](https://github.com/rust-random/rand). -Documentation: -[master branch](https://rust-random.github.io/small-rngs/rand_pcg/index.html), -[by release](https://docs.rs/rand_pcg) +Links: -[Changelog](CHANGELOG.md) +- [API documentation (master)](https://rust-random.github.io/rand/rand_pcg) +- [API documentation (docs.rs)](https://docs.rs/rand_pcg) +- [Changelog](CHANGELOG.md) ## Crate Features -`rand_pcg` is `no_std` compatible. It does not require any functionality -outside of the `core` lib, thus there are no features to configure. +`rand_pcg` is `no_std` compatible by default. The `serde1` feature includes implementations of `Serialize` and `Deserialize` for the included RNGs. - ## License `rand_pcg` is distributed under the terms of both the MIT license and the diff -Nru cargo-0.33.0/vendor/rand_pcg/src/lib.rs cargo-0.35.0/vendor/rand_pcg/src/lib.rs --- cargo-0.33.0/vendor/rand_pcg/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -7,13 +7,13 @@ // except according to those terms. //! The PCG random number generators. -//! +//! //! This is a native Rust implementation of a small selection of PCG generators. //! The primary goal of this crate is simple, minimal, well-tested code; in //! other words it is explicitly not a goal to re-implement all of PCG. -//! +//! //! This crate provides: -//! +//! //! - `Pcg32` aka `Lcg64Xsh32`, officially known as `pcg32`, a general //! purpose RNG. This is a good choice on both 32-bit and 64-bit CPUs //! (for 32-bit output). @@ -29,25 +29,20 @@ #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://docs.rs/rand_pcg/0.1.1")] + html_root_url = "https://rust-random.github.io/rand/")] #![deny(missing_docs)] #![deny(missing_debug_implementations)] -#![doc(test(attr(allow(unused_variables), deny(warnings))))] -#![cfg_attr(not(all(feature="serde1", test)), no_std)] +#![no_std] -extern crate rand_core; +pub extern crate rand_core; #[cfg(feature="serde1")] extern crate serde; #[cfg(feature="serde1")] #[macro_use] extern crate serde_derive; -// To test serialization we need bincode and the standard library -#[cfg(all(feature="serde1", test))] extern crate bincode; -#[cfg(all(feature="serde1", test))] extern crate std as core; - mod pcg64; -#[cfg(rust_1_26)] mod pcg128; +#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] mod pcg128; pub use self::pcg64::{Pcg32, Lcg64Xsh32}; -#[cfg(rust_1_26)] pub use self::pcg128::{Pcg64Mcg, Mcg128Xsl64}; +#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] pub use self::pcg128::{Pcg64Mcg, Mcg128Xsl64}; diff -Nru cargo-0.33.0/vendor/rand_pcg/src/pcg128.rs cargo-0.35.0/vendor/rand_pcg/src/pcg128.rs --- cargo-0.33.0/vendor/rand_pcg/src/pcg128.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/src/pcg128.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,23 +11,23 @@ //! PCG random number generators // This is the default multiplier used by PCG for 64-bit state. -const MULTIPLIER: u128 = 2549297995355413924u128 << 64 | 4865540595714422341; +const MULTIPLIER: u128 = 0x2360_ED05_1FC6_5DA4_4385_DF64_9FCC_F645; use core::fmt; use core::mem::transmute; use rand_core::{RngCore, SeedableRng, Error, le}; /// A PCG random number generator (XSL 128/64 (MCG) variant). -/// +/// /// Permuted Congruential Generator with 128-bit state, internal Multiplicative /// Congruential Generator, and 64-bit output via "xorshift low (bits), /// random rotation" output function. -/// +/// /// This is a 128-bit MCG with the PCG-XSL-RR output function. /// Note that compared to the standard `pcg64` (128-bit LCG with PCG-XSL-RR /// output function), this RNG is faster, also has a long cycle, and still has /// good performance on statistical tests. -/// +/// /// Note: this RNG is only available using Rust 1.26 or later. #[derive(Clone)] #[cfg_attr(feature="serde1", derive(Serialize,Deserialize))] @@ -40,9 +40,9 @@ impl Mcg128Xsl64 { /// Construct an instance compatible with PCG seed. - /// + /// /// Note that PCG specifies a default value for the parameter: - /// + /// /// - `state = 0xcafef00dd15ea5e5` pub fn new(state: u128) -> Self { // Force low bit to 1, as in C version (C++ uses `state | 3` instead). @@ -120,62 +120,3 @@ Ok(self.fill_bytes(dest)) } } - -#[cfg(test)] -mod tests { - use ::rand_core::{RngCore, SeedableRng}; - use super::*; - - #[test] - fn test_mcg128xsl64_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; - let mut rng1 = Mcg128Xsl64::from_seed(seed); - assert_eq!(rng1.next_u64(), 7071994460355047496); - - let mut rng2 = Mcg128Xsl64::from_rng(&mut rng1).unwrap(); - assert_eq!(rng2.next_u64(), 12300796107712034932); - - let mut rng3 = Mcg128Xsl64::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 6198063878555692194); - - // This is the same as Mcg128Xsl64, so we only have a single test: - let mut rng4 = Pcg64Mcg::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 6198063878555692194); - } - - #[test] - fn test_mcg128xsl64_true_values() { - // Numbers copied from official test suite (C version). - let mut rng = Mcg128Xsl64::new(42); - - let mut results = [0u64; 6]; - for i in results.iter_mut() { *i = rng.next_u64(); } - let expected: [u64; 6] = [0x63b4a3a813ce700a, 0x382954200617ab24, - 0xa7fd85ae3fe950ce, 0xd715286aa2887737, 0x60c92fee2e59f32c, 0x84c4e96beff30017]; - assert_eq!(results, expected); - } - - #[cfg(feature="serde1")] - #[test] - fn test_mcg128xsl64_serde() { - use bincode; - use std::io::{BufWriter, BufReader}; - - let mut rng = Mcg128Xsl64::seed_from_u64(0); - - let buf: Vec = Vec::new(); - let mut buf = BufWriter::new(buf); - bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); - - let buf = buf.into_inner().unwrap(); - let mut read = BufReader::new(&buf[..]); - let mut deserialized: Mcg128Xsl64 = bincode::deserialize_from(&mut read).expect("Could not deserialize"); - - assert_eq!(rng.state, deserialized.state); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } - } -} diff -Nru cargo-0.33.0/vendor/rand_pcg/src/pcg64.rs cargo-0.35.0/vendor/rand_pcg/src/pcg64.rs --- cargo-0.33.0/vendor/rand_pcg/src/pcg64.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/src/pcg64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -18,14 +18,14 @@ const MULTIPLIER: u64 = 6364136223846793005; /// A PCG random number generator (XSH RR 64/32 (LCG) variant). -/// +/// /// Permuted Congruential Generator with 64-bit state, internal Linear /// Congruential Generator, and 32-bit output via "xorshift high (bits), /// random rotation" output function. -/// +/// /// This is a 64-bit LCG with explicitly chosen stream with the PCG-XSH-RR /// output function. This combination is the standard `pcg32`. -/// +/// /// Despite the name, this implementation uses 16 bytes (128 bit) space /// comprising 64 bits of state and 64 bits stream selector. These are both set /// by `SeedableRng`, using a 128-bit seed. @@ -41,9 +41,9 @@ impl Lcg64Xsh32 { /// Construct an instance compatible with PCG seed and stream. - /// + /// /// Note that PCG specifies default values for both parameters: - /// + /// /// - `state = 0xcafef00dd15ea5e5` /// - `stream = 721347520444481703` pub fn new(state: u64, stream: u64) -> Self { @@ -51,7 +51,7 @@ let increment = (stream << 1) | 1; Lcg64Xsh32::from_state_incr(state, increment) } - + #[inline] fn from_state_incr(state: u64, increment: u64) -> Self { let mut pcg = Lcg64Xsh32 { state, increment }; @@ -60,7 +60,7 @@ pcg.step(); pcg } - + #[inline] fn step(&mut self) { // prepare the LCG for the next round @@ -139,62 +139,3 @@ Ok(self.fill_bytes(dest)) } } - -#[cfg(test)] -mod tests { - use ::rand_core::{RngCore, SeedableRng}; - use super::*; - - #[test] - fn test_lcg64xsh32_construction() { - // Test that various construction techniques produce a working RNG. - let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; - let mut rng1 = Lcg64Xsh32::from_seed(seed); - assert_eq!(rng1.next_u64(), 1204678643940597513); - - let mut rng2 = Lcg64Xsh32::from_rng(&mut rng1).unwrap(); - assert_eq!(rng2.next_u64(), 12384929573776311845); - - let mut rng3 = Lcg64Xsh32::seed_from_u64(0); - assert_eq!(rng3.next_u64(), 18195738587432868099); - - // This is the same as Lcg64Xsh32, so we only have a single test: - let mut rng4 = Pcg32::seed_from_u64(0); - assert_eq!(rng4.next_u64(), 18195738587432868099); - } - - #[test] - fn test_lcg64xsh32_true_values() { - // Numbers copied from official test suite. - let mut rng = Lcg64Xsh32::new(42, 54); - - let mut results = [0u32; 6]; - for i in results.iter_mut() { *i = rng.next_u32(); } - let expected: [u32; 6] = [0xa15c02b7, 0x7b47f409, 0xba1d3330, - 0x83d2f293, 0xbfa4784b, 0xcbed606e]; - assert_eq!(results, expected); - } - - #[cfg(feature="serde1")] - #[test] - fn test_lcg64xsh32_serde() { - use bincode; - use std::io::{BufWriter, BufReader}; - - let mut rng = Lcg64Xsh32::seed_from_u64(0); - - let buf: Vec = Vec::new(); - let mut buf = BufWriter::new(buf); - bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); - - let buf = buf.into_inner().unwrap(); - let mut read = BufReader::new(&buf[..]); - let mut deserialized: Lcg64Xsh32 = bincode::deserialize_from(&mut read).expect("Could not deserialize"); - - assert_eq!(rng.state, deserialized.state); - - for _ in 0..16 { - assert_eq!(rng.next_u64(), deserialized.next_u64()); - } - } -} diff -Nru cargo-0.33.0/vendor/rand_pcg/tests/lcg64xsh32.rs cargo-0.35.0/vendor/rand_pcg/tests/lcg64xsh32.rs --- cargo-0.33.0/vendor/rand_pcg/tests/lcg64xsh32.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/tests/lcg64xsh32.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,58 @@ +extern crate rand_pcg; +extern crate rand_core; +#[cfg(all(feature="serde1", test))] extern crate bincode; + +use rand_core::{RngCore, SeedableRng}; +use rand_pcg::{Lcg64Xsh32, Pcg32}; + +#[test] +fn test_lcg64xsh32_construction() { + // Test that various construction techniques produce a working RNG. + let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; + let mut rng1 = Lcg64Xsh32::from_seed(seed); + assert_eq!(rng1.next_u64(), 1204678643940597513); + + let mut rng2 = Lcg64Xsh32::from_rng(&mut rng1).unwrap(); + assert_eq!(rng2.next_u64(), 12384929573776311845); + + let mut rng3 = Lcg64Xsh32::seed_from_u64(0); + assert_eq!(rng3.next_u64(), 18195738587432868099); + + // This is the same as Lcg64Xsh32, so we only have a single test: + let mut rng4 = Pcg32::seed_from_u64(0); + assert_eq!(rng4.next_u64(), 18195738587432868099); +} + +#[test] +fn test_lcg64xsh32_true_values() { + // Numbers copied from official test suite. + let mut rng = Lcg64Xsh32::new(42, 54); + + let mut results = [0u32; 6]; + for i in results.iter_mut() { *i = rng.next_u32(); } + let expected: [u32; 6] = [0xa15c02b7, 0x7b47f409, 0xba1d3330, + 0x83d2f293, 0xbfa4784b, 0xcbed606e]; + assert_eq!(results, expected); +} + +#[cfg(feature="serde1")] +#[test] +fn test_lcg64xsh32_serde() { + use bincode; + use std::io::{BufWriter, BufReader}; + + let mut rng = Lcg64Xsh32::seed_from_u64(0); + + let buf: Vec = Vec::new(); + let mut buf = BufWriter::new(buf); + bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); + + let buf = buf.into_inner().unwrap(); + let mut read = BufReader::new(&buf[..]); + let mut deserialized: Lcg64Xsh32 = bincode::deserialize_from(&mut read) + .expect("Could not deserialize"); + + for _ in 0..16 { + assert_eq!(rng.next_u64(), deserialized.next_u64()); + } +} diff -Nru cargo-0.33.0/vendor/rand_pcg/tests/mcg128xsl64.rs cargo-0.35.0/vendor/rand_pcg/tests/mcg128xsl64.rs --- cargo-0.33.0/vendor/rand_pcg/tests/mcg128xsl64.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/rand_pcg/tests/mcg128xsl64.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,59 @@ +#![cfg(rustc_1_26)] +extern crate rand_pcg; +extern crate rand_core; +#[cfg(all(feature="serde1", test))] extern crate bincode; + +use rand_core::{RngCore, SeedableRng}; +use rand_pcg::{Mcg128Xsl64, Pcg64Mcg}; + +#[test] +fn test_mcg128xsl64_construction() { + // Test that various construction techniques produce a working RNG. + let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; + let mut rng1 = Mcg128Xsl64::from_seed(seed); + assert_eq!(rng1.next_u64(), 7071994460355047496); + + let mut rng2 = Mcg128Xsl64::from_rng(&mut rng1).unwrap(); + assert_eq!(rng2.next_u64(), 12300796107712034932); + + let mut rng3 = Mcg128Xsl64::seed_from_u64(0); + assert_eq!(rng3.next_u64(), 6198063878555692194); + + // This is the same as Mcg128Xsl64, so we only have a single test: + let mut rng4 = Pcg64Mcg::seed_from_u64(0); + assert_eq!(rng4.next_u64(), 6198063878555692194); +} + +#[test] +fn test_mcg128xsl64_true_values() { + // Numbers copied from official test suite (C version). + let mut rng = Mcg128Xsl64::new(42); + + let mut results = [0u64; 6]; + for i in results.iter_mut() { *i = rng.next_u64(); } + let expected: [u64; 6] = [0x63b4a3a813ce700a, 0x382954200617ab24, + 0xa7fd85ae3fe950ce, 0xd715286aa2887737, 0x60c92fee2e59f32c, 0x84c4e96beff30017]; + assert_eq!(results, expected); +} + +#[cfg(feature="serde1")] +#[test] +fn test_mcg128xsl64_serde() { + use bincode; + use std::io::{BufWriter, BufReader}; + + let mut rng = Mcg128Xsl64::seed_from_u64(0); + + let buf: Vec = Vec::new(); + let mut buf = BufWriter::new(buf); + bincode::serialize_into(&mut buf, &rng).expect("Could not serialize"); + + let buf = buf.into_inner().unwrap(); + let mut read = BufReader::new(&buf[..]); + let mut deserialized: Mcg128Xsl64 = bincode::deserialize_from(&mut read) + .expect("Could not deserialize"); + + for _ in 0..16 { + assert_eq!(rng.next_u64(), deserialized.next_u64()); + } +} diff -Nru cargo-0.33.0/vendor/redox_syscall/.cargo-checksum.json cargo-0.35.0/vendor/redox_syscall/.cargo-checksum.json --- cargo-0.33.0/vendor/redox_syscall/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"} \ No newline at end of file +{"files":{},"package":"12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/redox_syscall/Cargo.toml cargo-0.35.0/vendor/redox_syscall/Cargo.toml --- cargo-0.33.0/vendor/redox_syscall/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "redox_syscall" -version = "0.1.51" +version = "0.1.54" authors = ["Jeremy Soller "] description = "A Rust library to access raw Redox system calls" documentation = "https://docs.rs/redox_syscall" diff -Nru cargo-0.33.0/vendor/redox_syscall/src/flag.rs cargo-0.35.0/vendor/redox_syscall/src/flag.rs --- cargo-0.33.0/vendor/redox_syscall/src/flag.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/flag.rs 2019-05-15 11:26:24.000000000 +0000 @@ -4,6 +4,7 @@ pub const CLONE_SIGHAND: usize = 0x800; pub const CLONE_VFORK: usize = 0x4000; pub const CLONE_THREAD: usize = 0x10000; +pub const CLONE_STACK: usize = 0x1000_0000; pub const CLOCK_REALTIME: usize = 1; pub const CLOCK_MONOTONIC: usize = 4; @@ -55,8 +56,9 @@ pub const O_NOFOLLOW: usize = 0x8000_0000; pub const O_ACCMODE: usize = O_RDONLY | O_WRONLY | O_RDWR; -pub const PHYSMAP_WRITE: usize = 1; -pub const PHYSMAP_WRITE_COMBINE: usize = 2; +pub const PHYSMAP_WRITE: usize = 0x0000_0001; +pub const PHYSMAP_WRITE_COMBINE: usize = 0x0000_0002; +pub const PHYSMAP_NO_CACHE: usize = 0x0000_0004; pub const PROT_NONE: usize = 0x0000_0000; pub const PROT_EXEC: usize = 0x0001_0000; diff -Nru cargo-0.33.0/vendor/redox_syscall/src/lib.rs cargo-0.35.0/vendor/redox_syscall/src/lib.rs --- cargo-0.33.0/vendor/redox_syscall/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,5 @@ -#![deny(warnings)] #![feature(asm)] #![feature(const_fn)] -#![feature(transpose_result)] #![no_std] pub use self::arch::*; diff -Nru cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_block_mut.rs cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_block_mut.rs --- cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_block_mut.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_block_mut.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,6 +25,7 @@ } else { Err(Error::new(EFAULT)) }, + SYS_FUNMAP => self.funmap(packet.b), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { @@ -119,6 +120,11 @@ Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn funmap(&mut self, address: usize) -> Result> { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) diff -Nru cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_block.rs cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_block.rs --- cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_block.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_block.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,6 +25,7 @@ } else { Err(Error::new(EFAULT)) }, + SYS_FUNMAP => self.funmap(packet.b), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { @@ -119,6 +120,11 @@ Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn funmap(&self, address: usize) -> Result> { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn fpath(&self, id: usize, buf: &mut [u8]) -> Result> { Err(Error::new(EBADF)) diff -Nru cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_mut.rs cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_mut.rs --- cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme_mut.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme_mut.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,6 +25,7 @@ } else { Err(Error::new(EFAULT)) }, + SYS_FUNMAP => self.funmap(packet.b), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { @@ -119,6 +120,11 @@ Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn funmap(&mut self, address: usize) -> Result { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) diff -Nru cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme.rs cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme.rs --- cargo-0.33.0/vendor/redox_syscall/src/scheme/scheme.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/redox_syscall/src/scheme/scheme.rs 2019-05-15 11:26:24.000000000 +0000 @@ -25,6 +25,7 @@ } else { Err(Error::new(EFAULT)) }, + SYS_FUNMAP => self.funmap(packet.b), SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), SYS_FRENAME => self.frename(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }, packet.uid, packet.gid), SYS_FSTAT => if packet.d >= mem::size_of::() { @@ -119,6 +120,11 @@ Err(Error::new(EBADF)) } + #[allow(unused_variables)] + fn funmap(&self, address: usize) -> Result { + Err(Error::new(EBADF)) + } + #[allow(unused_variables)] fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { Err(Error::new(EBADF)) diff -Nru cargo-0.33.0/vendor/regex/build.rs cargo-0.35.0/vendor/regex/build.rs --- cargo-0.33.0/vendor/regex/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,36 +3,29 @@ use std::process::Command; fn main() { - let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc")); - let output = Command::new(&rustc) - .arg("--version") - .output() - .unwrap() - .stdout; - let version = String::from_utf8(output).unwrap(); - - enable_simd_optimizations(&version); + let version = match Version::read() { + Ok(version) => version, + Err(err) => { + eprintln!("failed to parse `rustc --version`: {}", err); + return; + } + }; + enable_simd_optimizations(version); } -fn enable_simd_optimizations(version: &str) { +fn enable_simd_optimizations(version: Version) { // We don't activate SIMD optimizations these if we've explicitly disabled // them. Disabling auto optimizations is intended for use in tests, so that // we can reliably test fallback implementations. if env::var_os("CARGO_CFG_REGEX_DISABLE_AUTO_OPTIMIZATIONS").is_some() { return; } - let parsed = match Version::parse(&version) { - Ok(parsed) => parsed, - Err(err) => { - eprintln!("failed to parse `rustc --version`: {}", err); - return; - } - }; - let minimum = Version { major: 1, minor: 27, patch: 0 }; - if version.contains("nightly") || parsed >= minimum { - println!("cargo:rustc-cfg=regex_runtime_teddy_ssse3"); - println!("cargo:rustc-cfg=regex_runtime_teddy_avx2"); + if version < (Version { major: 1, minor: 27, patch: 0 }) { + return; } + + println!("cargo:rustc-cfg=regex_runtime_teddy_ssse3"); + println!("cargo:rustc-cfg=regex_runtime_teddy_avx2"); } #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -43,6 +36,16 @@ } impl Version { + fn read() -> Result { + let rustc = env::var_os("RUSTC").unwrap_or(OsString::from("rustc")); + let output = Command::new(&rustc) + .arg("--version") + .output() + .unwrap() + .stdout; + Version::parse(&String::from_utf8(output).unwrap()) + } + fn parse(mut s: &str) -> Result { if !s.starts_with("rustc ") { return Err(format!("unrecognized version string: {}", s)); diff -Nru cargo-0.33.0/vendor/regex/.cargo-checksum.json cargo-0.35.0/vendor/regex/.cargo-checksum.json --- cargo-0.33.0/vendor/regex/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"} \ No newline at end of file +{"files":{},"package":"8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/regex/Cargo.toml cargo-0.35.0/vendor/regex/Cargo.toml --- cargo-0.33.0/vendor/regex/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "regex" -version = "1.1.0" +version = "1.1.6" authors = ["The Rust Project Developers"] exclude = ["/.travis.yml", "/appveyor.yml", "/ci/*", "/scripts/*"] autotests = false @@ -71,13 +71,13 @@ name = "crates-regex" path = "tests/test_crates_regex.rs" [dependencies.aho-corasick] -version = "0.6.7" +version = "0.7.3" [dependencies.memchr] version = "2.0.2" [dependencies.regex-syntax] -version = "0.6.2" +version = "0.6.6" [dependencies.thread_local] version = "0.3.6" @@ -92,7 +92,7 @@ default-features = false [dev-dependencies.rand] -version = "0.5" +version = "0.6.5" [features] default = ["use_std"] diff -Nru cargo-0.33.0/vendor/regex/CHANGELOG.md cargo-0.35.0/vendor/regex/CHANGELOG.md --- cargo-0.33.0/vendor/regex/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,3 +1,80 @@ +1.1.6 (2019-04-16) +================== +This release fixes a regression introduced by a bug fix (for +[BUG #557](https://github.com/rust-lang/regex/issues/557)) which could cause +the regex engine to enter an infinite loop. This bug was originally +[reported against ripgrep](https://github.com/BurntSushi/ripgrep/issues/1247). + + +1.1.5 (2019-04-01) +================== +This release fixes a bug in regex's dependency specification where it requires +a newer version of regex-syntax, but this wasn't communicated correctly in the +Cargo.toml. This would have been caught by a minimal version check, but this +check was disabled because the `rand` crate itself advertises incorrect +dependency specifications. + +Bug fixes: + +* [BUG #570](https://github.com/rust-lang/regex/pull/570): + Fix regex-syntax minimal version. + + +1.1.4 (2019-03-31) +================== +This release fixes a backwards compatibility regression where Regex was no +longer UnwindSafe. This was caused by the upgrade to aho-corasick 0.7, whose +AhoCorasick type was itself not UnwindSafe. This has been fixed in aho-corasick +0.7.4, which we now require. + +Bug fixes: + +* [BUG #568](https://github.com/rust-lang/regex/pull/568): + Fix an API regression where Regex was no longer UnwindSafe. + + +1.1.3 (2019-03-30) +================== +This releases fixes a few bugs and adds a performance improvement when a regex +is a simple alternation of literals. + +Performance improvements: + +* [OPT #566](https://github.com/rust-lang/regex/pull/566): + Upgrades `aho-corasick` to 0.7 and uses it for `foo|bar|...|quux` regexes. + +Bug fixes: + +* [BUG #527](https://github.com/rust-lang/regex/issues/527): + Fix a bug where the parser would panic on patterns like `((?x))`. +* [BUG #555](https://github.com/rust-lang/regex/issues/555): + Fix a bug where the parser would panic on patterns like `(?m){1,1}`. +* [BUG #557](https://github.com/rust-lang/regex/issues/557): + Fix a bug where captures could lead to an incorrect match. + + +1.1.2 (2019-02-27) +================== +This release fixes a bug found in the fix introduced in 1.1.1. + +Bug fixes: + +* [BUG edf45e6f](https://github.com/rust-lang/regex/commit/edf45e6f): + Fix bug introduced in reverse suffix literal matcher in the 1.1.1 release. + + +1.1.1 (2019-02-27) +================== +This is a small release with one fix for a bug caused by literal optimizations. + +Bug fixes: + +* [BUG 661bf53d](https://github.com/rust-lang/regex/commit/661bf53d): + Fixes a bug in the reverse suffix literal optimization. This was originally + reported + [against ripgrep](https://github.com/BurntSushi/ripgrep/issues/1203). + + 1.1.0 (2018-11-30) ================== This is a small release with a couple small enhancements. This release also diff -Nru cargo-0.33.0/vendor/regex/README.md cargo-0.35.0/vendor/regex/README.md --- cargo-0.33.0/vendor/regex/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -7,11 +7,11 @@ Much of the syntax and implementation is inspired by [RE2](https://github.com/google/re2). -[![Build Status](https://travis-ci.org/rust-lang/regex.svg?branch=master)](https://travis-ci.org/rust-lang/regex) +[![Build Status](https://travis-ci.com/rust-lang/regex.svg?branch=master)](https://travis-ci.com/rust-lang/regex) [![Build status](https://ci.appveyor.com/api/projects/status/github/rust-lang/regex?svg=true)](https://ci.appveyor.com/project/rust-lang-libs/regex) [![Coverage Status](https://coveralls.io/repos/github/rust-lang/regex/badge.svg?branch=master)](https://coveralls.io/github/rust-lang/regex?branch=master) -[![](http://meritbadge.herokuapp.com/regex)](https://crates.io/crates/regex) -[![Rust](https://img.shields.io/badge/rust-1.20%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/regex) +[![](https://meritbadge.herokuapp.com/regex)](https://crates.io/crates/regex) +[![Rust](https://img.shields.io/badge/rust-1.24.1%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/regex) ### Documentation @@ -32,7 +32,7 @@ regex = "1" ``` -and this to your crate root: +and this to your crate root (if you're using Rust 2015): ```rust extern crate regex; @@ -42,8 +42,6 @@ year, month and day: ```rust -extern crate regex; - use regex::Regex; fn main() { @@ -66,8 +64,6 @@ easy to adapt the above example with an iterator: ```rust -extern crate regex; - use regex::Regex; const TO_SEARCH: &'static str = " @@ -112,9 +108,6 @@ For example: ```rust -#[macro_use] extern crate lazy_static; -extern crate regex; - use regex::Regex; fn some_helper_function(text: &str) -> bool { diff -Nru cargo-0.33.0/vendor/regex/src/backtrack.rs cargo-0.35.0/vendor/regex/src/backtrack.rs --- cargo-0.33.0/vendor/regex/src/backtrack.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/backtrack.rs 2019-05-15 11:26:24.000000000 +0000 @@ -98,6 +98,7 @@ slots: &'s mut [Slot], input: I, start: usize, + end: usize, ) -> bool { let mut cache = cache.borrow_mut(); let cache = &mut cache.backtrack; @@ -109,7 +110,7 @@ slots: slots, m: cache, }; - b.exec_(start) + b.exec_(start, end) } /// Clears the cache such that the backtracking engine can be executed @@ -147,7 +148,7 @@ /// Start backtracking at the given position in the input, but also look /// for literal prefixes. - fn exec_(&mut self, mut at: InputAt) -> bool { + fn exec_(&mut self, mut at: InputAt, end: usize) -> bool { self.clear(); // If this is an anchored regex at the beginning of the input, then // we're either already done or we only need to try backtracking once. @@ -170,7 +171,7 @@ if matched && self.prog.matches.len() == 1 { return true; } - if at.is_end() { + if at.pos() == end || at.is_end() { break; } at = self.input.at(at.next_pos()); diff -Nru cargo-0.33.0/vendor/regex/src/exec.rs cargo-0.35.0/vendor/regex/src/exec.rs --- cargo-0.33.0/vendor/regex/src/exec.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/exec.rs 2019-05-15 11:26:24.000000000 +0000 @@ -10,9 +10,9 @@ use std::cell::RefCell; use std::collections::HashMap; -use std::cmp; use std::sync::Arc; +use aho_corasick::{AhoCorasick, AhoCorasickBuilder, MatchKind}; use thread_local::CachedThreadLocal; use syntax::ParserBuilder; use syntax::hir::Hir; @@ -86,6 +86,16 @@ /// Prefix literals are stored on the `Program`, since they are used inside /// the matching engines. suffixes: LiteralSearcher, + /// An Aho-Corasick automaton with leftmost-first match semantics. + /// + /// This is only set when the entire regex is a simple unanchored + /// alternation of literals. We could probably use it more circumstances, + /// but this is already hacky enough in this architecture. + /// + /// N.B. We use u32 as a state ID representation under the assumption that + /// if we were to exhaust the ID space, we probably would have long + /// surpassed the compilation size limit. + ac: Option>, /// match_type encodes as much upfront knowledge about how we're going to /// execute a search as possible. match_type: MatchType, @@ -287,6 +297,7 @@ dfa: Program::new(), dfa_reverse: Program::new(), suffixes: LiteralSearcher::empty(), + ac: None, match_type: MatchType::Nothing, }); return Ok(Exec { ro: ro, cache: CachedThreadLocal::new() }); @@ -319,12 +330,32 @@ dfa.dfa_size_limit = self.options.dfa_size_limit; dfa_reverse.dfa_size_limit = self.options.dfa_size_limit; + let mut ac = None; + if parsed.exprs.len() == 1 { + if let Some(lits) = alternation_literals(&parsed.exprs[0]) { + // If we have a small number of literals, then let Teddy + // handle things (see literal/mod.rs). + if lits.len() > 32 { + let fsm = AhoCorasickBuilder::new() + .match_kind(MatchKind::LeftmostFirst) + .auto_configure(&lits) + // We always want this to reduce size, regardless of + // what auto-configure does. + .byte_classes(true) + .build_with_size::(&lits) + .expect("AC automaton too big"); + ac = Some(fsm); + } + } + } + let mut ro = ExecReadOnly { res: self.options.pats, nfa: nfa, dfa: dfa, dfa_reverse: dfa_reverse, suffixes: LiteralSearcher::suffixes(suffixes), + ac: ac, match_type: MatchType::Nothing, }; ro.match_type = ro.choose_match_type(self.match_type); @@ -557,7 +588,8 @@ match self.ro.match_type { MatchType::Literal(ty) => { self.find_literals(ty, text, start).and_then(|(s, e)| { - self.captures_nfa_with_match(slots, text, s, e) + self.captures_nfa_type( + MatchNfaType::Auto, slots, text, s, e) }) } MatchType::Dfa => { @@ -566,17 +598,21 @@ } else { match self.find_dfa_forward(text, start) { dfa::Result::Match((s, e)) => { - self.captures_nfa_with_match(slots, text, s, e) + self.captures_nfa_type( + MatchNfaType::Auto, slots, text, s, e) } dfa::Result::NoMatch(_) => None, - dfa::Result::Quit => self.captures_nfa(slots, text, start), + dfa::Result::Quit => { + self.captures_nfa(slots, text, start) + } } } } MatchType::DfaAnchoredReverse => { match self.find_dfa_anchored_reverse(text, start) { dfa::Result::Match((s, e)) => { - self.captures_nfa_with_match(slots, text, s, e) + self.captures_nfa_type( + MatchNfaType::Auto, slots, text, s, e) } dfa::Result::NoMatch(_) => None, dfa::Result::Quit => self.captures_nfa(slots, text, start), @@ -585,14 +621,15 @@ MatchType::DfaSuffix => { match self.find_dfa_reverse_suffix(text, start) { dfa::Result::Match((s, e)) => { - self.captures_nfa_with_match(slots, text, s, e) + self.captures_nfa_type( + MatchNfaType::Auto, slots, text, s, e) } dfa::Result::NoMatch(_) => None, dfa::Result::Quit => self.captures_nfa(slots, text, start), } } MatchType::Nfa(ty) => { - self.captures_nfa_type(ty, slots, text, start) + self.captures_nfa_type(ty, slots, text, start, text.len()) } MatchType::Nothing => None, MatchType::DfaMany => { @@ -633,6 +670,11 @@ lits.find_end(&text[start..]) .map(|(s, e)| (start + s, start + e)) } + AhoCorasick => { + self.ro.ac.as_ref().unwrap() + .find(&text[start..]) + .map(|m| (start + m.start(), start + m.end())) + } } } @@ -745,12 +787,13 @@ debug_assert!(lcs.len() >= 1); let mut start = original_start; let mut end = start; + let mut last_literal = start; while end <= text.len() { - start = end; - end += match lcs.find(&text[end..]) { + last_literal += match lcs.find(&text[last_literal..]) { None => return Some(NoMatch(text.len())), - Some(start) => start + lcs.len(), + Some(i) => i, }; + end = last_literal + lcs.len(); match dfa::Fsm::reverse( &self.ro.dfa_reverse, self.cache, @@ -759,8 +802,12 @@ end - start, ) { Match(0) | NoMatch(0) => return None, - Match(s) => return Some(Match((s + start, end))), - NoMatch(_) => continue, + Match(i) => return Some(Match((start + i, end))), + NoMatch(i) => { + start += i; + last_literal += 1; + continue; + } Quit => return Some(Quit), }; } @@ -825,7 +872,7 @@ text: &[u8], start: usize, ) -> bool { - self.exec_nfa(ty, &mut [false], &mut [], true, text, start) + self.exec_nfa(ty, &mut [false], &mut [], true, text, start, text.len()) } /// Finds the shortest match using an NFA. @@ -841,7 +888,15 @@ start: usize, ) -> Option { let mut slots = [None, None]; - if self.exec_nfa(ty, &mut [false], &mut slots, true, text, start) { + if self.exec_nfa( + ty, + &mut [false], + &mut slots, + true, + text, + start, + text.len() + ) { slots[1] } else { None @@ -856,7 +911,15 @@ start: usize, ) -> Option<(usize, usize)> { let mut slots = [None, None]; - if self.exec_nfa(ty, &mut [false], &mut slots, false, text, start) { + if self.exec_nfa( + ty, + &mut [false], + &mut slots, + false, + text, + start, + text.len() + ) { match (slots[0], slots[1]) { (Some(s), Some(e)) => Some((s, e)), _ => None, @@ -866,26 +929,6 @@ } } - /// Like find_nfa, but fills in captures and restricts the search space - /// using previously found match information. - /// - /// `slots` should have length equal to `2 * nfa.captures.len()`. - fn captures_nfa_with_match( - &self, - slots: &mut [Slot], - text: &[u8], - match_start: usize, - match_end: usize, - ) -> Option<(usize, usize)> { - // We can't use match_end directly, because we may need to examine one - // "character" after the end of a match for lookahead operators. We - // need to move two characters beyond the end, since some look-around - // operations may falsely assume a premature end of text otherwise. - let e = cmp::min( - next_utf8(text, next_utf8(text, match_end)), text.len()); - self.captures_nfa(slots, &text[..e], match_start) - } - /// Like find_nfa, but fills in captures. /// /// `slots` should have length equal to `2 * nfa.captures.len()`. @@ -895,7 +938,8 @@ text: &[u8], start: usize, ) -> Option<(usize, usize)> { - self.captures_nfa_type(MatchNfaType::Auto, slots, text, start) + self.captures_nfa_type( + MatchNfaType::Auto, slots, text, start, text.len()) } /// Like captures_nfa, but allows specification of type of NFA engine. @@ -905,8 +949,9 @@ slots: &mut [Slot], text: &[u8], start: usize, + end: usize, ) -> Option<(usize, usize)> { - if self.exec_nfa(ty, &mut [false], slots, false, text, start) { + if self.exec_nfa(ty, &mut [false], slots, false, text, start, end) { match (slots[0], slots[1]) { (Some(s), Some(e)) => Some((s, e)), _ => None, @@ -924,6 +969,7 @@ quit_after_match: bool, text: &[u8], start: usize, + end: usize, ) -> bool { use self::MatchNfaType::*; if let Auto = ty { @@ -935,10 +981,10 @@ } match ty { Auto => unreachable!(), - Backtrack => self.exec_backtrack(matches, slots, text, start), + Backtrack => self.exec_backtrack(matches, slots, text, start, end), PikeVM => { self.exec_pikevm( - matches, slots, quit_after_match, text, start) + matches, slots, quit_after_match, text, start, end) } } } @@ -951,6 +997,7 @@ quit_after_match: bool, text: &[u8], start: usize, + end: usize, ) -> bool { if self.ro.nfa.uses_bytes() { pikevm::Fsm::exec( @@ -960,7 +1007,8 @@ slots, quit_after_match, ByteInput::new(text, self.ro.nfa.only_utf8), - start) + start, + end) } else { pikevm::Fsm::exec( &self.ro.nfa, @@ -969,7 +1017,8 @@ slots, quit_after_match, CharInput::new(text), - start) + start, + end) } } @@ -980,6 +1029,7 @@ slots: &mut [Slot], text: &[u8], start: usize, + end: usize, ) -> bool { if self.ro.nfa.uses_bytes() { backtrack::Bounded::exec( @@ -988,7 +1038,8 @@ matches, slots, ByteInput::new(text, self.ro.nfa.only_utf8), - start) + start, + end) } else { backtrack::Bounded::exec( &self.ro.nfa, @@ -996,7 +1047,8 @@ matches, slots, CharInput::new(text), - start) + start, + end) } } @@ -1040,11 +1092,15 @@ &mut [], false, text, - start) + start, + text.len()) } } } - Nfa(ty) => self.exec_nfa(ty, matches, &mut [], false, text, start), + Nfa(ty) => { + self.exec_nfa( + ty, matches, &mut [], false, text, start, text.len()) + } Nothing => false, } } @@ -1076,7 +1132,9 @@ /// Get a searcher that isn't Sync. #[inline(always)] // reduces constant overhead pub fn searcher(&self) -> ExecNoSync { - let create = || Box::new(RefCell::new(ProgramCacheInner::new(&self.ro))); + let create = || { + Box::new(RefCell::new(ProgramCacheInner::new(&self.ro))) + }; ExecNoSync { ro: &self.ro, // a clone is too expensive here! (and not needed) cache: self.cache.get_or(create), @@ -1158,6 +1216,9 @@ // aren't anchored. We would then only search for all of them when at // the beginning of the input and use the subset in all other cases. if self.res.len() == 1 { + if self.ac.is_some() { + return Literal(MatchLiteralType::AhoCorasick); + } if self.nfa.prefixes.complete() { return if self.nfa.is_anchored_start { Literal(MatchLiteralType::AnchoredStart) @@ -1249,6 +1310,9 @@ AnchoredStart, /// Match literals only at the end of text. AnchoredEnd, + /// Use an Aho-Corasick automaton. This requires `ac` to be Some on + /// ExecReadOnly. + AhoCorasick, } #[derive(Clone, Copy, Debug)] @@ -1290,6 +1354,59 @@ } } +/// Alternation literals checks if the given HIR is a simple alternation of +/// literals, and if so, returns them. Otherwise, this returns None. +fn alternation_literals(expr: &Hir) -> Option>> { + use syntax::hir::{HirKind, Literal}; + + // This is pretty hacky, but basically, if `is_alternation_literal` is + // true, then we can make several assumptions about the structure of our + // HIR. This is what justifies the `unreachable!` statements below. + // + // This code should be refactored once we overhaul this crate's + // optimization pipeline, because this is a terribly inflexible way to go + // about things. + + if !expr.is_alternation_literal() { + return None; + } + let alts = match *expr.kind() { + HirKind::Alternation(ref alts) => alts, + _ => return None, // one literal isn't worth it + }; + + let extendlit = |lit: &Literal, dst: &mut Vec| { + match *lit { + Literal::Unicode(c) => { + let mut buf = [0; 4]; + dst.extend_from_slice(c.encode_utf8(&mut buf).as_bytes()); + } + Literal::Byte(b) => { + dst.push(b); + } + } + }; + + let mut lits = vec![]; + for alt in alts { + let mut lit = vec![]; + match *alt.kind() { + HirKind::Literal(ref x) => extendlit(x, &mut lit), + HirKind::Concat(ref exprs) => { + for e in exprs { + match *e.kind() { + HirKind::Literal(ref x) => extendlit(x, &mut lit), + _ => unreachable!("expected literal, got {:?}", e), + } + } + } + _ => unreachable!("expected literal or concat, got {:?}", alt), + } + lits.push(lit); + } + Some(lits) +} + #[cfg(test)] mod test { #[test] diff -Nru cargo-0.33.0/vendor/regex/src/lib.rs cargo-0.35.0/vendor/regex/src/lib.rs --- cargo-0.33.0/vendor/regex/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -143,7 +143,7 @@ `Regex::replace` for more details.) Note that if your regex gets complicated, you can use the `x` flag to -enable insigificant whitespace mode, which also lets you write comments: +enable insignificant whitespace mode, which also lets you write comments: ```rust # extern crate regex; use regex::Regex; diff -Nru cargo-0.33.0/vendor/regex/src/literal/mod.rs cargo-0.35.0/vendor/regex/src/literal/mod.rs --- cargo-0.33.0/vendor/regex/src/literal/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/literal/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -11,7 +11,7 @@ use std::cmp; use std::mem; -use aho_corasick::{Automaton, AcAutomaton, FullAcAutomaton}; +use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; use memchr::{memchr, memchr2, memchr3}; use syntax::hir::literal::{Literal, Literals}; @@ -46,7 +46,7 @@ /// A single substring, find using Boyer-Moore. BoyerMoore(BoyerMooreSearch), /// An Aho-Corasick automaton. - AC(FullAcAutomaton), + AC { ac: AhoCorasick, lits: Vec }, /// A simd accelerated multiple string matcher. Used only for a small /// number of small literals. TeddySSSE3(TeddySSSE3), @@ -102,7 +102,9 @@ Bytes(ref sset) => sset.find(haystack).map(|i| (i, i + 1)), FreqyPacked(ref s) => s.find(haystack).map(|i| (i, i + s.len())), BoyerMoore(ref s) => s.find(haystack).map(|i| (i, i + s.len())), - AC(ref aut) => aut.find(haystack).next().map(|m| (m.start, m.end)), + AC { ref ac, .. } => { + ac.find(haystack).map(|m| (m.start(), m.end())) + } TeddySSSE3(ref t) => t.find(haystack).map(|m| (m.start, m.end)), TeddyAVX2(ref t) => t.find(haystack).map(|m| (m.start, m.end)), } @@ -141,7 +143,7 @@ Matcher::Bytes(ref sset) => LiteralIter::Bytes(&sset.dense), Matcher::FreqyPacked(ref s) => LiteralIter::Single(&s.pat), Matcher::BoyerMoore(ref s) => LiteralIter::Single(&s.pattern), - Matcher::AC(ref ac) => LiteralIter::AC(ac.patterns()), + Matcher::AC { ref lits, .. } => LiteralIter::AC(lits), Matcher::TeddySSSE3(ref ted) => { LiteralIter::TeddySSSE3(ted.patterns()) } @@ -174,7 +176,7 @@ Bytes(ref sset) => sset.dense.len(), FreqyPacked(_) => 1, BoyerMoore(_) => 1, - AC(ref aut) => aut.len(), + AC { ref ac, .. } => ac.pattern_count(), TeddySSSE3(ref ted) => ted.len(), TeddyAVX2(ref ted) => ted.len(), } @@ -188,7 +190,7 @@ Bytes(ref sset) => sset.approximate_size(), FreqyPacked(ref single) => single.approximate_size(), BoyerMoore(ref single) => single.approximate_size(), - AC(ref aut) => aut.heap_bytes(), + AC { ref ac, .. } => ac.heap_bytes(), TeddySSSE3(ref ted) => ted.approximate_size(), TeddyAVX2(ref ted) => ted.approximate_size(), } @@ -258,7 +260,11 @@ // Fallthrough to ol' reliable Aho-Corasick... } let pats = lits.literals().to_owned(); - Matcher::AC(AcAutomaton::new(pats).into_full()) + let ac = AhoCorasickBuilder::new() + .dfa(true) + .build_with_size::(&pats) + .unwrap(); + Matcher::AC { ac, lits: pats } } } @@ -772,8 +778,6 @@ mut window_end: usize, backstop: usize, ) -> Option { - use std::mem; - let window_end_snapshot = window_end; let skip_of = |we: usize| -> usize { // Unsafe might make this faster, but the benchmarks diff -Nru cargo-0.33.0/vendor/regex/src/literal/teddy_avx2/imp.rs cargo-0.35.0/vendor/regex/src/literal/teddy_avx2/imp.rs --- cargo-0.33.0/vendor/regex/src/literal/teddy_avx2/imp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/literal/teddy_avx2/imp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,7 +9,7 @@ use std::cmp; -use aho_corasick::{Automaton, AcAutomaton, FullAcAutomaton}; +use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; use syntax::hir::literal::Literals; use vector::avx2::{AVX2VectorBuilder, u8x32}; @@ -38,7 +38,7 @@ pats: Vec>, /// An Aho-Corasick automaton of the patterns. We use this when we need to /// search pieces smaller than the Teddy block size. - ac: FullAcAutomaton>, + ac: AhoCorasick, /// A set of 8 buckets. Each bucket corresponds to a single member of a /// bitset. A bucket contains zero or more substrings. This is useful /// when the number of substrings exceeds 8, since our bitsets cannot have @@ -88,10 +88,14 @@ buckets[bucket].push(pati); masks.add(bucket as u8, pat); } + let ac = AhoCorasickBuilder::new() + .dfa(true) + .prefilter(false) + .build(&pats); Some(Teddy { vb: vb, pats: pats.to_vec(), - ac: AcAutomaton::new(pats.to_vec()).into_full(), + ac: ac, buckets: buckets, masks: masks, }) @@ -341,11 +345,11 @@ /// block based approach. #[inline(never)] fn slow(&self, haystack: &[u8], pos: usize) -> Option { - self.ac.find(&haystack[pos..]).next().map(|m| { + self.ac.find(&haystack[pos..]).map(|m| { Match { - pat: m.pati, - start: pos + m.start, - end: pos + m.end, + pat: m.pattern(), + start: pos + m.start(), + end: pos + m.end(), } }) } diff -Nru cargo-0.33.0/vendor/regex/src/literal/teddy_ssse3/imp.rs cargo-0.35.0/vendor/regex/src/literal/teddy_ssse3/imp.rs --- cargo-0.33.0/vendor/regex/src/literal/teddy_ssse3/imp.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/literal/teddy_ssse3/imp.rs 2019-05-15 11:26:24.000000000 +0000 @@ -320,7 +320,7 @@ use std::cmp; -use aho_corasick::{Automaton, AcAutomaton, FullAcAutomaton}; +use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; use syntax::hir::literal::Literals; use vector::ssse3::{SSSE3VectorBuilder, u8x16}; @@ -349,7 +349,7 @@ pats: Vec>, /// An Aho-Corasick automaton of the patterns. We use this when we need to /// search pieces smaller than the Teddy block size. - ac: FullAcAutomaton>, + ac: AhoCorasick, /// A set of 8 buckets. Each bucket corresponds to a single member of a /// bitset. A bucket contains zero or more substrings. This is useful /// when the number of substrings exceeds 8, since our bitsets cannot have @@ -399,10 +399,14 @@ buckets[bucket].push(pati); masks.add(bucket as u8, pat); } + let ac = AhoCorasickBuilder::new() + .dfa(true) + .prefilter(false) + .build(&pats); Some(Teddy { vb: vb, pats: pats.to_vec(), - ac: AcAutomaton::new(pats.to_vec()).into_full(), + ac: ac, buckets: buckets, masks: masks, }) @@ -651,11 +655,11 @@ /// block based approach. #[inline(never)] fn slow(&self, haystack: &[u8], pos: usize) -> Option { - self.ac.find(&haystack[pos..]).next().map(|m| { + self.ac.find(&haystack[pos..]).map(|m| { Match { - pat: m.pati, - start: pos + m.start, - end: pos + m.end, + pat: m.pattern(), + start: pos + m.start(), + end: pos + m.end(), } }) } diff -Nru cargo-0.33.0/vendor/regex/src/pikevm.rs cargo-0.35.0/vendor/regex/src/pikevm.rs --- cargo-0.33.0/vendor/regex/src/pikevm.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/src/pikevm.rs 2019-05-15 11:26:24.000000000 +0000 @@ -107,6 +107,7 @@ quit_after_match: bool, input: I, start: usize, + end: usize, ) -> bool { let mut cache = cache.borrow_mut(); let cache = &mut cache.pikevm; @@ -124,6 +125,7 @@ slots, quit_after_match, at, + end, ) } @@ -135,6 +137,7 @@ slots: &mut [Slot], quit_after_match: bool, mut at: InputAt, + end: usize, ) -> bool { let mut matched = false; let mut all_matched = false; @@ -212,7 +215,7 @@ } } } - if at.is_end() { + if at.pos() == end || at.is_end() { break; } at = at_next; diff -Nru cargo-0.33.0/vendor/regex/tests/regression.rs cargo-0.35.0/vendor/regex/tests/regression.rs --- cargo-0.33.0/vendor/regex/tests/regression.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/tests/regression.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,6 +14,18 @@ assert_eq!(vec![(0, 1)], findall!(re, "a")); } +// See: https://github.com/rust-lang/regex/issues/555 +#[test] +fn regression_invalid_repetition_expr() { + assert!(regex_new!("(?m){1,1}").is_err()); +} + +// See: https://github.com/rust-lang/regex/issues/527 +#[test] +fn regression_invalid_flags_expression() { + assert!(regex_new!("(((?x)))").is_ok()); +} + // See: https://github.com/rust-lang/regex/issues/75 mat!(regression_unsorted_binary_search_1, r"(?i)[a_]+", "A_", Some((0, 2))); mat!(regression_unsorted_binary_search_2, r"(?i)[A_]+", "a_", Some((0, 2))); @@ -82,9 +94,19 @@ ismatch!(strange_anchor_non_complete_prefix, r"a^{2}", "", false); ismatch!(strange_anchor_non_complete_suffix, r"${2}a", "", false); +// See: https://github.com/BurntSushi/ripgrep/issues/1203 +ismatch!(reverse_suffix1, r"[0-4][0-4][0-4]000", "153.230000", true); +ismatch!(reverse_suffix2, r"\d\d\d000", "153.230000\n", true); +matiter!(reverse_suffix3, r"\d\d\d000", "153.230000\n", (4, 10)); + // See: https://github.com/rust-lang/regex/issues/334 -mat!(captures_after_dfa_premature_end, r"a(b*(X|$))?", "abcbX", +// See: https://github.com/rust-lang/regex/issues/557 +mat!(captures_after_dfa_premature_end1, r"a(b*(X|$))?", "abcbX", + Some((0, 1)), None, None); +mat!(captures_after_dfa_premature_end2, r"a(bc*(X|$))?", "abcbX", Some((0, 1)), None, None); +mat!(captures_after_dfa_premature_end3, r"(aa$)?", "aaz", + Some((0, 0))); // See: https://github.com/rust-lang/regex/issues/437 ismatch!( @@ -109,3 +131,20 @@ \u{10}\u{11}\u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\ \u{18}\u{19}\u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f}", true); + +// Tests that our Aho-Corasick optimization works correctly. It only +// kicks in when we have >32 literals. +mat!( + ahocorasick1, + "samwise|sam|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|\ + A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z", + "samwise", + Some((0, 7)) +); + +// See: https://github.com/BurntSushi/ripgrep/issues/1247 +#[test] +fn regression_nfa_stops1() { + let re = ::regex::bytes::Regex::new(r"\bs(?:[ab])").unwrap(); + assert_eq!(0, re.find_iter(b"s\xE4").count()); +} diff -Nru cargo-0.33.0/vendor/regex/tests/test_default.rs cargo-0.35.0/vendor/regex/tests/test_default.rs --- cargo-0.33.0/vendor/regex/tests/test_default.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex/tests/test_default.rs 2019-05-15 11:26:24.000000000 +0000 @@ -85,3 +85,37 @@ fn allow_octal() { assert!(regex::RegexBuilder::new(r"\0").octal(true).build().is_ok()); } + +#[test] +fn oibits() { + use std::panic::UnwindSafe; + use regex::{Regex, RegexBuilder}; + use regex::bytes; + + fn assert_send() {} + fn assert_sync() {} + fn assert_unwind_safe() {} + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); + assert_send::(); + assert_sync::(); + assert_unwind_safe::(); +} + +// See: https://github.com/rust-lang/regex/issues/568 +#[test] +fn oibits_regression() { + use std::panic; + use regex::Regex; + + let _ = panic::catch_unwind(|| Regex::new("a").unwrap()); +} diff -Nru cargo-0.33.0/vendor/regex-syntax/.cargo-checksum.json cargo-0.35.0/vendor/regex-syntax/.cargo-checksum.json --- cargo-0.33.0/vendor/regex-syntax/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex-syntax/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"} \ No newline at end of file +{"files":{},"package":"dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/regex-syntax/Cargo.toml cargo-0.35.0/vendor/regex-syntax/Cargo.toml --- cargo-0.33.0/vendor/regex-syntax/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex-syntax/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "regex-syntax" -version = "0.6.5" +version = "0.6.6" authors = ["The Rust Project Developers"] description = "A regular expression parser." homepage = "https://github.com/rust-lang/regex" diff -Nru cargo-0.33.0/vendor/regex-syntax/src/ast/parse.rs cargo-0.35.0/vendor/regex-syntax/src/ast/parse.rs --- cargo-0.33.0/vendor/regex-syntax/src/ast/parse.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex-syntax/src/ast/parse.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1100,6 +1100,13 @@ ast::ErrorKind::RepetitionMissing, )), }; + match ast { + Ast::Empty(_) | Ast::Flags(_) => return Err(self.error( + self.span(), + ast::ErrorKind::RepetitionMissing, + )), + _ => {} + } if !self.bump_and_bump_space() { return Err(self.error( Span::new(start, self.pos()), @@ -3125,6 +3132,18 @@ }))); assert_eq!( + parser(r"(?i){0}").parse().unwrap_err(), + TestError { + span: span(4..4), + kind: ast::ErrorKind::RepetitionMissing, + }); + assert_eq!( + parser(r"(?m){1,1}").parse().unwrap_err(), + TestError { + span: span(4..4), + kind: ast::ErrorKind::RepetitionMissing, + }); + assert_eq!( parser(r"a{").parse().unwrap_err(), TestError { span: span(1..2), diff -Nru cargo-0.33.0/vendor/regex-syntax/src/hir/mod.rs cargo-0.35.0/vendor/regex-syntax/src/hir/mod.rs --- cargo-0.33.0/vendor/regex-syntax/src/hir/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex-syntax/src/hir/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -227,6 +227,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(true); + info.set_literal(true); + info.set_alternation_literal(true); Hir { kind: HirKind::Empty, info: info, @@ -253,6 +255,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(false); + info.set_literal(true); + info.set_alternation_literal(true); Hir { kind: HirKind::Literal(lit), info: info, @@ -271,6 +275,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(false); + info.set_literal(false); + info.set_alternation_literal(false); Hir { kind: HirKind::Class(class), info: info, @@ -289,6 +295,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(true); + info.set_literal(false); + info.set_alternation_literal(false); if let Anchor::StartText = anchor { info.set_anchored_start(true); info.set_line_anchored_start(true); @@ -322,6 +330,8 @@ info.set_line_anchored_end(false); info.set_any_anchored_start(false); info.set_any_anchored_end(false); + info.set_literal(false); + info.set_alternation_literal(false); // A negated word boundary matches the empty string, but a normal // word boundary does not! info.set_match_empty(word_boundary.is_negated()); @@ -357,6 +367,8 @@ info.set_any_anchored_start(rep.hir.is_any_anchored_start()); info.set_any_anchored_end(rep.hir.is_any_anchored_end()); info.set_match_empty(rep.is_match_empty() || rep.hir.is_match_empty()); + info.set_literal(false); + info.set_alternation_literal(false); Hir { kind: HirKind::Repetition(rep), info: info, @@ -375,6 +387,8 @@ info.set_any_anchored_start(group.hir.is_any_anchored_start()); info.set_any_anchored_end(group.hir.is_any_anchored_end()); info.set_match_empty(group.hir.is_match_empty()); + info.set_literal(false); + info.set_alternation_literal(false); Hir { kind: HirKind::Group(group), info: info, @@ -395,6 +409,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(true); + info.set_literal(true); + info.set_alternation_literal(true); // Some attributes require analyzing all sub-expressions. for e in &exprs { @@ -416,6 +432,14 @@ let x = info.is_match_empty() && e.is_match_empty(); info.set_match_empty(x); + + let x = info.is_literal() && e.is_literal(); + info.set_literal(x); + + let x = + info.is_alternation_literal() + && e.is_alternation_literal(); + info.set_alternation_literal(x); } // Anchored attributes require something slightly more // sophisticated. Normally, WLOG, to determine whether an @@ -488,6 +512,8 @@ info.set_any_anchored_start(false); info.set_any_anchored_end(false); info.set_match_empty(false); + info.set_literal(false); + info.set_alternation_literal(true); // Some attributes require analyzing all sub-expressions. for e in &exprs { @@ -523,6 +549,11 @@ let x = info.is_match_empty() || e.is_match_empty(); info.set_match_empty(x); + + let x = + info.is_alternation_literal() + && e.is_literal(); + info.set_alternation_literal(x); } Hir { kind: HirKind::Alternation(exprs), @@ -655,6 +686,28 @@ pub fn is_match_empty(&self) -> bool { self.info.is_match_empty() } + + /// Return true if and only if this HIR is a simple literal. This is only + /// true when this HIR expression is either itself a `Literal` or a + /// concatenation of only `Literal`s. + /// + /// For example, `f` and `foo` are literals, but `f+`, `(foo)`, `foo()` + /// are not (even though that contain sub-expressions that are literals). + pub fn is_literal(&self) -> bool { + self.info.is_literal() + } + + /// Return true if and only if this HIR is either a simple literal or an + /// alternation of simple literals. This is only + /// true when this HIR expression is either itself a `Literal` or a + /// concatenation of only `Literal`s or an alternation of only `Literal`s. + /// + /// For example, `f`, `foo`, `a|b|c`, and `foo|bar|baz` are alternaiton + /// literals, but `f+`, `(foo)`, `foo()` + /// are not (even though that contain sub-expressions that are literals). + pub fn is_alternation_literal(&self) -> bool { + self.info.is_alternation_literal() + } } impl HirKind { @@ -1415,6 +1468,8 @@ define_bool!(6, is_any_anchored_start, set_any_anchored_start); define_bool!(7, is_any_anchored_end, set_any_anchored_end); define_bool!(8, is_match_empty, set_match_empty); + define_bool!(9, is_literal, set_literal); + define_bool!(10, is_alternation_literal, set_alternation_literal); } #[cfg(test)] diff -Nru cargo-0.33.0/vendor/regex-syntax/src/hir/translate.rs cargo-0.35.0/vendor/regex-syntax/src/hir/translate.rs --- cargo-0.33.0/vendor/regex-syntax/src/hir/translate.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/regex-syntax/src/hir/translate.rs 2019-05-15 11:26:24.000000000 +0000 @@ -240,11 +240,6 @@ type Err = Error; fn finish(self) -> Result { - if self.trans().stack.borrow().is_empty() { - // This can happen if the Ast given consists of a single set of - // flags. e.g., `(?i)`. /shrug - return Ok(Hir::empty()); - } // ... otherwise, we should have exactly one HIR on the stack. assert_eq!(self.trans().stack.borrow().len(), 1); Ok(self.pop().unwrap().unwrap_expr()) @@ -287,6 +282,16 @@ } Ast::Flags(ref x) => { self.set_flags(&x.flags); + // Flags in the AST are generally considered directives and + // not actual sub-expressions. However, they can be used in + // the concrete syntax like `((?i))`, and we need some kind of + // indication of an expression there, and Empty is the correct + // choice. + // + // There can also be things like `(?i)+`, but we rule those out + // in the parser. In the future, we might allow them for + // consistency sake. + self.push(HirFrame::Expr(Hir::empty())); } Ast::Literal(ref x) => { self.push(HirFrame::Expr(self.hir_literal(x)?)); @@ -1547,6 +1552,10 @@ hir_group_name(2, "foo", hir_lit("b")), hir_group(3, hir_lit("c")), ])); + assert_eq!(t("()"), hir_group(1, Hir::empty())); + assert_eq!(t("((?i))"), hir_group(1, Hir::empty())); + assert_eq!(t("((?x))"), hir_group(1, Hir::empty())); + assert_eq!(t("(((?x)))"), hir_group(1, hir_group(2, Hir::empty()))); } #[test] @@ -2589,4 +2598,49 @@ assert!(!t(r"\b").is_match_empty()); assert!(!t(r"(?-u)\b").is_match_empty()); } + + #[test] + fn analysis_is_literal() { + // Positive examples. + assert!(t(r"").is_literal()); + assert!(t(r"a").is_literal()); + assert!(t(r"ab").is_literal()); + assert!(t(r"abc").is_literal()); + assert!(t(r"(?m)abc").is_literal()); + + // Negative examples. + assert!(!t(r"^").is_literal()); + assert!(!t(r"a|b").is_literal()); + assert!(!t(r"(a)").is_literal()); + assert!(!t(r"a+").is_literal()); + assert!(!t(r"foo(a)").is_literal()); + assert!(!t(r"(a)foo").is_literal()); + assert!(!t(r"[a]").is_literal()); + } + + #[test] + fn analysis_is_alternation_literal() { + // Positive examples. + assert!(t(r"").is_alternation_literal()); + assert!(t(r"a").is_alternation_literal()); + assert!(t(r"ab").is_alternation_literal()); + assert!(t(r"abc").is_alternation_literal()); + assert!(t(r"(?m)abc").is_alternation_literal()); + assert!(t(r"a|b").is_alternation_literal()); + assert!(t(r"a|b|c").is_alternation_literal()); + assert!(t(r"foo|bar").is_alternation_literal()); + assert!(t(r"foo|bar|baz").is_alternation_literal()); + + // Negative examples. + assert!(!t(r"^").is_alternation_literal()); + assert!(!t(r"(a)").is_alternation_literal()); + assert!(!t(r"a+").is_alternation_literal()); + assert!(!t(r"foo(a)").is_alternation_literal()); + assert!(!t(r"(a)foo").is_alternation_literal()); + assert!(!t(r"[a]").is_alternation_literal()); + assert!(!t(r"[a]|b").is_alternation_literal()); + assert!(!t(r"a|[b]").is_alternation_literal()); + assert!(!t(r"(a)|b").is_alternation_literal()); + assert!(!t(r"a|(b)").is_alternation_literal()); + } } diff -Nru cargo-0.33.0/vendor/rustc-demangle/.cargo-checksum.json cargo-0.35.0/vendor/rustc-demangle/.cargo-checksum.json --- cargo-0.33.0/vendor/rustc-demangle/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustc-demangle/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"} \ No newline at end of file +{"files":{},"package":"ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rustc-demangle/Cargo.toml cargo-0.35.0/vendor/rustc-demangle/Cargo.toml --- cargo-0.33.0/vendor/rustc-demangle/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustc-demangle/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "rustc-demangle" -version = "0.1.13" +version = "0.1.14" authors = ["Alex Crichton "] description = "Rust compiler symbol demangling.\n" homepage = "https://github.com/alexcrichton/rustc-demangle" @@ -20,3 +20,14 @@ readme = "README.md" license = "MIT/Apache-2.0" repository = "https://github.com/alexcrichton/rustc-demangle" +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" + +[features] +rustc-dep-of-std = ["core", "compiler_builtins"] diff -Nru cargo-0.33.0/vendor/rustc-demangle/src/legacy.rs cargo-0.35.0/vendor/rustc-demangle/src/legacy.rs --- cargo-0.33.0/vendor/rustc-demangle/src/legacy.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/rustc-demangle/src/legacy.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,370 @@ +use core::fmt; + +/// Representation of a demangled symbol name. +pub struct Demangle<'a> { + inner: &'a str, + /// The number of ::-separated elements in the original name. + elements: usize, +} + +/// De-mangles a Rust symbol into a more readable version +/// +/// All Rust symbols by default are mangled as they contain characters that +/// cannot be represented in all object files. The mangling mechanism is similar +/// to C++'s, but Rust has a few specifics to handle items like lifetimes in +/// symbols. +/// +/// This function will take a **mangled** symbol and return a value. When printed, +/// the de-mangled version will be written. If the symbol does not look like +/// a mangled symbol, the original value will be written instead. +/// +/// # Examples +/// +/// ``` +/// use rustc_demangle::demangle; +/// +/// assert_eq!(demangle("_ZN4testE").to_string(), "test"); +/// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar"); +/// assert_eq!(demangle("foo").to_string(), "foo"); +/// ``` + +// All Rust symbols are in theory lists of "::"-separated identifiers. Some +// assemblers, however, can't handle these characters in symbol names. To get +// around this, we use C++-style mangling. The mangling method is: +// +// 1. Prefix the symbol with "_ZN" +// 2. For each element of the path, emit the length plus the element +// 3. End the path with "E" +// +// For example, "_ZN4testE" => "test" and "_ZN3foo3barE" => "foo::bar". +// +// We're the ones printing our backtraces, so we can't rely on anything else to +// demangle our symbols. It's *much* nicer to look at demangled symbols, so +// this function is implemented to give us nice pretty output. +// +// Note that this demangler isn't quite as fancy as it could be. We have lots +// of other information in our symbols like hashes, version, type information, +// etc. Additionally, this doesn't handle glue symbols at all. +pub fn demangle(s: &str) -> Result { + // First validate the symbol. If it doesn't look like anything we're + // expecting, we just print it literally. Note that we must handle non-Rust + // symbols because we could have any function in the backtrace. + let inner; + if s.len() > 4 && s.starts_with("_ZN") && s.ends_with('E') { + inner = &s[3..s.len() - 1]; + } else if s.len() > 3 && s.starts_with("ZN") && s.ends_with('E') { + // On Windows, dbghelp strips leading underscores, so we accept "ZN...E" + // form too. + inner = &s[2..s.len() - 1]; + } else if s.len() > 5 && s.starts_with("__ZN") && s.ends_with('E') { + // On OSX, symbols are prefixed with an extra _ + inner = &s[4..s.len() - 1]; + } else { + return Err(()); + } + + // only work with ascii text + if inner.bytes().any(|c| c & 0x80 != 0) { + return Err(()); + } + + let mut elements = 0; + let mut chars = inner.chars().peekable(); + loop { + let mut i = 0usize; + while let Some(&c) = chars.peek() { + if !c.is_digit(10) { + break + } + chars.next(); + let next = i.checked_mul(10) + .and_then(|i| i.checked_add(c as usize - '0' as usize)); + i = match next { + Some(i) => i, + None => { + return Err(()); + } + }; + } + + if i == 0 { + if !chars.next().is_none() { + return Err(()); + } + break; + } else if chars.by_ref().take(i).count() != i { + return Err(()); + } else { + elements += 1; + } + } + + Ok(Demangle { + inner: inner, + elements: elements, + }) +} + +// Rust hashes are hex digits with an `h` prepended. +fn is_rust_hash(s: &str) -> bool { + s.starts_with('h') && s[1..].chars().all(|c| c.is_digit(16)) +} + +impl<'a> fmt::Display for Demangle<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Alright, let's do this. + let mut inner = self.inner; + for element in 0..self.elements { + let mut rest = inner; + while rest.chars().next().unwrap().is_digit(10) { + rest = &rest[1..]; + } + let i: usize = inner[..(inner.len() - rest.len())].parse().unwrap(); + inner = &rest[i..]; + rest = &rest[..i]; + // Skip printing the hash if alternate formatting + // was requested. + if f.alternate() && element+1 == self.elements && is_rust_hash(&rest) { + break; + } + if element != 0 { + try!(f.write_str("::")); + } + if rest.starts_with("_$") { + rest = &rest[1..]; + } + while !rest.is_empty() { + if rest.starts_with('.') { + if let Some('.') = rest[1..].chars().next() { + try!(f.write_str("::")); + rest = &rest[2..]; + } else { + try!(f.write_str(".")); + rest = &rest[1..]; + } + } else if rest.starts_with('$') { + macro_rules! demangle { + ($($pat:expr => $demangled:expr,)*) => ({ + $(if rest.starts_with($pat) { + try!(f.write_str($demangled)); + rest = &rest[$pat.len()..]; + } else)* + { + try!(f.write_str(rest)); + break; + } + + }) + } + + // see src/librustc/back/link.rs for these mappings + demangle! { + "$SP$" => "@", + "$BP$" => "*", + "$RF$" => "&", + "$LT$" => "<", + "$GT$" => ">", + "$LP$" => "(", + "$RP$" => ")", + "$C$" => ",", + + // in theory we can demangle any Unicode code point, but + // for simplicity we just catch the common ones. + "$u7e$" => "~", + "$u20$" => " ", + "$u27$" => "'", + "$u3d$" => "=", + "$u5b$" => "[", + "$u5d$" => "]", + "$u7b$" => "{", + "$u7d$" => "}", + "$u3b$" => ";", + "$u2b$" => "+", + "$u21$" => "!", + "$u22$" => "\"", + } + } else { + let idx = match rest.char_indices().find(|&(_, c)| c == '$' || c == '.') { + None => rest.len(), + Some((i, _)) => i, + }; + try!(f.write_str(&rest[..idx])); + rest = &rest[idx..]; + } + } + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use std::prelude::v1::*; + + macro_rules! t { + ($a:expr, $b:expr) => (assert!(ok($a, $b))) + } + + macro_rules! t_err { + ($a:expr) => (assert!(ok_err($a))) + } + + macro_rules! t_nohash { + ($a:expr, $b:expr) => ({ + assert_eq!(format!("{:#}", ::demangle($a)), $b); + }) + } + + fn ok(sym: &str, expected: &str) -> bool { + match ::try_demangle(sym) { + Ok(s) => { + if s.to_string() == expected { + true + } else { + println!("\n{}\n!=\n{}\n", s, expected); + false + } + } + Err(_) => { + println!("error demangling"); + false + } + } + } + + fn ok_err(sym: &str) -> bool { + match ::try_demangle(sym) { + Ok(_) => { + println!("succeeded in demangling"); + false + } + Err(_) => ::demangle(sym).to_string() == sym, + } + } + + #[test] + fn demangle() { + t_err!("test"); + t!("_ZN4testE", "test"); + t_err!("_ZN4test"); + t!("_ZN4test1a2bcE", "test::a::bc"); + } + + #[test] + fn demangle_dollars() { + t!("_ZN4$RP$E", ")"); + t!("_ZN8$RF$testE", "&test"); + t!("_ZN8$BP$test4foobE", "*test::foob"); + t!("_ZN9$u20$test4foobE", " test::foob"); + t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>"); + } + + #[test] + fn demangle_many_dollars() { + t!("_ZN13test$u20$test4foobE", "test test::foob"); + t!("_ZN12test$BP$test4foobE", "test*test::foob"); + } + + + #[test] + fn demangle_osx() { + t!("__ZN5alloc9allocator6Layout9for_value17h02a996811f781011E", "alloc::allocator::Layout::for_value::h02a996811f781011"); + t!("__ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap18_MSG_FILE_LINE_COL17haf7cb8d5824ee659E", ">::unwrap::_MSG_FILE_LINE_COL::haf7cb8d5824ee659"); + t!("__ZN4core5slice89_$LT$impl$u20$core..iter..traits..IntoIterator$u20$for$u20$$RF$$u27$a$u20$$u5b$T$u5d$$GT$9into_iter17h450e234d27262170E", "core::slice::::into_iter::h450e234d27262170"); + } + + #[test] + fn demangle_windows() { + t!("ZN4testE", "test"); + t!("ZN13test$u20$test4foobE", "test test::foob"); + t!("ZN12test$RF$test4foobE", "test&test::foob"); + } + + #[test] + fn demangle_elements_beginning_with_underscore() { + t!("_ZN13_$LT$test$GT$E", ""); + t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}"); + t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR"); + } + + #[test] + fn demangle_trait_impls() { + t!("_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE", + ">::bar"); + } + + #[test] + fn demangle_without_hash() { + let s = "_ZN3foo17h05af221e174051e9E"; + t!(s, "foo::h05af221e174051e9"); + t_nohash!(s, "foo"); + } + + #[test] + fn demangle_without_hash_edgecases() { + // One element, no hash. + t_nohash!("_ZN3fooE", "foo"); + // Two elements, no hash. + t_nohash!("_ZN3foo3barE", "foo::bar"); + // Longer-than-normal hash. + t_nohash!("_ZN3foo20h05af221e174051e9abcE", "foo"); + // Shorter-than-normal hash. + t_nohash!("_ZN3foo5h05afE", "foo"); + // Valid hash, but not at the end. + t_nohash!("_ZN17h05af221e174051e93fooE", "h05af221e174051e9::foo"); + // Not a valid hash, missing the 'h'. + t_nohash!("_ZN3foo16ffaf221e174051e9E", "foo::ffaf221e174051e9"); + // Not a valid hash, has a non-hex-digit. + t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9"); + } + + #[test] + fn demangle_thinlto() { + // One element, no hash. + t!("_ZN3fooE.llvm.9D1C9369", "foo"); + t!("_ZN3fooE.llvm.9D1C9369@@16", "foo"); + t_nohash!("_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9", "backtrace::foo"); + } + + #[test] + fn demangle_llvm_ir_branch_labels() { + t!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut::haf9727c2edfbc47b.exit.i.i"); + t_nohash!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice:: for [T]>::index_mut.exit.i.i"); + } + + #[test] + fn demangle_ignores_suffix_that_doesnt_look_like_a_symbol() { + t_err!("_ZN3fooE.llvm moocow"); + } + + #[test] + fn dont_panic() { + ::demangle("_ZN2222222222222222222222EE").to_string(); + ::demangle("_ZN5*70527e27.ll34csaғE").to_string(); + ::demangle("_ZN5*70527a54.ll34_$b.1E").to_string(); + ::demangle("\ + _ZN5~saäb4e\n\ + 2734cOsbE\n\ + 5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\ + ").to_string(); + } + + #[test] + fn invalid_no_chop() { + t_err!("_ZNfooE"); + } + + #[test] + fn handle_assoc_types() { + t!("_ZN151_$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$9call_once17h69e8f44b3723e1caE", " + 'a> as core::ops::function::FnOnce>::call_once::h69e8f44b3723e1ca"); + } + + #[test] + fn handle_bang() { + t!( + "_ZN88_$LT$core..result..Result$LT$$u21$$C$$u20$E$GT$$u20$as$u20$std..process..Termination$GT$6report17hfc41d0da4a40b3e8E", + " as std::process::Termination>::report::hfc41d0da4a40b3e8" + ); + } +} diff -Nru cargo-0.33.0/vendor/rustc-demangle/src/lib.rs cargo-0.35.0/vendor/rustc-demangle/src/lib.rs --- cargo-0.33.0/vendor/rustc-demangle/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustc-demangle/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -30,25 +30,25 @@ #[macro_use] extern crate std; +mod legacy; +mod v0; + use core::fmt; /// Representation of a demangled symbol name. pub struct Demangle<'a> { + style: Option>, original: &'a str, - inner: &'a str, suffix: &'a str, - valid: bool, - /// The number of ::-separated elements in the original name. - elements: usize, +} + +enum DemangleStyle<'a> { + Legacy(legacy::Demangle<'a>), + V0(v0::Demangle<'a>), } /// De-mangles a Rust symbol into a more readable version /// -/// All Rust symbols by default are mangled as they contain characters that -/// cannot be represented in all object files. The mangling mechanism is similar -/// to C++'s, but Rust has a few specifics to handle items like lifetimes in -/// symbols. -/// /// This function will take a **mangled** symbol and return a value. When printed, /// the de-mangled version will be written. If the symbol does not look like /// a mangled symbol, the original value will be written instead. @@ -62,24 +62,6 @@ /// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar"); /// assert_eq!(demangle("foo").to_string(), "foo"); /// ``` - -// All Rust symbols are in theory lists of "::"-separated identifiers. Some -// assemblers, however, can't handle these characters in symbol names. To get -// around this, we use C++-style mangling. The mangling method is: -// -// 1. Prefix the symbol with "_ZN" -// 2. For each element of the path, emit the length plus the element -// 3. End the path with "E" -// -// For example, "_ZN4testE" => "test" and "_ZN3foo3barE" => "foo::bar". -// -// We're the ones printing our backtraces, so we can't rely on anything else to -// demangle our symbols. It's *much* nicer to look at demangled symbols, so -// this function is implemented to give us nice pretty output. -// -// Note that this demangler isn't quite as fancy as it could be. We have lots -// of other information in our symbols like hashes, version, type information, -// etc. Additionally, this doesn't handle glue symbols at all. pub fn demangle(mut s: &str) -> Demangle { // During ThinLTO LLVM may import and rename internal symbols, so strip out // those endings first as they're one of the last manglings applied to symbol @@ -111,67 +93,17 @@ } } - // First validate the symbol. If it doesn't look like anything we're - // expecting, we just print it literally. Note that we must handle non-Rust - // symbols because we could have any function in the backtrace. - let mut valid = true; - let mut inner = s; - if s.len() > 4 && s.starts_with("_ZN") && s.ends_with('E') { - inner = &s[3..s.len() - 1]; - } else if s.len() > 3 && s.starts_with("ZN") && s.ends_with('E') { - // On Windows, dbghelp strips leading underscores, so we accept "ZN...E" - // form too. - inner = &s[2..s.len() - 1]; - } else if s.len() > 5 && s.starts_with("__ZN") && s.ends_with('E') { - // On OSX, symbols are prefixed with an extra _ - inner = &s[4..s.len() - 1]; - } else { - valid = false; - } - - // only work with ascii text - if inner.bytes().any(|c| c & 0x80 != 0) { - valid = false; - } - - let mut elements = 0; - if valid { - let mut chars = inner.chars().peekable(); - while valid { - let mut i = 0usize; - while let Some(&c) = chars.peek() { - if !c.is_digit(10) { - break - } - chars.next(); - let next = i.checked_mul(10) - .and_then(|i| i.checked_add(c as usize - '0' as usize)); - i = match next { - Some(i) => i, - None => { - valid = false; - break - } - }; - } - - if i == 0 { - valid = chars.next().is_none(); - break; - } else if chars.by_ref().take(i).count() != i { - valid = false; - } else { - elements += 1; - } - } - } - + let style = match legacy::demangle(s) { + Ok(d) => Some(DemangleStyle::Legacy(d)), + Err(()) => match v0::demangle(s) { + Ok(d) => Some(DemangleStyle::V0(d)), + Err(v0::Invalid) => None, + }, + }; Demangle { - inner: inner, - suffix: suffix, - valid: valid, - elements: elements, + style: style, original: s, + suffix: suffix, } } @@ -197,7 +129,7 @@ /// ``` pub fn try_demangle(s: &str) -> Result { let sym = demangle(s); - if sym.valid { + if sym.style.is_some() { Ok(sym) } else { Err(TryDemangleError { _priv: () }) @@ -211,11 +143,6 @@ } } -// Rust hashes are hex digits with an `h` prepended. -fn is_rust_hash(s: &str) -> bool { - s.starts_with('h') && s[1..].chars().all(|c| c.is_digit(16)) -} - fn is_symbol_like(s: &str) -> bool { s.chars().all(|c| { // Once `char::is_ascii_punctuation` and `char::is_ascii_alphanumeric` @@ -247,95 +174,16 @@ impl<'a> fmt::Display for Demangle<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Alright, let's do this. - if !self.valid { - return f.write_str(self.original); - } - - let mut inner = self.inner; - for element in 0..self.elements { - let mut rest = inner; - while rest.chars().next().unwrap().is_digit(10) { - rest = &rest[1..]; - } - let i: usize = inner[..(inner.len() - rest.len())].parse().unwrap(); - inner = &rest[i..]; - rest = &rest[..i]; - // Skip printing the hash if alternate formatting - // was requested. - if f.alternate() && element+1 == self.elements && is_rust_hash(&rest) { - break; - } - if element != 0 { - try!(f.write_str("::")); + match self.style { + None => try!(f.write_str(self.original)), + Some(DemangleStyle::Legacy(ref d)) => { + try!(fmt::Display::fmt(d, f)) } - if rest.starts_with("_$") { - rest = &rest[1..]; - } - while !rest.is_empty() { - if rest.starts_with('.') { - if let Some('.') = rest[1..].chars().next() { - try!(f.write_str("::")); - rest = &rest[2..]; - } else { - try!(f.write_str(".")); - rest = &rest[1..]; - } - } else if rest.starts_with('$') { - macro_rules! demangle { - ($($pat:expr => $demangled:expr,)*) => ({ - $(if rest.starts_with($pat) { - try!(f.write_str($demangled)); - rest = &rest[$pat.len()..]; - } else)* - { - try!(f.write_str(rest)); - break; - } - - }) - } - - // see src/librustc/back/link.rs for these mappings - demangle! { - "$SP$" => "@", - "$BP$" => "*", - "$RF$" => "&", - "$LT$" => "<", - "$GT$" => ">", - "$LP$" => "(", - "$RP$" => ")", - "$C$" => ",", - - // in theory we can demangle any Unicode code point, but - // for simplicity we just catch the common ones. - "$u7e$" => "~", - "$u20$" => " ", - "$u27$" => "'", - "$u3d$" => "=", - "$u5b$" => "[", - "$u5d$" => "]", - "$u7b$" => "{", - "$u7d$" => "}", - "$u3b$" => ";", - "$u2b$" => "+", - "$u21$" => "!", - "$u22$" => "\"", - } - } else { - let idx = match rest.char_indices().find(|&(_, c)| c == '$' || c == '.') { - None => rest.len(), - Some((i, _)) => i, - }; - try!(f.write_str(&rest[..idx])); - rest = &rest[idx..]; - } + Some(DemangleStyle::V0(ref d)) => { + try!(fmt::Display::fmt(d, f)) } } - - try!(f.write_str(self.suffix)); - - Ok(()) + f.write_str(self.suffix) } } diff -Nru cargo-0.33.0/vendor/rustc-demangle/src/v0.rs cargo-0.35.0/vendor/rustc-demangle/src/v0.rs --- cargo-0.33.0/vendor/rustc-demangle/src/v0.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/rustc-demangle/src/v0.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1071 @@ +use core::char; +use core::fmt; +use core::fmt::Display; + +/// Representation of a demangled symbol name. +pub struct Demangle<'a> { + inner: &'a str, +} + +/// De-mangles a Rust symbol into a more readable version +/// +/// This function will take a **mangled** symbol and return a value. When printed, +/// the de-mangled version will be written. If the symbol does not look like +/// a mangled symbol, the original value will be written instead. +pub fn demangle(s: &str) -> Result { + // First validate the symbol. If it doesn't look like anything we're + // expecting, we just print it literally. Note that we must handle non-Rust + // symbols because we could have any function in the backtrace. + let inner; + if s.len() > 2 && s.starts_with("_R") { + inner = &s[2..]; + } else if s.len() > 1 && s.starts_with("R") { + // On Windows, dbghelp strips leading underscores, so we accept "R..." + // form too. + inner = &s[1..]; + } else if s.len() > 3 && s.starts_with("__R") { + // On OSX, symbols are prefixed with an extra _ + inner = &s[3..]; + } else { + return Err(Invalid); + } + + // Paths always start with uppercase characters. + match inner.as_bytes()[0] { + b'A'...b'Z' => {} + _ => return Err(Invalid), + } + + // only work with ascii text + if inner.bytes().any(|c| c & 0x80 != 0) { + return Err(Invalid); + } + + // Verify that the symbol is indeed a valid path. + let mut parser = Parser { + sym: inner, + next: 0, + }; + try!(parser.skip_path()); + if parser.next < parser.sym.len() { + // Instantiating crate. + try!(parser.skip_path()); + } + if parser.next != parser.sym.len() { + return Err(Invalid); + } + + Ok(Demangle { + inner: inner, + }) +} + +impl<'s> Display for Demangle<'s> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut printer = Printer { + parser: Ok(Parser { + sym: self.inner, + next: 0, + }), + out: f, + bound_lifetime_depth: 0, + }; + printer.print_path(true) + } +} + +#[derive(PartialEq, Eq)] +pub struct Invalid; + +struct Ident<'s> { + /// ASCII part of the identifier. + ascii: &'s str, + /// Punycode insertion codes for Unicode codepoints, if any. + punycode: &'s str, +} + +const SMALL_PUNYCODE_LEN: usize = 128; + +impl<'s> Ident<'s> { + /// Attempt to decode punycode on the stack (allocation-free), + /// and pass the char slice to the closure, if successful. + /// This supports up to `SMALL_PUNYCODE_LEN` characters. + fn try_small_punycode_decode R, R>( + &self, + f: F, + ) -> Option { + let mut out = ['\0'; SMALL_PUNYCODE_LEN]; + let mut out_len = 0; + let r = self.punycode_decode(|i, c| { + // Check there's space left for another character. + try!(out.get(out_len).ok_or(())); + + // Move the characters after the insert position. + let mut j = out_len; + out_len += 1; + + while j > i { + out[j] = out[j - 1]; + j -= 1; + } + + // Insert the new character. + out[i] = c; + + Ok(()) + }); + if r.is_ok() { + Some(f(&out[..out_len])) + } else { + None + } + } + + /// Decode punycode as insertion positions and characters + /// and pass them to the closure, which can return `Err(())` + /// to stop the decoding process. + fn punycode_decode Result<(), ()>>( + &self, + mut insert: F, + ) -> Result<(), ()> { + let mut punycode_bytes = self.punycode.bytes().peekable(); + if punycode_bytes.peek().is_none() { + return Err(()); + } + + let mut len = 0; + + // Populate initial output from ASCII fragment. + for c in self.ascii.chars() { + try!(insert(len, c)); + len += 1; + } + + // Punycode parameters and initial state. + let base = 36; + let t_min = 1; + let t_max = 26; + let skew = 38; + let mut damp = 700; + let mut bias = 72; + let mut i: usize = 0; + let mut n: usize = 0x80; + + loop { + // Read one delta value. + let mut delta: usize = 0; + let mut w = 1; + let mut k: usize = 0; + loop { + use core::cmp::{min, max}; + + k += base; + let t = min(max(k.saturating_sub(bias), t_min), t_max); + + let d = match punycode_bytes.next() { + Some(d @ b'a'...b'z') => d - b'a', + Some(d @ b'A'...b'J') => 26 + (d - b'A'), + _ => return Err(()), + }; + let d = d as usize; + delta = try!(delta.checked_add( + try!(d.checked_mul(w).ok_or(())) + ).ok_or(())); + if d < t { + break; + } + w = try!(w.checked_mul(base - t).ok_or(())); + } + + // Compute the new insert position and character. + len += 1; + i = try!(i.checked_add(delta).ok_or(())); + n = try!(n.checked_add(i / len).ok_or(())); + i %= len; + + let n_u32 = n as u32; + let c = if n_u32 as usize == n { + try!(char::from_u32(n_u32).ok_or(())) + } else { + return Err(()); + }; + + // Insert the new character and increment the insert position. + try!(insert(i, c)); + i += 1; + + // If there are no more deltas, decoding is complete. + if punycode_bytes.peek().is_none() { + return Ok(()); + } + + // Perform bias adaptation. + delta /= damp; + damp = 2; + + delta += delta / len; + let mut k = 0; + while delta > ((base - t_min) * t_max) / 2 { + delta /= base - t_min; + k += base; + } + bias = k + ((base - t_min + 1) * delta) / (delta + skew); + } + } +} + +impl<'s> Display for Ident<'s> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.try_small_punycode_decode(|chars| { + for &c in chars { + try!(c.fmt(f)); + } + Ok(()) + }).unwrap_or_else(|| { + if !self.punycode.is_empty() { + try!(f.write_str("punycode{")); + + // Reconstruct a standard Punycode encoding, + // by using `-` as the separator and replacing + // [A-J] with [0-9] (in the base36 codes). + if !self.ascii.is_empty() { + try!(f.write_str(self.ascii)); + try!(f.write_str("-")); + } + for mut b in self.punycode.bytes() { + if let b'A'...b'J' = b { + b = b - b'A' + b'0'; + } + try!((b as char).fmt(f)); + } + + f.write_str("}") + } else { + f.write_str(self.ascii) + } + }) + } +} + +fn basic_type(tag: u8) -> Option<&'static str> { + Some(match tag { + b'b' => "bool", + b'c' => "char", + b'e' => "str", + b'u' => "()", + b'a' => "i8", + b's' => "i16", + b'l' => "i32", + b'x' => "i64", + b'n' => "i128", + b'i' => "isize", + b'h' => "u8", + b't' => "u16", + b'm' => "u32", + b'y' => "u64", + b'o' => "u128", + b'j' => "usize", + b'f' => "f32", + b'd' => "f64", + b'z' => "!", + b'p' => "_", + b'v' => "...", + + _ => return None, + }) +} + +struct Parser<'s> { + sym: &'s str, + next: usize, +} + +impl<'s> Parser<'s> { + fn peek(&self) -> Option { + self.sym.as_bytes().get(self.next).cloned() + } + + fn eat(&mut self, b: u8) -> bool { + if self.peek() == Some(b) { + self.next += 1; + true + } else { + false + } + } + + fn next(&mut self) -> Result { + let b = try!(self.peek().ok_or(Invalid)); + self.next += 1; + Ok(b) + } + + fn hex_nibbles(&mut self) -> Result<&'s str, Invalid> { + let start = self.next; + loop { + match try!(self.next()) { + b'0'...b'9' | b'a'...b'f' => {} + b'_' => break, + _ => return Err(Invalid), + } + } + Ok(&self.sym[start..self.next - 1]) + } + + fn digit_10(&mut self) -> Result { + let d = match self.peek() { + Some(d @ b'0'...b'9') => d - b'0', + _ => return Err(Invalid), + }; + self.next += 1; + Ok(d) + } + + fn digit_62(&mut self) -> Result { + let d = match self.peek() { + Some(d @ b'0'...b'9') => d - b'0', + Some(d @ b'a'...b'z') => 10 + (d - b'a'), + Some(d @ b'A'...b'Z') => 10 + 26 + (d - b'A'), + _ => return Err(Invalid), + }; + self.next += 1; + Ok(d) + } + + fn integer_62(&mut self) -> Result { + if self.eat(b'_') { + return Ok(0); + } + + let mut x: u64 = 0; + while !self.eat(b'_') { + let d = try!(self.digit_62()) as u64; + x = try!(x.checked_mul(62).ok_or(Invalid)); + x = try!(x.checked_add(d).ok_or(Invalid)); + } + x.checked_add(1).ok_or(Invalid) + } + + fn opt_integer_62(&mut self, tag: u8) -> Result { + if !self.eat(tag) { + return Ok(0); + } + try!(self.integer_62()).checked_add(1).ok_or(Invalid) + } + + fn disambiguator(&mut self) -> Result { + self.opt_integer_62(b's') + } + + fn namespace(&mut self) -> Result, Invalid> { + match try!(self.next()) { + // Special namespaces, like closures and shims. + ns @ b'A'...b'Z' => Ok(Some(ns as char)), + + // Implementation-specific/unspecified namespaces. + b'a'...b'z' => Ok(None), + + _ => Err(Invalid), + } + } + + fn backref(&mut self) -> Result, Invalid> { + let s_start = self.next - 1; + let i = try!(self.integer_62()); + if i >= s_start as u64 { + return Err(Invalid); + } + Ok(Parser { + sym: self.sym, + next: i as usize, + }) + } + + fn ident(&mut self) -> Result, Invalid> { + let is_punycode = self.eat(b'u'); + let mut len = try!(self.digit_10()) as usize; + if len != 0 { + loop { + match self.digit_10() { + Ok(d) => { + len = try!(len.checked_mul(10).ok_or(Invalid)); + len = try!(len.checked_add(d as usize).ok_or(Invalid)); + } + Err(Invalid) => break, + } + } + } + + let start = self.next; + self.next = try!(self.next.checked_add(len).ok_or(Invalid)); + if self.next > self.sym.len() { + return Err(Invalid); + } + + let ident = &self.sym[start..self.next]; + + if is_punycode { + let ident = match ident.bytes().rposition(|b| b == b'_') { + Some(i) => Ident { + ascii: &ident[..i], + punycode: &ident[i + 1..], + }, + None => Ident { + ascii: "", + punycode: ident, + }, + }; + if ident.punycode.is_empty() { + return Err(Invalid); + } + Ok(ident) + } else { + Ok(Ident { + ascii: ident, + punycode: "", + }) + } + } + + fn skip_path(&mut self) -> Result<(), Invalid> { + match try!(self.next()) { + b'C' => { + try!(self.disambiguator()); + try!(self.ident()); + } + b'N' => { + try!(self.namespace()); + try!(self.skip_path()); + try!(self.disambiguator()); + try!(self.ident()); + } + b'M' => { + try!(self.disambiguator()); + try!(self.skip_path()); + try!(self.skip_type()); + } + b'X' => { + try!(self.disambiguator()); + try!(self.skip_path()); + try!(self.skip_type()); + try!(self.skip_path()); + } + b'Y' => { + try!(self.skip_type()); + try!(self.skip_path()); + } + b'I' => { + try!(self.skip_path()); + while !self.eat(b'E') { + try!(self.skip_generic_arg()); + } + } + b'B' => { + try!(self.backref()); + } + _ => return Err(Invalid), + } + Ok(()) + } + + fn skip_generic_arg(&mut self) -> Result<(), Invalid> { + if self.eat(b'L') { + try!(self.integer_62()); + Ok(()) + } else if self.eat(b'K') { + self.skip_const() + } else { + self.skip_type() + } + } + + fn skip_type(&mut self) -> Result<(), Invalid> { + match try!(self.next()) { + tag if basic_type(tag).is_some() => {} + + b'R' | b'Q' => { + if self.eat(b'L') { + try!(self.integer_62()); + } + try!(self.skip_type()); + } + b'P' | b'O' | b'S' => try!(self.skip_type()), + b'A' => { + try!(self.skip_type()); + try!(self.skip_const()); + } + b'T' => while !self.eat(b'E') { + try!(self.skip_type()); + }, + b'F' => { + let _binder = try!(self.opt_integer_62(b'G')); + let _is_unsafe = self.eat(b'U'); + if self.eat(b'K') { + let c_abi = self.eat(b'C'); + if !c_abi { + let abi = try!(self.ident()); + if abi.ascii.is_empty() || !abi.punycode.is_empty() { + return Err(Invalid); + } + } + } + while !self.eat(b'E') { + try!(self.skip_type()); + } + try!(self.skip_type()); + } + b'D' => { + let _binder = try!(self.opt_integer_62(b'G')); + while !self.eat(b'E') { + try!(self.skip_path()); + while self.eat(b'p') { + try!(self.ident()); + try!(self.skip_type()); + } + } + if !self.eat(b'L') { + return Err(Invalid); + } + try!(self.integer_62()); + } + b'B' => { + try!(self.backref()); + } + _ => { + // Go back to the tag, so `skip_path` also sees it. + self.next -= 1; + try!(self.skip_path()); + } + } + Ok(()) + } + + fn skip_const(&mut self) -> Result<(), Invalid> { + if self.eat(b'B') { + try!(self.backref()); + return Ok(()); + } + + match try!(self.next()) { + // Unsigned integer types. + b'h' | b't' | b'm' | b'y' | b'o' | b'j' => {} + + _ => return Err(Invalid), + } + + if self.eat(b'p') { + return Ok(()); + } + try!(self.hex_nibbles()); + Ok(()) + } +} + +struct Printer<'a, 'b: 'a, 's> { + parser: Result, Invalid>, + out: &'a mut fmt::Formatter<'b>, + bound_lifetime_depth: u32, +} + +/// Mark the parser as errored, print `?` and return early. +/// This allows callers to keep printing the approximate +/// syntax of the path/type/const, despite having errors. +/// E.g. `Vec<[(A, ?); ?]>` instead of `Vec<[(A, ?`. +macro_rules! invalid { + ($printer:ident) => {{ + $printer.parser = Err(Invalid); + return $printer.out.write_str("?"); + }} +} + +/// Call a parser method (if the parser hasn't errored yet), +/// and mark the parser as errored if it returns `Err(Invalid)`. +/// +/// If the parser errored, before or now, prints `?`, and +/// returns early the current function (see `invalid!` above). +macro_rules! parse { + ($printer:ident, $method:ident $(($($arg:expr),*))*) => { + match $printer.parser_mut().and_then(|p| p.$method($($($arg),*)*)) { + Ok(x) => x, + Err(Invalid) => invalid!($printer), + } + }; +} + +impl<'a, 'b, 's> Printer<'a, 'b, 's> { + fn parser_mut<'c>(&'c mut self) -> Result<&'c mut Parser<'s>, Invalid> { + self.parser.as_mut().map_err(|_| Invalid) + } + + /// Eat the given character from the parser, + /// returning `false` if the parser errored. + fn eat(&mut self, b: u8) -> bool { + self.parser_mut().map(|p| p.eat(b)) == Ok(true) + } + + /// Return a nested parser for a backref. + fn backref_printer<'c>(&'c mut self) -> Printer<'c, 'b, 's> { + Printer { + parser: self.parser_mut().and_then(|p| p.backref()), + out: self.out, + bound_lifetime_depth: self.bound_lifetime_depth, + } + } + + /// Print the lifetime according to the previously decoded index. + /// An index of `0` always refers to `'_`, but starting with `1`, + /// indices refer to late-bound lifetimes introduced by a binder. + fn print_lifetime_from_index(&mut self, lt: u64) -> fmt::Result { + try!(self.out.write_str("'")); + if lt == 0 { + return self.out.write_str("_"); + } + match (self.bound_lifetime_depth as u64).checked_sub(lt) { + Some(depth) => { + // Try to print lifetimes alphabetically first. + if depth < 26 { + let c = (b'a' + depth as u8) as char; + c.fmt(self.out) + } else { + // Use `'_123` after running out of letters. + try!(self.out.write_str("_")); + depth.fmt(self.out) + } + } + None => invalid!(self), + } + } + + /// Optionally enter a binder ('G') for late-bound lifetimes, + /// printing e.g. `for<'a, 'b> ` before calling the closure, + /// and make those lifetimes visible to it (via depth level). + fn in_binder(&mut self, f: F) -> fmt::Result + where F: FnOnce(&mut Self) -> fmt::Result, + { + let bound_lifetimes = parse!(self, opt_integer_62(b'G')); + + if bound_lifetimes > 0 { + try!(self.out.write_str("for<")); + for i in 0..bound_lifetimes { + if i > 0 { + try!(self.out.write_str(", ")); + } + self.bound_lifetime_depth += 1; + try!(self.print_lifetime_from_index(1)); + } + try!(self.out.write_str("> ")); + } + + let r = f(self); + + // Restore `bound_lifetime_depth` to the previous value. + self.bound_lifetime_depth -= bound_lifetimes as u32; + + r + } + + /// Print list elements using the given closure and separator, + /// until the end of the list ('E') is found, or the parser errors. + /// Returns the number of elements printed. + fn print_sep_list(&mut self, f: F, sep: &str) -> Result + where F: Fn(&mut Self) -> fmt::Result, + { + let mut i = 0; + while self.parser.is_ok() && !self.eat(b'E') { + if i > 0 { + try!(self.out.write_str(sep)); + } + try!(f(self)); + i += 1; + } + Ok(i) + } + + fn print_path(&mut self, in_value: bool) -> fmt::Result { + let tag = parse!(self, next); + match tag { + b'C' => { + let dis = parse!(self, disambiguator); + let name = parse!(self, ident); + + if name.punycode.is_empty() { + // Unescape `_[0-9_]`. + let mut name = name.ascii; + if name.starts_with("_") { + name = &name[1..]; + } + try!(self.out.write_str(name)); + } else { + try!(name.fmt(self.out)); + } + if !self.out.alternate() { + try!(self.out.write_str("[")); + try!(fmt::LowerHex::fmt(&dis, self.out)); + try!(self.out.write_str("]")); + } + } + b'N' => { + let ns = parse!(self, namespace); + + try!(self.print_path(in_value)); + + let dis = parse!(self, disambiguator); + let name = parse!(self, ident); + + match ns { + // Special namespaces, like closures and shims. + Some(ns) => { + try!(self.out.write_str("::{")); + match ns { + 'C' => try!(self.out.write_str("closure")), + 'S' => try!(self.out.write_str("shim")), + _ => try!(ns.fmt(self.out)), + } + if !name.ascii.is_empty() || !name.punycode.is_empty() { + try!(self.out.write_str(":")); + try!(name.fmt(self.out)); + } + try!(self.out.write_str("#")); + try!(dis.fmt(self.out)); + try!(self.out.write_str("}")); + } + + // Implementation-specific/unspecified namespaces. + None => { + if !name.ascii.is_empty() || !name.punycode.is_empty() { + try!(self.out.write_str("::")); + try!(name.fmt(self.out)); + } + } + } + } + b'M' | b'X' | b'Y' => { + if tag != b'Y' { + // Ignore the `impl`'s own path. + parse!(self, disambiguator); + parse!(self, skip_path); + } + + try!(self.out.write_str("<")); + try!(self.print_type()); + if tag != b'M' { + try!(self.out.write_str(" as ")); + try!(self.print_path(false)); + } + try!(self.out.write_str(">")); + } + b'I' => { + try!(self.print_path(in_value)); + if in_value { + try!(self.out.write_str("::")); + } + try!(self.out.write_str("<")); + try!(self.print_sep_list(Self::print_generic_arg, ", ")); + try!(self.out.write_str(">")); + } + b'B' => { + try!(self.backref_printer().print_path(in_value)); + } + _ => invalid!(self), + } + Ok(()) + } + + fn print_generic_arg(&mut self) -> fmt::Result { + if self.eat(b'L') { + let lt = parse!(self, integer_62); + self.print_lifetime_from_index(lt) + } else if self.eat(b'K') { + self.print_const() + } else { + self.print_type() + } + } + + fn print_type(&mut self) -> fmt::Result { + let tag = parse!(self, next); + + match basic_type(tag) { + Some(ty) => return self.out.write_str(ty), + None => {} + } + + match tag { + b'R' | b'Q' => { + try!(self.out.write_str("&")); + if self.eat(b'L') { + let lt = parse!(self, integer_62); + if lt != 0 { + try!(self.print_lifetime_from_index(lt)); + try!(self.out.write_str(" ")); + } + } + if tag != b'R' { + try!(self.out.write_str("mut ")); + } + try!(self.print_type()); + } + + b'P' | b'O' => { + try!(self.out.write_str("*")); + if tag != b'P' { + try!(self.out.write_str("mut ")); + } else { + try!(self.out.write_str("const ")); + } + try!(self.print_type()); + } + + b'A' | b'S' => { + try!(self.out.write_str("[")); + try!(self.print_type()); + if tag == b'A' { + try!(self.out.write_str("; ")); + try!(self.print_const()); + } + try!(self.out.write_str("]")); + } + b'T' => { + try!(self.out.write_str("(")); + let count = try!(self.print_sep_list(Self::print_type, ", ")); + if count == 1 { + try!(self.out.write_str(",")); + } + try!(self.out.write_str(")")); + } + b'F' => try!(self.in_binder(|this| { + let is_unsafe = this.eat(b'U'); + let abi = if this.eat(b'K') { + if this.eat(b'C') { + Some("C") + } else { + let abi = parse!(this, ident); + if abi.ascii.is_empty() || !abi.punycode.is_empty() { + invalid!(this); + } + Some(abi.ascii) + } + } else { + None + }; + + if is_unsafe { + try!(this.out.write_str("unsafe ")); + } + + match abi { + Some(abi) => { + try!(this.out.write_str("extern \"")); + + // If the ABI had any `-`, they were replaced with `_`, + // so the parts between `_` have to be re-joined with `-`. + let mut parts = abi.split('_'); + try!(this.out.write_str(parts.next().unwrap())); + for part in parts { + try!(this.out.write_str("-")); + try!(this.out.write_str(part)); + } + + try!(this.out.write_str("\" ")); + } + None => {} + } + + try!(this.out.write_str("fn(")); + try!(this.print_sep_list(Self::print_type, ", ")); + try!(this.out.write_str(")")); + + if this.eat(b'u') { + // Skip printing the return type if it's 'u', i.e. `()`. + } else { + try!(this.out.write_str(" -> ")); + try!(this.print_type()); + } + + Ok(()) + })), + b'D' => { + try!(self.out.write_str("dyn ")); + try!(self.in_binder(|this| { + try!(this.print_sep_list(Self::print_dyn_trait, " + ")); + Ok(()) + })); + + if !self.eat(b'L') { + invalid!(self); + } + let lt = parse!(self, integer_62); + if lt != 0 { + try!(self.out.write_str(" + ")); + try!(self.print_lifetime_from_index(lt)); + } + } + b'B' => { + try!(self.backref_printer().print_type()); + } + _ => { + // Go back to the tag, so `print_path` also sees it. + let _ = self.parser_mut().map(|p| p.next -= 1); + try!(self.print_path(false)); + } + } + Ok(()) + } + + /// A trait in a trait object may have some "existential projections" + /// (i.e. associated type bindings) after it, which should be printed + /// in the `<...>` of the trait, e.g. `dyn Trait`. + /// To this end, this method will keep the `<...>` of an 'I' path + /// open, by omitting the `>`, and return `Ok(true)` in that case. + fn print_path_maybe_open_generics(&mut self) -> Result { + if self.eat(b'B') { + self.backref_printer().print_path_maybe_open_generics() + } else if self.eat(b'I') { + try!(self.print_path(false)); + try!(self.out.write_str("<")); + try!(self.print_sep_list(Self::print_generic_arg, ", ")); + Ok(true) + } else { + try!(self.print_path(false)); + Ok(false) + } + } + + fn print_dyn_trait(&mut self) -> fmt::Result { + let mut open = try!(self.print_path_maybe_open_generics()); + + while self.eat(b'p') { + if !open { + try!(self.out.write_str("<")); + open = true; + } else { + try!(self.out.write_str(", ")); + } + + let name = parse!(self, ident); + try!(name.fmt(self.out)); + try!(self.out.write_str(" = ")); + try!(self.print_type()); + } + + if open { + try!(self.out.write_str(">")); + } + + Ok(()) + } + + fn print_const(&mut self) -> fmt::Result { + if self.eat(b'B') { + return self.backref_printer().print_const(); + } + + let ty_tag = parse!(self, next); + let ty = match ty_tag { + // Unsigned integer types. + b'h' | b't' | b'm' | b'y' | b'o' | b'j' => { + basic_type(ty_tag).unwrap() + } + + _ => invalid!(self), + }; + + + if self.eat(b'p') { + try!(self.out.write_str("_")); + } else { + try!(self.print_const_uint()); + } + + if !self.out.alternate() { + try!(self.out.write_str(": ")); + try!(self.out.write_str(ty)); + } + + Ok(()) + } + + fn print_const_uint(&mut self) -> fmt::Result { + let hex = parse!(self, hex_nibbles); + + // Print anything that doesn't fit in `u64` verbatim. + if hex.len() > 16 { + try!(self.out.write_str("0x")); + return self.out.write_str(hex); + } + + let mut v = 0; + for c in hex.chars() { + v = (v << 4) | (c.to_digit(16).unwrap() as u64); + } + v.fmt(self.out) + } +} + +#[cfg(test)] +mod tests { + macro_rules! t_nohash { + ($a:expr, $b:expr) => ({ + assert_eq!(format!("{:#}", ::demangle($a)), $b); + }) + } + macro_rules! t_nohash_type { + ($a:expr, $b:expr) => ( + t_nohash!(concat!("_RMC0", $a), concat!("<", $b, ">")) + ) + } + + #[test] + fn demangle_utf8_idents() { + t_nohash!( + "_RNqCs4fqI2P2rA04_11utf8_identsu30___HhkackfeceaBcbdathfdhJhlqGy", + "utf8_idents::საჭმელად_გემრიელი_სადილი" + ); + } + + #[test] + fn demangle_closure() { + t_nohash!( + "_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_", + "cc::spawn::{closure#0}::{closure#0}" + ); + t_nohash!( + "_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_", + " as core::iter::iterator::Iterator>::rposition::::{closure#0}" + ); + } + + #[test] + fn demangle_dyn_trait() { + t_nohash!( + "_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std", + "alloc::alloc::box_free::>" + ); + } + + #[test] + fn demangle_const_generics() { + // NOTE(eddyb) this was hand-written, before rustc had working + // const generics support (but the mangling format did include them). + t_nohash_type!( + "INtC8arrayvec8ArrayVechKj7b_E", + "arrayvec::ArrayVec" + ); + } + + #[test] + fn demangle_exponential_explosion() { + // NOTE(eddyb) because of the prefix added by `t_nohash_type!` is + // 3 bytes long, `B2_` refers to the start of the type, not `B_`. + // 6 backrefs (`B8_E` through `B3_E`) result in 2^6 = 64 copies of `_`. + // Also, because the `p` (`_`) type is after all of the starts of the + // backrefs, it can be replaced with any other type, independently. + t_nohash_type!( + concat!("TTTTTT", "p", "B8_E", "B7_E", "B6_E", "B5_E", "B4_E", "B3_E"), + "((((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), \ + ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))), \ + (((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _)))), \ + ((((_, _), (_, _)), ((_, _), (_, _))), (((_, _), (_, _)), ((_, _), (_, _))))))" + ); + } +} diff -Nru cargo-0.33.0/vendor/rustfix/.cargo-checksum.json cargo-0.35.0/vendor/rustfix/.cargo-checksum.json --- cargo-0.33.0/vendor/rustfix/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustfix/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"af7c21531a91512a4a51b490be6ba1c8eff34fdda0dc5bf87dc28d86748aac56"} \ No newline at end of file +{"files":{},"package":"b96ea6eeae40f488397ccc9e1c0da19d720b23c75972bc63eaa6852b84d161e2"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rustfix/Cargo.toml cargo-0.35.0/vendor/rustfix/Cargo.toml --- cargo-0.33.0/vendor/rustfix/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustfix/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "rustfix" -version = "0.4.4" +version = "0.4.5" authors = ["Pascal Hertleif ", "Oliver Schneider "] exclude = ["etc/*", "examples/*", "tests/*"] description = "Automatically apply the suggestions made by rustc" diff -Nru cargo-0.33.0/vendor/rustfix/src/diagnostics.rs cargo-0.35.0/vendor/rustfix/src/diagnostics.rs --- cargo-0.33.0/vendor/rustfix/src/diagnostics.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustfix/src/diagnostics.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2,7 +2,7 @@ //! //! The following data types are copied from [rust-lang/rust](https://github.com/rust-lang/rust/blob/de78655bca47cac8e783dbb563e7e5c25c1fae40/src/libsyntax/json.rs) -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, Hash, Eq, PartialEq)] pub struct Diagnostic { /// The primary error message. pub message: String, @@ -18,7 +18,7 @@ pub rendered: Option, } -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, Hash, Eq, PartialEq)] pub struct DiagnosticSpan { pub file_name: String, pub byte_start: u32, @@ -46,7 +46,7 @@ expansion: Option>, } -#[derive(Copy, Clone, Debug, PartialEq, Deserialize)] +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)] pub enum Applicability { MachineApplicable, HasPlaceholders, @@ -54,7 +54,7 @@ Unspecified, } -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, Eq, PartialEq, Hash)] pub struct DiagnosticSpanLine { pub text: String, @@ -64,7 +64,7 @@ pub highlight_end: usize, } -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, Eq, PartialEq, Hash)] struct DiagnosticSpanMacroExpansion { /// span where macro was applied to generate this code; note that /// this may itself derive from a macro (if @@ -78,7 +78,7 @@ def_site_span: Option, } -#[derive(Deserialize, Debug)] +#[derive(Clone, Deserialize, Debug, Eq, PartialEq, Hash)] pub struct DiagnosticCode { /// The code itself. pub code: String, diff -Nru cargo-0.33.0/vendor/rustfix/src/lib.rs cargo-0.35.0/vendor/rustfix/src/lib.rs --- cargo-0.33.0/vendor/rustfix/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rustfix/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -37,7 +37,7 @@ Ok(result) } -#[derive(Debug, Copy, Clone, Hash, PartialEq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct LinePosition { pub line: usize, pub column: usize, @@ -49,7 +49,7 @@ } } -#[derive(Debug, Copy, Clone, Hash, PartialEq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct LineRange { pub start: LinePosition, pub end: LinePosition, @@ -61,7 +61,7 @@ } } -#[derive(Debug, Clone, Hash, PartialEq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] /// An error/warning and possible solutions for fixing it pub struct Suggestion { pub message: String, @@ -69,13 +69,13 @@ pub solutions: Vec, } -#[derive(Debug, Clone, Hash, PartialEq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Solution { pub message: String, pub replacements: Vec, } -#[derive(Debug, Clone, Hash, PartialEq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Snippet { pub file_name: String, pub line_range: LineRange, @@ -86,7 +86,7 @@ pub text: (String, String, String), } -#[derive(Debug, Clone, Hash, PartialEq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Replacement { pub snippet: Snippet, pub replacement: String, @@ -114,11 +114,16 @@ } let mut tail = String::new(); let last = &span.text[span.text.len() - 1]; + + // If we get a DiagnosticSpanLine where highlight_end > text.len(), we prevent an 'out of + // bounds' access by making sure the index is within the array bounds. + let last_tail_index = last.highlight_end.min(last.text.len()) - 1; + if span.text.len() > 1 { body.push('\n'); - body.push_str(&last.text[indent..last.highlight_end - 1]); + body.push_str(&last.text[indent..last_tail_index]); } - tail.push_str(&last.text[last.highlight_end - 1..]); + tail.push_str(&last.text[last_tail_index..]); Some(Snippet { file_name: span.file_name.clone(), line_range: LineRange { diff -Nru cargo-0.33.0/vendor/rusty-fork/.cargo-checksum.json cargo-0.35.0/vendor/rusty-fork/.cargo-checksum.json --- cargo-0.33.0/vendor/rusty-fork/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"9591f190d2852720b679c21f66ad929f9f1d7bb09d1193c26167586029d8489c"} \ No newline at end of file +{"files":{},"package":"3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/rusty-fork/Cargo.toml cargo-0.35.0/vendor/rusty-fork/Cargo.toml --- cargo-0.33.0/vendor/rusty-fork/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,8 +12,9 @@ [package] name = "rusty-fork" -version = "0.2.1" +version = "0.2.2" authors = ["Jason Lingle"] +exclude = ["/gen-readme.sh", "/readme-*.md"] description = "Cross-platform library for running Rust tests in sub-processes using a\nfork-like interface.\n" documentation = "https://docs.rs/rusty-fork" readme = "README.md" @@ -31,7 +32,7 @@ version = "3.0" [dependencies.wait-timeout] -version = "0.1.4" +version = "0.2" optional = true [dev-dependencies] diff -Nru cargo-0.33.0/vendor/rusty-fork/CHANGELOG.md cargo-0.35.0/vendor/rusty-fork/CHANGELOG.md --- cargo-0.33.0/vendor/rusty-fork/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,3 +1,9 @@ +## 0.2.2 + +### Minor changes + +- `wait_timeout` has been bumped to `0.2.0`. + ## 0.2.1 ### Bug Fixes diff -Nru cargo-0.33.0/vendor/rusty-fork/gen-readme.sh cargo-0.35.0/vendor/rusty-fork/gen-readme.sh --- cargo-0.33.0/vendor/rusty-fork/gen-readme.sh 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/gen-readme.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -#! /bin/sh - -# Generate `README.md` from the crate documentation, plus some extra stuff. - -cat readme-prologue.md >README.md ->README.md -cat readme-antelogue.md >>README.md diff -Nru cargo-0.33.0/vendor/rusty-fork/readme-antelogue.md cargo-0.35.0/vendor/rusty-fork/readme-antelogue.md --- cargo-0.33.0/vendor/rusty-fork/readme-antelogue.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/readme-antelogue.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - -## Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. diff -Nru cargo-0.33.0/vendor/rusty-fork/readme-prologue.md cargo-0.35.0/vendor/rusty-fork/readme-prologue.md --- cargo-0.33.0/vendor/rusty-fork/readme-prologue.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/readme-prologue.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -# rusty-fork - -[![Build Status](https://travis-ci.org/AltSysrq/rusty-fork.svg?branch=master)](https://travis-ci.org/AltSysrq/rusty-fork) -[![](http://meritbadge.herokuapp.com/rusty-fork)](https://crates.io/crates/rusty-fork) - diff -Nru cargo-0.33.0/vendor/rusty-fork/src/child_wrapper.rs cargo-0.35.0/vendor/rusty-fork/src/child_wrapper.rs --- cargo-0.33.0/vendor/rusty-fork/src/child_wrapper.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/rusty-fork/src/child_wrapper.rs 2019-05-15 11:26:24.000000000 +0000 @@ -14,23 +14,21 @@ use std::time::Duration; #[cfg(feature = "timeout")] -use wait_timeout::{self, ChildExt}; +use wait_timeout::ChildExt; -/// Wraps `std::process::ExitStatus` and (if enabled) -/// `wait_timeout::ExitStatus` to give a uniform interface to both. +/// Wraps `std::process::ExitStatus`. Historically, this was due to the +/// `wait_timeout` crate having its own `ExitStatus` type. /// /// Method documentation is copied from the [Rust std /// docs](https://doc.rust-lang.org/stable/std/process/struct.ExitStatus.html) /// and the [`wait_timeout` -/// docs](https://docs.rs/wait-timeout/0.1.5/wait_timeout/struct.ExitStatus.html) +/// docs](https://docs.rs/wait-timeout/0.1.5/wait_timeout/struct.ExitStatus.html). #[derive(Clone, Copy)] pub struct ExitStatusWrapper(ExitStatusEnum); #[derive(Debug, Clone, Copy)] enum ExitStatusEnum { Std(::std::process::ExitStatus), - #[cfg(feature = "timeout")] - Wt(wait_timeout::ExitStatus), } impl ExitStatusWrapper { @@ -38,18 +36,11 @@ ExitStatusWrapper(ExitStatusEnum::Std(es)) } - #[cfg(feature = "timeout")] - fn wt(es: wait_timeout::ExitStatus) -> Self { - ExitStatusWrapper(ExitStatusEnum::Wt(es)) - } - /// Was termination successful? Signal termination is not considered a /// success, and success is defined as a zero exit status. pub fn success(&self) -> bool { match self.0 { ExitStatusEnum::Std(es) => es.success(), - #[cfg(feature = "timeout")] - ExitStatusEnum::Wt(es) => es.success(), } } @@ -61,8 +52,6 @@ pub fn code(&self) -> Option { match self.0 { ExitStatusEnum::Std(es) => es.code(), - #[cfg(feature = "timeout")] - ExitStatusEnum::Wt(es) => es.code(), } } @@ -79,8 +68,6 @@ match self.0 { ExitStatusEnum::Std(es) => es.signal(), - #[cfg(feature = "timeout")] - ExitStatusEnum::Wt(es) => es.unix_signal(), } } @@ -101,8 +88,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.0 { ExitStatusEnum::Std(ref es) => fmt::Debug::fmt(es, f), - #[cfg(feature = "timeout")] - ExitStatusEnum::Wt(ref es) => fmt::Debug::fmt(es, f), } } } @@ -111,8 +96,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.0 { ExitStatusEnum::Std(ref es) => fmt::Display::fmt(es, f), - #[cfg(feature = "timeout")] - ExitStatusEnum::Wt(ref es) => fmt::Display::fmt(es, f), } } } @@ -257,7 +240,7 @@ if let Some(status) = self.exit_status { Ok(Some(status)) } else { - let status = self.child.wait_timeout(dur)?.map(ExitStatusWrapper::wt); + let status = self.child.wait_timeout(dur)?.map(ExitStatusWrapper::std); self.exit_status = status; Ok(status) } diff -Nru cargo-0.33.0/vendor/ryu/benches/bench.rs cargo-0.35.0/vendor/ryu/benches/bench.rs --- cargo-0.33.0/vendor/ryu/benches/bench.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/benches/bench.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,59 @@ +// cargo bench + +#![feature(test)] + +extern crate ryu; +extern crate test; + +macro_rules! benches { + ($($name:ident($value:expr),)*) => { + mod bench_ryu { + use test::{Bencher, black_box}; + $( + #[bench] + fn $name(b: &mut Bencher) { + use ryu; + + let mut buf = ryu::Buffer::new(); + + b.iter(move || { + let value = black_box($value); + let formatted = buf.format(value); + black_box(formatted); + }); + } + )* + } + + mod bench_std_fmt { + use test::{Bencher, black_box}; + $( + #[bench] + fn $name(b: &mut Bencher) { + use std::io::Write; + + let mut buf = Vec::with_capacity(20); + + b.iter(|| { + buf.clear(); + let value = black_box($value); + write!(&mut buf, "{}", value).unwrap(); + black_box(buf.as_slice()); + }); + } + )* + } + } +} + +benches!( + bench_0_f64(0f64), + bench_short_f64(0.1234f64), + bench_e_f64(2.718281828459045f64), + bench_max_f64(::std::f64::MAX), + + bench_0_f32(0f32), + bench_short_f32(0.1234f32), + bench_e_f32(2.718281828459045f32), + bench_max_f32(::std::f32::MAX), +); diff -Nru cargo-0.33.0/vendor/ryu/benchmark/benchmark.rs cargo-0.35.0/vendor/ryu/benchmark/benchmark.rs --- cargo-0.33.0/vendor/ryu/benchmark/benchmark.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/benchmark/benchmark.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -extern crate rand; -extern crate ryu; - -use rand::{Rng, SeedableRng}; - -const SAMPLES: usize = 10000; -const ITERATIONS: usize = 1000; - -struct MeanAndVariance { - n: i64, - mean: f64, - m2: f64, -} - -impl MeanAndVariance { - fn new() -> Self { - MeanAndVariance { - n: 0, - mean: 0.0, - m2: 0.0, - } - } - - fn update(&mut self, x: f64) { - self.n += 1; - let d = x - self.mean; - self.mean += d / self.n as f64; - let d2 = x - self.mean; - self.m2 += d * d2; - } - - fn variance(&self) -> f64 { - self.m2 / (self.n - 1) as f64 - } - - fn stddev(&self) -> f64 { - self.variance().sqrt() - } -} - -macro_rules! benchmark { - ($name:ident, $ty:ident) => { - fn $name() -> usize { - let mut rng = rand::prng::XorShiftRng::from_seed([123u8; 16]); - let mut mv = MeanAndVariance::new(); - let mut throwaway = 0; - for _ in 0..SAMPLES { - let f = loop { - let f = $ty::from_bits(rng.gen()); - if f.is_finite() { - break f; - } - }; - - let t1 = std::time::SystemTime::now(); - for _ in 0..ITERATIONS { - throwaway += ryu::Buffer::new().format(f).len(); - } - let duration = t1.elapsed().unwrap(); - let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; - mv.update(nanos as f64 / ITERATIONS as f64); - } - println!( - "{:12} {:8.3} {:8.3}", - concat!(stringify!($name), ":"), - mv.mean, - mv.stddev(), - ); - throwaway - } - }; -} - -benchmark!(pretty32, f32); -benchmark!(pretty64, f64); - -fn main() { - println!("{:>20}{:>9}", "Average", "Stddev"); - let mut throwaway = 0; - throwaway += pretty32(); - throwaway += pretty64(); - if std::env::var_os("ryu-benchmark").is_some() { - // Prevent the compiler from optimizing the code away. - println!("{}", throwaway); - } -} diff -Nru cargo-0.33.0/vendor/ryu/.cargo-checksum.json cargo-0.35.0/vendor/ryu/.cargo-checksum.json --- cargo-0.33.0/vendor/ryu/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"} \ No newline at end of file +{"files":{},"package":"b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/ryu/Cargo.toml cargo-0.35.0/vendor/ryu/Cargo.toml --- cargo-0.33.0/vendor/ryu/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "ryu" -version = "0.2.7" +version = "0.2.8" authors = ["David Tolnay "] build = "build.rs" description = "Fast floating point to string conversion" @@ -20,10 +20,6 @@ readme = "README.md" license = "Apache-2.0 OR BSL-1.0" repository = "https://github.com/dtolnay/ryu" - -[[example]] -name = "benchmark" -path = "benchmark/benchmark.rs" [dependencies.no-panic] version = "0.1" optional = true diff -Nru cargo-0.33.0/vendor/ryu/examples/upstream_benchmark.rs cargo-0.35.0/vendor/ryu/examples/upstream_benchmark.rs --- cargo-0.33.0/vendor/ryu/examples/upstream_benchmark.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/examples/upstream_benchmark.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,88 @@ +// cargo run --example upstream_benchmark --release + +extern crate rand; +extern crate ryu; + +use rand::{Rng, SeedableRng}; + +const SAMPLES: usize = 10000; +const ITERATIONS: usize = 1000; + +struct MeanAndVariance { + n: i64, + mean: f64, + m2: f64, +} + +impl MeanAndVariance { + fn new() -> Self { + MeanAndVariance { + n: 0, + mean: 0.0, + m2: 0.0, + } + } + + fn update(&mut self, x: f64) { + self.n += 1; + let d = x - self.mean; + self.mean += d / self.n as f64; + let d2 = x - self.mean; + self.m2 += d * d2; + } + + fn variance(&self) -> f64 { + self.m2 / (self.n - 1) as f64 + } + + fn stddev(&self) -> f64 { + self.variance().sqrt() + } +} + +macro_rules! benchmark { + ($name:ident, $ty:ident) => { + fn $name() -> usize { + let mut rng = rand::prng::XorShiftRng::from_seed([123u8; 16]); + let mut mv = MeanAndVariance::new(); + let mut throwaway = 0; + for _ in 0..SAMPLES { + let f = loop { + let f = $ty::from_bits(rng.gen()); + if f.is_finite() { + break f; + } + }; + + let t1 = std::time::SystemTime::now(); + for _ in 0..ITERATIONS { + throwaway += ryu::Buffer::new().format(f).len(); + } + let duration = t1.elapsed().unwrap(); + let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; + mv.update(nanos as f64 / ITERATIONS as f64); + } + println!( + "{:12} {:8.3} {:8.3}", + concat!(stringify!($name), ":"), + mv.mean, + mv.stddev(), + ); + throwaway + } + }; +} + +benchmark!(pretty32, f32); +benchmark!(pretty64, f64); + +fn main() { + println!("{:>20}{:>9}", "Average", "Stddev"); + let mut throwaway = 0; + throwaway += pretty32(); + throwaway += pretty64(); + if std::env::var_os("ryu-benchmark").is_some() { + // Prevent the compiler from optimizing the code away. + println!("{}", throwaway); + } +} diff -Nru cargo-0.33.0/vendor/ryu/README.md cargo-0.35.0/vendor/ryu/README.md --- cargo-0.33.0/vendor/ryu/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -24,18 +24,16 @@ uses nothing from the Rust standard library so is usable from no_std crates.* [paper]: https://dl.acm.org/citation.cfm?id=3192369 -[upstream]: https://github.com/ulfjack/ryu/tree/66ba13274ca0247ad46fd4fe8a2f6d36f5d39b01 +[upstream]: https://github.com/ulfjack/ryu/tree/795c8b57aa454c723194bbea8e4bf2ccd28e865f ```toml [dependencies] ryu = "0.2" ``` -## Examples +## Example ```rust -extern crate ryu; - fn main() { let mut buffer = ryu::Buffer::new(); let printed = buffer.format(1.234); @@ -53,12 +51,12 @@ $ bazel run -c opt //ryu/benchmark ``` -And our benchmarks with: +And the same benchmark against our implementation with: ```console -$ git clone https://github.com/ulfjack/ryu rust-ryu +$ git clone https://github.com/dtolnay/ryu rust-ryu $ cd rust-ryu -$ cargo run --example benchmark --release +$ cargo run --example upstream_benchmark --release ``` These benchmarks measure the average time to print a 32-bit float and average @@ -69,6 +67,39 @@ all perform the same, taking around 21 nanoseconds to format a 32-bit float and 31 nanoseconds to format a 64-bit float. +There is also a Rust-specific benchmark comparing this implementation to the +standard library which you can run with: + +```console +$ cargo bench +``` + +The benchmark shows Ryu approximately 4-10x faster than the standard library +across a range of f32 and f64 inputs. Measurements are in nanoseconds per +iteration; smaller is better. + +| type=f32 | 0.0 | 0.1234 | 2.718281828459045 | f32::MAX | +|:--------:|:----:|:------:|:-----------------:|:--------:| +| RYU | 3ns | 28ns | 23ns | 22ns | +| STD | 40ns | 106ns | 128ns | 110ns | + +| type=f64 | 0.0 | 0.1234 | 2.718281828459045 | f64::MAX | +|:--------:|:----:|:------:|:-----------------:|:--------:| +| RYU | 3ns | 50ns | 35ns | 32ns | +| STD | 39ns | 105ns | 128ns | 202ns | + +## Formatting + +This library tends to produce more human-readable output than the standard +library's to\_string, which never uses scientific notation. Here are two +examples: + +- *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000 +- *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123 + +Both libraries print short decimals such as 0.0000123 without scientific +notation. + ## License Licensed under either of the following at your option. diff -Nru cargo-0.33.0/vendor/ryu/src/buffer/mod.rs cargo-0.35.0/vendor/ryu/src/buffer/mod.rs --- cargo-0.33.0/vendor/ryu/src/buffer/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/buffer/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -9,7 +9,7 @@ /// /// ## Example /// -/// ```rust +/// ```edition2018 /// let mut buffer = ryu::Buffer::new(); /// let printed = buffer.format(1.234); /// assert_eq!(printed, "1.234"); diff -Nru cargo-0.33.0/vendor/ryu/src/common.rs cargo-0.35.0/vendor/ryu/src/common.rs --- cargo-0.33.0/vendor/ryu/src/common.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/common.rs 2019-05-15 11:26:24.000000000 +0000 @@ -22,31 +22,31 @@ // Returns e == 0 ? 1 : ceil(log_2(5^e)). #[cfg_attr(feature = "no-panic", inline)] -pub fn pow5bits(e: i32) -> u32 { +pub fn pow5bits(e: i32) -> i32 { // This approximation works up to the point that the multiplication overflows at e = 3529. // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater // than 2^9297. debug_assert!(e >= 0); debug_assert!(e <= 3528); - ((e as u32 * 1217359) >> 19) + 1 + (((e as u32 * 1217359) >> 19) + 1) as i32 } // Returns floor(log_10(2^e)). #[cfg_attr(feature = "no-panic", inline)] -pub fn log10_pow2(e: i32) -> i32 { +pub fn log10_pow2(e: i32) -> u32 { // The first value this approximation fails for is 2^1651 which is just greater than 10^297. debug_assert!(e >= 0); debug_assert!(e <= 1650); - ((e as u32 * 78913) >> 18) as i32 + (e as u32 * 78913) >> 18 } // Returns floor(log_10(5^e)). #[cfg_attr(feature = "no-panic", inline)] -pub fn log10_pow5(e: i32) -> i32 { +pub fn log10_pow5(e: i32) -> u32 { // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. debug_assert!(e >= 0); debug_assert!(e <= 2620); - ((e as u32 * 732923) >> 20) as i32 + (e as u32 * 732923) >> 20 } #[cfg_attr(feature = "no-panic", inline)] diff -Nru cargo-0.33.0/vendor/ryu/src/d2s.rs cargo-0.35.0/vendor/ryu/src/d2s.rs --- cargo-0.33.0/vendor/ryu/src/d2s.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/d2s.rs 2019-05-15 11:26:24.000000000 +0000 @@ -34,6 +34,7 @@ pub const DOUBLE_MANTISSA_BITS: u32 = 52; pub const DOUBLE_EXPONENT_BITS: u32 = 11; +const DOUBLE_BIAS: i32 = 1023; const DOUBLE_POW5_INV_BITCOUNT: i32 = 122; const DOUBLE_POW5_BITCOUNT: i32 = 121; @@ -183,24 +184,22 @@ #[cfg_attr(feature = "no-panic", inline)] pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 { - let bias = (1u32 << (DOUBLE_EXPONENT_BITS - 1)) - 1; - let (e2, m2) = if ieee_exponent == 0 { ( // We subtract 2 so that the bounds computation has 2 additional bits. - 1 - bias as i32 - DOUBLE_MANTISSA_BITS as i32 - 2, + 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS as i32 - 2, ieee_mantissa, ) } else { ( - ieee_exponent as i32 - bias as i32 - DOUBLE_MANTISSA_BITS as i32 - 2, + ieee_exponent as i32 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS as i32 - 2, (1u64 << DOUBLE_MANTISSA_BITS) | ieee_mantissa, ) }; let even = (m2 & 1) == 0; let accept_bounds = even; - // Step 2: Determine the interval of legal decimal representations. + // Step 2: Determine the interval of valid decimal representations. let mv = 4 * m2; // Implicit bool -> int conversion. True is 1, false is 0. let mm_shift = (ieee_mantissa != 0 || ieee_exponent <= 1) as u32; @@ -218,9 +217,9 @@ if e2 >= 0 { // I tried special-casing q == 0, but there was no effect on performance. // This expression is slightly faster than max(0, log10_pow2(e2) - 1). - let q = (log10_pow2(e2) - (e2 > 3) as i32) as u32; + let q = log10_pow2(e2) - (e2 > 3) as u32; e10 = q as i32; - let k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q as i32) as i32 - 1; + let k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q as i32) - 1; let i = -e2 + q as i32 + k; vr = mul_shift_all( m2, @@ -257,10 +256,10 @@ } } else { // This expression is slightly faster than max(0, log10_pow5(-e2) - 1). - let q = (log10_pow5(-e2) - (-e2 > 1) as i32) as u32; + let q = log10_pow5(-e2) - (-e2 > 1) as u32; e10 = q as i32 + e2; let i = -e2 - q as i32; - let k = pow5bits(i) as i32 - DOUBLE_POW5_BITCOUNT; + let k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; let j = q as i32 - k; vr = mul_shift_all( m2, @@ -300,8 +299,8 @@ } } - // Step 4: Find the shortest decimal representation in the interval of legal representations. - let mut removed = 0u32; + // Step 4: Find the shortest decimal representation in the interval of valid representations. + let mut removed = 0i32; let mut last_removed_digit = 0u8; // On average, we remove ~2 digits. let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { @@ -384,7 +383,7 @@ // We need to take vr + 1 if vr is outside bounds or we need to round up. vr + (vr == vm || round_up) as u64 }; - let exp = e10 + removed as i32; + let exp = e10 + removed; FloatingDecimal64 { exponent: exp, @@ -549,7 +548,7 @@ /// /// ## Example /// -/// ```rust +/// ```edition2018 /// let f = 1.234f64; /// /// unsafe { diff -Nru cargo-0.33.0/vendor/ryu/src/d2s_small_table.rs cargo-0.35.0/vendor/ryu/src/d2s_small_table.rs --- cargo-0.33.0/vendor/ryu/src/d2s_small_table.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/d2s_small_table.rs 2019-05-15 11:26:24.000000000 +0000 @@ -168,9 +168,9 @@ let delta = pow5bits(i as i32) - pow5bits(base2 as i32); debug_assert!(base < POW5_OFFSETS.len() as u32); ( - shiftright128(low0, sum, delta) + shiftright128(low0, sum, delta as u32) + ((*POW5_OFFSETS.get_unchecked(base as usize) >> offset) & 1) as u64, - shiftright128(sum, high1, delta), + shiftright128(sum, high1, delta as u32), ) } @@ -198,9 +198,9 @@ let delta = pow5bits(base2 as i32) - pow5bits(i as i32); debug_assert!(base < POW5_INV_OFFSETS.len() as u32); ( - shiftright128(low0, sum, delta) + shiftright128(low0, sum, delta as u32) + 1 + ((*POW5_INV_OFFSETS.get_unchecked((i / 16) as usize) >> ((i % 16) << 1)) & 3) as u64, - shiftright128(sum, high1, delta), + shiftright128(sum, high1, delta as u32), ) } diff -Nru cargo-0.33.0/vendor/ryu/src/f2s.rs cargo-0.35.0/vendor/ryu/src/f2s.rs --- cargo-0.33.0/vendor/ryu/src/f2s.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/f2s.rs 2019-05-15 11:26:24.000000000 +0000 @@ -29,6 +29,7 @@ pub const FLOAT_MANTISSA_BITS: u32 = 23; pub const FLOAT_EXPONENT_BITS: u32 = 8; +const FLOAT_BIAS: i32 = 127; const FLOAT_POW5_INV_BITCOUNT: i32 = 59; const FLOAT_POW5_BITCOUNT: i32 = 61; @@ -213,24 +214,22 @@ #[cfg_attr(feature = "no-panic", inline)] pub fn f2d(ieee_mantissa: u32, ieee_exponent: u32) -> FloatingDecimal32 { - let bias = (1u32 << (FLOAT_EXPONENT_BITS - 1)) - 1; - let (e2, m2) = if ieee_exponent == 0 { ( // We subtract 2 so that the bounds computation has 2 additional bits. - 1 - bias as i32 - FLOAT_MANTISSA_BITS as i32 - 2, + 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS as i32 - 2, ieee_mantissa, ) } else { ( - ieee_exponent as i32 - bias as i32 - FLOAT_MANTISSA_BITS as i32 - 2, + ieee_exponent as i32 - FLOAT_BIAS - FLOAT_MANTISSA_BITS as i32 - 2, (1u32 << FLOAT_MANTISSA_BITS) | ieee_mantissa, ) }; let even = (m2 & 1) == 0; let accept_bounds = even; - // Step 2: Determine the interval of legal decimal representations. + // Step 2: Determine the interval of valid decimal representations. let mv = 4 * m2; let mp = 4 * m2 + 2; // Implicit bool -> int conversion. True is 1, false is 0. @@ -246,9 +245,9 @@ let mut vr_is_trailing_zeros = false; let mut last_removed_digit = 0u8; if e2 >= 0 { - let q = log10_pow2(e2) as u32; + let q = log10_pow2(e2); e10 = q as i32; - let k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32) as i32 - 1; + let k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32) - 1; let i = -e2 + q as i32 + k; vr = mul_pow5_inv_div_pow2(mv, q, i); vp = mul_pow5_inv_div_pow2(mp, q, i); @@ -257,7 +256,7 @@ // We need to know one removed digit even if we are not going to loop below. We could use // q = X - 1 above, except that would require 33 bits for the result, and we've found that // 32-bit arithmetic is faster even on 64-bit machines. - let l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32 - 1) as i32 - 1; + let l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32 - 1) - 1; last_removed_digit = (mul_pow5_inv_div_pow2(mv, q - 1, -e2 + q as i32 - 1 + l) % 10) as u8; } @@ -273,16 +272,16 @@ } } } else { - let q = log10_pow5(-e2) as u32; + let q = log10_pow5(-e2); e10 = q as i32 + e2; let i = -e2 - q as i32; - let k = pow5bits(i) as i32 - FLOAT_POW5_BITCOUNT; + let k = pow5bits(i) - FLOAT_POW5_BITCOUNT; let mut j = q as i32 - k; vr = mul_pow5_div_pow2(mv, i as u32, j); vp = mul_pow5_div_pow2(mp, i as u32, j); vm = mul_pow5_div_pow2(mm, i as u32, j); if q != 0 && (vp - 1) / 10 <= vm / 10 { - j = q as i32 - 1 - (pow5bits(i + 1) as i32 - FLOAT_POW5_BITCOUNT); + j = q as i32 - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); last_removed_digit = (mul_pow5_div_pow2(mv, (i + 1) as u32, j) % 10) as u8; } if q <= 1 { @@ -302,8 +301,8 @@ } } - // Step 4: Find the shortest decimal representation in the interval of legal representations. - let mut removed = 0u32; + // Step 4: Find the shortest decimal representation in the interval of valid representations. + let mut removed = 0i32; let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { // General case, which happens rarely (~4.0%). while vp / 10 > vm / 10 { @@ -346,7 +345,7 @@ // We need to take vr + 1 if vr is outside bounds or we need to round up. vr + (vr == vm || last_removed_digit >= 5) as u32 }; - let exp = e10 + removed as i32; + let exp = e10 + removed; FloatingDecimal32 { exponent: exp, @@ -461,7 +460,7 @@ /// /// ## Example /// -/// ```rust +/// ```edition2018 /// let f = 1.234f32; /// /// unsafe { diff -Nru cargo-0.33.0/vendor/ryu/src/lib.rs cargo-0.35.0/vendor/ryu/src/lib.rs --- cargo-0.33.0/vendor/ryu/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -17,20 +17,78 @@ //! [upstream]: https://github.com/ulfjack/ryu //! [raw]: raw/index.html //! -//! # Examples -//! -//! ```rust -//! extern crate ryu; +//! # Example //! +//! ```edition2018 //! fn main() { //! let mut buffer = ryu::Buffer::new(); //! let printed = buffer.format(1.234); //! assert_eq!(printed, "1.234"); //! } //! ``` +//! +//! ## Performance +//! +//! You can run upstream's benchmarks with: +//! +//! ```console +//! $ git clone https://github.com/ulfjack/ryu c-ryu +//! $ cd c-ryu +//! $ bazel run -c opt //ryu/benchmark +//! ``` +//! +//! And the same benchmark against our implementation with: +//! +//! ```console +//! $ git clone https://github.com/dtolnay/ryu rust-ryu +//! $ cd rust-ryu +//! $ cargo run --example upstream_benchmark --release +//! ``` +//! +//! These benchmarks measure the average time to print a 32-bit float and average +//! time to print a 64-bit float, where the inputs are distributed as uniform random +//! bit patterns 32 and 64 bits wide. +//! +//! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API +//! all perform the same, taking around 21 nanoseconds to format a 32-bit float and +//! 31 nanoseconds to format a 64-bit float. +//! +//! There is also a Rust-specific benchmark comparing this implementation to the +//! standard library which you can run with: +//! +//! ```console +//! $ cargo bench +//! ``` +//! +//! The benchmark shows Ryu approximately 4-10x faster than the standard library +//! across a range of f32 and f64 inputs. Measurements are in nanoseconds per +//! iteration; smaller is better. +//! +//! | type=f32 | 0.0 | 0.1234 | 2.718281828459045 | f32::MAX | +//! |:--------:|:----:|:------:|:-----------------:|:--------:| +//! | RYU | 3ns | 28ns | 23ns | 22ns | +//! | STD | 40ns | 106ns | 128ns | 110ns | +//! +//! | type=f64 | 0.0 | 0.1234 | 2.718281828459045 | f64::MAX | +//! |:--------:|:----:|:------:|:-----------------:|:--------:| +//! | RYU | 3ns | 50ns | 35ns | 32ns | +//! | STD | 39ns | 105ns | 128ns | 202ns | +//! +//! ## Formatting +//! +//! This library tends to produce more human-readable output than the standard +//! library's to\_string, which never uses scientific notation. Here are two +//! examples: +//! +//! - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000 +//! - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123 +//! +//! Both libraries print short decimals such as 0.0000123 without scientific +//! notation. #![no_std] -#![doc(html_root_url = "https://docs.rs/ryu/0.2.7")] +#![doc(html_root_url = "https://docs.rs/ryu/0.2.8")] +#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr( feature = "cargo-clippy", allow( diff -Nru cargo-0.33.0/vendor/ryu/src/pretty/mod.rs cargo-0.35.0/vendor/ryu/src/pretty/mod.rs --- cargo-0.33.0/vendor/ryu/src/pretty/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/ryu/src/pretty/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -38,7 +38,7 @@ /// /// ## Example /// -/// ```rust +/// ```edition2018 /// let f = 1.234f64; /// /// unsafe { @@ -143,7 +143,7 @@ /// /// ## Example /// -/// ```rust +/// ```edition2018 /// let f = 1.234f32; /// /// unsafe { diff -Nru cargo-0.33.0/vendor/schannel/appveyor.yml cargo-0.35.0/vendor/schannel/appveyor.yml --- cargo-0.33.0/vendor/schannel/appveyor.yml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/schannel/appveyor.yml 2019-05-15 11:26:24.000000000 +0000 @@ -7,7 +7,7 @@ - TARGET: x86_64-pc-windows-gnu VERSION: nightly - TARGET: i686-pc-windows-gnu - VERSION: 1.20.0 + VERSION: 1.24.1 access_token: secure: ZxcrtxQXwszRYNN6c1ZIagczEqzmQQZeYHY58izcmF0jdq/cptxJvFUoVxDmnoqj install: diff -Nru cargo-0.33.0/vendor/schannel/.cargo-checksum.json cargo-0.35.0/vendor/schannel/.cargo-checksum.json --- cargo-0.33.0/vendor/schannel/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/schannel/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"} \ No newline at end of file +{"files":{},"package":"f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/schannel/Cargo.toml cargo-0.35.0/vendor/schannel/Cargo.toml --- cargo-0.33.0/vendor/schannel/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/schannel/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "schannel" -version = "0.1.14" +version = "0.1.15" authors = ["Steven Fackler ", "Steffen Butzer "] description = "Schannel bindings for rust, allowing SSL/TLS (e.g. https) without openssl" documentation = "https://docs.rs/schannel/0/x86_64-pc-windows-gnu/schannel/" diff -Nru cargo-0.33.0/vendor/schannel/src/cert_context.rs cargo-0.35.0/vendor/schannel/src/cert_context.rs --- cargo-0.33.0/vendor/schannel/src/cert_context.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/schannel/src/cert_context.rs 2019-05-15 11:26:24.000000000 +0000 @@ -86,6 +86,38 @@ self.get_encoded_bytes() } + /// Certificate subject public key info + pub fn subject_public_key_info_der(&self) -> io::Result> { + unsafe { + let mut len:u32 = 0; + let ok = wincrypt::CryptEncodeObjectEx(wincrypt::X509_ASN_ENCODING, + wincrypt::CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG as *const u32 as *const _, + &(*(*self.0).pCertInfo).SubjectPublicKeyInfo as *const wincrypt::CERT_PUBLIC_KEY_INFO as _, + 0, + ptr::null_mut(), + ptr::null_mut(), + &mut len as *mut _); + if ok != winapi::TRUE { + return Err(io::Error::last_os_error()); + } + if len > 0 { + let mut buf = vec![0; len as usize]; + let ok = wincrypt::CryptEncodeObjectEx(wincrypt::X509_ASN_ENCODING, + wincrypt::CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG as *const u32 as *const _, + &(*(*self.0).pCertInfo).SubjectPublicKeyInfo as *const wincrypt::CERT_PUBLIC_KEY_INFO as _, + 0, + ptr::null_mut(), + buf.as_mut_ptr() as _, + &mut len as *mut _); + if ok != winapi::TRUE { + return Err(io::Error::last_os_error()); + } + return Ok(buf); + } + } + Err(io::Error::last_os_error()) + } + /// Decodes a PEM-formatted X509 certificate. pub fn from_pem(pem: &str) -> io::Result { unsafe { diff -Nru cargo-0.33.0/vendor/serde/build.rs cargo-0.35.0/vendor/serde/build.rs --- cargo-0.33.0/vendor/serde/build.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -23,6 +23,12 @@ println!("cargo:rustc-cfg=collections_bound"); } + // core::cmp::Reverse stabilized in Rust 1.19: + // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html + if minor >= 19 { + println!("cargo:rustc-cfg=core_reverse"); + } + // CString::into_boxed_c_str stabilized in Rust 1.20: // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str if minor >= 20 { diff -Nru cargo-0.33.0/vendor/serde/.cargo-checksum.json cargo-0.35.0/vendor/serde/.cargo-checksum.json --- cargo-0.33.0/vendor/serde/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"2e20fde37801e83c891a2dc4ebd3b81f0da4d1fb67a9e0a2a3b921e2536a58ee"} \ No newline at end of file +{"files":{},"package":"a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/serde/Cargo.toml cargo-0.35.0/vendor/serde/Cargo.toml --- cargo-0.33.0/vendor/serde/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "serde" -version = "1.0.87" +version = "1.0.91" authors = ["Erick Tryzelaar ", "David Tolnay "] build = "build.rs" include = ["Cargo.toml", "build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] diff -Nru cargo-0.33.0/vendor/serde/src/de/impls.rs cargo-0.35.0/vendor/serde/src/de/impls.rs --- cargo-0.33.0/vendor/serde/src/de/impls.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/de/impls.rs 2019-05-15 11:26:24.000000000 +0000 @@ -578,6 +578,9 @@ #[cfg(all(feature = "std", de_boxed_c_str))] forwarded_impl!((), Box, CString::into_boxed_c_str); +#[cfg(core_reverse)] +forwarded_impl!((T), Reverse, Reverse); + //////////////////////////////////////////////////////////////////////////////// struct OptionVisitor { diff -Nru cargo-0.33.0/vendor/serde/src/de/mod.rs cargo-0.35.0/vendor/serde/src/de/mod.rs --- cargo-0.33.0/vendor/serde/src/de/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/de/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -59,13 +59,13 @@ //! - Box\ //! - Box\<\[T\]\> //! - Box\ -//! - Rc\ -//! - Arc\ //! - Cow\<'a, T\> //! - Cell\ //! - RefCell\ //! - Mutex\ //! - RwLock\ +//! - Rc\ *(if* features = ["rc"] *is enabled)* +//! - Arc\ *(if* features = ["rc"] *is enabled)* //! - **Collection types**: //! - BTreeMap\ //! - BTreeSet\ diff -Nru cargo-0.33.0/vendor/serde/src/de/value.rs cargo-0.35.0/vendor/serde/src/de/value.rs --- cargo-0.33.0/vendor/serde/src/de/value.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/de/value.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1287,10 +1287,40 @@ visitor.visit_map(self.map) } + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer +where + A: de::MapAccess<'de>, +{ + type Error = A::Error; + type Variant = private::MapAsEnum; + + fn variant_seed(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.map.next_key_seed(seed)? { + Some(key) => Ok((key, private::map_as_enum(self.map))), + None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")), + } } } @@ -1299,7 +1329,7 @@ mod private { use lib::*; - use de::{self, Unexpected}; + use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor}; #[derive(Clone, Debug)] pub struct UnitOnly { @@ -1360,6 +1390,92 @@ } } + #[derive(Clone, Debug)] + pub struct MapAsEnum { + map: A, + } + + pub fn map_as_enum(map: A) -> MapAsEnum { + MapAsEnum { map: map } + } + + impl<'de, A> VariantAccess<'de> for MapAsEnum + where + A: MapAccess<'de>, + { + type Error = A::Error; + + fn unit_variant(mut self) -> Result<(), Self::Error> { + self.map.next_value() + } + + fn newtype_variant_seed(mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + self.map.next_value_seed(seed) + } + + fn tuple_variant(mut self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.map.next_value_seed(SeedTupleVariant { + len: len, + visitor: visitor, + }) + } + + fn struct_variant( + mut self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.map + .next_value_seed(SeedStructVariant { visitor: visitor }) + } + } + + struct SeedTupleVariant { + len: usize, + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple(self.len, self.visitor) + } + } + + struct SeedStructVariant { + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedStructVariant + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(self.visitor) + } + } + /// Avoid having to restate the generic types on `MapDeserializer`. The /// `Iterator::Item` contains enough information to figure out K and V. pub trait Pair { diff -Nru cargo-0.33.0/vendor/serde/src/lib.rs cargo-0.35.0/vendor/serde/src/lib.rs --- cargo-0.33.0/vendor/serde/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -46,7 +46,6 @@ //! - [BSON], the data storage and network transfer format used by MongoDB. //! - [Avro], a binary format used within Apache Hadoop, with support for schema //! definition. -//! - [Hjson], a variant of JSON designed to be readable and writable by humans. //! - [JSON5], A superset of JSON including some productions from ES5. //! - [URL], the x-www-form-urlencoded format. //! - [Envy], a way to deserialize environment variables into Rust structs. @@ -64,7 +63,6 @@ //! [RON]: https://github.com/ron-rs/ron //! [BSON]: https://github.com/zonyitoo/bson-rs //! [Avro]: https://github.com/flavray/avro-rs -//! [Hjson]: https://github.com/laktak/hjson-rust //! [JSON5]: https://github.com/callum-oakley/json5-rs //! [URL]: https://github.com/nox/serde_urlencoded //! [Envy]: https://github.com/softprops/envy @@ -75,7 +73,7 @@ //////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/serde/1.0.87")] +#![doc(html_root_url = "https://docs.rs/serde/1.0.91")] // Support using Serde without the standard library! #![cfg_attr(not(feature = "std"), no_std)] // Unstable functionality only if the user asks for it. For tracking and @@ -202,17 +200,20 @@ #[cfg(feature = "std")] pub use std::time::{SystemTime, UNIX_EPOCH}; - #[cfg(any(core_duration, feature = "std"))] - pub use self::core::time::Duration; - - #[cfg(range_inclusive)] - pub use self::core::ops::RangeInclusive; - #[cfg(all(feature = "std", collections_bound))] pub use std::collections::Bound; + #[cfg(core_reverse)] + pub use self::core::cmp::Reverse; + #[cfg(ops_bound)] pub use self::core::ops::Bound; + + #[cfg(range_inclusive)] + pub use self::core::ops::RangeInclusive; + + #[cfg(any(core_duration, feature = "std"))] + pub use self::core::time::Duration; } //////////////////////////////////////////////////////////////////////////////// diff -Nru cargo-0.33.0/vendor/serde/src/private/de.rs cargo-0.35.0/vendor/serde/src/private/de.rs --- cargo-0.33.0/vendor/serde/src/private/de.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/private/de.rs 2019-05-15 11:26:24.000000000 +0000 @@ -2709,7 +2709,7 @@ } Err(Error::custom(format_args!( - "no variant of enum {} not found in flattened data", + "no variant of enum {} found in flattened data", name ))) } diff -Nru cargo-0.33.0/vendor/serde/src/ser/impls.rs cargo-0.35.0/vendor/serde/src/ser/impls.rs --- cargo-0.33.0/vendor/serde/src/ser/impls.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/ser/impls.rs 2019-05-15 11:26:24.000000000 +0000 @@ -160,10 +160,12 @@ } } -array_impls!(01 02 03 04 05 06 07 08 09 10 - 11 12 13 14 15 16 17 18 19 20 - 21 22 23 24 25 26 27 28 29 30 - 31 32); +array_impls! { + 01 02 03 04 05 06 07 08 09 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 +} //////////////////////////////////////////////////////////////////////////////// @@ -814,6 +816,20 @@ where T: Serialize, { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(core_reverse)] +impl Serialize for Reverse +where + T: Serialize, +{ #[inline] fn serialize(&self, serializer: S) -> Result where diff -Nru cargo-0.33.0/vendor/serde/src/ser/mod.rs cargo-0.35.0/vendor/serde/src/ser/mod.rs --- cargo-0.33.0/vendor/serde/src/ser/mod.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde/src/ser/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -56,13 +56,13 @@ //! - PhantomData\ //! - **Wrapper types**: //! - Box\ -//! - Rc\ -//! - Arc\ //! - Cow\<'a, T\> //! - Cell\ //! - RefCell\ //! - Mutex\ //! - RwLock\ +//! - Rc\ *(if* features = ["rc"] *is enabled)* +//! - Arc\ *(if* features = ["rc"] *is enabled)* //! - **Collection types**: //! - BTreeMap\ //! - BTreeSet\ diff -Nru cargo-0.33.0/vendor/serde_derive/.cargo-checksum.json cargo-0.35.0/vendor/serde_derive/.cargo-checksum.json --- cargo-0.33.0/vendor/serde_derive/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"633e97856567e518b59ffb2ad7c7a4fd4c5d91d9c7f32dd38a27b2bf7e8114ea"} \ No newline at end of file +{"files":{},"package":"101b495b109a3e3ca8c4cbe44cf62391527cdfb6ba15821c5ce80bcd5ea23f9f"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/serde_derive/Cargo.toml cargo-0.35.0/vendor/serde_derive/Cargo.toml --- cargo-0.33.0/vendor/serde_derive/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "serde_derive" -version = "1.0.87" +version = "1.0.91" authors = ["Erick Tryzelaar ", "David Tolnay "] include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff -Nru cargo-0.33.0/vendor/serde_derive/src/de.rs cargo-0.35.0/vendor/serde_derive/src/de.rs --- cargo-0.33.0/vendor/serde_derive/src/de.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/de.rs 2019-05-15 11:26:24.000000000 +0000 @@ -27,15 +27,16 @@ let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); let body = Stmts(deserialize_body(&cont, ¶ms)); let delife = params.borrowed.de_lifetime(); + let serde = cont.attrs.serde_path(); let impl_block = if let Some(remote) = cont.attrs.remote() { let vis = &input.vis; let used = pretend::pretend_used(&cont); quote! { impl #de_impl_generics #ident #ty_generics #where_clause { - #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error> + #vis fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result<#remote #ty_generics, __D::Error> where - __D: _serde::Deserializer<#delife>, + __D: #serde::Deserializer<#delife>, { #used #body @@ -47,10 +48,10 @@ quote! { #[automatically_derived] - impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause { - fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result + impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause { + fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result where - __D: _serde::Deserializer<#delife>, + __D: #serde::Deserializer<#delife>, { #body } @@ -60,7 +61,12 @@ } }; - Ok(dummy::wrap_in_const("DESERIALIZE", ident, impl_block)) + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + "DESERIALIZE", + ident, + impl_block, + )) } fn precondition(cx: &Ctxt, cont: &Container) { @@ -2384,7 +2390,12 @@ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); quote!({ #wrapper - try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value + match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::export::Ok(__wrapper) => __wrapper.value, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + } }) } }; @@ -2451,7 +2462,7 @@ let extract_collected = fields_names .iter() - .filter(|&&(field, _)| field.attrs.flatten()) + .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing()) .map(|&(field, ref name)| { let field_ty = field.ty; let func = match field.attrs.deserialize_with() { @@ -2471,7 +2482,9 @@ let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() { Some(quote! { - if let _serde::export::Some(_serde::export::Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() { + if let _serde::export::Some(_serde::export::Some((__key, _))) = + __collect.into_iter().filter(_serde::export::Option::is_some).next() + { if let _serde::export::Some(__key) = __key.as_str() { return _serde::export::Err( _serde::de::Error::custom(format_args!("unknown field `{}`", &__key))); @@ -2615,7 +2628,12 @@ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); quote!({ #wrapper - self.place.#member = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value + self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::export::Ok(__wrapper) => __wrapper.value, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + }; }) } }; diff -Nru cargo-0.33.0/vendor/serde_derive/src/dummy.rs cargo-0.35.0/vendor/serde_derive/src/dummy.rs --- cargo-0.33.0/vendor/serde_derive/src/dummy.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/dummy.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,8 +1,14 @@ use proc_macro2::{Ident, Span, TokenStream}; +use syn; use try; -pub fn wrap_in_const(trait_: &str, ty: &Ident, code: TokenStream) -> TokenStream { +pub fn wrap_in_const( + serde_path: Option<&syn::Path>, + trait_: &str, + ty: &Ident, + code: TokenStream, +) -> TokenStream { let try_replacement = try::replacement(); let dummy_const = Ident::new( @@ -10,13 +16,22 @@ Span::call_site(), ); - quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + let use_serde = match serde_path { + Some(path) => quote! { + use #path as _serde; + }, + None => quote! { #[allow(unknown_lints)] #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] #[allow(rust_2018_idioms)] extern crate serde as _serde; + }, + }; + + quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + #use_serde #try_replacement #code }; diff -Nru cargo-0.33.0/vendor/serde_derive/src/internals/attr.rs cargo-0.35.0/vendor/serde_derive/src/internals/attr.rs --- cargo-0.33.0/vendor/serde_derive/src/internals/attr.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/internals/attr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,7 @@ use internals::Ctxt; use proc_macro2::{Group, Span, TokenStream, TokenTree}; use quote::ToTokens; +use std::borrow::Cow; use std::collections::BTreeSet; use std::str::FromStr; use syn; @@ -218,6 +219,7 @@ remote: Option, identifier: Identifier, has_flatten: bool, + serde_path: Option, } /// Styles of representing an enum. @@ -298,6 +300,7 @@ let mut remote = Attr::none(cx, "remote"); let mut field_identifier = BoolAttr::none(cx, "field_identifier"); let mut variant_identifier = BoolAttr::none(cx, "variant_identifier"); + let mut serde_path = Attr::none(cx, "crate"); for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -582,6 +585,13 @@ variant_identifier.set_true(word); } + // Parse `#[serde(crate = "foo")]` + Meta(NameValue(ref m)) if m.ident == "crate" => { + if let Ok(path) = parse_lit_into_path(cx, &m.ident, &m.lit) { + serde_path.set(&m.ident, path) + } + } + Meta(ref meta_item) => { cx.error_spanned_by( meta_item.name(), @@ -613,6 +623,7 @@ remote: remote.get(), identifier: decide_identifier(cx, item, field_identifier, variant_identifier), has_flatten: false, + serde_path: serde_path.get(), } } @@ -671,6 +682,15 @@ pub fn mark_has_flatten(&mut self) { self.has_flatten = true; } + + pub fn custom_serde_path(&self) -> Option<&syn::Path> { + self.serde_path.as_ref() + } + + pub fn serde_path(&self) -> Cow { + self.custom_serde_path() + .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed) + } } fn decide_tag( diff -Nru cargo-0.33.0/vendor/serde_derive/src/internals/check.rs cargo-0.35.0/vendor/serde_derive/src/internals/check.rs --- cargo-0.33.0/vendor/serde_derive/src/internals/check.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/internals/check.rs 2019-05-15 11:26:24.000000000 +0000 @@ -76,25 +76,6 @@ } _ => {} } - if field.attrs.skip_serializing() { - cx.error_spanned_by( - field.original, - "#[serde(flatten)] can not be combined with \ - #[serde(skip_serializing)]", - ); - } else if field.attrs.skip_serializing_if().is_some() { - cx.error_spanned_by( - field.original, - "#[serde(flatten)] can not be combined with \ - #[serde(skip_serializing_if = \"...\")]", - ); - } else if field.attrs.skip_deserializing() { - cx.error_spanned_by( - field.original, - "#[serde(flatten)] can not be combined with \ - #[serde(skip_deserializing)]", - ); - } } /// The `other` attribute must be used at most once and it must be the last diff -Nru cargo-0.33.0/vendor/serde_derive/src/lib.rs cargo-0.35.0/vendor/serde_derive/src/lib.rs --- cargo-0.33.0/vendor/serde_derive/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -13,14 +13,14 @@ //! //! [https://serde.rs/derive.html]: https://serde.rs/derive.html -#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.87")] +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.91")] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] // Ignored clippy lints #![cfg_attr( feature = "cargo-clippy", allow( - cyclomatic_complexity, + cognitive_complexity, enum_variant_names, needless_pass_by_value, redundant_field_names, diff -Nru cargo-0.33.0/vendor/serde_derive/src/ser.rs cargo-0.35.0/vendor/serde_derive/src/ser.rs --- cargo-0.33.0/vendor/serde_derive/src/ser.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_derive/src/ser.rs 2019-05-15 11:26:24.000000000 +0000 @@ -22,15 +22,16 @@ let params = Parameters::new(&cont); let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); let body = Stmts(serialize_body(&cont, ¶ms)); + let serde = cont.attrs.serde_path(); let impl_block = if let Some(remote) = cont.attrs.remote() { let vis = &input.vis; let used = pretend::pretend_used(&cont); quote! { impl #impl_generics #ident #ty_generics #where_clause { - #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error> where - __S: _serde::Serializer, + __S: #serde::Serializer, { #used #body @@ -40,10 +41,10 @@ } else { quote! { #[automatically_derived] - impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { - fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error> where - __S: _serde::Serializer, + __S: #serde::Serializer, { #body } @@ -51,7 +52,12 @@ } }; - Ok(dummy::wrap_in_const("SERIALIZE", ident, impl_block)) + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + "SERIALIZE", + ident, + impl_block, + )) } fn precondition(cx: &Ctxt, cont: &Container) { diff -Nru cargo-0.33.0/vendor/serde_json/.cargo-checksum.json cargo-0.35.0/vendor/serde_json/.cargo-checksum.json --- cargo-0.33.0/vendor/serde_json/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_json/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9"} \ No newline at end of file +{"files":{},"package":"5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/serde_json/Cargo.toml cargo-0.35.0/vendor/serde_json/Cargo.toml --- cargo-0.33.0/vendor/serde_json/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_json/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "serde_json" -version = "1.0.38" +version = "1.0.39" authors = ["Erick Tryzelaar ", "David Tolnay "] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] description = "A JSON serialization file format" @@ -39,6 +39,9 @@ [dependencies.serde] version = "1.0.60" +[dev-dependencies.automod] +version = "0.1" + [dev-dependencies.compiletest_rs] version = "0.3" features = ["stable"] diff -Nru cargo-0.33.0/vendor/serde_json/src/error.rs cargo-0.35.0/vendor/serde_json/src/error.rs --- cargo-0.33.0/vendor/serde_json/src/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_json/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -3,8 +3,8 @@ use std::error; use std::fmt::{self, Debug, Display}; use std::io; -use std::str::FromStr; use std::result; +use std::str::FromStr; use serde::de; use serde::ser; diff -Nru cargo-0.33.0/vendor/serde_json/src/lib.rs cargo-0.35.0/vendor/serde_json/src/lib.rs --- cargo-0.33.0/vendor/serde_json/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_json/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -294,7 +294,7 @@ //! [macro]: https://docs.serde.rs/serde_json/macro.json.html //! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ -#![doc(html_root_url = "https://docs.rs/serde_json/1.0.38")] +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.39")] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] // Ignored clippy lints diff -Nru cargo-0.33.0/vendor/serde_json/src/number.rs cargo-0.35.0/vendor/serde_json/src/number.rs --- cargo-0.33.0/vendor/serde_json/src/number.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/serde_json/src/number.rs 2019-05-15 11:26:24.000000000 +0000 @@ -473,7 +473,7 @@ } else if let Some(i) = self.as_i64() { return visitor.visit_i64(i); } else if let Some(f) = self.as_f64() { - if f.to_string() == self.n { + if ryu::Buffer::new().format(f) == self.n || f.to_string() == self.n { return visitor.visit_f64(f); } } diff -Nru cargo-0.33.0/vendor/sized-chunks/.cargo-checksum.json cargo-0.35.0/vendor/sized-chunks/.cargo-checksum.json --- cargo-0.33.0/vendor/sized-chunks/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1 @@ +{"files":{},"package":"9d3e7f23bad2d6694e0f46f5e470ec27eb07b8f3e8b309a4b0dc17501928b9f2"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/sized-chunks/Cargo.toml cargo-0.35.0/vendor/sized-chunks/Cargo.toml --- cargo-0.33.0/vendor/sized-chunks/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,34 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "sized-chunks" +version = "0.1.3" +authors = ["Bodil Stokke "] +exclude = ["release.toml", "proptest-regressions/**"] +description = "Efficient sized chunk datatypes" +documentation = "http://docs.rs/sized-chunks" +readme = "./README.md" +keywords = ["sparse-array"] +categories = ["data-structures"] +license = "MPL-2.0+" +repository = "https://github.com/bodil/sized-chunks" +[dependencies.typenum] +version = "1.10.0" +[dev-dependencies.proptest] +version = "0.9.1" + +[dev-dependencies.proptest-derive] +version = "0.1.0" +[badges.travis-ci] +repository = "bodil/sized-chunks" diff -Nru cargo-0.33.0/vendor/sized-chunks/CHANGELOG.md cargo-0.35.0/vendor/sized-chunks/CHANGELOG.md --- cargo-0.33.0/vendor/sized-chunks/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,43 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic +Versioning](http://semver.org/spec/v2.0.0.html). + +## [0.1.3] - 2019-04-12 + +### ADDED + +- `SparseChunk` now has a default length of `U64`. +- `Chunk` now has `PartialEq` defined for anything that can be borrowed as a + slice. +- `SparseChunk` likewise has `PartialEq` defined for `BTreeMap` and + `HashMap`. These are intended for debugging and aren't optimally + `efficient. +- `Chunk` and `SparseChunk` now have a new method `capacity()` which returns its + maximum capacity (the number in the type) as a usize. +- Added an `entries()` method to `SparseChunk`. +- `SparseChunk` now has a `Debug` implementation. + +### FIXED + +- Extensive integration tests were added for `Chunk` and `SparseChunk`. +- `Chunk::clear` is now very slightly faster. + +## [0.1.2] - 2019-03-11 + +### FIXED + +- Fixed an alignment issue in `Chunk::drain_from_back`. (#1) + +## [0.1.1] - 2019-02-19 + +### FIXED + +- Some 2018 edition issues. + +## [0.1.0] - 2019-02-19 + +Initial release. diff -Nru cargo-0.33.0/vendor/sized-chunks/CODE_OF_CONDUCT.md cargo-0.35.0/vendor/sized-chunks/CODE_OF_CONDUCT.md --- cargo-0.33.0/vendor/sized-chunks/CODE_OF_CONDUCT.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/CODE_OF_CONDUCT.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at admin@immutable.rs. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org diff -Nru cargo-0.33.0/vendor/sized-chunks/LICENCE.md cargo-0.35.0/vendor/sized-chunks/LICENCE.md --- cargo-0.33.0/vendor/sized-chunks/LICENCE.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/LICENCE.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,355 @@ +Mozilla Public License Version 2.0 +================================== + +### 1. Definitions + +**1.1. “Contributor”** + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +**1.2. “Contributor Version”** + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +**1.3. “Contribution”** + means Covered Software of a particular Contributor. + +**1.4. “Covered Software”** + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +**1.5. “Incompatible With Secondary Licenses”** + means + +* **(a)** that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or +* **(b)** that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +**1.6. “Executable Form”** + means any form of the work other than Source Code Form. + +**1.7. “Larger Work”** + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +**1.8. “License”** + means this document. + +**1.9. “Licensable”** + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +**1.10. “Modifications”** + means any of the following: + +* **(a)** any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or +* **(b)** any new file in Source Code Form that contains any Covered + Software. + +**1.11. “Patent Claims” of a Contributor** + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +**1.12. “Secondary License”** + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +**1.13. “Source Code Form”** + means the form of the work preferred for making modifications. + +**1.14. “You” (or “Your”)** + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, “control” means **(a)** the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or **(b)** ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + + +### 2. License Grants and Conditions + +#### 2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +* **(a)** under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and +* **(b)** under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +#### 2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +#### 2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +* **(a)** for any code that a Contributor has removed from Covered Software; + or +* **(b)** for infringements caused by: **(i)** Your and any other third party's + modifications of Covered Software, or **(ii)** the combination of its + Contributions with other software (except as part of its Contributor + Version); or +* **(c)** under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +#### 2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +#### 2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +#### 2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +#### 2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + + +### 3. Responsibilities + +#### 3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +#### 3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +* **(a)** such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +* **(b)** You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +#### 3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +#### 3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +#### 3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + + +### 4. Inability to Comply Due to Statute or Regulation + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: **(a)** comply with +the terms of this License to the maximum extent possible; and **(b)** +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + + +### 5. Termination + +**5.1.** The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated **(a)** provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and **(b)** on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +**5.2.** If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + + +### 6. Disclaimer of Warranty + +> Covered Software is provided under this License on an “as is” +> basis, without warranty of any kind, either expressed, implied, or +> statutory, including, without limitation, warranties that the +> Covered Software is free of defects, merchantable, fit for a +> particular purpose or non-infringing. The entire risk as to the +> quality and performance of the Covered Software is with You. +> Should any Covered Software prove defective in any respect, You +> (not any Contributor) assume the cost of any necessary servicing, +> repair, or correction. This disclaimer of warranty constitutes an +> essential part of this License. No use of any Covered Software is +> authorized under this License except under this disclaimer. + +### 7. Limitation of Liability + +> Under no circumstances and under no legal theory, whether tort +> (including negligence), contract, or otherwise, shall any +> Contributor, or anyone who distributes Covered Software as +> permitted above, be liable to You for any direct, indirect, +> special, incidental, or consequential damages of any character +> including, without limitation, damages for lost profits, loss of +> goodwill, work stoppage, computer failure or malfunction, or any +> and all other commercial damages or losses, even if such party +> shall have been informed of the possibility of such damages. This +> limitation of liability shall not apply to liability for death or +> personal injury resulting from such party's negligence to the +> extent applicable law prohibits such limitation. Some +> jurisdictions do not allow the exclusion or limitation of +> incidental or consequential damages, so this exclusion and +> limitation may not apply to You. + + +### 8. Litigation + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + + +### 9. Miscellaneous + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + + +### 10. Versions of the License + +#### 10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +#### 10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +#### 10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +## Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +## Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff -Nru cargo-0.33.0/vendor/sized-chunks/README.md cargo-0.35.0/vendor/sized-chunks/README.md --- cargo-0.33.0/vendor/sized-chunks/README.md 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,35 @@ +# sized-chunks + +Various fixed length array data types, designed for [immutable.rs]. + +## Overview + +This crate provides the core building blocks for the immutable data structures +in [immutable.rs]: a sized array with O(1) amortised double ended push/pop and +smarter insert/remove performance (used by `im::Vector` and `im::OrdMap`), and a +fixed size sparse array (used by `im::HashMap`). + +In a nutshell, this crate contains the unsafe bits from [immutable.rs], which +may or may not be useful to anyone else, and have been split out for ease of +auditing. + +## Documentation + +* [API docs](https://docs.rs/sized-chunks) + +## Licence + +Copyright 2019 Bodil Stokke + +This software is subject to the terms of the Mozilla Public +License, v. 2.0. If a copy of the MPL was not distributed with this +file, You can obtain one at http://mozilla.org/MPL/2.0/. + +## Code of Conduct + +Please note that this project is released with a [Contributor Code of +Conduct][coc]. By participating in this project you agree to abide by its +terms. + +[immutable.rs]: https://immutable.rs/ +[coc]: https://github.com/bodil/sized-chunks/blob/master/CODE_OF_CONDUCT.md diff -Nru cargo-0.33.0/vendor/sized-chunks/src/bitmap.rs cargo-0.35.0/vendor/sized-chunks/src/bitmap.rs --- cargo-0.33.0/vendor/sized-chunks/src/bitmap.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/bitmap.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,165 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//! A fixed capacity sparse array. +//! +//! See [`Bitmap`](struct.Bitmap.html) + +use std::fmt::{Debug, Error, Formatter}; + +use crate::types::Bits; + +/// A compact array of bits. +/// +/// The bitmap is stored as a primitive type, so the maximum value of `Size` is +/// currently 128, corresponding to a type of `u128`. The type used to store the +/// bitmap will be the minimum unsigned integer type required to fit the number +/// of bits required, from `u8` to `u128`. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] extern crate sized_chunks; +/// # extern crate typenum; +/// # use sized_chunks::bitmap::Bitmap; +/// # use typenum::U10; +/// # fn main() { +/// let mut bitmap = Bitmap::::new(); +/// assert_eq!(bitmap.set(5, true), false); +/// assert_eq!(bitmap.set(5, true), true); +/// assert_eq!(bitmap.get(5), true); +/// assert_eq!(bitmap.get(6), false); +/// assert_eq!(bitmap.len(), 1); +/// assert_eq!(bitmap.set(3, true), false); +/// assert_eq!(bitmap.len(), 2); +/// assert_eq!(bitmap.first_index(), Some(3)); +/// # } +/// ``` +pub struct Bitmap { + data: Size::Store, +} + +impl Clone for Bitmap { + fn clone(&self) -> Self { + Bitmap { data: self.data } + } +} + +impl Copy for Bitmap {} + +impl Default for Bitmap { + fn default() -> Self { + Bitmap { + data: Size::Store::default(), + } + } +} + +impl PartialEq for Bitmap { + fn eq(&self, other: &Self) -> bool { + self.data == other.data + } +} + +impl Debug for Bitmap { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + self.data.fmt(f) + } +} + +impl Bitmap { + /// Construct an empty bitmap. + #[inline] + pub fn new() -> Self { + Self::default() + } + + /// Count the number of `true` bits in the bitmap. + #[inline] + pub fn len(self) -> usize { + Size::len(&self.data) + } + + /// Test if the bitmap contains only `false` bits. + #[inline] + pub fn is_empty(self) -> bool { + self.first_index().is_none() + } + + /// Get the value of the bit at a given index. + #[inline] + pub fn get(self, index: usize) -> bool { + Size::get(&self.data, index) + } + + /// Set the value of the bit at a given index. + /// + /// Returns the previous value of the bit. + #[inline] + pub fn set(&mut self, index: usize, value: bool) -> bool { + Size::set(&mut self.data, index, value) + } + + /// Find the index of the first `true` bit in the bitmap. + #[inline] + pub fn first_index(self) -> Option { + Size::first_index(&self.data) + } +} + +impl IntoIterator for Bitmap { + type Item = usize; + type IntoIter = Iter; + + fn into_iter(self) -> Self::IntoIter { + Iter { + index: 0, + data: self.data, + } + } +} + +pub struct Iter { + index: usize, + data: Size::Store, +} + +impl Iterator for Iter { + type Item = usize; + + fn next(&mut self) -> Option { + if self.index >= Size::USIZE { + return None; + } + if Size::get(&self.data, self.index) { + self.index += 1; + Some(self.index - 1) + } else { + self.index += 1; + self.next() + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use proptest::collection::btree_set; + use proptest::proptest; + use typenum::U64; + + proptest! { + #[test] + fn get_set_and_iter(bits in btree_set(0..64usize, 0..64)) { + let mut bitmap = Bitmap::::new(); + for i in &bits { + bitmap.set(*i, true); + } + for i in 0..64 { + assert_eq!(bitmap.get(i), bits.contains(&i)); + } + assert!(bitmap.into_iter().eq(bits.into_iter())); + } + } +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/lib.rs cargo-0.35.0/vendor/sized-chunks/src/lib.rs --- cargo-0.33.0/vendor/sized-chunks/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,18 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +pub mod bitmap; +pub mod sized_chunk; +pub mod sparse_chunk; +pub mod types; + +#[cfg(test)] +mod tests; + +#[doc(inline)] +pub use crate::bitmap::Bitmap; +#[doc(inline)] +pub use crate::sized_chunk::Chunk; +#[doc(inline)] +pub use crate::sparse_chunk::SparseChunk; diff -Nru cargo-0.33.0/vendor/sized-chunks/src/sized_chunk.rs cargo-0.35.0/vendor/sized-chunks/src/sized_chunk.rs --- cargo-0.33.0/vendor/sized-chunks/src/sized_chunk.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/sized_chunk.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,1178 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//! A fixed capacity smart array. +//! +//! See [`Chunk`](struct.Chunk.html) + +use std::borrow::{Borrow, BorrowMut}; +use std::cmp::Ordering; +use std::fmt::{Debug, Error, Formatter}; +use std::hash::{Hash, Hasher}; +use std::io; +use std::iter::{FromIterator, FusedIterator}; +use std::mem::{self, replace, ManuallyDrop}; +use std::ops::{Deref, DerefMut, Index, IndexMut}; +use std::ptr; +use std::slice::{ + from_raw_parts, from_raw_parts_mut, Iter as SliceIter, IterMut as SliceIterMut, SliceIndex, +}; + +use typenum::U64; + +use crate::types::ChunkLength; + +/// A fixed capacity smart array. +/// +/// An inline array of items with a variable length but a fixed, preallocated +/// capacity given by the `N` type, which must be an [`Unsigned`][Unsigned] type +/// level numeral. +/// +/// It's 'smart' because it's able to reorganise its contents based on expected +/// behaviour. If you construct one using `push_back`, it will be laid out like +/// a `Vec` with space at the end. If you `push_front` it will start filling in +/// values from the back instead of the front, so that you still get linear time +/// push as long as you don't reverse direction. If you do, and there's no room +/// at the end you're pushing to, it'll shift its contents over to the other +/// side, creating more space to push into. This technique is tuned for +/// `Chunk`'s expected use case in [im::Vector]: usually, chunks always see +/// either `push_front` or `push_back`, but not both unless they move around +/// inside the tree, in which case they're able to reorganise themselves with +/// reasonable efficiency to suit their new usage patterns. +/// +/// It maintains a `left` index and a `right` index instead of a simple length +/// counter in order to accomplish this, much like a ring buffer would, except +/// that the `Chunk` keeps all its items sequentially in memory so that you can +/// always get a `&[A]` slice for them, at the price of the occasional +/// reordering operation. The allocated size of a `Chunk` is thus `usize` * 2 + +/// `A` * `N`. +/// +/// This technique also lets us choose to shift the shortest side to account for +/// the inserted or removed element when performing insert and remove +/// operations, unlike `Vec` where you always need to shift the right hand side. +/// +/// Unlike a `Vec`, the `Chunk` has a fixed capacity and cannot grow beyond it. +/// Being intended for low level use, it expects you to know or test whether +/// you're pushing to a full array, and has an API more geared towards panics +/// than returning `Option`s, on the assumption that you know what you're doing. +/// Of course, if you don't, you can expect it to panic immediately rather than +/// do something undefined and usually bad. +/// +/// ## Isn't this just a less efficient ring buffer? +/// +/// You might be wondering why you would want to use this data structure rather +/// than a [ring buffer], which is similar but doesn't need to shift its content +/// around when it hits the sides of the allocated buffer. The answer is that +/// `Chunk` can be dereferenced into a slice, while a ring buffer can not. If +/// you don't need to be able to do that, a ring buffer will generally be the +/// more efficient choice. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] extern crate sized_chunks; +/// # extern crate typenum; +/// # use sized_chunks::Chunk; +/// # use typenum::U64; +/// # fn main() { +/// // Construct a chunk with a 64 item capacity +/// let mut chunk = Chunk::::new(); +/// // Fill it with descending numbers +/// chunk.extend((0..64).rev()); +/// // It derefs to a slice so we can use standard slice methods +/// chunk.sort(); +/// // It's got all the amenities like `FromIterator` and `Eq` +/// let expected: Chunk = (0..64).collect(); +/// assert_eq!(expected, chunk); +/// # } +/// ``` +/// +/// [Unsigned]: https://docs.rs/typenum/1.10.0/typenum/marker_traits/trait.Unsigned.html +/// [im::Vector]: https://docs.rs/im/latest/im/vector/enum.Vector.html +/// [ring buffer]: https://en.wikipedia.org/wiki/Circular_buffer +pub struct Chunk +where + N: ChunkLength, +{ + left: usize, + right: usize, + data: ManuallyDrop, +} + +impl Drop for Chunk +where + N: ChunkLength, +{ + fn drop(&mut self) { + if mem::needs_drop::() { + for i in self.left..self.right { + unsafe { Chunk::force_drop(i, self) } + } + } + } +} + +impl Clone for Chunk +where + A: Clone, + N: ChunkLength, +{ + fn clone(&self) -> Self { + let mut out = Self::new(); + out.left = self.left; + out.right = self.right; + for index in self.left..self.right { + unsafe { Chunk::force_write(index, self.values()[index].clone(), &mut out) } + } + out + } +} + +impl Chunk +where + N: ChunkLength, +{ + /// Construct a new empty chunk. + pub fn new() -> Self { + let mut chunk: Self; + unsafe { + chunk = mem::zeroed(); + ptr::write(&mut chunk.left, 0); + ptr::write(&mut chunk.right, 0); + } + chunk + } + + /// Construct a new chunk with one item. + pub fn unit(value: A) -> Self { + let mut chunk: Self; + unsafe { + chunk = mem::zeroed(); + ptr::write(&mut chunk.left, 0); + ptr::write(&mut chunk.right, 1); + Chunk::force_write(0, value, &mut chunk); + } + chunk + } + + /// Construct a new chunk with two items. + pub fn pair(left: A, right: A) -> Self { + let mut chunk: Self; + unsafe { + chunk = mem::zeroed(); + ptr::write(&mut chunk.left, 0); + ptr::write(&mut chunk.right, 2); + Chunk::force_write(0, left, &mut chunk); + Chunk::force_write(1, right, &mut chunk); + } + chunk + } + + /// Construct a new chunk and move every item from `other` into the new + /// chunk. + /// + /// Time: O(n) + pub fn drain_from(other: &mut Self) -> Self { + let other_len = other.len(); + Self::from_front(other, other_len) + } + + /// Construct a new chunk and populate it by taking `count` items from the + /// iterator `iter`. + /// + /// Panics if the iterator contains less than `count` items. + /// + /// Time: O(n) + pub fn collect_from(iter: &mut I, mut count: usize) -> Self + where + I: Iterator, + { + let mut chunk = Self::new(); + while count > 0 { + count -= 1; + chunk.push_back( + iter.next() + .expect("Chunk::collect_from: underfull iterator"), + ); + } + chunk + } + + /// Construct a new chunk and populate it by taking `count` items from the + /// front of `other`. + /// + /// Time: O(n) for the number of items moved + pub fn from_front(other: &mut Self, count: usize) -> Self { + let other_len = other.len(); + debug_assert!(count <= other_len); + let mut chunk = Self::new(); + unsafe { Chunk::force_copy_to(other.left, 0, count, other, &mut chunk) }; + chunk.right = count; + other.left += count; + chunk + } + + /// Construct a new chunk and populate it by taking `count` items from the + /// back of `other`. + /// + /// Time: O(n) for the number of items moved + pub fn from_back(other: &mut Self, count: usize) -> Self { + let other_len = other.len(); + debug_assert!(count <= other_len); + let mut chunk = Self::new(); + unsafe { Chunk::force_copy_to(other.right - count, 0, count, other, &mut chunk) }; + chunk.right = count; + other.right -= count; + chunk + } + + /// Get the length of the chunk. + #[inline] + pub fn len(&self) -> usize { + self.right - self.left + } + + /// Get the capacity of a chunk of this type. + #[inline] + pub fn capacity() -> usize { + N::USIZE + } + + /// Test if the chunk is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.left == self.right + } + + /// Test if the chunk is at capacity. + #[inline] + pub fn is_full(&self) -> bool { + self.left == 0 && self.right == N::USIZE + } + + #[inline] + fn values(&self) -> &[A] { + unsafe { + from_raw_parts( + &self.data as *const ManuallyDrop as *const A, + N::USIZE, + ) + } + } + + #[inline] + fn values_mut(&mut self) -> &mut [A] { + unsafe { + from_raw_parts_mut( + &mut self.data as *mut ManuallyDrop as *mut A, + N::USIZE, + ) + } + } + + /// Copy the value at an index, discarding ownership of the copied value + #[inline] + unsafe fn force_read(index: usize, chunk: &mut Self) -> A { + ptr::read(&chunk.values()[index]) + } + + /// Write a value at an index without trying to drop what's already there + #[inline] + unsafe fn force_write(index: usize, value: A, chunk: &mut Self) { + ptr::write(&mut chunk.values_mut()[index], value) + } + + /// Drop the value at an index + #[inline] + unsafe fn force_drop(index: usize, chunk: &mut Self) { + ptr::drop_in_place(&mut chunk.values_mut()[index]) + } + + /// Copy a range within a chunk + #[inline] + unsafe fn force_copy(from: usize, to: usize, count: usize, chunk: &mut Self) { + if count > 0 { + ptr::copy(&chunk.values()[from], &mut chunk.values_mut()[to], count) + } + } + + /// Copy a range between chunks + #[inline] + unsafe fn force_copy_to( + from: usize, + to: usize, + count: usize, + chunk: &mut Self, + other: &mut Self, + ) { + if count > 0 { + ptr::copy_nonoverlapping(&chunk.values()[from], &mut other.values_mut()[to], count) + } + } + + /// Push an item to the front of the chunk. + /// + /// Panics if the capacity of the chunk is exceeded. + /// + /// Time: O(1) if there's room at the front, O(n) otherwise + pub fn push_front(&mut self, value: A) { + if self.is_full() { + panic!("Chunk::push_front: can't push to full chunk"); + } + if self.is_empty() { + self.left = N::USIZE; + self.right = N::USIZE; + } else if self.left == 0 { + self.left = N::USIZE - self.right; + unsafe { Chunk::force_copy(0, self.left, self.right, self) }; + self.right = N::USIZE; + } + self.left -= 1; + unsafe { Chunk::force_write(self.left, value, self) } + } + + /// Push an item to the back of the chunk. + /// + /// Panics if the capacity of the chunk is exceeded. + /// + /// Time: O(1) if there's room at the back, O(n) otherwise + pub fn push_back(&mut self, value: A) { + if self.is_full() { + panic!("Chunk::push_back: can't push to full chunk"); + } + if self.is_empty() { + self.left = 0; + self.right = 0; + } else if self.right == N::USIZE { + unsafe { Chunk::force_copy(self.left, 0, self.len(), self) }; + self.right = N::USIZE - self.left; + self.left = 0; + } + unsafe { Chunk::force_write(self.right, value, self) } + self.right += 1; + } + + /// Pop an item off the front of the chunk. + /// + /// Panics if the chunk is empty. + /// + /// Time: O(1) + pub fn pop_front(&mut self) -> A { + if self.is_empty() { + panic!("Chunk::pop_front: can't pop from empty chunk"); + } else { + let value = unsafe { Chunk::force_read(self.left, self) }; + self.left += 1; + value + } + } + + /// Pop an item off the back of the chunk. + /// + /// Panics if the chunk is empty. + /// + /// Time: O(1) + pub fn pop_back(&mut self) -> A { + if self.is_empty() { + panic!("Chunk::pop_back: can't pop from empty chunk"); + } else { + self.right -= 1; + unsafe { Chunk::force_read(self.right, self) } + } + } + + /// Discard all items up to but not including `index`. + /// + /// Panics if `index` is out of bounds. + /// + /// Time: O(n) for the number of items dropped + pub fn drop_left(&mut self, index: usize) { + if index > 0 { + if index > self.len() { + panic!("Chunk::drop_left: index out of bounds"); + } + let start = self.left; + for i in start..(start + index) { + unsafe { Chunk::force_drop(i, self) } + } + self.left += index; + } + } + + /// Discard all items from `index` onward. + /// + /// Panics if `index` is out of bounds. + /// + /// Time: O(n) for the number of items dropped + pub fn drop_right(&mut self, index: usize) { + if index > self.len() { + panic!("Chunk::drop_right: index out of bounds"); + } + if index == self.len() { + return; + } + let start = self.left + index; + for i in start..self.right { + unsafe { Chunk::force_drop(i, self) } + } + self.right = start; + } + + /// Split a chunk into two, the original chunk containing + /// everything up to `index` and the returned chunk containing + /// everything from `index` onwards. + /// + /// Panics if `index` is out of bounds. + /// + /// Time: O(n) for the number of items in the new chunk + pub fn split_off(&mut self, index: usize) -> Self { + if index > self.len() { + panic!("Chunk::split: index out of bounds"); + } + if index == self.len() { + return Self::new(); + } + let mut right_chunk = Self::new(); + let start = self.left + index; + let len = self.right - start; + unsafe { Chunk::force_copy_to(start, 0, len, self, &mut right_chunk) }; + right_chunk.right = len; + self.right = start; + right_chunk + } + + /// Remove all items from `other` and append them to the back of `self`. + /// + /// Panics if the capacity of the chunk is exceeded. + /// + /// Time: O(n) for the number of items moved + pub fn append(&mut self, other: &mut Self) { + let self_len = self.len(); + let other_len = other.len(); + if self_len + other_len > N::USIZE { + panic!("Chunk::append: chunk size overflow"); + } + if self.right + other_len > N::USIZE { + unsafe { Chunk::force_copy(self.left, 0, self_len, self) }; + self.right -= self.left; + self.left = 0; + } + unsafe { Chunk::force_copy_to(other.left, self.right, other_len, other, self) }; + self.right += other_len; + other.left = 0; + other.right = 0; + } + + /// Remove `count` items from the front of `other` and append them to the + /// back of `self`. + /// + /// Panics if `self` doesn't have `count` items left, or if `other` has + /// fewer than `count` items. + /// + /// Time: O(n) for the number of items moved + pub fn drain_from_front(&mut self, other: &mut Self, count: usize) { + let self_len = self.len(); + let other_len = other.len(); + debug_assert!(self_len + count <= N::USIZE); + debug_assert!(other_len >= count); + if self.right + count > N::USIZE { + unsafe { Chunk::force_copy(self.left, 0, self_len, self) }; + self.right -= self.left; + self.left = 0; + } + unsafe { Chunk::force_copy_to(other.left, self.right, count, other, self) }; + self.right += count; + other.left += count; + } + + /// Remove `count` items from the back of `other` and append them to the + /// front of `self`. + /// + /// Panics if `self` doesn't have `count` items left, or if `other` has + /// fewer than `count` items. + /// + /// Time: O(n) for the number of items moved + pub fn drain_from_back(&mut self, other: &mut Self, count: usize) { + let self_len = self.len(); + let other_len = other.len(); + debug_assert!(self_len + count <= N::USIZE); + debug_assert!(other_len >= count); + if self.left < count { + unsafe { Chunk::force_copy(self.left, N::USIZE - self_len, self_len, self) }; + self.left = N::USIZE - self_len; + self.right = N::USIZE; + } + unsafe { Chunk::force_copy_to(other.right - count, self.left - count, count, other, self) }; + self.left -= count; + other.right -= count; + } + + /// Update the value at index `index`, returning the old value. + /// + /// Panics if `index` is out of bounds. + /// + /// Time: O(1) + pub fn set(&mut self, index: usize, value: A) -> A { + replace(&mut self[index], value) + } + + /// Insert a new value at index `index`, shifting all the following values + /// to the right. + /// + /// Panics if the index is out of bounds. + /// + /// Time: O(n) for the number of items shifted + pub fn insert(&mut self, index: usize, value: A) { + if self.is_full() { + panic!("Chunk::insert: chunk is full"); + } + if index > self.len() { + panic!("Chunk::insert: index out of bounds"); + } + let real_index = index + self.left; + let left_size = index; + let right_size = self.right - real_index; + if self.right == N::USIZE || (self.left > 0 && left_size < right_size) { + unsafe { + Chunk::force_copy(self.left, self.left - 1, left_size, self); + Chunk::force_write(real_index - 1, value, self); + } + self.left -= 1; + } else { + unsafe { + Chunk::force_copy(real_index, real_index + 1, right_size, self); + Chunk::force_write(real_index, value, self); + } + self.right += 1; + } + } + + /// Remove the value at index `index`, shifting all the following values to + /// the left. + /// + /// Returns the removed value. + /// + /// Panics if the index is out of bounds. + /// + /// Time: O(n) for the number of items shifted + pub fn remove(&mut self, index: usize) -> A { + if index >= self.len() { + panic!("Chunk::remove: index out of bounds"); + } + let real_index = index + self.left; + let value = unsafe { Chunk::force_read(real_index, self) }; + let left_size = index; + let right_size = self.right - real_index - 1; + if left_size < right_size { + unsafe { Chunk::force_copy(self.left, self.left + 1, left_size, self) }; + self.left += 1; + } else { + unsafe { Chunk::force_copy(real_index + 1, real_index, right_size, self) }; + self.right -= 1; + } + value + } + + /// Construct an iterator that drains values from the front of the chunk. + pub fn drain(&mut self) -> Drain<'_, A, N> { + Drain { chunk: self } + } + + /// Discard the contents of the chunk. + /// + /// Time: O(n) + pub fn clear(&mut self) { + for i in self.left..self.right { + unsafe { Chunk::force_drop(i, self) } + } + self.left = 0; + self.right = 0; + } + + /// Get a reference to the contents of the chunk as a slice. + pub fn as_slice(&self) -> &[A] { + unsafe { + from_raw_parts( + (&self.data as *const ManuallyDrop as *const A).add(self.left), + self.len(), + ) + } + } + + /// Get a reference to the contents of the chunk as a mutable slice. + pub fn as_mut_slice(&mut self) -> &mut [A] { + unsafe { + from_raw_parts_mut( + (&mut self.data as *mut ManuallyDrop as *mut A).add(self.left), + self.len(), + ) + } + } +} + +impl Default for Chunk +where + N: ChunkLength, +{ + fn default() -> Self { + Self::new() + } +} + +impl Index for Chunk +where + I: SliceIndex<[A]>, + N: ChunkLength, +{ + type Output = I::Output; + fn index(&self, index: I) -> &Self::Output { + self.as_slice().index(index) + } +} + +impl IndexMut for Chunk +where + I: SliceIndex<[A]>, + N: ChunkLength, +{ + fn index_mut(&mut self, index: I) -> &mut Self::Output { + self.as_mut_slice().index_mut(index) + } +} + +impl Debug for Chunk +where + A: Debug, + N: ChunkLength, +{ + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + f.write_str("Chunk")?; + f.debug_list().entries(self.iter()).finish() + } +} + +impl Hash for Chunk +where + A: Hash, + N: ChunkLength, +{ + fn hash(&self, hasher: &mut H) + where + H: Hasher, + { + for item in self { + item.hash(hasher) + } + } +} + +impl PartialEq for Chunk +where + Slice: Borrow<[A]>, + A: PartialEq, + N: ChunkLength, +{ + fn eq(&self, other: &Slice) -> bool { + self.as_slice() == other.borrow() + } +} + +impl Eq for Chunk +where + A: Eq, + N: ChunkLength, +{ +} + +impl PartialOrd for Chunk +where + A: PartialOrd, + N: ChunkLength, +{ + fn partial_cmp(&self, other: &Self) -> Option { + self.iter().partial_cmp(other.iter()) + } +} + +impl Ord for Chunk +where + A: Ord, + N: ChunkLength, +{ + fn cmp(&self, other: &Self) -> Ordering { + self.iter().cmp(other.iter()) + } +} + +impl io::Write for Chunk +where + N: ChunkLength, +{ + fn write(&mut self, buf: &[u8]) -> io::Result { + let old_len = self.len(); + self.extend(buf.iter().cloned().take(N::USIZE - old_len)); + Ok(self.len() - old_len) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Borrow<[A]> for Chunk +where + N: ChunkLength, +{ + fn borrow(&self) -> &[A] { + self.as_slice() + } +} + +impl BorrowMut<[A]> for Chunk +where + N: ChunkLength, +{ + fn borrow_mut(&mut self) -> &mut [A] { + self.as_mut_slice() + } +} + +impl AsRef<[A]> for Chunk +where + N: ChunkLength, +{ + fn as_ref(&self) -> &[A] { + self.as_slice() + } +} + +impl AsMut<[A]> for Chunk +where + N: ChunkLength, +{ + fn as_mut(&mut self) -> &mut [A] { + self.as_mut_slice() + } +} + +impl Deref for Chunk +where + N: ChunkLength, +{ + type Target = [A]; + + fn deref(&self) -> &Self::Target { + self.as_slice() + } +} + +impl DerefMut for Chunk +where + N: ChunkLength, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() + } +} + +impl FromIterator for Chunk +where + N: ChunkLength, +{ + fn from_iter(it: I) -> Self + where + I: IntoIterator, + { + let mut chunk = Self::new(); + for item in it { + chunk.push_back(item); + } + chunk + } +} + +impl<'a, A, N> IntoIterator for &'a Chunk +where + N: ChunkLength, +{ + type Item = &'a A; + type IntoIter = SliceIter<'a, A>; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, A, N> IntoIterator for &'a mut Chunk +where + N: ChunkLength, +{ + type Item = &'a mut A; + type IntoIter = SliceIterMut<'a, A>; + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +impl Extend for Chunk +where + N: ChunkLength, +{ + /// Append the contents of the iterator to the back of the chunk. + /// + /// Panics if the chunk exceeds its capacity. + /// + /// Time: O(n) for the length of the iterator + fn extend(&mut self, it: I) + where + I: IntoIterator, + { + for item in it { + self.push_back(item); + } + } +} + +impl<'a, A, N> Extend<&'a A> for Chunk +where + A: 'a + Copy, + N: ChunkLength, +{ + /// Append the contents of the iterator to the back of the chunk. + /// + /// Panics if the chunk exceeds its capacity. + /// + /// Time: O(n) for the length of the iterator + fn extend(&mut self, it: I) + where + I: IntoIterator, + { + for item in it { + self.push_back(*item); + } + } +} + +pub struct Iter +where + N: ChunkLength, +{ + chunk: Chunk, +} + +impl Iterator for Iter +where + N: ChunkLength, +{ + type Item = A; + fn next(&mut self) -> Option { + if self.chunk.is_empty() { + None + } else { + Some(self.chunk.pop_front()) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.chunk.len(), Some(self.chunk.len())) + } +} + +impl DoubleEndedIterator for Iter +where + N: ChunkLength, +{ + fn next_back(&mut self) -> Option { + if self.chunk.is_empty() { + None + } else { + Some(self.chunk.pop_back()) + } + } +} + +impl ExactSizeIterator for Iter where N: ChunkLength {} + +impl FusedIterator for Iter where N: ChunkLength {} + +impl IntoIterator for Chunk +where + N: ChunkLength, +{ + type Item = A; + type IntoIter = Iter; + + fn into_iter(self) -> Self::IntoIter { + Iter { chunk: self } + } +} + +pub struct Drain<'a, A, N> +where + A: 'a, + N: ChunkLength + 'a, +{ + chunk: &'a mut Chunk, +} + +impl<'a, A, N> Iterator for Drain<'a, A, N> +where + A: 'a, + N: ChunkLength + 'a, +{ + type Item = A; + + fn next(&mut self) -> Option { + if self.chunk.is_empty() { + None + } else { + Some(self.chunk.pop_front()) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.chunk.len(), Some(self.chunk.len())) + } +} + +impl<'a, A, N> ExactSizeIterator for Drain<'a, A, N> +where + A: 'a, + N: ChunkLength + 'a, +{ +} + +impl<'a, A, N> FusedIterator for Drain<'a, A, N> +where + A: 'a, + N: ChunkLength + 'a, +{ +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn is_full() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + assert_eq!(false, chunk.is_full()); + chunk.push_back(i); + } + assert_eq!(true, chunk.is_full()); + } + + #[test] + fn push_back_front() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 12..20 { + chunk.push_back(i); + } + assert_eq!(8, chunk.len()); + for i in (0..12).rev() { + chunk.push_front(i); + } + assert_eq!(20, chunk.len()); + for i in 20..32 { + chunk.push_back(i); + } + assert_eq!(32, chunk.len()); + let right: Vec = chunk.into_iter().collect(); + let left: Vec = (0..32).collect(); + assert_eq!(left, right); + } + + #[test] + fn push_and_pop() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + chunk.push_back(i); + } + for i in 0..64 { + assert_eq!(i, chunk.pop_front()); + } + for i in 0..64 { + chunk.push_front(i); + } + for i in 0..64 { + assert_eq!(i, chunk.pop_back()); + } + } + + #[test] + fn drop_left() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..6 { + chunk.push_back(i); + } + chunk.drop_left(3); + let vec: Vec = chunk.into_iter().collect(); + assert_eq!(vec![3, 4, 5], vec); + } + + #[test] + fn drop_right() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..6 { + chunk.push_back(i); + } + chunk.drop_right(3); + let vec: Vec = chunk.into_iter().collect(); + assert_eq!(vec![0, 1, 2], vec); + } + + #[test] + fn split_off() { + let mut left = Chunk::<_, U64>::new(); + for i in 0..6 { + left.push_back(i); + } + let right = left.split_off(3); + let left_vec: Vec = left.into_iter().collect(); + let right_vec: Vec = right.into_iter().collect(); + assert_eq!(vec![0, 1, 2], left_vec); + assert_eq!(vec![3, 4, 5], right_vec); + } + + #[test] + fn append() { + let mut left = Chunk::<_, U64>::new(); + for i in 0..32 { + left.push_back(i); + } + let mut right = Chunk::<_, U64>::new(); + for i in (32..64).rev() { + right.push_front(i); + } + left.append(&mut right); + let out_vec: Vec = left.into_iter().collect(); + let should_vec: Vec = (0..64).collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn ref_iter() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + chunk.push_back(i); + } + let out_vec: Vec<&i32> = chunk.iter().collect(); + let should_vec_p: Vec = (0..64).collect(); + let should_vec: Vec<&i32> = should_vec_p.iter().collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn mut_ref_iter() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + chunk.push_back(i); + } + let out_vec: Vec<&mut i32> = chunk.iter_mut().collect(); + let mut should_vec_p: Vec = (0..64).collect(); + let should_vec: Vec<&mut i32> = should_vec_p.iter_mut().collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn consuming_iter() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + chunk.push_back(i); + } + let out_vec: Vec = chunk.into_iter().collect(); + let should_vec: Vec = (0..64).collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn insert_middle() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..32 { + chunk.push_back(i); + } + for i in 33..64 { + chunk.push_back(i); + } + chunk.insert(32, 32); + let out_vec: Vec = chunk.into_iter().collect(); + let should_vec: Vec = (0..64).collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn insert_back() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..63 { + chunk.push_back(i); + } + chunk.insert(63, 63); + let out_vec: Vec = chunk.into_iter().collect(); + let should_vec: Vec = (0..64).collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn insert_front() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 1..64 { + chunk.push_front(64 - i); + } + chunk.insert(0, 0); + let out_vec: Vec = chunk.into_iter().collect(); + let should_vec: Vec = (0..64).collect(); + assert_eq!(should_vec, out_vec); + } + + #[test] + fn remove_value() { + let mut chunk = Chunk::<_, U64>::new(); + for i in 0..64 { + chunk.push_back(i); + } + chunk.remove(32); + let out_vec: Vec = chunk.into_iter().collect(); + let should_vec: Vec = (0..32).chain(33..64).collect(); + assert_eq!(should_vec, out_vec); + } + + use std::sync::atomic::{AtomicUsize, Ordering}; + + struct DropTest<'a> { + counter: &'a AtomicUsize, + } + + impl<'a> DropTest<'a> { + fn new(counter: &'a AtomicUsize) -> Self { + counter.fetch_add(1, Ordering::Relaxed); + DropTest { counter } + } + } + + impl<'a> Drop for DropTest<'a> { + fn drop(&mut self) { + self.counter.fetch_sub(1, Ordering::Relaxed); + } + } + + #[test] + fn dropping() { + let counter = AtomicUsize::new(0); + { + let mut chunk: Chunk = Chunk::new(); + for _i in 0..20 { + chunk.push_back(DropTest::new(&counter)) + } + for _i in 0..20 { + chunk.push_front(DropTest::new(&counter)) + } + assert_eq!(40, counter.load(Ordering::Relaxed)); + for _i in 0..10 { + chunk.pop_back(); + } + assert_eq!(30, counter.load(Ordering::Relaxed)); + } + assert_eq!(0, counter.load(Ordering::Relaxed)); + } +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/sparse_chunk.rs cargo-0.35.0/vendor/sized-chunks/src/sparse_chunk.rs --- cargo-0.33.0/vendor/sized-chunks/src/sparse_chunk.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/sparse_chunk.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,454 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//! A fixed capacity sparse array. +//! +//! See [`SparseChunk`](struct.SparseChunk.html) + +use std::collections::{BTreeMap, HashMap}; +use std::fmt::{Debug, Error, Formatter}; +use std::mem::{self, ManuallyDrop}; +use std::ops::Index; +use std::ops::IndexMut; +use std::ptr; +use std::slice::{from_raw_parts, from_raw_parts_mut}; + +use typenum::U64; + +use crate::bitmap::{Bitmap, Iter as BitmapIter}; +use crate::types::{Bits, ChunkLength}; + +/// A fixed capacity sparse array. +/// +/// An inline sparse array of up to `N` items of type `A`, where `N` is an +/// [`Unsigned`][Unsigned] type level numeral. You can think of it as an array +/// of `Option`, where the discriminant (whether the value is `Some` or +/// `None`) is kept in a bitmap instead of adjacent to the value. +/// +/// Because the bitmap is kept in a primitive type, the maximum value of `N` is +/// currently 128, corresponding to a type of `u128`. The type of the bitmap +/// will be the minimum unsigned integer type required to fit the number of bits +/// required. Thus, disregarding memory alignment rules, the allocated size of a +/// `SparseChunk` will be `uX` + `A` * `N` where `uX` is the type of the +/// discriminant bitmap, either `u8`, `u16`, `u32`, `u64` or `u128`. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] extern crate sized_chunks; +/// # extern crate typenum; +/// # use sized_chunks::SparseChunk; +/// # use typenum::U20; +/// # fn main() { +/// // Construct a chunk with a 20 item capacity +/// let mut chunk = SparseChunk::::new(); +/// // Set the 18th index to the value 5. +/// chunk.insert(18, 5); +/// // Set the 5th index to the value 23. +/// chunk.insert(5, 23); +/// +/// assert_eq!(chunk.len(), 2); +/// assert_eq!(chunk.get(5), Some(&23)); +/// assert_eq!(chunk.get(6), None); +/// assert_eq!(chunk.get(18), Some(&5)); +/// # } +/// ``` +/// +/// [Unsigned]: https://docs.rs/typenum/1.10.0/typenum/marker_traits/trait.Unsigned.html +pub struct SparseChunk = U64> { + map: Bitmap, + data: ManuallyDrop, +} + +impl> Drop for SparseChunk { + fn drop(&mut self) { + if mem::needs_drop::() { + for index in self.map { + unsafe { SparseChunk::force_drop(index, self) } + } + } + } +} + +impl> Clone for SparseChunk { + fn clone(&self) -> Self { + let mut out = Self::new(); + for index in self.map { + out.insert(index, self[index].clone()); + } + out + } +} + +impl> SparseChunk { + #[inline] + fn values(&self) -> &[A] { + unsafe { + from_raw_parts( + &self.data as *const ManuallyDrop as *const A, + N::USIZE, + ) + } + } + + #[inline] + fn values_mut(&mut self) -> &mut [A] { + unsafe { + from_raw_parts_mut( + &mut self.data as *mut ManuallyDrop as *mut A, + N::USIZE, + ) + } + } + + /// Copy the value at an index, discarding ownership of the copied value + #[inline] + unsafe fn force_read(index: usize, chunk: &Self) -> A { + ptr::read(&chunk.values()[index as usize]) + } + + /// Write a value at an index without trying to drop what's already there + #[inline] + unsafe fn force_write(index: usize, value: A, chunk: &mut Self) { + ptr::write(&mut chunk.values_mut()[index as usize], value) + } + + /// Drop the value at an index + #[inline] + unsafe fn force_drop(index: usize, chunk: &mut Self) { + ptr::drop_in_place(&mut chunk.values_mut()[index]) + } + + /// Construct a new empty chunk. + pub fn new() -> Self { + let mut chunk: Self; + unsafe { + chunk = mem::zeroed(); + ptr::write(&mut chunk.map, Bitmap::new()); + } + chunk + } + + /// Construct a new chunk with one item. + pub fn unit(index: usize, value: A) -> Self { + let mut chunk = Self::new(); + chunk.insert(index, value); + chunk + } + + /// Construct a new chunk with two items. + pub fn pair(index1: usize, value1: A, index2: usize, value2: A) -> Self { + let mut chunk = Self::new(); + chunk.insert(index1, value1); + chunk.insert(index2, value2); + chunk + } + + /// Get the length of the chunk. + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Get the capacity of a chunk of this type. + #[inline] + pub fn capacity() -> usize { + N::USIZE + } + + /// Test if the chunk is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.map.len() == 0 + } + + /// Test if the chunk is at capacity. + #[inline] + pub fn is_full(&self) -> bool { + self.len() == N::USIZE + } + + /// Insert a new value at a given index. + /// + /// Returns the previous value at that index, if any. + pub fn insert(&mut self, index: usize, value: A) -> Option { + if index >= N::USIZE { + panic!("SparseChunk::insert: index out of bounds"); + } + let prev = if self.map.set(index, true) { + Some(unsafe { SparseChunk::force_read(index, self) }) + } else { + None + }; + unsafe { SparseChunk::force_write(index, value, self) }; + prev + } + + /// Remove the value at a given index. + /// + /// Returns the value, or `None` if the index had no value. + pub fn remove(&mut self, index: usize) -> Option { + if index >= N::USIZE { + panic!("SparseChunk::remove: index out of bounds"); + } + if self.map.set(index, false) { + Some(unsafe { SparseChunk::force_read(index, self) }) + } else { + None + } + } + + /// Remove the first value present in the array. + /// + /// Returns the value that was removed, or `None` if the array was empty. + pub fn pop(&mut self) -> Option { + self.first_index().and_then(|index| self.remove(index)) + } + + /// Get the value at a given index. + pub fn get(&self, index: usize) -> Option<&A> { + if index >= N::USIZE { + return None; + } + if self.map.get(index) { + Some(&self.values()[index]) + } else { + None + } + } + + /// Get a mutable reference to the value at a given index. + pub fn get_mut(&mut self, index: usize) -> Option<&mut A> { + if index >= N::USIZE { + return None; + } + if self.map.get(index) { + Some(&mut self.values_mut()[index]) + } else { + None + } + } + + /// Make an iterator over the indices which contain values. + pub fn indices(&self) -> BitmapIter { + self.map.into_iter() + } + + /// Find the first index which contains a value. + pub fn first_index(&self) -> Option { + self.map.first_index() + } + + /// Make an iterator of references to the values contained in the array. + pub fn iter(&self) -> Iter<'_, A, N> { + Iter { + indices: self.indices(), + chunk: self, + } + } + + /// Make an iterator of mutable references to the values contained in the + /// array. + pub fn iter_mut(&mut self) -> IterMut<'_, A, N> { + IterMut { + indices: self.indices(), + chunk: self, + } + } + + /// Turn the chunk into an iterator over the values contained within it. + pub fn drain(self) -> Drain { + Drain { chunk: self } + } + + /// Make an iterator of pairs of indices and references to the values + /// contained in the array. + pub fn entries(&self) -> impl Iterator { + self.indices().zip(self.iter()) + } +} + +impl> Index for SparseChunk { + type Output = A; + + #[inline] + fn index(&self, index: usize) -> &Self::Output { + self.get(index).unwrap() + } +} + +impl> IndexMut for SparseChunk { + #[inline] + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.get_mut(index).unwrap() + } +} + +impl> IntoIterator for SparseChunk { + type Item = A; + type IntoIter = Drain; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.drain() + } +} + +impl PartialEq for SparseChunk +where + A: PartialEq, + N: Bits + ChunkLength, +{ + fn eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + for index in self.indices() { + if self.get(index) != other.get(index) { + return false; + } + } + true + } +} + +impl PartialEq> for SparseChunk +where + A: PartialEq, + N: Bits + ChunkLength, +{ + fn eq(&self, other: &BTreeMap) -> bool { + if self.len() != other.len() { + return false; + } + for index in 0..N::USIZE { + if self.get(index) != other.get(&index) { + return false; + } + } + true + } +} + +impl PartialEq> for SparseChunk +where + A: PartialEq, + N: Bits + ChunkLength, +{ + fn eq(&self, other: &HashMap) -> bool { + if self.len() != other.len() { + return false; + } + for index in 0..N::USIZE { + if self.get(index) != other.get(&index) { + return false; + } + } + true + } +} + +impl Eq for SparseChunk +where + A: Eq, + N: Bits + ChunkLength, +{ +} + +impl Debug for SparseChunk +where + A: Debug, + N: Bits + ChunkLength, +{ + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + f.write_str("SparseChunk")?; + f.debug_map().entries(self.entries()).finish() + } +} + +pub struct Iter<'a, A: 'a, N: 'a + Bits + ChunkLength> { + indices: BitmapIter, + chunk: &'a SparseChunk, +} + +impl<'a, A, N: Bits + ChunkLength> Iterator for Iter<'a, A, N> { + type Item = &'a A; + + fn next(&mut self) -> Option { + self.indices.next().map(|index| &self.chunk.values()[index]) + } +} + +pub struct IterMut<'a, A: 'a, N: 'a + Bits + ChunkLength> { + indices: BitmapIter, + chunk: &'a mut SparseChunk, +} + +impl<'a, A, N: Bits + ChunkLength> Iterator for IterMut<'a, A, N> { + type Item = &'a mut A; + + fn next(&mut self) -> Option { + if let Some(index) = self.indices.next() { + unsafe { + let p: *mut A = &mut self.chunk.values_mut()[index]; + Some(&mut *p) + } + } else { + None + } + } +} + +pub struct Drain> { + chunk: SparseChunk, +} + +impl<'a, A, N: Bits + ChunkLength> Iterator for Drain { + type Item = A; + + fn next(&mut self) -> Option { + self.chunk.pop() + } +} + +#[cfg(test)] +mod test { + use super::*; + use typenum::U32; + + #[test] + fn insert_remove_iterate() { + let mut chunk: SparseChunk<_, U32> = SparseChunk::new(); + assert_eq!(None, chunk.insert(5, 5)); + assert_eq!(None, chunk.insert(1, 1)); + assert_eq!(None, chunk.insert(24, 42)); + assert_eq!(None, chunk.insert(22, 22)); + assert_eq!(Some(42), chunk.insert(24, 24)); + assert_eq!(None, chunk.insert(31, 31)); + assert_eq!(Some(24), chunk.remove(24)); + assert_eq!(4, chunk.len()); + let indices: Vec<_> = chunk.indices().collect(); + assert_eq!(vec![1, 5, 22, 31], indices); + let values: Vec<_> = chunk.into_iter().collect(); + assert_eq!(vec![1, 5, 22, 31], values); + } + + #[test] + fn clone_chunk() { + let mut chunk: SparseChunk<_, U32> = SparseChunk::new(); + assert_eq!(None, chunk.insert(5, 5)); + assert_eq!(None, chunk.insert(1, 1)); + assert_eq!(None, chunk.insert(24, 42)); + assert_eq!(None, chunk.insert(22, 22)); + let cloned = chunk.clone(); + let right_indices: Vec<_> = chunk.indices().collect(); + let left_indices: Vec<_> = cloned.indices().collect(); + let right: Vec<_> = chunk.into_iter().collect(); + let left: Vec<_> = cloned.into_iter().collect(); + assert_eq!(left, right); + assert_eq!(left_indices, right_indices); + assert_eq!(vec![1, 5, 22, 24], left_indices); + assert_eq!(vec![1, 5, 22, 24], right_indices); + } +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/tests/mod.rs cargo-0.35.0/vendor/sized-chunks/src/tests/mod.rs --- cargo-0.33.0/vendor/sized-chunks/src/tests/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/tests/mod.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,9 @@ +mod sized_chunk; +mod sparse_chunk; + +pub fn action_count() -> usize { + std::env::var("ACTION_COUNT") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(100) +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/tests/sized_chunk.rs cargo-0.35.0/vendor/sized-chunks/src/tests/sized_chunk.rs --- cargo-0.33.0/vendor/sized-chunks/src/tests/sized_chunk.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/tests/sized_chunk.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,286 @@ +#![allow(clippy::unit_arg)] + +use std::fmt::Debug; +use std::iter::FromIterator; +use std::panic::{catch_unwind, AssertUnwindSafe}; + +use proptest::{arbitrary::any, collection::vec, prelude::*, proptest}; +use proptest_derive::Arbitrary; + +use crate::sized_chunk::Chunk; + +#[derive(Debug)] +struct InputVec(Vec); + +impl InputVec { + fn unwrap(self) -> Vec { + self.0 + } +} + +impl Arbitrary for InputVec +where + A: Arbitrary + Debug, + ::Strategy: 'static, +{ + type Parameters = usize; + type Strategy = BoxedStrategy>; + fn arbitrary_with(_: Self::Parameters) -> Self::Strategy { + #[allow(clippy::redundant_closure)] + proptest::collection::vec(any::(), 0..64) + .prop_map(|v| InputVec(v)) + .boxed() + } +} + +#[derive(Arbitrary, Debug)] +enum Construct +where + A: Arbitrary, + ::Strategy: 'static, +{ + Empty, + Single(A), + Pair((A, A)), + DrainFrom(InputVec), + CollectFrom(InputVec, usize), + FromFront(InputVec, usize), + FromBack(InputVec, usize), +} + +#[derive(Arbitrary, Debug)] +enum Action +where + A: Arbitrary, + ::Strategy: 'static, +{ + PushFront(A), + PushBack(A), + PopFront, + PopBack, + DropLeft(usize), + DropRight(usize), + SplitOff(usize), + Append(Construct), + DrainFromFront(Construct, usize), + DrainFromBack(Construct, usize), + Set(usize, A), + Insert(usize, A), + Remove(usize), + Drain, + Clear, +} + +impl Construct +where + A: Arbitrary + Clone + Debug + Eq, + ::Strategy: 'static, +{ + fn make(self) -> Chunk { + match self { + Construct::Empty => { + let out = Chunk::new(); + assert!(out.is_empty()); + out + } + Construct::Single(value) => { + let out = Chunk::unit(value.clone()); + assert_eq!(out, vec![value]); + out + } + Construct::Pair((left, right)) => { + let out = Chunk::pair(left.clone(), right.clone()); + assert_eq!(out, vec![left, right]); + out + } + Construct::DrainFrom(vec) => { + let vec = vec.unwrap(); + let mut source = Chunk::from_iter(vec.iter().cloned()); + let out = Chunk::drain_from(&mut source); + assert!(source.is_empty()); + assert_eq!(out, vec); + out + } + Construct::CollectFrom(vec, len) => { + let mut vec = vec.unwrap(); + if vec.is_empty() { + return Chunk::new(); + } + let len = len % vec.len(); + let mut source = vec.clone().into_iter(); + let out = Chunk::collect_from(&mut source, len); + let expected_remainder = vec.split_off(len); + let remainder: Vec<_> = source.collect(); + assert_eq!(expected_remainder, remainder); + assert_eq!(out, vec); + out + } + Construct::FromFront(vec, len) => { + let mut vec = vec.unwrap(); + if vec.is_empty() { + return Chunk::new(); + } + let len = len % vec.len(); + let mut source = Chunk::from_iter(vec.iter().cloned()); + let out = Chunk::from_front(&mut source, len); + let remainder = vec.split_off(len); + assert_eq!(source, remainder); + assert_eq!(out, vec); + out + } + Construct::FromBack(vec, len) => { + let mut vec = vec.unwrap(); + if vec.is_empty() { + return Chunk::new(); + } + let len = len % vec.len(); + let mut source = Chunk::from_iter(vec.iter().cloned()); + let out = Chunk::from_back(&mut source, len); + let remainder = vec.split_off(vec.len() - len); + assert_eq!(out, remainder); + assert_eq!(source, vec); + out + } + } + } +} + +proptest! { + #[test] + fn test_constructors(cons: Construct) { + cons.make(); + } + + #[test] + fn test_actions(cons: Construct, actions in vec(any::>(), 0..super::action_count())) { + let capacity = Chunk::::capacity(); + let mut chunk = cons.make(); + let mut guide: Vec<_> = chunk.iter().cloned().collect(); + for action in actions { + match action { + Action::PushFront(value) => { + if chunk.is_full() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.push_front(value))).is_err()); + } else { + chunk.push_front(value); + guide.insert(0, value); + } + } + Action::PushBack(value) => { + if chunk.is_full() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.push_back(value))).is_err()); + } else { + chunk.push_back(value); + guide.push(value); + } + } + Action::PopFront => { + if chunk.is_empty() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.pop_front())).is_err()); + } else { + assert_eq!(chunk.pop_front(), guide.remove(0)); + } + } + Action::PopBack => { + if chunk.is_empty() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.pop_back())).is_err()); + } else { + assert_eq!(chunk.pop_back(), guide.pop().unwrap()); + } + } + Action::DropLeft(index) => { + if index >= chunk.len() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.drop_left(index))).is_err()); + } else { + chunk.drop_left(index); + guide.drain(..index); + } + } + Action::DropRight(index) => { + if index >= chunk.len() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.drop_right(index))).is_err()); + } else { + chunk.drop_right(index); + guide.drain(index..); + } + } + Action::SplitOff(index) => { + if index >= chunk.len() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.split_off(index))).is_err()); + } else { + let chunk_off = chunk.split_off(index); + let guide_off = guide.split_off(index); + assert_eq!(chunk_off, guide_off); + } + } + Action::Append(other) => { + let mut other = other.make(); + let mut other_guide: Vec<_> = other.iter().cloned().collect(); + if other.len() + chunk.len() > capacity { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.append(&mut other))).is_err()); + } else { + chunk.append(&mut other); + guide.append(&mut other_guide); + } + } + Action::DrainFromFront(other, count) => { + let mut other = other.make(); + let mut other_guide: Vec<_> = other.iter().cloned().collect(); + if count >= other.len() || chunk.len() + count > capacity { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.drain_from_front(&mut other, count))).is_err()); + } else { + chunk.drain_from_front(&mut other, count); + guide.extend(other_guide.drain(..count)); + assert_eq!(other, other_guide); + } + } + Action::DrainFromBack(other, count) => { + let mut other = other.make(); + let mut other_guide: Vec<_> = other.iter().cloned().collect(); + if count >= other.len() || chunk.len() + count > capacity { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.drain_from_back(&mut other, count))).is_err()); + } else { + chunk.drain_from_back(&mut other, count); + let other_index = other.len() - count; + guide = other_guide.drain(other_index..).chain(guide.into_iter()).collect(); + assert_eq!(other, other_guide); + } + } + Action::Set(index, value) => { + if index >= chunk.len() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.set(index, value))).is_err()); + } else { + chunk.set(index, value); + guide[index] = value; + } + } + Action::Insert(index, value) => { + if index >= chunk.len() || chunk.is_full() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.insert(index, value))).is_err()); + } else { + chunk.insert(index, value); + guide.insert(index, value); + } + } + Action::Remove(index) => { + if index >= chunk.len() { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.remove(index))).is_err()); + } else { + assert_eq!(chunk.remove(index), guide.remove(index)); + } + } + Action::Drain => { + let drained: Vec<_> = chunk.drain().collect(); + let drained_guide: Vec<_> = guide.drain(..).collect(); + assert_eq!(drained, drained_guide); + } + Action::Clear => { + chunk.clear(); + guide.clear(); + } + } + assert_eq!(chunk, guide); + assert!(guide.len() <= capacity); + } + } +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/tests/sparse_chunk.rs cargo-0.35.0/vendor/sized-chunks/src/tests/sparse_chunk.rs --- cargo-0.33.0/vendor/sized-chunks/src/tests/sparse_chunk.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/tests/sparse_chunk.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,99 @@ +#![allow(clippy::unit_arg)] + +use std::collections::BTreeMap; +use std::fmt::Debug; +use std::panic::{catch_unwind, AssertUnwindSafe}; + +use proptest::{arbitrary::any, collection::vec, prelude::*, proptest}; +use proptest_derive::Arbitrary; + +use crate::sparse_chunk::SparseChunk; + +#[derive(Arbitrary, Debug)] +enum Construct { + Empty, + Single((usize, A)), + Pair((usize, A, usize, A)), +} + +#[derive(Arbitrary, Debug)] +enum Action { + Insert(usize, A), + Remove(usize), + Pop, +} + +impl Construct +where + A: Arbitrary + Clone + Debug + Eq, + ::Strategy: 'static, +{ + fn make(self) -> SparseChunk { + match self { + Construct::Empty => { + let out = SparseChunk::new(); + assert!(out.is_empty()); + out + } + Construct::Single((index, value)) => { + let index = index % SparseChunk::::capacity(); + let out = SparseChunk::unit(index, value.clone()); + let mut guide = BTreeMap::new(); + guide.insert(index, value); + assert_eq!(out, guide); + out + } + Construct::Pair((left_index, left, right_index, right)) => { + let left_index = left_index % SparseChunk::::capacity(); + let right_index = right_index % SparseChunk::::capacity(); + let out = SparseChunk::pair(left_index, left.clone(), right_index, right.clone()); + let mut guide = BTreeMap::new(); + guide.insert(left_index, left); + guide.insert(right_index, right); + assert_eq!(out, guide); + out + } + } + } +} + +proptest! { + #[test] + fn test_constructors(cons: Construct) { + cons.make(); + } + + #[test] + fn test_actions(cons: Construct, actions in vec(any::>(), 0..super::action_count())) { + let capacity = SparseChunk::::capacity(); + let mut chunk = cons.make(); + let mut guide: BTreeMap<_, _> = chunk.entries().map(|(i, v)| (i, *v)).collect(); + for action in actions { + match action { + Action::Insert(index, value) => { + if index >= capacity { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.insert(index, value))).is_err()); + } else { + assert_eq!(chunk.insert(index, value), guide.insert(index, value)); + } + } + Action::Remove(index) => { + if index >= capacity { + assert!(catch_unwind(AssertUnwindSafe(|| chunk.remove(index))).is_err()); + } else { + assert_eq!(chunk.remove(index), guide.remove(&index)); + } + } + Action::Pop => { + if let Some(index) = chunk.first_index() { + assert_eq!(chunk.pop(), guide.remove(&index)); + } else { + assert_eq!(chunk.pop(), None); + } + } + } + assert_eq!(chunk, guide); + assert!(guide.len() <= SparseChunk::::capacity()); + } + } +} diff -Nru cargo-0.33.0/vendor/sized-chunks/src/types.rs cargo-0.35.0/vendor/sized-chunks/src/types.rs --- cargo-0.33.0/vendor/sized-chunks/src/types.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/sized-chunks/src/types.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,244 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use std::fmt::Debug; +use std::marker::PhantomData; + +use typenum::*; + +// Chunk sizes + +pub trait ChunkLength: Unsigned { + type SizedType; +} + +impl ChunkLength for UTerm { + type SizedType = (); +} + +#[doc(hidden)] +#[allow(dead_code)] +pub struct SizeEven { + parent1: B, + parent2: B, + _marker: PhantomData, +} + +#[doc(hidden)] +#[allow(dead_code)] +pub struct SizeOdd { + parent1: B, + parent2: B, + data: A, +} + +impl ChunkLength for UInt +where + N: ChunkLength, +{ + type SizedType = SizeEven; +} + +impl ChunkLength for UInt +where + N: ChunkLength, +{ + type SizedType = SizeOdd; +} + +// Bit field sizes + +/// A type level number signifying the number of bits in a bitmap. +/// +/// This trait is implemented for type level numbers from `U1` to `U128`. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] extern crate sized_chunks; +/// # extern crate typenum; +/// # use sized_chunks::types::Bits; +/// # use typenum::U10; +/// # fn main() { +/// assert_eq!( +/// std::mem::size_of::<::Store>(), +/// std::mem::size_of::() +/// ); +/// # } +/// ``` +pub trait Bits: Unsigned { + /// A primitive integer type suitable for storing this many bits. + type Store: Default + Copy + PartialEq + Debug; + + fn get(bits: &Self::Store, index: usize) -> bool; + fn set(bits: &mut Self::Store, index: usize, value: bool) -> bool; + fn len(bits: &Self::Store) -> usize; + fn first_index(bits: &Self::Store) -> Option; +} + +macro_rules! bits_for { + ($num:ty, $result:ty) => { + impl Bits for $num { + type Store = $result; + + fn get(bits: &$result, index: usize) -> bool { + debug_assert!(index < Self::USIZE); + bits & (1 << index) != 0 + } + + fn set(bits: &mut $result, index: usize, value: bool) -> bool { + debug_assert!(index < Self::USIZE); + let mask = 1 << index; + let prev = *bits & mask; + if value { + *bits |= mask; + } else { + *bits &= !mask; + } + prev != 0 + } + + fn len(bits: &$result) -> usize { + bits.count_ones() as usize + } + + fn first_index(bits: &$result) -> Option { + if *bits == 0 { + None + } else { + Some(bits.trailing_zeros() as usize) + } + } + } + }; +} + +bits_for!(U1, u8); +bits_for!(U2, u8); +bits_for!(U3, u8); +bits_for!(U4, u8); +bits_for!(U5, u8); +bits_for!(U6, u8); +bits_for!(U7, u8); +bits_for!(U8, u8); +bits_for!(U9, u16); +bits_for!(U10, u16); +bits_for!(U11, u16); +bits_for!(U12, u16); +bits_for!(U13, u16); +bits_for!(U14, u16); +bits_for!(U15, u16); +bits_for!(U16, u16); +bits_for!(U17, u32); +bits_for!(U18, u32); +bits_for!(U19, u32); +bits_for!(U20, u32); +bits_for!(U21, u32); +bits_for!(U22, u32); +bits_for!(U23, u32); +bits_for!(U24, u32); +bits_for!(U25, u32); +bits_for!(U26, u32); +bits_for!(U27, u32); +bits_for!(U28, u32); +bits_for!(U29, u32); +bits_for!(U30, u32); +bits_for!(U31, u32); +bits_for!(U32, u32); +bits_for!(U33, u64); +bits_for!(U34, u64); +bits_for!(U35, u64); +bits_for!(U36, u64); +bits_for!(U37, u64); +bits_for!(U38, u64); +bits_for!(U39, u64); +bits_for!(U40, u64); +bits_for!(U41, u64); +bits_for!(U42, u64); +bits_for!(U43, u64); +bits_for!(U44, u64); +bits_for!(U45, u64); +bits_for!(U46, u64); +bits_for!(U47, u64); +bits_for!(U48, u64); +bits_for!(U49, u64); +bits_for!(U50, u64); +bits_for!(U51, u64); +bits_for!(U52, u64); +bits_for!(U53, u64); +bits_for!(U54, u64); +bits_for!(U55, u64); +bits_for!(U56, u64); +bits_for!(U57, u64); +bits_for!(U58, u64); +bits_for!(U59, u64); +bits_for!(U60, u64); +bits_for!(U61, u64); +bits_for!(U62, u64); +bits_for!(U63, u64); +bits_for!(U64, u64); +bits_for!(U65, u128); +bits_for!(U66, u128); +bits_for!(U67, u128); +bits_for!(U68, u128); +bits_for!(U69, u128); +bits_for!(U70, u128); +bits_for!(U71, u128); +bits_for!(U72, u128); +bits_for!(U73, u128); +bits_for!(U74, u128); +bits_for!(U75, u128); +bits_for!(U76, u128); +bits_for!(U77, u128); +bits_for!(U78, u128); +bits_for!(U79, u128); +bits_for!(U80, u128); +bits_for!(U81, u128); +bits_for!(U82, u128); +bits_for!(U83, u128); +bits_for!(U84, u128); +bits_for!(U85, u128); +bits_for!(U86, u128); +bits_for!(U87, u128); +bits_for!(U88, u128); +bits_for!(U89, u128); +bits_for!(U90, u128); +bits_for!(U91, u128); +bits_for!(U92, u128); +bits_for!(U93, u128); +bits_for!(U94, u128); +bits_for!(U95, u128); +bits_for!(U96, u128); +bits_for!(U97, u128); +bits_for!(U98, u128); +bits_for!(U99, u128); +bits_for!(U100, u128); +bits_for!(U101, u128); +bits_for!(U102, u128); +bits_for!(U103, u128); +bits_for!(U104, u128); +bits_for!(U105, u128); +bits_for!(U106, u128); +bits_for!(U107, u128); +bits_for!(U108, u128); +bits_for!(U109, u128); +bits_for!(U110, u128); +bits_for!(U111, u128); +bits_for!(U112, u128); +bits_for!(U113, u128); +bits_for!(U114, u128); +bits_for!(U115, u128); +bits_for!(U116, u128); +bits_for!(U117, u128); +bits_for!(U118, u128); +bits_for!(U119, u128); +bits_for!(U120, u128); +bits_for!(U121, u128); +bits_for!(U122, u128); +bits_for!(U123, u128); +bits_for!(U124, u128); +bits_for!(U125, u128); +bits_for!(U126, u128); +bits_for!(U127, u128); +bits_for!(U128, u128); diff -Nru cargo-0.33.0/vendor/smallvec/.cargo-checksum.json cargo-0.35.0/vendor/smallvec/.cargo-checksum.json --- cargo-0.33.0/vendor/smallvec/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/smallvec/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15"} \ No newline at end of file +{"files":{},"package":"c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/smallvec/Cargo.toml cargo-0.35.0/vendor/smallvec/Cargo.toml --- cargo-0.33.0/vendor/smallvec/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/smallvec/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "smallvec" -version = "0.6.8" +version = "0.6.9" authors = ["Simon Sapin "] description = "'Small vector' optimization: store up to a small number of items on the stack" documentation = "https://doc.servo.org/smallvec/" @@ -28,9 +28,6 @@ [dependencies.serde] version = "1" optional = true - -[dependencies.unreachable] -version = "1.0.0" [dev-dependencies.bincode] version = "1.0.1" diff -Nru cargo-0.33.0/vendor/smallvec/lib.rs cargo-0.35.0/vendor/smallvec/lib.rs --- cargo-0.33.0/vendor/smallvec/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/smallvec/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -46,9 +46,6 @@ #[cfg(feature = "serde")] extern crate serde; -extern crate unreachable; -use unreachable::UncheckedOptionExt; - #[cfg(not(feature = "std"))] mod std { pub use core::*; @@ -131,13 +128,24 @@ }); } +/// Hint to the optimizer that any code path which calls this function is +/// statically unreachable and can be removed. +/// +/// Equivalent to `std::hint::unreachable_unchecked` but works in older versions of Rust. +#[inline] +pub unsafe fn unreachable() -> ! { + enum Void {} + let x: &Void = mem::transmute(1usize); + match *x {} +} + /// `panic!()` in debug builds, optimization hint in release. #[cfg(not(feature = "union"))] macro_rules! debug_unreachable { () => { debug_unreachable!("entered unreachable code") }; ($e:expr) => { if cfg!(not(debug_assertions)) { - unreachable::unreachable(); + unreachable(); } else { panic!($e); } @@ -758,7 +766,7 @@ pub fn swap_remove(&mut self, index: usize) -> A::Item { let len = self.len(); self.swap(len - 1, index); - unsafe { self.pop().unchecked_unwrap() } + self.pop().unwrap_or_else(|| unsafe { unreachable() }) } /// Remove all elements from the vector. diff -Nru cargo-0.33.0/vendor/socket2/.cargo-checksum.json cargo-0.35.0/vendor/socket2/.cargo-checksum.json --- cargo-0.33.0/vendor/socket2/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"} \ No newline at end of file +{"files":{},"package":"4e626972d3593207547f14bf5fc9efa4d0e7283deb73fef1dff313dae9ab8878"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/socket2/Cargo.toml cargo-0.35.0/vendor/socket2/Cargo.toml --- cargo-0.33.0/vendor/socket2/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "socket2" -version = "0.3.8" +version = "0.3.9" authors = ["Alex Crichton "] description = "Utilities for handling networking sockets with a maximal amount of configuration\npossible intended.\n" homepage = "https://github.com/alexcrichton/socket2-rs" diff -Nru cargo-0.33.0/vendor/socket2/README.md cargo-0.35.0/vendor/socket2/README.md --- cargo-0.33.0/vendor/socket2/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -1,6 +1,6 @@ # socket2-rs -[![Build Status](https://travis-ci.org/alexcrichton/socket2-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/socket2-rs) +[![Build Status](https://travis-ci.com/alexcrichton/socket2-rs.svg?branch=master)](https://travis-ci.com/alexcrichton/socket2-rs) [![Build status](https://ci.appveyor.com/api/projects/status/hovebj1gr4bgm3d9?svg=true)](https://ci.appveyor.com/project/alexcrichton/socket2-rs) [Documentation](https://docs.rs/socket2) diff -Nru cargo-0.33.0/vendor/socket2/src/sockaddr.rs cargo-0.35.0/vendor/socket2/src/sockaddr.rs --- cargo-0.33.0/vendor/socket2/src/sockaddr.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/src/sockaddr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -123,7 +123,7 @@ unsafe { self.as_(AF_INET as sa_family_t) } } - /// Returns this address as a `SocketAddrV4` if it is in the `AF_INET6` + /// Returns this address as a `SocketAddrV6` if it is in the `AF_INET6` /// family. pub fn as_inet6(&self) -> Option { unsafe { self.as_(AF_INET6 as sa_family_t) } diff -Nru cargo-0.33.0/vendor/socket2/src/socket.rs cargo-0.35.0/vendor/socket2/src/socket.rs --- cargo-0.33.0/vendor/socket2/src/socket.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/src/socket.rs 2019-05-15 11:26:24.000000000 +0000 @@ -982,4 +982,16 @@ #[cfg(unix)] assert_eq!(socket.keepalive().unwrap(), None); } + + #[test] + fn nodelay() { + let socket = Socket::new(Domain::ipv4(), Type::stream(), None).unwrap(); + + assert!(socket.set_nodelay(true).is_ok()); + + let result = socket.nodelay(); + + assert!(result.is_ok()); + assert!(result.unwrap()); + } } diff -Nru cargo-0.33.0/vendor/socket2/src/sys/windows.rs cargo-0.35.0/vendor/socket2/src/sys/windows.rs --- cargo-0.33.0/vendor/socket2/src/sys/windows.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/socket2/src/sys/windows.rs 2019-05-15 11:26:24.000000000 +0000 @@ -445,13 +445,13 @@ pub fn nodelay(&self) -> io::Result { unsafe { - let raw: c_int = self.getsockopt(IPPROTO_TCP, TCP_NODELAY)?; + let raw: c_char = self.getsockopt(IPPROTO_TCP, TCP_NODELAY)?; Ok(raw != 0) } } pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { - unsafe { self.setsockopt(IPPROTO_TCP, TCP_NODELAY, nodelay as c_int) } + unsafe { self.setsockopt(IPPROTO_TCP, TCP_NODELAY, nodelay as c_char) } } pub fn broadcast(&self) -> io::Result { diff -Nru cargo-0.33.0/vendor/strsim/benches/benches.rs cargo-0.35.0/vendor/strsim/benches/benches.rs --- cargo-0.33.0/vendor/strsim/benches/benches.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/benches/benches.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,84 @@ +//! Benchmarks for strsim. + +#![feature(test)] + +extern crate strsim; + +mod benches { + use super::*; + + extern crate test; + use self::test::Bencher; + + #[bench] + fn bench_hamming(bencher: &mut Bencher) { + let a = "ACAAGATGCCATTGTCCCCCGGCCTCCTGCTGCTGCTGCTCTCCGGGG"; + let b = "CCTGGAGGGTGGCCCCACCGGCCGAGACAGCGAGCATATGCAGGAAGC"; + bencher.iter(|| { + strsim::hamming(&a, &b).unwrap(); + }) + } + + #[bench] + fn bench_jaro(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::jaro(&a, &b); + }) + } + + #[bench] + fn bench_jaro_winkler(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::jaro_winkler(&a, &b); + }) + } + + #[bench] + fn bench_levenshtein(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::levenshtein(&a, &b); + }) + } + + #[bench] + fn bench_normalized_levenshtein(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::normalized_levenshtein(&a, &b); + }) + } + + #[bench] + fn bench_osa_distance(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::osa_distance(&a, &b); + }) + } + + #[bench] + fn bench_damerau_levenshtein(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::damerau_levenshtein(&a, &b); + }) + } + + #[bench] + fn bench_normalized_damerau_levenshtein(bencher: &mut Bencher) { + let a = "Philosopher Friedrich Nietzsche"; + let b = "Philosopher Jean-Paul Sartre"; + bencher.iter(|| { + strsim::normalized_damerau_levenshtein(&a, &b); + }) + } +} diff -Nru cargo-0.33.0/vendor/strsim/.cargo-checksum.json cargo-0.35.0/vendor/strsim/.cargo-checksum.json --- cargo-0.33.0/vendor/strsim/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"} \ No newline at end of file +{"files":{},"package":"8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/strsim/Cargo.toml cargo-0.35.0/vendor/strsim/Cargo.toml --- cargo-0.33.0/vendor/strsim/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -12,7 +12,7 @@ [package] name = "strsim" -version = "0.7.0" +version = "0.8.0" authors = ["Danny Guo "] description = "Implementations of string similarity metrics.\nIncludes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, and Jaro-Winkler.\n" homepage = "https://github.com/dguo/strsim-rs" @@ -21,8 +21,8 @@ keywords = ["string", "similarity", "Hamming", "Levenshtein", "Jaro"] license = "MIT" repository = "https://github.com/dguo/strsim-rs" -[badges.travis-ci] +[badges.appveyor] repository = "dguo/strsim-rs" -[badges.appveyor] +[badges.travis-ci] repository = "dguo/strsim-rs" diff -Nru cargo-0.33.0/vendor/strsim/CHANGELOG.md cargo-0.35.0/vendor/strsim/CHANGELOG.md --- cargo-0.33.0/vendor/strsim/CHANGELOG.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/CHANGELOG.md 2019-05-15 11:26:24.000000000 +0000 @@ -3,9 +3,13 @@ ## [Unreleased] +## [0.8.0] - (2018-08-19) +### Added +- Normalized versions of Levenshtein and Damerau-Levenshtein (thanks [@gentoid](https://github.com/gentoid)) + ## [0.7.0] - (2018-01-17) ### Changed -- Faster Levenshtein implementation (thanks @wdv4758h) +- Faster Levenshtein implementation (thanks [@wdv4758h](https://github.com/wdv4758h)) ### Removed - Remove the "against_vec" functions. They are one-liners now, so they don't @@ -90,13 +94,14 @@ ### Fixed - Limit Jaro-Winkler return value to a maximum of 1.0 -- Fix float comparsions in tests +- Fix float comparisons in tests ## [0.1.0] - (2015-02-09) ### Added - Implement Hamming, Jaro, Jaro-Winkler, and Levenshtein -[Unreleased]: https://github.com/dguo/strsim-rs/compare/0.7.0...HEAD +[Unreleased]: https://github.com/dguo/strsim-rs/compare/0.8.0...HEAD +[0.8.0]: https://github.com/dguo/strsim-rs/compare/0.7.0...0.8.0 [0.7.0]: https://github.com/dguo/strsim-rs/compare/0.6.0...0.7.0 [0.6.0]: https://github.com/dguo/strsim-rs/compare/0.5.2...0.6.0 [0.5.2]: https://github.com/dguo/strsim-rs/compare/0.5.1...0.5.2 diff -Nru cargo-0.33.0/vendor/strsim/README.md cargo-0.35.0/vendor/strsim/README.md --- cargo-0.33.0/vendor/strsim/README.md 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/README.md 2019-05-15 11:26:24.000000000 +0000 @@ -2,16 +2,16 @@ [Rust](https://www.rust-lang.org) implementations of [string similarity metrics]: - [Hamming] - - [Levenshtein] + - [Levenshtein] - distance & normalized - [Optimal string alignment] - - [Damerau-Levenshtein] + - [Damerau-Levenshtein] - distance & normalized - [Jaro and Jaro-Winkler] - this implementation of Jaro-Winkler does not limit the common prefix length ### Installation ```toml # Cargo.toml [dependencies] -strsim = "0.7.0" +strsim = "0.8.0" ``` ### [Documentation](https://docs.rs/strsim/) @@ -23,7 +23,8 @@ ```rust extern crate strsim; -use strsim::{hamming, levenshtein, osa_distance, damerau_levenshtein, jaro, +use strsim::{hamming, levenshtein, normalized_levenshtein, osa_distance, + damerau_levenshtein, normalized_damerau_levenshtein, jaro, jaro_winkler}; fn main() { @@ -34,10 +35,14 @@ assert_eq!(3, levenshtein("kitten", "sitting")); + assert!((normalized_levenshtein("kitten", "sitting") - 0.57142).abs() < 0.00001); + assert_eq!(3, osa_distance("ac", "cba")); assert_eq!(2, damerau_levenshtein("ac", "cba")); + assert!((normalized_damerau_levenshtein("levenshtein", "löwenbräu") - 0.27272).abs() < 0.00001) + assert!((0.392 - jaro("Friedrich Nietzsche", "Jean-Paul Sartre")).abs() < 0.001); @@ -50,6 +55,8 @@ If you don't want to install Rust itself, you can run `$ ./dev` for a development CLI if you have [Docker] installed. +Benchmarks require a Nightly toolchain. They are run by `cargo +nightly bench`. + ### License [MIT](https://github.com/dguo/strsim-rs/blob/master/LICENSE) diff -Nru cargo-0.33.0/vendor/strsim/src/lib.rs cargo-0.35.0/vendor/strsim/src/lib.rs --- cargo-0.33.0/vendor/strsim/src/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/src/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -171,6 +171,25 @@ result } +/// Calculates a normalized score of the Levenshtein algorithm between 0.0 and +/// 1.0 (inclusive), where 1.0 means the strings are the same. +/// +/// ``` +/// use strsim::normalized_levenshtein; +/// +/// assert!((normalized_levenshtein("kitten", "sitting") - 0.57142).abs() < 0.00001); +/// assert!((normalized_levenshtein("", "") - 1.0).abs() < 0.00001); +/// assert!(normalized_levenshtein("", "second").abs() < 0.00001); +/// assert!(normalized_levenshtein("first", "").abs() < 0.00001); +/// assert!((normalized_levenshtein("string", "string") - 1.0).abs() < 0.00001); +/// ``` +pub fn normalized_levenshtein(a: &str, b: &str) -> f64 { + if a.is_empty() && b.is_empty() { + return 1.0; + } + 1.0 - (levenshtein(a, b) as f64) / (a.chars().count().max(b.chars().count()) as f64) +} + /// Like Levenshtein but allows for adjacent transpositions. Each substring can /// only be edited once. /// @@ -295,6 +314,25 @@ distances[a_len + 1][b_len + 1] } +/// Calculates a normalized score of the Damerau–Levenshtein algorithm between +/// 0.0 and 1.0 (inclusive), where 1.0 means the strings are the same. +/// +/// ``` +/// use strsim::normalized_damerau_levenshtein; +/// +/// assert!((normalized_damerau_levenshtein("levenshtein", "löwenbräu") - 0.27272).abs() < 0.00001); +/// assert!((normalized_damerau_levenshtein("", "") - 1.0).abs() < 0.00001); +/// assert!(normalized_damerau_levenshtein("", "flower").abs() < 0.00001); +/// assert!(normalized_damerau_levenshtein("tree", "").abs() < 0.00001); +/// assert!((normalized_damerau_levenshtein("sunglasses", "sunglasses") - 1.0).abs() < 0.00001); +/// ``` +pub fn normalized_damerau_levenshtein(a: &str, b: &str) -> f64 { + if a.is_empty() && b.is_empty() { + return 1.0; + } + 1.0 - (damerau_levenshtein(a, b) as f64) / (a.chars().count().max(b.chars().count()) as f64) +} + #[cfg(test)] mod tests { use super::*; @@ -531,6 +569,31 @@ } #[test] + fn normalized_levenshtein_diff_short() { + assert!((normalized_levenshtein("kitten", "sitting") - 0.57142).abs() < 0.00001); + } + + #[test] + fn normalized_levenshtein_for_empty_strings() { + assert!((normalized_levenshtein("", "") - 1.0).abs() < 0.00001); + } + + #[test] + fn normalized_levenshtein_first_empty() { + assert!(normalized_levenshtein("", "second").abs() < 0.00001); + } + + #[test] + fn normalized_levenshtein_second_empty() { + assert!(normalized_levenshtein("first", "").abs() < 0.00001); + } + + #[test] + fn normalized_levenshtein_identical_strings() { + assert!((normalized_levenshtein("identical", "identical") - 1.0).abs() < 0.00001); + } + + #[test] fn osa_distance_empty() { assert_eq!(0, osa_distance("", "")); } @@ -695,4 +758,29 @@ fn damerau_levenshtein_unrestricted_edit() { assert_eq!(3, damerau_levenshtein("a cat", "an abct")); } + + #[test] + fn normalized_damerau_levenshtein_diff_short() { + assert!((normalized_damerau_levenshtein("levenshtein", "löwenbräu") - 0.27272).abs() < 0.00001); + } + + #[test] + fn normalized_damerau_levenshtein_for_empty_strings() { + assert!((normalized_damerau_levenshtein("", "") - 1.0).abs() < 0.00001); + } + + #[test] + fn normalized_damerau_levenshtein_first_empty() { + assert!(normalized_damerau_levenshtein("", "flower").abs() < 0.00001); + } + + #[test] + fn normalized_damerau_levenshtein_second_empty() { + assert!(normalized_damerau_levenshtein("tree", "").abs() < 0.00001); + } + + #[test] + fn normalized_damerau_levenshtein_identical_strings() { + assert!((normalized_damerau_levenshtein("sunglasses", "sunglasses") - 1.0).abs() < 0.00001); + } } diff -Nru cargo-0.33.0/vendor/strsim/tests/lib.rs cargo-0.35.0/vendor/strsim/tests/lib.rs --- cargo-0.33.0/vendor/strsim/tests/lib.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/strsim/tests/lib.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,7 +1,7 @@ extern crate strsim; -use strsim::{hamming, levenshtein, osa_distance, damerau_levenshtein, jaro, - jaro_winkler}; +use strsim::{hamming, levenshtein, normalized_levenshtein, osa_distance,damerau_levenshtein, + normalized_damerau_levenshtein, jaro, jaro_winkler}; #[test] fn hamming_works() { @@ -17,6 +17,11 @@ } #[test] +fn normalized_levenshtein_works() { + assert!((normalized_levenshtein("kitten", "sitting") - 0.57142).abs() < 0.00001); +} + +#[test] fn osa_distance_works() { assert_eq!(3, osa_distance("ac", "cba")); } @@ -27,6 +32,11 @@ } #[test] +fn normalized_damerau_levenshtein_works() { + assert!((normalized_damerau_levenshtein("levenshtein", "löwenbräu") - 0.27272).abs() < 0.00001); +} + +#[test] fn jaro_works() { assert!((0.392 - jaro("Friedrich Nietzsche", "Jean-Paul Sartre")).abs() < 0.001); diff -Nru cargo-0.33.0/vendor/syn/build.rs cargo-0.35.0/vendor/syn/build.rs --- cargo-0.33.0/vendor/syn/build.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/syn/build.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,72 @@ +use std::env; +use std::process::Command; +use std::str::{self, FromStr}; + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let compiler = match rustc_version() { + Some(compiler) => compiler, + None => return, + }; + + if compiler.minor >= 19 { + println!("cargo:rustc-cfg=syn_can_use_thread_id"); + } + + if compiler.minor >= 20 { + println!("cargo:rustc-cfg=syn_can_use_associated_constants"); + } + + // Macro modularization allows re-exporting the `quote!` macro in 1.30+. + if compiler.minor >= 30 { + println!("cargo:rustc-cfg=syn_can_call_macro_by_path"); + } + + if !compiler.nightly { + println!("cargo:rustc-cfg=syn_disable_nightly_tests"); + } +} + +struct Compiler { + minor: u32, + nightly: bool, +} + +fn rustc_version() -> Option { + let rustc = match env::var_os("RUSTC") { + Some(rustc) => rustc, + None => return None, + }; + + let output = match Command::new(rustc).arg("--version").output() { + Ok(output) => output, + Err(_) => return None, + }; + + let version = match str::from_utf8(&output.stdout) { + Ok(version) => version, + Err(_) => return None, + }; + + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + + let next = match pieces.next() { + Some(next) => next, + None => return None, + }; + + let minor = match u32::from_str(next) { + Ok(minor) => minor, + Err(_) => return None, + }; + + Some(Compiler { + minor: minor, + nightly: version.contains("nightly"), + }) +} diff -Nru cargo-0.33.0/vendor/syn/.cargo-checksum.json cargo-0.35.0/vendor/syn/.cargo-checksum.json --- cargo-0.33.0/vendor/syn/.cargo-checksum.json 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/syn/.cargo-checksum.json 2019-05-15 11:26:24.000000000 +0000 @@ -1 +1 @@ -{"files":{},"package":"f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"} \ No newline at end of file +{"files":{},"package":"a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"} \ No newline at end of file diff -Nru cargo-0.33.0/vendor/syn/Cargo.toml cargo-0.35.0/vendor/syn/Cargo.toml --- cargo-0.33.0/vendor/syn/Cargo.toml 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/syn/Cargo.toml 2019-05-15 11:26:24.000000000 +0000 @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,9 +12,9 @@ [package] name = "syn" -version = "0.15.26" +version = "0.15.34" authors = ["David Tolnay "] -include = ["/Cargo.toml", "/src/**/*.rs", "/README.md", "/LICENSE-APACHE", "/LICENSE-MIT"] +include = ["/build.rs", "/Cargo.toml", "/LICENSE-APACHE", "/LICENSE-MIT", "/README.md", "/src/**/*.rs"] description = "Parser for Rust source code" documentation = "https://docs.rs/syn" readme = "README.md" @@ -26,14 +26,6 @@ [package.metadata.playground] all-features = true - -[lib] -name = "syn" - -[[example]] -name = "dump-syntax" -path = "examples/dump-syntax/main.rs" -required-features = ["full", "parsing", "extra-traits"] [dependencies.proc-macro2] version = "0.4.4" default-features = false @@ -45,6 +37,12 @@ [dependencies.unicode-xid] version = "0.1" +[dev-dependencies.colored] +version = "1.7" + +[dev-dependencies.insta] +version = "0.7" + [dev-dependencies.rayon] version = "1.0" diff -Nru cargo-0.33.0/vendor/syn/src/attr.rs cargo-0.35.0/vendor/syn/src/attr.rs --- cargo-0.33.0/vendor/syn/src/attr.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/syn/src/attr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -133,8 +133,8 @@ } impl Attribute { - /// Parses the tokens after the path as a [`Meta`](enum.Meta.html) if - /// possible. + /// Parses the content of the attribute, consisting of the path and tts, as + /// a [`Meta`](enum.Meta.html) if possible. /// /// Deprecated; use `parse_meta` instead. #[doc(hidden)] @@ -174,8 +174,8 @@ } } - /// Parses the tokens after the path as a [`Meta`](enum.Meta.html) if - /// possible. + /// Parses the content of the attribute, consisting of the path and tts, as + /// a [`Meta`](enum.Meta.html) if possible. #[cfg(feature = "parsing")] pub fn parse_meta(&self) -> Result { if let Some(ref colon) = self.path.leading_colon { diff -Nru cargo-0.33.0/vendor/syn/src/custom_keyword.rs cargo-0.35.0/vendor/syn/src/custom_keyword.rs --- cargo-0.33.0/vendor/syn/src/custom_keyword.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/syn/src/custom_keyword.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,252 @@ +/// Define a type that supports parsing and printing a given identifier as if it +/// were a keyword. +/// +/// # Usage +/// +/// As a convention, it is recommended that this macro be invoked within a +/// module called `kw` or `keyword` and that the resulting parser be invoked +/// with a `kw::` or `keyword::` prefix. +/// +/// ```edition2018 +/// mod kw { +/// syn::custom_keyword!(whatever); +/// } +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in keyword token. +/// +/// - [Peeking] — `input.peek(kw::whatever)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #whatever_token ... )` +/// +/// - Construction from a [`Span`] — `let whatever_token = kw::whatever(sp)` +/// +/// - Field access to its span — `let sp = whatever_token.span` +/// +/// [Peeking]: parse/struct.ParseBuffer.html#method.peek +/// [Parsing]: parse/struct.ParseBuffer.html#method.parse +/// [Printing]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html +/// [`Span`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html +/// +/// # Example +/// +/// This example parses input that looks like `bool = true` or `str = "value"`. +/// The key must be either the identifier `bool` or the identifier `str`. If +/// `bool`, the value may be either `true` or `false`. If `str`, the value may +/// be any string literal. +/// +/// The symbols `bool` and `str` are not reserved keywords in Rust so these are +/// not considered keywords in the `syn::token` module. Like any other +/// identifier that is not a keyword, these can be declared as custom keywords +/// by crates that need to use them as such. +/// +/// ```edition2018 +/// use syn::{LitBool, LitStr, Result, Token}; +/// use syn::parse::{Parse, ParseStream}; +/// +/// mod kw { +/// syn::custom_keyword!(bool); +/// syn::custom_keyword!(str); +/// } +/// +/// enum Argument { +/// Bool { +/// bool_token: kw::bool, +/// eq_token: Token![=], +/// value: LitBool, +/// }, +/// Str { +/// str_token: kw::str, +/// eq_token: Token![=], +/// value: LitStr, +/// }, +/// } +/// +/// impl Parse for Argument { +/// fn parse(input: ParseStream) -> Result { +/// let lookahead = input.lookahead1(); +/// if lookahead.peek(kw::bool) { +/// Ok(Argument::Bool { +/// bool_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else if lookahead.peek(kw::str) { +/// Ok(Argument::Str { +/// str_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else { +/// Err(lookahead.error()) +/// } +/// } +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! custom_keyword { + ($ident:ident) => { + #[allow(non_camel_case_types)] + pub struct $ident { + pub span: $crate::export::Span, + } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub fn $ident<__S: $crate::export::IntoSpans<[$crate::export::Span; 1]>>( + span: __S, + ) -> $ident { + $ident { + span: $crate::export::IntoSpans::into_spans(span)[0], + } + } + + impl $crate::export::Default for $ident { + fn default() -> Self { + $ident { + span: $crate::export::Span::call_site(), + } + } + } + + impl_parse_for_custom_keyword!($ident); + impl_to_tokens_for_custom_keyword!($ident); + impl_clone_for_custom_keyword!($ident); + impl_extra_traits_for_custom_keyword!($ident); + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => { + // For peek. + impl $crate::token::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::export::bool { + if let Some((ident, _rest)) = cursor.ident() { + ident == stringify!($ident) + } else { + false + } + } + + fn display() -> &'static $crate::export::str { + concat!("`", stringify!($ident), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + input.step(|cursor| { + if let $crate::export::Some((ident, rest)) = cursor.ident() { + if ident == stringify!($ident) { + return $crate::export::Ok(($ident { span: ident.span() }, rest)); + } + } + $crate::export::Err(cursor.error(concat!( + "expected `", + stringify!($ident), + "`" + ))) + }) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => { + impl $crate::export::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::export::TokenStream2) { + let ident = $crate::Ident::new(stringify!($ident), self.span); + $crate::export::TokenStreamExt::append(tokens, ident); + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => { + impl $crate::export::Copy for $ident {} + + impl $crate::export::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => { + impl $crate::export::Debug for $ident { + fn fmt(&self, f: &mut $crate::export::Formatter) -> $crate::export::fmt::Result { + $crate::export::Formatter::write_str( + f, + concat!("Keyword [", stringify!($ident), "]"), + ) + } + } + + impl $crate::export::Eq for $ident {} + + impl $crate::export::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::export::bool { + true + } + } + + impl $crate::export::Hash for $ident { + fn hash<__H: $crate::export::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => {}; +} diff -Nru cargo-0.33.0/vendor/syn/src/custom_punctuation.rs cargo-0.35.0/vendor/syn/src/custom_punctuation.rs --- cargo-0.33.0/vendor/syn/src/custom_punctuation.rs 1970-01-01 00:00:00.000000000 +0000 +++ cargo-0.35.0/vendor/syn/src/custom_punctuation.rs 2019-05-15 11:26:24.000000000 +0000 @@ -0,0 +1,309 @@ +/// Define a type that supports parsing and printing a multi-character symbol +/// as if it were a punctuation token. +/// +/// # Usage +/// +/// ```edition2018 +/// syn::custom_punctuation!(LeftRightArrow, <=>); +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in punctuation token. +/// +/// - [Peeking] — `input.peek(LeftRightArrow)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #lrarrow ... )` +/// +/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` +/// +/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` +/// +/// - Field access to its spans — `let spans = lrarrow.spans` +/// +/// [Peeking]: parse/struct.ParseBuffer.html#method.peek +/// [Parsing]: parse/struct.ParseBuffer.html#method.parse +/// [Printing]: https://docs.rs/quote/0.6/quote/trait.ToTokens.html +/// [`Span`]: https://docs.rs/proc-macro2/0.4/proc_macro2/struct.Span.html +/// +/// # Example +/// +/// ```edition2018 +/// use proc_macro2::{TokenStream, TokenTree}; +/// use syn::parse::{Parse, ParseStream, Peek, Result}; +/// use syn::punctuated::Punctuated; +/// use syn::Expr; +/// +/// syn::custom_punctuation!(PathSeparator, ); +/// +/// // expr expr expr ... +/// struct PathSegments { +/// segments: Punctuated, +/// } +/// +/// impl Parse for PathSegments { +/// fn parse(input: ParseStream) -> Result { +/// let mut segments = Punctuated::new(); +/// +/// let first = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(first)?); +/// +/// while input.peek(PathSeparator) { +/// segments.push_punct(input.parse()?); +/// +/// let next = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(next)?); +/// } +/// +/// Ok(PathSegments { segments }) +/// } +/// } +/// +/// fn parse_until(input: ParseStream, end: E) -> Result { +/// let mut tokens = TokenStream::new(); +/// while !input.is_empty() && !input.peek(end) { +/// let next: TokenTree = input.parse()?; +/// tokens.extend(Some(next)); +/// } +/// Ok(tokens) +/// } +/// +/// fn main() { +/// let input = r#" a::b c::d::e "#; +/// let _: PathSegments = syn::parse_str(input).unwrap(); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + pub struct $ident { + pub spans: custom_punctuation_repr!($($tt)+), + } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub fn $ident<__S: $crate::export::IntoSpans>( + spans: __S, + ) -> $ident { + let _validate_len = 0 $(+ custom_punctuation_len!(strict, $tt))*; + $ident { + spans: $crate::export::IntoSpans::into_spans(spans) + } + } + + impl $crate::export::Default for $ident { + fn default() -> Self { + $ident($crate::export::Span::call_site()) + } + } + + impl_parse_for_custom_punctuation!($ident, $($tt)+); + impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); + impl_clone_for_custom_punctuation!($ident, $($tt)+); + impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::token::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> bool { + $crate::token::parsing::peek_punct(cursor, stringify_punct!($($tt)+)) + } + + fn display() -> &'static $crate::export::str { + custom_punctuation_concat!("`", stringify_punct!($($tt)+), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + let spans: custom_punctuation_repr!($($tt)+) = + $crate::token::parsing::punct(input, stringify_punct!($($tt)+))?; + Ok($ident(spans)) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::export::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::export::TokenStream2) { + $crate::token::printing::punct(stringify_punct!($($tt)+), &self.spans, tokens) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::export::Copy for $ident {} + + impl $crate::export::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::export::Debug for $ident { + fn fmt(&self, f: &mut $crate::export::Formatter) -> $crate::export::fmt::Result { + $crate::export::Formatter::write_str(f, stringify!($ident)) + } + } + + impl $crate::export::Eq for $ident {} + + impl $crate::export::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::export::bool { + true + } + } + + impl $crate::export::Hash for $ident { + fn hash<__H: $crate::export::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! custom_punctuation_repr { + ($($tt:tt)+) => { + [$crate::export::Span; 0 $(+ custom_punctuation_len!(lenient, $tt))+] + }; +} + +// Not public API. +#[doc(hidden)] +#[macro_export(local_inner_macros)] +#[cfg_attr(rustfmt, rustfmt_skip)] +macro_rules! custom_punctuation_len { + ($mode:ident, +) => { 1 }; + ($mode:ident, +=) => { 2 }; + ($mode:ident, &) => { 1 }; + ($mode:ident, &&) => { 2 }; + ($mode:ident, &=) => { 2 }; + ($mode:ident, @) => { 1 }; + ($mode:ident, !) => { 1 }; + ($mode:ident, ^) => { 1 }; + ($mode:ident, ^=) => { 2 }; + ($mode:ident, :) => { 1 }; + ($mode:ident, ::) => { 2 }; + ($mode:ident, ,) => { 1 }; + ($mode:ident, /) => { 1 }; + ($mode:ident, /=) => { 2 }; + ($mode:ident, .) => { 1 }; + ($mode:ident, ..) => { 2 }; + ($mode:ident, ...) => { 3 }; + ($mode:ident, ..=) => { 3 }; + ($mode:ident, =) => { 1 }; + ($mode:ident, ==) => { 2 }; + ($mode:ident, >=) => { 2 }; + ($mode:ident, >) => { 1 }; + ($mode:ident, <=) => { 2 }; + ($mode:ident, <) => { 1 }; + ($mode:ident, *=) => { 2 }; + ($mode:ident, !=) => { 2 }; + ($mode:ident, |) => { 1 }; + ($mode:ident, |=) => { 2 }; + ($mode:ident, ||) => { 2 }; + ($mode:ident, #) => { 1 }; + ($mode:ident, ?) => { 1 }; + ($mode:ident, ->) => { 2 }; + ($mode:ident, <-) => { 2 }; + ($mode:ident, %) => { 1 }; + ($mode:ident, %=) => { 2 }; + ($mode:ident, =>) => { 2 }; + ($mode:ident, ;) => { 1 }; + ($mode:ident, <<) => { 2 }; + ($mode:ident, <<=) => { 3 }; + ($mode:ident, >>) => { 2 }; + ($mode:ident, >>=) => { 3 }; + ($mode:ident, *) => { 1 }; + ($mode:ident, -) => { 1 }; + ($mode:ident, -=) => { 2 }; + ($mode:ident, ~) => { 1 }; + (lenient, $tt:tt) => { 0 }; + (strict, $tt:tt) => {{ custom_punctuation_unexpected!($tt); 0 }}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_unexpected { + () => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! stringify_punct { + ($($tt:tt)+) => { + concat!($(stringify!($tt)),+) + }; +} + +// Not public API. +// Without this, local_inner_macros breaks when looking for concat! +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_concat { + ($($tt:tt)*) => { + concat!($($tt)*) + }; +} diff -Nru cargo-0.33.0/vendor/syn/src/error.rs cargo-0.35.0/vendor/syn/src/error.rs --- cargo-0.33.0/vendor/syn/src/error.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/syn/src/error.rs 2019-05-15 11:26:24.000000000 +0000 @@ -1,5 +1,5 @@ use std; -use std::fmt::{self, Display}; +use std::fmt::{self, Debug, Display}; use std::iter::FromIterator; use proc_macro2::{ @@ -24,7 +24,6 @@ /// [module documentation]: index.html /// /// *This type is available if Syn is built with the `"parsing"` feature.* -#[derive(Debug)] pub struct Error { // Span is implemented as an index into a thread-local interner to keep the // size small. It is not safe to access from a different thread. We want @@ -181,6 +180,12 @@ } } +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.debug_tuple("Error").field(&self.message).finish() + } +} + impl Display for Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(&self.message) diff -Nru cargo-0.33.0/vendor/syn/src/expr.rs cargo-0.35.0/vendor/syn/src/expr.rs --- cargo-0.33.0/vendor/syn/src/expr.rs 2019-02-06 04:11:58.000000000 +0000 +++ cargo-0.35.0/vendor/syn/src/expr.rs 2019-05-15 11:26:24.000000000 +0000 @@ -36,9 +36,10 @@ /// Expr::If(expr) => { /// /* ... */ /// } + /// /// /* ... */ /// # _ => {} - /// } + /// # } /// # } /// ``` /// @@ -50,28 +51,15 @@ /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. /// - /// The pattern is similar if the input expression is borrowed: - /// - /// ```edition2018 - /// # use syn::Expr; - /// # - /// # fn example(expr: &Expr) { - /// match *expr { - /// Expr::MethodCall(ref expr) => { - /// # } - /// # _ => {} - /// # } - /// # } - /// ``` - /// /// This approach avoids repeating the variant names twice on every line. /// /// ```edition2018 /// # use syn::{Expr, ExprMethodCall}; /// # /// # fn example(expr: Expr) { - /// # match expr { - /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { // repetitive + /// // Repetitive; recommend not doing this. + /// match expr { + /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { /// # } /// # _ => {} /// # } @@ -84,10 +72,10 @@ /// ```edition2018 /// # use syn::{Expr, ExprField}; /// # - /// # fn example(discriminant: &ExprField) { + /// # fn example(discriminant: ExprField) { /// // Binding is called `base` which is the name I would use if I were /// // assigning `*discriminant.base` without an `if let`. - /// if let Expr::Tuple(ref base) = *discriminant.base { + /// if let Expr::Tuple(base) = *discriminant.base { /// # } /// # } /// ``` @@ -799,8 +787,8 @@ /// A path pattern like `Color::Red`, optionally qualified with a /// self-type. /// - /// Unquailfied path patterns can legally refer to variants, structs, - /// constants or associated constants. Quailfied path patterns like + /// Unqualified path patterns can legally refer to variants, structs, + /// constants or associated constants. Qualified path patterns like /// `::B::C` and `::B::C` can only legally refer to /// associated constants. /// @@ -1464,7 +1452,7 @@ if input.peek(token::Group) { input.call(expr_group).map(Expr::Group) } else if input.peek(Lit) { - input.call(expr_lit).map(Expr::Lit) + input.parse().map(Expr::Lit) } else if input.peek(Token![async]) && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace)) { @@ -1500,15 +1488,15 @@ } else if input.peek(Token![let]) { input.call(expr_let).map(Expr::Let) } else if input.peek(Token![if]) { - input.call(expr_if).map(Expr::If) + input.parse().map(Expr::If) } else if input.peek(Token![while]) { - input.call(expr_while).map(Expr::While) + input.parse().map(Expr::While) } else if input.peek(Token![for]) { - input.call(expr_for_loop).map(Expr::ForLoop) + input.parse().map(Expr::ForLoop) } else if input.peek(Token![loop]) { - input.call(expr_loop).map(Expr::Loop) + input.parse().map(Expr::Loop) } else if input.peek(Token![match]) { - input.call(expr_match).map(Expr::Match) + input.parse().map(Expr::Match) } else if input.peek(Token![yield]) { input.call(expr_yield).map(Expr::Yield) } else if input.peek(Token![unsafe]) { @@ -1520,11 +1508,11 @@ } else if input.peek(Lifetime) { let the_label: Label = input.parse()?; let mut expr = if input.peek(Token![while]) { - Expr::While(input.call(expr_while)?) + Expr::While(input.parse()?) } else if input.peek(Token![for]) { - Expr::ForLoop(input.call(expr_for_loop)?) + Expr::ForLoop(input.parse()?) } else if input.peek(Token![loop]) { - Expr::Loop(input.call(expr_loop)?) + Expr::Loop(input.parse()?) } else if input.peek(token::Brace) { Expr::Block(input.call(expr_block)?) } else { @@ -1546,7 +1534,7 @@ #[cfg(not(feature = "full"))] fn atom_expr(input: ParseStream, _allow_struct: AllowStruct) -> Result { if input.peek(Lit) { - input.call(expr_lit).map(Expr::Lit) + input.parse().map(Expr::Lit) } else if input.peek(token::Paren) { input.call(expr_paren).map(Expr::Paren) } else if input.peek(Ident) @@ -1695,15 +1683,15 @@ fn expr_early(input: ParseStream) -> Result { let mut attrs = input.call(Attribute::parse_outer)?; let mut expr = if input.peek(Token![if]) { - Expr::If(input.call(expr_if)?) + Expr::If(input.parse()?) } else if input.peek(Token![while]) { - Expr::While(input.call(expr_while)?) + Expr::While(input.parse()?) } else if input.peek(Token![for]) { - Expr::ForLoop(input.call(expr_for_loop)?) + Expr::ForLoop(input.parse()?) } else if input.peek(Token![loop]) { - Expr::Loop(input.call(expr_loop)?) + Expr::Loop(input.parse()?) } else if input.peek(Token![match]) { - Expr::Match(input.call(expr_match)?) + Expr::Match(input.parse()?) } else if input.peek(Token![try]) && input.peek2(token::Brace) { Expr::TryBlock(input.call(expr_try_block)?) } else if input.peek(Token![unsafe]) { @@ -1735,11 +1723,13 @@ Ok(expr) } - pub fn expr_lit(input: ParseStream) -> Result { - Ok(ExprLit { - attrs: Vec::new(), - lit: input.parse()?, - }) + impl Parse for ExprLit { + fn parse(input: ParseStream) -> Result { + Ok(ExprLit { + attrs: Vec::new(), + lit: input.parse()?, + }) + } } #[cfg(feature = "full")] @@ -1792,20 +1782,22 @@ } #[cfg(feature = "full")] - fn expr_if(input: ParseStream) -> Result { - Ok(ExprIf { - attrs: Vec::new(), - if_token: input.parse()?, - cond: Box::new(input.call(expr_no_struct)?), - then_branch: input.parse()?, - else_branch: { - if input.peek(Token![else]) { - Some(input.call(else_block)?) - } else { - None - } - }, - }) + impl Parse for ExprIf { + fn parse(input: ParseStream) -> Result { + Ok(ExprIf { + attrs: Vec::new(), + if_token: input.parse()?, + cond: Box::new(input.call(expr_no_struct)?), + then_branch: input.parse()?, + else_branch: { + if input.peek(Token![else]) { + Some(input.call(else_block)?) + } else { + None + } + }, + }) + } } #[cfg(feature = "full")] @@ -1814,7 +1806,7 @@ let lookahead = input.lookahead1(); let else_branch = if input.peek(Token![if]) { - input.call(expr_if).map(Expr::If)? + input.parse().map(Expr::If)? } else if input.peek(token::Brace) { Expr::Block(ExprBlock { attrs: Vec::new(), @@ -1829,76 +1821,132 @@ } #[cfg(feature = "full")] - fn expr_for_loop(input: ParseStream) -> Result { - let label: Option