created vendored crates
This commit is contained in:
parent
8bede44aa8
commit
8ed487c4cd
15672 changed files with 6291182 additions and 0 deletions
4
prepare-vendor.sh
Executable file
4
prepare-vendor.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
mkdir -p vendor .cargo
|
||||
cargo vendor --locked vendor --manifest-path upstream/zeroidc/Cargo.toml > .cargo/config.toml
|
||||
tar -cvf zeroidc-cargo-vendor.tar vendor .cargo/config.toml
|
||||
1
vendor/addr2line/.cargo-checksum.json
vendored
Normal file
1
vendor/addr2line/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"bb2a79143e8a86d09bc6eb3522b5abb8e9cf6f9f3be955e683efa7a3202d0c94","CHANGELOG.md":"b278b1b797ac494c3653c85ede8a0f423a866300137117d2e914e4a52a87c08d","Cargo.lock":"ded666c16c5232c89b807781768ee73a4f8ed51d3b05a86850856d1a482dd5e6","Cargo.toml":"af4c88d2c7e685f9adf0f473fc9a0c33a2c8f54e3497f8eb92c8ec5d1dcfb1b5","Cargo.toml.orig":"8d11a89cafe93e86ce8d849907d07182a31b3b4fd30fab1dc5a762f72a528031","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"e99d88d232bf57d70f0fb87f6b496d44b6653f99f8a63d250a54c61ea4bcde40","README.md":"76d28502bd2e83f6a9e3576bd45e9a7fe5308448c4b5384b0d249515b5f67a5c","bench.plot.r":"6a5d7a4d36ed6b3d9919be703a479bef47698bf947818b483ff03951df2d4e01","benchmark.sh":"b35f89b1ca2c1dc0476cdd07f0284b72d41920d1c7b6054072f50ffba296d78d","coverage.sh":"4677e81922d08a82e83068a911717a247c66af12e559f37b78b6be3337ac9f07","examples/addr2line.rs":"0ffdd45eeac7a2a5ddb71895009ea5e41306e22404bce375600b8371728e36ed","rustfmt.toml":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","src/builtin_split_dwarf_loader.rs":"dc6979de81b35f82e97275e6be27ec61f3c4225ea10574a9e031813e00185174","src/function.rs":"68f047e0c78afe18ad165db255c8254ee74c35cd6df0cc07e400252981f661ed","src/lazy.rs":"0bf23f7098f1902f181e43c2ffa82a3f86df2c0dbcb9bc0ebce6a0168dd8b060","src/lib.rs":"ebfdd66a4b553e6dcbb937903c4f30bfe3f4a0b6ae9fec810ec9eb9e6bf0ec2f","tests/correctness.rs":"4081f8019535305e3aa254c6a4e1436272dd873f9717c687ca0e66ea8d5871ed","tests/output_equivalence.rs":"b2cd7c59fa55808a2e66e9fe7f160d846867e3ecefe22c22a818f822c3c41f23","tests/parse.rs":"c2f7362e4679c1b4803b12ec6e8dca6da96aed7273fd210a857524a4182c30e7"},"package":"f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"}
|
||||
6
vendor/addr2line/.cargo_vcs_info.json
vendored
Normal file
6
vendor/addr2line/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "2edc700412f2a17b0b997c4b89e0f04886bfb0c0"
|
||||
},
|
||||
"path_in_vcs": ""
|
||||
}
|
||||
321
vendor/addr2line/CHANGELOG.md
vendored
Normal file
321
vendor/addr2line/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
# `addr2line` Change Log
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.20.0 (2023/04/15)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* The minimum supported rust version is 1.58.0.
|
||||
|
||||
* Changed `Context::find_frames` to return `LookupResult`.
|
||||
Use `LookupResult::skip_all_loads` to obtain the result without loading split DWARF.
|
||||
[#260](https://github.com/gimli-rs/addr2line/pull/260)
|
||||
|
||||
* Replaced `Context::find_dwarf_unit` with `Context::find_dwarf_and_unit`.
|
||||
[#260](https://github.com/gimli-rs/addr2line/pull/260)
|
||||
|
||||
* Updated `object` dependency.
|
||||
|
||||
### Changed
|
||||
|
||||
* Fix handling of file index 0 for DWARF 5.
|
||||
[#264](https://github.com/gimli-rs/addr2line/pull/264)
|
||||
|
||||
### Added
|
||||
|
||||
* Added types and methods to support loading split DWARF:
|
||||
`LookupResult`, `SplitDwarfLoad`, `SplitDwarfLoader`, `Context::preload_units`.
|
||||
[#260](https://github.com/gimli-rs/addr2line/pull/260)
|
||||
[#262](https://github.com/gimli-rs/addr2line/pull/262)
|
||||
[#263](https://github.com/gimli-rs/addr2line/pull/263)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.19.0 (2022/11/24)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.18.0 (2022/07/16)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `object` dependency.
|
||||
|
||||
### Changed
|
||||
|
||||
* Fixed handling of relative path for `DW_AT_comp_dir`.
|
||||
[#239](https://github.com/gimli-rs/addr2line/pull/239)
|
||||
|
||||
* Fixed handling of `DW_FORM_addrx` for DWARF 5 support.
|
||||
[#243](https://github.com/gimli-rs/addr2line/pull/243)
|
||||
|
||||
* Fixed handling of units that are missing range information.
|
||||
[#249](https://github.com/gimli-rs/addr2line/pull/249)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.17.0 (2021/10/24)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
### Changed
|
||||
|
||||
* Use `skip_attributes` to improve performance.
|
||||
[#236](https://github.com/gimli-rs/addr2line/pull/236)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.16.0 (2021/07/26)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.15.2 (2021/06/04)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Allow `Context` to be `Send`.
|
||||
[#219](https://github.com/gimli-rs/addr2line/pull/219)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.15.1 (2021/05/02)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Don't ignore aranges with address 0.
|
||||
[#217](https://github.com/gimli-rs/addr2line/pull/217)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.15.0 (2021/05/02)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
[#215](https://github.com/gimli-rs/addr2line/pull/215)
|
||||
|
||||
* Added `debug_aranges` parameter to `Context::from_sections`.
|
||||
[#200](https://github.com/gimli-rs/addr2line/pull/200)
|
||||
|
||||
### Added
|
||||
|
||||
* Added `.debug_aranges` support.
|
||||
[#200](https://github.com/gimli-rs/addr2line/pull/200)
|
||||
|
||||
* Added supplementary object file support.
|
||||
[#208](https://github.com/gimli-rs/addr2line/pull/208)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed handling of Windows paths in locations.
|
||||
[#209](https://github.com/gimli-rs/addr2line/pull/209)
|
||||
|
||||
* examples/addr2line: Flush stdout after each response.
|
||||
[#210](https://github.com/gimli-rs/addr2line/pull/210)
|
||||
|
||||
* examples/addr2line: Avoid copying every section.
|
||||
[#213](https://github.com/gimli-rs/addr2line/pull/213)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.14.1 (2020/12/31)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix location lookup for skeleton units.
|
||||
[#201](https://github.com/gimli-rs/addr2line/pull/201)
|
||||
|
||||
### Added
|
||||
|
||||
* Added `Context::find_location_range`.
|
||||
[#196](https://github.com/gimli-rs/addr2line/pull/196)
|
||||
[#199](https://github.com/gimli-rs/addr2line/pull/199)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.14.0 (2020/10/27)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Handle units that only have line information.
|
||||
[#188](https://github.com/gimli-rs/addr2line/pull/188)
|
||||
|
||||
* Handle DWARF units with version <= 4 and no `DW_AT_name`.
|
||||
[#191](https://github.com/gimli-rs/addr2line/pull/191)
|
||||
|
||||
* Fix handling of `DW_FORM_ref_addr`.
|
||||
[#193](https://github.com/gimli-rs/addr2line/pull/193)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.13.0 (2020/07/07)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
* Added `rustc-dep-of-std` feature.
|
||||
[#166](https://github.com/gimli-rs/addr2line/pull/166)
|
||||
|
||||
### Changed
|
||||
|
||||
* Improve performance by parsing function contents lazily.
|
||||
[#178](https://github.com/gimli-rs/addr2line/pull/178)
|
||||
|
||||
* Don't skip `.debug_info` and `.debug_line` entries with a zero address.
|
||||
[#182](https://github.com/gimli-rs/addr2line/pull/182)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.12.2 (2020/06/21)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Avoid linear search for `DW_FORM_ref_addr`.
|
||||
[#175](https://github.com/gimli-rs/addr2line/pull/175)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.12.1 (2020/05/19)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Handle units with overlapping address ranges.
|
||||
[#163](https://github.com/gimli-rs/addr2line/pull/163)
|
||||
|
||||
* Don't assert for functions with overlapping address ranges.
|
||||
[#168](https://github.com/gimli-rs/addr2line/pull/168)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.12.0 (2020/05/12)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
* Added more optional features: `smallvec` and `fallible-iterator`.
|
||||
[#160](https://github.com/gimli-rs/addr2line/pull/160)
|
||||
|
||||
### Added
|
||||
|
||||
* Added `Context::dwarf` and `Context::find_dwarf_unit`.
|
||||
[#159](https://github.com/gimli-rs/addr2line/pull/159)
|
||||
|
||||
### Changed
|
||||
|
||||
* Removed `lazycell` dependency.
|
||||
[#160](https://github.com/gimli-rs/addr2line/pull/160)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.11.0 (2020/01/11)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Updated `gimli` and `object` dependencies.
|
||||
|
||||
* [#130](https://github.com/gimli-rs/addr2line/pull/130)
|
||||
Changed `Location::file` from `Option<String>` to `Option<&str>`.
|
||||
This required adding lifetime parameters to `Location` and other structs that
|
||||
contain it.
|
||||
|
||||
* [#152](https://github.com/gimli-rs/addr2line/pull/152)
|
||||
Changed `Location::line` and `Location::column` from `Option<u64>`to `Option<u32>`.
|
||||
|
||||
* [#156](https://github.com/gimli-rs/addr2line/pull/156)
|
||||
Deleted `alloc` feature, and fixed `no-std` builds with stable rust.
|
||||
Removed default `Reader` parameter for `Context`, and added `ObjectContext` instead.
|
||||
|
||||
### Added
|
||||
|
||||
* [#134](https://github.com/gimli-rs/addr2line/pull/134)
|
||||
Added `Context::from_dwarf`.
|
||||
|
||||
### Changed
|
||||
|
||||
* [#133](https://github.com/gimli-rs/addr2line/pull/133)
|
||||
Fixed handling of units that can't be parsed.
|
||||
|
||||
* [#155](https://github.com/gimli-rs/addr2line/pull/155)
|
||||
Fixed `addr2line` output to match binutils.
|
||||
|
||||
* [#130](https://github.com/gimli-rs/addr2line/pull/130)
|
||||
Improved `.debug_line` parsing performance.
|
||||
|
||||
* [#148](https://github.com/gimli-rs/addr2line/pull/148)
|
||||
[#150](https://github.com/gimli-rs/addr2line/pull/150)
|
||||
[#151](https://github.com/gimli-rs/addr2line/pull/151)
|
||||
[#152](https://github.com/gimli-rs/addr2line/pull/152)
|
||||
Improved `.debug_info` parsing performance.
|
||||
|
||||
* [#137](https://github.com/gimli-rs/addr2line/pull/137)
|
||||
[#138](https://github.com/gimli-rs/addr2line/pull/138)
|
||||
[#139](https://github.com/gimli-rs/addr2line/pull/139)
|
||||
[#140](https://github.com/gimli-rs/addr2line/pull/140)
|
||||
[#146](https://github.com/gimli-rs/addr2line/pull/146)
|
||||
Improved benchmarks.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.10.0 (2019/07/07)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* [#127](https://github.com/gimli-rs/addr2line/pull/127)
|
||||
Update `gimli`.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.9.0 (2019/05/02)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* [#121](https://github.com/gimli-rs/addr2line/pull/121)
|
||||
Update `gimli`, `object`, and `fallible-iterator` dependencies.
|
||||
|
||||
### Added
|
||||
|
||||
* [#121](https://github.com/gimli-rs/addr2line/pull/121)
|
||||
Reexport `gimli`, `object`, and `fallible-iterator`.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 0.8.0 (2019/02/06)
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* [#107](https://github.com/gimli-rs/addr2line/pull/107)
|
||||
Update `object` dependency to 0.11. This is part of the public API.
|
||||
|
||||
### Added
|
||||
|
||||
* [#101](https://github.com/gimli-rs/addr2line/pull/101)
|
||||
Add `object` feature (enabled by default). Disable this feature to remove
|
||||
the `object` dependency and `Context::new` API.
|
||||
|
||||
* [#102](https://github.com/gimli-rs/addr2line/pull/102)
|
||||
Add `std` (enabled by default) and `alloc` features.
|
||||
|
||||
### Changed
|
||||
|
||||
* [#108](https://github.com/gimli-rs/addr2line/issues/108)
|
||||
`demangle` no longer outputs the hash for rust symbols.
|
||||
|
||||
* [#109](https://github.com/gimli-rs/addr2line/issues/109)
|
||||
Set default `R` for `Context<R>`.
|
||||
548
vendor/addr2line/Cargo.lock
generated
vendored
Normal file
548
vendor/addr2line/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.20.0"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"clap",
|
||||
"compiler_builtins",
|
||||
"cpp_demangle",
|
||||
"fallible-iterator",
|
||||
"findshlibs",
|
||||
"gimli",
|
||||
"libtest-mimic",
|
||||
"memmap2",
|
||||
"object 0.31.0",
|
||||
"rustc-demangle",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"smallvec",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
|
||||
dependencies = [
|
||||
"addr2line 0.19.0",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object 0.30.3",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "571298a3cce7e2afbd3d61abb91a18667d5ab25993ec577a88ee8ac45f00cc3a"
|
||||
|
||||
[[package]]
|
||||
name = "cpp_demangle"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c76f98bdfc7f66172e6c7065f981ebb576ffc903fe4c0561d9f0c2509226dc6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "findshlibs"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"fallible-iterator",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.141"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
|
||||
|
||||
[[package]]
|
||||
name = "libtest-mimic"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79529479c298f5af41375b0c1a77ef670d450b4c9cd7949d2b43af08121b20ec"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"termcolor",
|
||||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.30.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d08090140cfee2e09897d6be320b47a45b79eb68b414de87130f9532966e2f1d"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-alloc"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff66d57013a5686e1917ed6a025d54dd591fcda71a41fe07edf4d16726aefa86"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-std-workspace-core"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c"
|
||||
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"thiserror",
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||
dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "1.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
145
vendor/addr2line/Cargo.toml
vendored
Normal file
145
vendor/addr2line/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# 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 are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "addr2line"
|
||||
version = "0.20.0"
|
||||
exclude = [
|
||||
"/benches/*",
|
||||
"/fixtures/*",
|
||||
".github",
|
||||
]
|
||||
description = "A cross-platform symbolication library written in Rust, using `gimli`"
|
||||
documentation = "https://docs.rs/addr2line"
|
||||
readme = "./README.md"
|
||||
keywords = [
|
||||
"DWARF",
|
||||
"debug",
|
||||
"elf",
|
||||
"symbolicate",
|
||||
"atos",
|
||||
]
|
||||
categories = ["development-tools::debugging"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/gimli-rs/addr2line"
|
||||
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = true
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
[[example]]
|
||||
name = "addr2line"
|
||||
required-features = ["default"]
|
||||
|
||||
[[test]]
|
||||
name = "output_equivalence"
|
||||
harness = false
|
||||
required-features = ["default"]
|
||||
|
||||
[[test]]
|
||||
name = "correctness"
|
||||
required-features = ["default"]
|
||||
|
||||
[[test]]
|
||||
name = "parse"
|
||||
required-features = ["std-object"]
|
||||
|
||||
[dependencies.alloc]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-alloc"
|
||||
|
||||
[dependencies.compiler_builtins]
|
||||
version = "0.1.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.core]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-core"
|
||||
|
||||
[dependencies.cpp_demangle]
|
||||
version = "0.4"
|
||||
features = ["alloc"]
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.fallible-iterator]
|
||||
version = "0.2"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.gimli]
|
||||
version = "0.27.2"
|
||||
features = ["read"]
|
||||
default-features = false
|
||||
|
||||
[dependencies.memmap2]
|
||||
version = "0.5.5"
|
||||
optional = true
|
||||
|
||||
[dependencies.object]
|
||||
version = "0.31.0"
|
||||
features = ["read"]
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.rustc-demangle]
|
||||
version = "0.1"
|
||||
optional = true
|
||||
|
||||
[dependencies.smallvec]
|
||||
version = "1"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.backtrace]
|
||||
version = "0.3.13"
|
||||
|
||||
[dev-dependencies.clap]
|
||||
version = "3.1.6"
|
||||
|
||||
[dev-dependencies.findshlibs]
|
||||
version = "0.10"
|
||||
|
||||
[dev-dependencies.libtest-mimic]
|
||||
version = "0.5.2"
|
||||
|
||||
[dev-dependencies.typed-arena]
|
||||
version = "2"
|
||||
|
||||
[features]
|
||||
default = [
|
||||
"rustc-demangle",
|
||||
"cpp_demangle",
|
||||
"std-object",
|
||||
"fallible-iterator",
|
||||
"smallvec",
|
||||
"memmap2",
|
||||
]
|
||||
rustc-dep-of-std = [
|
||||
"core",
|
||||
"alloc",
|
||||
"compiler_builtins",
|
||||
"gimli/rustc-dep-of-std",
|
||||
]
|
||||
std = ["gimli/std"]
|
||||
std-object = [
|
||||
"std",
|
||||
"object",
|
||||
"object/std",
|
||||
"object/compression",
|
||||
"gimli/endian-reader",
|
||||
]
|
||||
68
vendor/addr2line/Cargo.toml.orig
generated
vendored
Normal file
68
vendor/addr2line/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
[package]
|
||||
name = "addr2line"
|
||||
version = "0.20.0"
|
||||
description = "A cross-platform symbolication library written in Rust, using `gimli`"
|
||||
documentation = "https://docs.rs/addr2line"
|
||||
exclude = ["/benches/*", "/fixtures/*", ".github"]
|
||||
keywords = ["DWARF", "debug", "elf", "symbolicate", "atos"]
|
||||
categories = ["development-tools::debugging"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
readme = "./README.md"
|
||||
repository = "https://github.com/gimli-rs/addr2line"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
gimli = { version = "0.27.2", default-features = false, features = ["read"] }
|
||||
fallible-iterator = { version = "0.2", default-features = false, optional = true }
|
||||
memmap2 = { version = "0.5.5", optional = true }
|
||||
object = { version = "0.31.0", default-features = false, features = ["read"], optional = true }
|
||||
smallvec = { version = "1", default-features = false, optional = true }
|
||||
rustc-demangle = { version = "0.1", optional = true }
|
||||
cpp_demangle = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
|
||||
|
||||
# Internal feature, only used when building as part of libstd, not part of the
|
||||
# stable interface of this crate.
|
||||
core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' }
|
||||
alloc = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-alloc' }
|
||||
compiler_builtins = { version = '0.1.2', optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
clap = "3.1.6"
|
||||
backtrace = "0.3.13"
|
||||
findshlibs = "0.10"
|
||||
libtest-mimic = "0.5.2"
|
||||
auxiliary = { path = "tests/auxiliary" }
|
||||
typed-arena = "2"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
[profile.bench]
|
||||
debug = true
|
||||
codegen-units = 1
|
||||
|
||||
[features]
|
||||
default = ["rustc-demangle", "cpp_demangle", "std-object", "fallible-iterator", "smallvec", "memmap2"]
|
||||
std = ["gimli/std"]
|
||||
std-object = ["std", "object", "object/std", "object/compression", "gimli/endian-reader"]
|
||||
|
||||
# Internal feature, only used when building as part of libstd, not part of the
|
||||
# stable interface of this crate.
|
||||
rustc-dep-of-std = ['core', 'alloc', 'compiler_builtins', 'gimli/rustc-dep-of-std']
|
||||
|
||||
[[test]]
|
||||
name = "output_equivalence"
|
||||
harness = false
|
||||
required-features = ["default"]
|
||||
|
||||
[[test]]
|
||||
name = "correctness"
|
||||
required-features = ["default"]
|
||||
|
||||
[[test]]
|
||||
name = "parse"
|
||||
required-features = ["std-object"]
|
||||
|
||||
[[example]]
|
||||
name = "addr2line"
|
||||
required-features = ["default"]
|
||||
201
vendor/addr2line/LICENSE-APACHE
vendored
Normal file
201
vendor/addr2line/LICENSE-APACHE
vendored
Normal file
|
|
@ -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.
|
||||
25
vendor/addr2line/LICENSE-MIT
vendored
Normal file
25
vendor/addr2line/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2016-2018 The gimli 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.
|
||||
48
vendor/addr2line/README.md
vendored
Normal file
48
vendor/addr2line/README.md
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# addr2line
|
||||
|
||||
[](https://crates.io/crates/addr2line)
|
||||
[](https://docs.rs/addr2line)
|
||||
[](https://coveralls.io/github/gimli-rs/addr2line?branch=master)
|
||||
|
||||
A cross-platform library for retrieving per-address debug information
|
||||
from files with DWARF debug information.
|
||||
|
||||
`addr2line` uses [`gimli`](https://github.com/gimli-rs/gimli) to parse
|
||||
the debug information, and exposes an interface for finding
|
||||
the source file, line number, and wrapping function for instruction
|
||||
addresses within the target program. These lookups can either be
|
||||
performed programmatically through `Context::find_location` and
|
||||
`Context::find_frames`, or via the included example binary,
|
||||
`addr2line` (named and modelled after the equivalent utility from
|
||||
[GNU binutils](https://sourceware.org/binutils/docs/binutils/addr2line.html)).
|
||||
|
||||
# Quickstart
|
||||
- Add the [`addr2line` crate](https://crates.io/crates/addr2line) to your `Cargo.toml`
|
||||
- Load the file and parse it with [`addr2line::object::read::File::parse`](https://docs.rs/object/*/object/read/struct.File.html#method.parse)
|
||||
- Pass the parsed file to [`addr2line::Context::new` ](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.new)
|
||||
- Use [`addr2line::Context::find_location`](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.find_location)
|
||||
or [`addr2line::Context::find_frames`](https://docs.rs/addr2line/*/addr2line/struct.Context.html#method.find_frames)
|
||||
to look up debug information for an address
|
||||
|
||||
# Performance
|
||||
|
||||
`addr2line` optimizes for speed over memory by caching parsed information.
|
||||
The DWARF information is parsed lazily where possible.
|
||||
|
||||
The library aims to perform similarly to equivalent existing tools such
|
||||
as `addr2line` from binutils, `eu-addr2line` from elfutils, and
|
||||
`llvm-symbolize` from the llvm project, and in the past some benchmarking
|
||||
was done that indicates a comparable performance.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0 ([`LICENSE-APACHE`](./LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([`LICENSE-MIT`](./LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
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.
|
||||
23
vendor/addr2line/bench.plot.r
vendored
Normal file
23
vendor/addr2line/bench.plot.r
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
v <- read.table(file("stdin"))
|
||||
t <- data.frame(prog=v[,1], funcs=(v[,2]=="func"), time=v[,3], mem=v[,4], stringsAsFactors=FALSE)
|
||||
|
||||
t$prog <- as.character(t$prog)
|
||||
t$prog[t$prog == "master"] <- "gimli-rs/addr2line"
|
||||
t$funcs[t$funcs == TRUE] <- "With functions"
|
||||
t$funcs[t$funcs == FALSE] <- "File/line only"
|
||||
t$mem = t$mem / 1024.0
|
||||
|
||||
library(ggplot2)
|
||||
p <- ggplot(data=t, aes(x=prog, y=time, fill=prog))
|
||||
p <- p + geom_bar(stat = "identity")
|
||||
p <- p + facet_wrap(~ funcs)
|
||||
p <- p + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank())
|
||||
p <- p + ylab("time (s)") + ggtitle("addr2line runtime")
|
||||
ggsave('time.png',plot=p,width=10,height=6)
|
||||
|
||||
p <- ggplot(data=t, aes(x=prog, y=mem, fill=prog))
|
||||
p <- p + geom_bar(stat = "identity")
|
||||
p <- p + facet_wrap(~ funcs)
|
||||
p <- p + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank())
|
||||
p <- p + ylab("memory (kB)") + ggtitle("addr2line memory usage")
|
||||
ggsave('memory.png',plot=p,width=10,height=6)
|
||||
112
vendor/addr2line/benchmark.sh
vendored
Executable file
112
vendor/addr2line/benchmark.sh
vendored
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
#!/bin/bash
|
||||
if [[ $# -le 1 ]]; then
|
||||
echo "Usage: $0 <executable> [<addresses>] REFS..."
|
||||
exit 1
|
||||
fi
|
||||
target="$1"
|
||||
shift
|
||||
|
||||
addresses=""
|
||||
if [[ -e "$1" ]]; then
|
||||
addresses="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
# path to "us"
|
||||
# readlink -f, but more portable:
|
||||
dirname=$(perl -e 'use Cwd "abs_path";print abs_path(shift)' "$(dirname "$0")")
|
||||
|
||||
# https://stackoverflow.com/a/2358432/472927
|
||||
{
|
||||
# compile all refs
|
||||
pushd "$dirname" > /dev/null
|
||||
# if the user has some local changes, preserve them
|
||||
nstashed=$(git stash list | wc -l)
|
||||
echo "==> Stashing any local modifications"
|
||||
git stash --keep-index > /dev/null
|
||||
popstash() {
|
||||
# https://stackoverflow.com/q/24520791/472927
|
||||
if [[ "$(git stash list | wc -l)" -ne "$nstashed" ]]; then
|
||||
echo "==> Restoring stashed state"
|
||||
git stash pop > /dev/null
|
||||
fi
|
||||
}
|
||||
# if the user has added stuff to the index, abort
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
echo "Refusing to overwrite outstanding git changes"
|
||||
popstash
|
||||
exit 2
|
||||
fi
|
||||
current=$(git symbolic-ref --short HEAD)
|
||||
for ref in "$@"; do
|
||||
echo "==> Compiling $ref"
|
||||
git checkout -q "$ref"
|
||||
commit=$(git rev-parse HEAD)
|
||||
fn="target/release/addr2line-$commit"
|
||||
if [[ ! -e "$fn" ]]; then
|
||||
cargo build --release --example addr2line
|
||||
cp target/release/examples/addr2line "$fn"
|
||||
fi
|
||||
if [[ "$ref" != "$commit" ]]; then
|
||||
ln -sfn "addr2line-$commit" target/release/addr2line-"$ref"
|
||||
fi
|
||||
done
|
||||
git checkout -q "$current"
|
||||
popstash
|
||||
popd > /dev/null
|
||||
|
||||
# get us some addresses to look up
|
||||
if [[ -z "$addresses" ]]; then
|
||||
echo "==> Looking for benchmarking addresses (this may take a while)"
|
||||
addresses=$(mktemp tmp.XXXXXXXXXX)
|
||||
objdump -C -x --disassemble -l "$target" \
|
||||
| grep -P '0[048]:' \
|
||||
| awk '{print $1}' \
|
||||
| sed 's/:$//' \
|
||||
> "$addresses"
|
||||
echo " -> Addresses stored in $addresses; you should re-use it next time"
|
||||
fi
|
||||
|
||||
run() {
|
||||
func="$1"
|
||||
name="$2"
|
||||
cmd="$3"
|
||||
args="$4"
|
||||
printf "%s\t%s\t" "$name" "$func"
|
||||
if [[ "$cmd" =~ llvm-symbolizer ]]; then
|
||||
/usr/bin/time -f '%e\t%M' "$cmd" $args -obj="$target" < "$addresses" 2>&1 >/dev/null
|
||||
else
|
||||
/usr/bin/time -f '%e\t%M' "$cmd" $args -e "$target" < "$addresses" 2>&1 >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# run without functions
|
||||
log1=$(mktemp tmp.XXXXXXXXXX)
|
||||
echo "==> Benchmarking"
|
||||
run nofunc binutils addr2line >> "$log1"
|
||||
#run nofunc elfutils eu-addr2line >> "$log1"
|
||||
run nofunc llvm-sym llvm-symbolizer -functions=none >> "$log1"
|
||||
for ref in "$@"; do
|
||||
run nofunc "$ref" "$dirname/target/release/addr2line-$ref" >> "$log1"
|
||||
done
|
||||
cat "$log1" | column -t
|
||||
|
||||
# run with functions
|
||||
log2=$(mktemp tmp.XXXXXXXXXX)
|
||||
echo "==> Benchmarking with -f"
|
||||
run func binutils addr2line "-f -i" >> "$log2"
|
||||
#run func elfutils eu-addr2line "-f -i" >> "$log2"
|
||||
run func llvm-sym llvm-symbolizer "-functions=linkage -demangle=0" >> "$log2"
|
||||
for ref in "$@"; do
|
||||
run func "$ref" "$dirname/target/release/addr2line-$ref" "-f -i" >> "$log2"
|
||||
done
|
||||
cat "$log2" | column -t
|
||||
cat "$log2" >> "$log1"; rm "$log2"
|
||||
|
||||
echo "==> Plotting"
|
||||
Rscript --no-readline --no-restore --no-save "$dirname/bench.plot.r" < "$log1"
|
||||
|
||||
echo "==> Cleaning up"
|
||||
rm "$log1"
|
||||
exit 0
|
||||
}
|
||||
5
vendor/addr2line/coverage.sh
vendored
Normal file
5
vendor/addr2line/coverage.sh
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
# Run tarpaulin and pycobertura to generate coverage.html.
|
||||
|
||||
cargo tarpaulin --skip-clean --out Xml
|
||||
pycobertura show --format html --output coverage.html cobertura.xml
|
||||
306
vendor/addr2line/examples/addr2line.rs
vendored
Normal file
306
vendor/addr2line/examples/addr2line.rs
vendored
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, Lines, StdinLock, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use clap::{Arg, Command, Values};
|
||||
use fallible_iterator::FallibleIterator;
|
||||
use object::{Object, ObjectSection, SymbolMap, SymbolMapName};
|
||||
use typed_arena::Arena;
|
||||
|
||||
use addr2line::{Context, Location};
|
||||
|
||||
fn parse_uint_from_hex_string(string: &str) -> Option<u64> {
|
||||
if string.len() > 2 && string.starts_with("0x") {
|
||||
u64::from_str_radix(&string[2..], 16).ok()
|
||||
} else {
|
||||
u64::from_str_radix(string, 16).ok()
|
||||
}
|
||||
}
|
||||
|
||||
enum Addrs<'a> {
|
||||
Args(Values<'a>),
|
||||
Stdin(Lines<StdinLock<'a>>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Addrs<'a> {
|
||||
type Item = Option<u64>;
|
||||
|
||||
fn next(&mut self) -> Option<Option<u64>> {
|
||||
let text = match *self {
|
||||
Addrs::Args(ref mut vals) => vals.next().map(Cow::from),
|
||||
Addrs::Stdin(ref mut lines) => lines.next().map(Result::unwrap).map(Cow::from),
|
||||
};
|
||||
text.as_ref()
|
||||
.map(Cow::as_ref)
|
||||
.map(parse_uint_from_hex_string)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_loc(loc: Option<&Location<'_>>, basenames: bool, llvm: bool) {
|
||||
if let Some(loc) = loc {
|
||||
if let Some(ref file) = loc.file.as_ref() {
|
||||
let path = if basenames {
|
||||
Path::new(Path::new(file).file_name().unwrap())
|
||||
} else {
|
||||
Path::new(file)
|
||||
};
|
||||
print!("{}:", path.display());
|
||||
} else {
|
||||
print!("??:");
|
||||
}
|
||||
if llvm {
|
||||
print!("{}:{}", loc.line.unwrap_or(0), loc.column.unwrap_or(0));
|
||||
} else if let Some(line) = loc.line {
|
||||
print!("{}", line);
|
||||
} else {
|
||||
print!("?");
|
||||
}
|
||||
println!();
|
||||
} else if llvm {
|
||||
println!("??:0:0");
|
||||
} else {
|
||||
println!("??:0");
|
||||
}
|
||||
}
|
||||
|
||||
fn print_function(name: Option<&str>, language: Option<gimli::DwLang>, demangle: bool) {
|
||||
if let Some(name) = name {
|
||||
if demangle {
|
||||
print!("{}", addr2line::demangle_auto(Cow::from(name), language));
|
||||
} else {
|
||||
print!("{}", name);
|
||||
}
|
||||
} else {
|
||||
print!("??");
|
||||
}
|
||||
}
|
||||
|
||||
fn load_file_section<'input, 'arena, Endian: gimli::Endianity>(
|
||||
id: gimli::SectionId,
|
||||
file: &object::File<'input>,
|
||||
endian: Endian,
|
||||
arena_data: &'arena Arena<Cow<'input, [u8]>>,
|
||||
) -> Result<gimli::EndianSlice<'arena, Endian>, ()> {
|
||||
// TODO: Unify with dwarfdump.rs in gimli.
|
||||
let name = id.name();
|
||||
match file.section_by_name(name) {
|
||||
Some(section) => match section.uncompressed_data().unwrap() {
|
||||
Cow::Borrowed(b) => Ok(gimli::EndianSlice::new(b, endian)),
|
||||
Cow::Owned(b) => Ok(gimli::EndianSlice::new(arena_data.alloc(b.into()), endian)),
|
||||
},
|
||||
None => Ok(gimli::EndianSlice::new(&[][..], endian)),
|
||||
}
|
||||
}
|
||||
|
||||
fn find_name_from_symbols<'a>(
|
||||
symbols: &'a SymbolMap<SymbolMapName<'_>>,
|
||||
probe: u64,
|
||||
) -> Option<&'a str> {
|
||||
symbols.get(probe).map(|x| x.name())
|
||||
}
|
||||
|
||||
struct Options<'a> {
|
||||
do_functions: bool,
|
||||
do_inlines: bool,
|
||||
pretty: bool,
|
||||
print_addrs: bool,
|
||||
basenames: bool,
|
||||
demangle: bool,
|
||||
llvm: bool,
|
||||
exe: &'a PathBuf,
|
||||
sup: Option<&'a PathBuf>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = Command::new("addr2line")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.about("A fast addr2line Rust port")
|
||||
.args(&[
|
||||
Arg::new("exe")
|
||||
.short('e')
|
||||
.long("exe")
|
||||
.value_name("filename")
|
||||
.value_parser(clap::value_parser!(PathBuf))
|
||||
.help(
|
||||
"Specify the name of the executable for which addresses should be translated.",
|
||||
)
|
||||
.required(true),
|
||||
Arg::new("sup")
|
||||
.long("sup")
|
||||
.value_name("filename")
|
||||
.value_parser(clap::value_parser!(PathBuf))
|
||||
.help("Path to supplementary object file."),
|
||||
Arg::new("functions")
|
||||
.short('f')
|
||||
.long("functions")
|
||||
.help("Display function names as well as file and line number information."),
|
||||
Arg::new("pretty").short('p').long("pretty-print").help(
|
||||
"Make the output more human friendly: each location are printed on one line.",
|
||||
),
|
||||
Arg::new("inlines").short('i').long("inlines").help(
|
||||
"If the address belongs to a function that was inlined, the source information for \
|
||||
all enclosing scopes back to the first non-inlined function will also be printed.",
|
||||
),
|
||||
Arg::new("addresses").short('a').long("addresses").help(
|
||||
"Display the address before the function name, file and line number information.",
|
||||
),
|
||||
Arg::new("basenames")
|
||||
.short('s')
|
||||
.long("basenames")
|
||||
.help("Display only the base of each file name."),
|
||||
Arg::new("demangle").short('C').long("demangle").help(
|
||||
"Demangle function names. \
|
||||
Specifying a specific demangling style (like GNU addr2line) is not supported. \
|
||||
(TODO)"
|
||||
),
|
||||
Arg::new("llvm")
|
||||
.long("llvm")
|
||||
.help("Display output in the same format as llvm-symbolizer."),
|
||||
Arg::new("addrs")
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true)
|
||||
.help("Addresses to use instead of reading from stdin."),
|
||||
])
|
||||
.get_matches();
|
||||
|
||||
let arena_data = Arena::new();
|
||||
|
||||
let opts = Options {
|
||||
do_functions: matches.is_present("functions"),
|
||||
do_inlines: matches.is_present("inlines"),
|
||||
pretty: matches.is_present("pretty"),
|
||||
print_addrs: matches.is_present("addresses"),
|
||||
basenames: matches.is_present("basenames"),
|
||||
demangle: matches.is_present("demangle"),
|
||||
llvm: matches.is_present("llvm"),
|
||||
exe: matches.get_one::<PathBuf>("exe").unwrap(),
|
||||
sup: matches.get_one::<PathBuf>("sup"),
|
||||
};
|
||||
|
||||
let file = File::open(opts.exe).unwrap();
|
||||
let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
|
||||
let object = &object::File::parse(&*map).unwrap();
|
||||
|
||||
let endian = if object.is_little_endian() {
|
||||
gimli::RunTimeEndian::Little
|
||||
} else {
|
||||
gimli::RunTimeEndian::Big
|
||||
};
|
||||
|
||||
let mut load_section = |id: gimli::SectionId| -> Result<_, _> {
|
||||
load_file_section(id, object, endian, &arena_data)
|
||||
};
|
||||
|
||||
let sup_map;
|
||||
let sup_object = if let Some(sup_path) = opts.sup {
|
||||
let sup_file = File::open(sup_path).unwrap();
|
||||
sup_map = unsafe { memmap2::Mmap::map(&sup_file).unwrap() };
|
||||
Some(object::File::parse(&*sup_map).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let symbols = object.symbol_map();
|
||||
let mut dwarf = gimli::Dwarf::load(&mut load_section).unwrap();
|
||||
if let Some(ref sup_object) = sup_object {
|
||||
let mut load_sup_section = |id: gimli::SectionId| -> Result<_, _> {
|
||||
load_file_section(id, sup_object, endian, &arena_data)
|
||||
};
|
||||
dwarf.load_sup(&mut load_sup_section).unwrap();
|
||||
}
|
||||
|
||||
let mut split_dwarf_loader = addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new(
|
||||
|data, endian| {
|
||||
gimli::EndianSlice::new(arena_data.alloc(Cow::Owned(data.into_owned())), endian)
|
||||
},
|
||||
Some(opts.exe.clone()),
|
||||
);
|
||||
let ctx = Context::from_dwarf(dwarf).unwrap();
|
||||
|
||||
let stdin = std::io::stdin();
|
||||
let addrs = matches
|
||||
.values_of("addrs")
|
||||
.map(Addrs::Args)
|
||||
.unwrap_or_else(|| Addrs::Stdin(stdin.lock().lines()));
|
||||
|
||||
for probe in addrs {
|
||||
if opts.print_addrs {
|
||||
let addr = probe.unwrap_or(0);
|
||||
if opts.llvm {
|
||||
print!("0x{:x}", addr);
|
||||
} else {
|
||||
print!("0x{:016x}", addr);
|
||||
}
|
||||
if opts.pretty {
|
||||
print!(": ");
|
||||
} else {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
if opts.do_functions || opts.do_inlines {
|
||||
let mut printed_anything = false;
|
||||
if let Some(probe) = probe {
|
||||
let frames = ctx.find_frames(probe);
|
||||
let frames = split_dwarf_loader.run(frames).unwrap();
|
||||
let mut frames = frames.enumerate();
|
||||
while let Some((i, frame)) = frames.next().unwrap() {
|
||||
if opts.pretty && i != 0 {
|
||||
print!(" (inlined by) ");
|
||||
}
|
||||
|
||||
if opts.do_functions {
|
||||
if let Some(func) = frame.function {
|
||||
print_function(
|
||||
func.raw_name().ok().as_ref().map(AsRef::as_ref),
|
||||
func.language,
|
||||
opts.demangle,
|
||||
);
|
||||
} else {
|
||||
let name = find_name_from_symbols(&symbols, probe);
|
||||
print_function(name, None, opts.demangle);
|
||||
}
|
||||
|
||||
if opts.pretty {
|
||||
print!(" at ");
|
||||
} else {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
print_loc(frame.location.as_ref(), opts.basenames, opts.llvm);
|
||||
|
||||
printed_anything = true;
|
||||
|
||||
if !opts.do_inlines {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !printed_anything {
|
||||
if opts.do_functions {
|
||||
let name = probe.and_then(|probe| find_name_from_symbols(&symbols, probe));
|
||||
print_function(name, None, opts.demangle);
|
||||
|
||||
if opts.pretty {
|
||||
print!(" at ");
|
||||
} else {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
print_loc(None, opts.basenames, opts.llvm);
|
||||
}
|
||||
} else {
|
||||
let loc = probe.and_then(|probe| ctx.find_location(probe).unwrap());
|
||||
print_loc(loc.as_ref(), opts.basenames, opts.llvm);
|
||||
}
|
||||
|
||||
if opts.llvm {
|
||||
println!();
|
||||
}
|
||||
std::io::stdout().flush().unwrap();
|
||||
}
|
||||
}
|
||||
1
vendor/addr2line/rustfmt.toml
vendored
Normal file
1
vendor/addr2line/rustfmt.toml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
164
vendor/addr2line/src/builtin_split_dwarf_loader.rs
vendored
Normal file
164
vendor/addr2line/src/builtin_split_dwarf_loader.rs
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
use alloc::borrow::Cow;
|
||||
use alloc::sync::Arc;
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use object::Object;
|
||||
|
||||
use crate::{LookupContinuation, LookupResult};
|
||||
|
||||
#[cfg(unix)]
|
||||
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
|
||||
r: &R,
|
||||
) -> Result<PathBuf, gimli::Error> {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
let bytes = r.to_slice()?;
|
||||
let s = OsStr::from_bytes(&bytes);
|
||||
Ok(PathBuf::from(s))
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
|
||||
r: &R,
|
||||
) -> Result<PathBuf, gimli::Error> {
|
||||
let bytes = r.to_slice()?;
|
||||
let s = std::str::from_utf8(&bytes).map_err(|_| gimli::Error::BadUtf8)?;
|
||||
Ok(PathBuf::from(s))
|
||||
}
|
||||
|
||||
fn load_section<'data: 'file, 'file, O, R, F>(
|
||||
id: gimli::SectionId,
|
||||
file: &'file O,
|
||||
endian: R::Endian,
|
||||
loader: &mut F,
|
||||
) -> Result<R, gimli::Error>
|
||||
where
|
||||
O: object::Object<'data, 'file>,
|
||||
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
|
||||
F: FnMut(Cow<'data, [u8]>, R::Endian) -> R,
|
||||
{
|
||||
use object::ObjectSection;
|
||||
|
||||
let data = id
|
||||
.dwo_name()
|
||||
.and_then(|dwo_name| {
|
||||
file.section_by_name(dwo_name)
|
||||
.and_then(|section| section.uncompressed_data().ok())
|
||||
})
|
||||
.unwrap_or(Cow::Borrowed(&[]));
|
||||
Ok(loader(data, endian))
|
||||
}
|
||||
|
||||
/// A simple builtin split DWARF loader.
|
||||
pub struct SplitDwarfLoader<R, F>
|
||||
where
|
||||
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
|
||||
F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
|
||||
{
|
||||
loader: F,
|
||||
dwarf_package: Option<gimli::DwarfPackage<R>>,
|
||||
}
|
||||
|
||||
impl<R, F> SplitDwarfLoader<R, F>
|
||||
where
|
||||
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
|
||||
F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
|
||||
{
|
||||
fn load_dwarf_package(loader: &mut F, path: Option<PathBuf>) -> Option<gimli::DwarfPackage<R>> {
|
||||
let mut path = path.map(Ok).unwrap_or_else(std::env::current_exe).ok()?;
|
||||
let dwp_extension = path
|
||||
.extension()
|
||||
.map(|previous_extension| {
|
||||
let mut previous_extension = previous_extension.to_os_string();
|
||||
previous_extension.push(".dwp");
|
||||
previous_extension
|
||||
})
|
||||
.unwrap_or_else(|| "dwp".into());
|
||||
path.set_extension(dwp_extension);
|
||||
let file = File::open(&path).ok()?;
|
||||
let map = unsafe { memmap2::Mmap::map(&file).ok()? };
|
||||
let dwp = object::File::parse(&*map).ok()?;
|
||||
|
||||
let endian = if dwp.is_little_endian() {
|
||||
gimli::RunTimeEndian::Little
|
||||
} else {
|
||||
gimli::RunTimeEndian::Big
|
||||
};
|
||||
|
||||
let empty = loader(Cow::Borrowed(&[]), endian);
|
||||
gimli::DwarfPackage::load(
|
||||
|section_id| load_section(section_id, &dwp, endian, loader),
|
||||
empty,
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Create a new split DWARF loader.
|
||||
pub fn new(mut loader: F, path: Option<PathBuf>) -> SplitDwarfLoader<R, F> {
|
||||
let dwarf_package = SplitDwarfLoader::load_dwarf_package(&mut loader, path);
|
||||
SplitDwarfLoader {
|
||||
loader,
|
||||
dwarf_package,
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the provided `LookupResult` to completion, loading any necessary
|
||||
/// split DWARF along the way.
|
||||
pub fn run<L>(&mut self, mut l: LookupResult<L>) -> L::Output
|
||||
where
|
||||
L: LookupContinuation<Buf = R>,
|
||||
{
|
||||
loop {
|
||||
let (load, continuation) = match l {
|
||||
LookupResult::Output(output) => break output,
|
||||
LookupResult::Load { load, continuation } => (load, continuation),
|
||||
};
|
||||
|
||||
let mut r: Option<Arc<gimli::Dwarf<_>>> = None;
|
||||
if let Some(dwp) = self.dwarf_package.as_ref() {
|
||||
if let Ok(Some(cu)) = dwp.find_cu(load.dwo_id, &load.parent) {
|
||||
r = Some(Arc::new(cu));
|
||||
}
|
||||
}
|
||||
|
||||
if r.is_none() {
|
||||
let mut path = PathBuf::new();
|
||||
if let Some(p) = load.comp_dir.as_ref() {
|
||||
if let Ok(p) = convert_path(p) {
|
||||
path.push(p);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(p) = load.path.as_ref() {
|
||||
if let Ok(p) = convert_path(p) {
|
||||
path.push(p);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(file) = File::open(&path) {
|
||||
if let Ok(map) = unsafe { memmap2::Mmap::map(&file) } {
|
||||
if let Ok(file) = object::File::parse(&*map) {
|
||||
let endian = if file.is_little_endian() {
|
||||
gimli::RunTimeEndian::Little
|
||||
} else {
|
||||
gimli::RunTimeEndian::Big
|
||||
};
|
||||
|
||||
r = gimli::Dwarf::load(|id| {
|
||||
load_section(id, &file, endian, &mut self.loader)
|
||||
})
|
||||
.ok()
|
||||
.map(|mut dwo_dwarf| {
|
||||
dwo_dwarf.make_dwo(&load.parent);
|
||||
Arc::new(dwo_dwarf)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l = continuation.resume(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
555
vendor/addr2line/src/function.rs
vendored
Normal file
555
vendor/addr2line/src/function.rs
vendored
Normal file
|
|
@ -0,0 +1,555 @@
|
|||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use core::cmp::Ordering;
|
||||
use core::iter;
|
||||
|
||||
use crate::lazy::LazyCell;
|
||||
use crate::maybe_small;
|
||||
use crate::{Context, DebugFile, Error, RangeAttributes};
|
||||
|
||||
pub(crate) struct Functions<R: gimli::Reader> {
|
||||
/// List of all `DW_TAG_subprogram` details in the unit.
|
||||
pub(crate) functions: Box<
|
||||
[(
|
||||
gimli::UnitOffset<R::Offset>,
|
||||
LazyCell<Result<Function<R>, Error>>,
|
||||
)],
|
||||
>,
|
||||
/// List of `DW_TAG_subprogram` address ranges in the unit.
|
||||
pub(crate) addresses: Box<[FunctionAddress]>,
|
||||
}
|
||||
|
||||
/// A single address range for a function.
|
||||
///
|
||||
/// It is possible for a function to have multiple address ranges; this
|
||||
/// is handled by having multiple `FunctionAddress` entries with the same
|
||||
/// `function` field.
|
||||
pub(crate) struct FunctionAddress {
|
||||
range: gimli::Range,
|
||||
/// An index into `Functions::functions`.
|
||||
pub(crate) function: usize,
|
||||
}
|
||||
|
||||
pub(crate) struct Function<R: gimli::Reader> {
|
||||
pub(crate) dw_die_offset: gimli::UnitOffset<R::Offset>,
|
||||
pub(crate) name: Option<R>,
|
||||
/// List of all `DW_TAG_inlined_subroutine` details in this function.
|
||||
inlined_functions: Box<[InlinedFunction<R>]>,
|
||||
/// List of `DW_TAG_inlined_subroutine` address ranges in this function.
|
||||
inlined_addresses: Box<[InlinedFunctionAddress]>,
|
||||
}
|
||||
|
||||
pub(crate) struct InlinedFunctionAddress {
|
||||
range: gimli::Range,
|
||||
call_depth: usize,
|
||||
/// An index into `Function::inlined_functions`.
|
||||
function: usize,
|
||||
}
|
||||
|
||||
pub(crate) struct InlinedFunction<R: gimli::Reader> {
|
||||
pub(crate) dw_die_offset: gimli::UnitOffset<R::Offset>,
|
||||
pub(crate) name: Option<R>,
|
||||
pub(crate) call_file: Option<u64>,
|
||||
pub(crate) call_line: u32,
|
||||
pub(crate) call_column: u32,
|
||||
}
|
||||
|
||||
impl<R: gimli::Reader> Functions<R> {
|
||||
pub(crate) fn parse(
|
||||
unit: &gimli::Unit<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
) -> Result<Functions<R>, Error> {
|
||||
let mut functions = Vec::new();
|
||||
let mut addresses = Vec::new();
|
||||
let mut entries = unit.entries_raw(None)?;
|
||||
while !entries.is_empty() {
|
||||
let dw_die_offset = entries.next_offset();
|
||||
if let Some(abbrev) = entries.read_abbreviation()? {
|
||||
if abbrev.tag() == gimli::DW_TAG_subprogram {
|
||||
let mut ranges = RangeAttributes::default();
|
||||
for spec in abbrev.attributes() {
|
||||
match entries.read_attribute(*spec) {
|
||||
Ok(ref attr) => {
|
||||
match attr.name() {
|
||||
gimli::DW_AT_low_pc => match attr.value() {
|
||||
gimli::AttributeValue::Addr(val) => {
|
||||
ranges.low_pc = Some(val)
|
||||
}
|
||||
gimli::AttributeValue::DebugAddrIndex(index) => {
|
||||
ranges.low_pc = Some(sections.address(unit, index)?);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
gimli::DW_AT_high_pc => match attr.value() {
|
||||
gimli::AttributeValue::Addr(val) => {
|
||||
ranges.high_pc = Some(val)
|
||||
}
|
||||
gimli::AttributeValue::DebugAddrIndex(index) => {
|
||||
ranges.high_pc = Some(sections.address(unit, index)?);
|
||||
}
|
||||
gimli::AttributeValue::Udata(val) => {
|
||||
ranges.size = Some(val)
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
gimli::DW_AT_ranges => {
|
||||
ranges.ranges_offset =
|
||||
sections.attr_ranges_offset(unit, attr.value())?;
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
let function_index = functions.len();
|
||||
if ranges.for_each_range(sections, unit, |range| {
|
||||
addresses.push(FunctionAddress {
|
||||
range,
|
||||
function: function_index,
|
||||
});
|
||||
})? {
|
||||
functions.push((dw_die_offset, LazyCell::new()));
|
||||
}
|
||||
} else {
|
||||
entries.skip_attributes(abbrev.attributes())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The binary search requires the addresses to be sorted.
|
||||
//
|
||||
// It also requires them to be non-overlapping. In practice, overlapping
|
||||
// function ranges are unlikely, so we don't try to handle that yet.
|
||||
//
|
||||
// It's possible for multiple functions to have the same address range if the
|
||||
// compiler can detect and remove functions with identical code. In that case
|
||||
// we'll nondeterministically return one of them.
|
||||
addresses.sort_by_key(|x| x.range.begin);
|
||||
|
||||
Ok(Functions {
|
||||
functions: functions.into_boxed_slice(),
|
||||
addresses: addresses.into_boxed_slice(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn find_address(&self, probe: u64) -> Option<usize> {
|
||||
self.addresses
|
||||
.binary_search_by(|address| {
|
||||
if probe < address.range.begin {
|
||||
Ordering::Greater
|
||||
} else if probe >= address.range.end {
|
||||
Ordering::Less
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
})
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub(crate) fn parse_inlined_functions(
|
||||
&self,
|
||||
file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
) -> Result<(), Error> {
|
||||
for function in &*self.functions {
|
||||
function
|
||||
.1
|
||||
.borrow_with(|| Function::parse(function.0, file, unit, ctx, sections))
|
||||
.as_ref()
|
||||
.map_err(Error::clone)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: gimli::Reader> Function<R> {
|
||||
pub(crate) fn parse(
|
||||
dw_die_offset: gimli::UnitOffset<R::Offset>,
|
||||
file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
) -> Result<Self, Error> {
|
||||
let mut entries = unit.entries_raw(Some(dw_die_offset))?;
|
||||
let depth = entries.next_depth();
|
||||
let abbrev = entries.read_abbreviation()?.unwrap();
|
||||
debug_assert_eq!(abbrev.tag(), gimli::DW_TAG_subprogram);
|
||||
|
||||
let mut name = None;
|
||||
for spec in abbrev.attributes() {
|
||||
match entries.read_attribute(*spec) {
|
||||
Ok(ref attr) => {
|
||||
match attr.name() {
|
||||
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
|
||||
if let Ok(val) = sections.attr_string(unit, attr.value()) {
|
||||
name = Some(val);
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_name => {
|
||||
if name.is_none() {
|
||||
name = sections.attr_string(unit, attr.value()).ok();
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
|
||||
if name.is_none() {
|
||||
name = name_attr(attr.value(), file, unit, ctx, sections, 16)?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
let mut inlined_functions = Vec::new();
|
||||
let mut inlined_addresses = Vec::new();
|
||||
Function::parse_children(
|
||||
&mut entries,
|
||||
depth,
|
||||
file,
|
||||
unit,
|
||||
ctx,
|
||||
sections,
|
||||
&mut inlined_functions,
|
||||
&mut inlined_addresses,
|
||||
0,
|
||||
)?;
|
||||
|
||||
// Sort ranges in "breadth-first traversal order", i.e. first by call_depth
|
||||
// and then by range.begin. This allows finding the range containing an
|
||||
// address at a certain depth using binary search.
|
||||
// Note: Using DFS order, i.e. ordering by range.begin first and then by
|
||||
// call_depth, would not work! Consider the two examples
|
||||
// "[0..10 at depth 0], [0..2 at depth 1], [6..8 at depth 1]" and
|
||||
// "[0..5 at depth 0], [0..2 at depth 1], [5..10 at depth 0], [6..8 at depth 1]".
|
||||
// In this example, if you want to look up address 7 at depth 0, and you
|
||||
// encounter [0..2 at depth 1], are you before or after the target range?
|
||||
// You don't know.
|
||||
inlined_addresses.sort_by(|r1, r2| {
|
||||
if r1.call_depth < r2.call_depth {
|
||||
Ordering::Less
|
||||
} else if r1.call_depth > r2.call_depth {
|
||||
Ordering::Greater
|
||||
} else if r1.range.begin < r2.range.begin {
|
||||
Ordering::Less
|
||||
} else if r1.range.begin > r2.range.begin {
|
||||
Ordering::Greater
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Function {
|
||||
dw_die_offset,
|
||||
name,
|
||||
inlined_functions: inlined_functions.into_boxed_slice(),
|
||||
inlined_addresses: inlined_addresses.into_boxed_slice(),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_children(
|
||||
entries: &mut gimli::EntriesRaw<'_, '_, R>,
|
||||
depth: isize,
|
||||
file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
inlined_functions: &mut Vec<InlinedFunction<R>>,
|
||||
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
|
||||
inlined_depth: usize,
|
||||
) -> Result<(), Error> {
|
||||
loop {
|
||||
let dw_die_offset = entries.next_offset();
|
||||
let next_depth = entries.next_depth();
|
||||
if next_depth <= depth {
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(abbrev) = entries.read_abbreviation()? {
|
||||
match abbrev.tag() {
|
||||
gimli::DW_TAG_subprogram => {
|
||||
Function::skip(entries, abbrev, next_depth)?;
|
||||
}
|
||||
gimli::DW_TAG_inlined_subroutine => {
|
||||
InlinedFunction::parse(
|
||||
dw_die_offset,
|
||||
entries,
|
||||
abbrev,
|
||||
next_depth,
|
||||
file,
|
||||
unit,
|
||||
ctx,
|
||||
sections,
|
||||
inlined_functions,
|
||||
inlined_addresses,
|
||||
inlined_depth,
|
||||
)?;
|
||||
}
|
||||
_ => {
|
||||
entries.skip_attributes(abbrev.attributes())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn skip(
|
||||
entries: &mut gimli::EntriesRaw<'_, '_, R>,
|
||||
abbrev: &gimli::Abbreviation,
|
||||
depth: isize,
|
||||
) -> Result<(), Error> {
|
||||
// TODO: use DW_AT_sibling
|
||||
entries.skip_attributes(abbrev.attributes())?;
|
||||
while entries.next_depth() > depth {
|
||||
if let Some(abbrev) = entries.read_abbreviation()? {
|
||||
entries.skip_attributes(abbrev.attributes())?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build the list of inlined functions that contain `probe`.
|
||||
pub(crate) fn find_inlined_functions(
|
||||
&self,
|
||||
probe: u64,
|
||||
) -> iter::Rev<maybe_small::IntoIter<&InlinedFunction<R>>> {
|
||||
// `inlined_functions` is ordered from outside to inside.
|
||||
let mut inlined_functions = maybe_small::Vec::new();
|
||||
let mut inlined_addresses = &self.inlined_addresses[..];
|
||||
loop {
|
||||
let current_depth = inlined_functions.len();
|
||||
// Look up (probe, current_depth) in inline_ranges.
|
||||
// `inlined_addresses` is sorted in "breadth-first traversal order", i.e.
|
||||
// by `call_depth` first, and then by `range.begin`. See the comment at
|
||||
// the sort call for more information about why.
|
||||
let search = inlined_addresses.binary_search_by(|range| {
|
||||
if range.call_depth > current_depth {
|
||||
Ordering::Greater
|
||||
} else if range.call_depth < current_depth {
|
||||
Ordering::Less
|
||||
} else if range.range.begin > probe {
|
||||
Ordering::Greater
|
||||
} else if range.range.end <= probe {
|
||||
Ordering::Less
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
});
|
||||
if let Ok(index) = search {
|
||||
let function_index = inlined_addresses[index].function;
|
||||
inlined_functions.push(&self.inlined_functions[function_index]);
|
||||
inlined_addresses = &inlined_addresses[index + 1..];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
inlined_functions.into_iter().rev()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: gimli::Reader> InlinedFunction<R> {
|
||||
fn parse(
|
||||
dw_die_offset: gimli::UnitOffset<R::Offset>,
|
||||
entries: &mut gimli::EntriesRaw<'_, '_, R>,
|
||||
abbrev: &gimli::Abbreviation,
|
||||
depth: isize,
|
||||
file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
inlined_functions: &mut Vec<InlinedFunction<R>>,
|
||||
inlined_addresses: &mut Vec<InlinedFunctionAddress>,
|
||||
inlined_depth: usize,
|
||||
) -> Result<(), Error> {
|
||||
let mut ranges = RangeAttributes::default();
|
||||
let mut name = None;
|
||||
let mut call_file = None;
|
||||
let mut call_line = 0;
|
||||
let mut call_column = 0;
|
||||
for spec in abbrev.attributes() {
|
||||
match entries.read_attribute(*spec) {
|
||||
Ok(ref attr) => match attr.name() {
|
||||
gimli::DW_AT_low_pc => match attr.value() {
|
||||
gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val),
|
||||
gimli::AttributeValue::DebugAddrIndex(index) => {
|
||||
ranges.low_pc = Some(sections.address(unit, index)?);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
gimli::DW_AT_high_pc => match attr.value() {
|
||||
gimli::AttributeValue::Addr(val) => ranges.high_pc = Some(val),
|
||||
gimli::AttributeValue::DebugAddrIndex(index) => {
|
||||
ranges.high_pc = Some(sections.address(unit, index)?);
|
||||
}
|
||||
gimli::AttributeValue::Udata(val) => ranges.size = Some(val),
|
||||
_ => {}
|
||||
},
|
||||
gimli::DW_AT_ranges => {
|
||||
ranges.ranges_offset = sections.attr_ranges_offset(unit, attr.value())?;
|
||||
}
|
||||
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
|
||||
if let Ok(val) = sections.attr_string(unit, attr.value()) {
|
||||
name = Some(val);
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_name => {
|
||||
if name.is_none() {
|
||||
name = sections.attr_string(unit, attr.value()).ok();
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
|
||||
if name.is_none() {
|
||||
name = name_attr(attr.value(), file, unit, ctx, sections, 16)?;
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_call_file => {
|
||||
// There is a spec issue [1] with how DW_AT_call_file is specified in DWARF 5.
|
||||
// Before, a file index of 0 would indicate no source file, however in
|
||||
// DWARF 5 this could be a valid index into the file table.
|
||||
//
|
||||
// Implementations such as LLVM generates a file index of 0 when DWARF 5 is
|
||||
// used.
|
||||
//
|
||||
// Thus, if we see a version of 5 or later, treat a file index of 0 as such.
|
||||
// [1]: http://wiki.dwarfstd.org/index.php?title=DWARF5_Line_Table_File_Numbers
|
||||
if let gimli::AttributeValue::FileIndex(fi) = attr.value() {
|
||||
if fi > 0 || unit.header.version() >= 5 {
|
||||
call_file = Some(fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_call_line => {
|
||||
call_line = attr.udata_value().unwrap_or(0) as u32;
|
||||
}
|
||||
gimli::DW_AT_call_column => {
|
||||
call_column = attr.udata_value().unwrap_or(0) as u32;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
let function_index = inlined_functions.len();
|
||||
inlined_functions.push(InlinedFunction {
|
||||
dw_die_offset,
|
||||
name,
|
||||
call_file,
|
||||
call_line,
|
||||
call_column,
|
||||
});
|
||||
|
||||
ranges.for_each_range(sections, unit, |range| {
|
||||
inlined_addresses.push(InlinedFunctionAddress {
|
||||
range,
|
||||
call_depth: inlined_depth,
|
||||
function: function_index,
|
||||
});
|
||||
})?;
|
||||
|
||||
Function::parse_children(
|
||||
entries,
|
||||
depth,
|
||||
file,
|
||||
unit,
|
||||
ctx,
|
||||
sections,
|
||||
inlined_functions,
|
||||
inlined_addresses,
|
||||
inlined_depth + 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn name_attr<R>(
|
||||
attr: gimli::AttributeValue<R>,
|
||||
mut file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
recursion_limit: usize,
|
||||
) -> Result<Option<R>, Error>
|
||||
where
|
||||
R: gimli::Reader,
|
||||
{
|
||||
if recursion_limit == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
match attr {
|
||||
gimli::AttributeValue::UnitRef(offset) => {
|
||||
name_entry(file, unit, offset, ctx, sections, recursion_limit)
|
||||
}
|
||||
gimli::AttributeValue::DebugInfoRef(dr) => {
|
||||
let (unit, offset) = ctx.find_unit(dr, file)?;
|
||||
name_entry(file, unit, offset, ctx, sections, recursion_limit)
|
||||
}
|
||||
gimli::AttributeValue::DebugInfoRefSup(dr) => {
|
||||
if let Some(sup_sections) = sections.sup.as_ref() {
|
||||
file = DebugFile::Supplementary;
|
||||
let (unit, offset) = ctx.find_unit(dr, file)?;
|
||||
name_entry(file, unit, offset, ctx, sup_sections, recursion_limit)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn name_entry<R>(
|
||||
file: DebugFile,
|
||||
unit: &gimli::Unit<R>,
|
||||
offset: gimli::UnitOffset<R::Offset>,
|
||||
ctx: &Context<R>,
|
||||
sections: &gimli::Dwarf<R>,
|
||||
recursion_limit: usize,
|
||||
) -> Result<Option<R>, Error>
|
||||
where
|
||||
R: gimli::Reader,
|
||||
{
|
||||
let mut entries = unit.entries_raw(Some(offset))?;
|
||||
let abbrev = if let Some(abbrev) = entries.read_abbreviation()? {
|
||||
abbrev
|
||||
} else {
|
||||
return Err(gimli::Error::NoEntryAtGivenOffset);
|
||||
};
|
||||
|
||||
let mut name = None;
|
||||
let mut next = None;
|
||||
for spec in abbrev.attributes() {
|
||||
match entries.read_attribute(*spec) {
|
||||
Ok(ref attr) => match attr.name() {
|
||||
gimli::DW_AT_linkage_name | gimli::DW_AT_MIPS_linkage_name => {
|
||||
if let Ok(val) = sections.attr_string(unit, attr.value()) {
|
||||
return Ok(Some(val));
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_name => {
|
||||
if let Ok(val) = sections.attr_string(unit, attr.value()) {
|
||||
name = Some(val);
|
||||
}
|
||||
}
|
||||
gimli::DW_AT_abstract_origin | gimli::DW_AT_specification => {
|
||||
next = Some(attr.value());
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
if name.is_some() {
|
||||
return Ok(name);
|
||||
}
|
||||
|
||||
if let Some(next) = next {
|
||||
return name_attr(next, file, unit, ctx, sections, recursion_limit - 1);
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
31
vendor/addr2line/src/lazy.rs
vendored
Normal file
31
vendor/addr2line/src/lazy.rs
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use core::cell::UnsafeCell;
|
||||
|
||||
pub struct LazyCell<T> {
|
||||
contents: UnsafeCell<Option<T>>,
|
||||
}
|
||||
impl<T> LazyCell<T> {
|
||||
pub fn new() -> LazyCell<T> {
|
||||
LazyCell {
|
||||
contents: UnsafeCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow(&self) -> Option<&T> {
|
||||
unsafe { &*self.contents.get() }.as_ref()
|
||||
}
|
||||
|
||||
pub fn borrow_with(&self, closure: impl FnOnce() -> T) -> &T {
|
||||
// First check if we're already initialized...
|
||||
let ptr = self.contents.get();
|
||||
if let Some(val) = unsafe { &*ptr } {
|
||||
return val;
|
||||
}
|
||||
// Note that while we're executing `closure` our `borrow_with` may
|
||||
// be called recursively. This means we need to check again after
|
||||
// the closure has executed. For that we use the `get_or_insert`
|
||||
// method which will only perform mutation if we aren't already
|
||||
// `Some`.
|
||||
let val = closure();
|
||||
unsafe { (*ptr).get_or_insert(val) }
|
||||
}
|
||||
}
|
||||
1729
vendor/addr2line/src/lib.rs
vendored
Normal file
1729
vendor/addr2line/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
126
vendor/addr2line/tests/correctness.rs
vendored
Normal file
126
vendor/addr2line/tests/correctness.rs
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
use addr2line::Context;
|
||||
use fallible_iterator::FallibleIterator;
|
||||
use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary};
|
||||
use object::Object;
|
||||
use std::borrow::Cow;
|
||||
use std::fs::File;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn find_debuginfo() -> memmap2::Mmap {
|
||||
let path = std::env::current_exe().unwrap();
|
||||
let file = File::open(&path).unwrap();
|
||||
let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
|
||||
let file = &object::File::parse(&*map).unwrap();
|
||||
if let Ok(uuid) = file.mach_uuid() {
|
||||
for candidate in path.parent().unwrap().read_dir().unwrap() {
|
||||
let path = candidate.unwrap().path();
|
||||
if !path.to_str().unwrap().ends_with(".dSYM") {
|
||||
continue;
|
||||
}
|
||||
for candidate in path.join("Contents/Resources/DWARF").read_dir().unwrap() {
|
||||
let path = candidate.unwrap().path();
|
||||
let file = File::open(&path).unwrap();
|
||||
let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
|
||||
let file = &object::File::parse(&*map).unwrap();
|
||||
if file.mach_uuid().unwrap() == uuid {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn correctness() {
|
||||
let map = find_debuginfo();
|
||||
let file = &object::File::parse(&*map).unwrap();
|
||||
let module_base = file.relative_address_base();
|
||||
|
||||
let endian = if file.is_little_endian() {
|
||||
gimli::RunTimeEndian::Little
|
||||
} else {
|
||||
gimli::RunTimeEndian::Big
|
||||
};
|
||||
|
||||
fn load_section<'data: 'file, 'file, O, Endian>(
|
||||
id: gimli::SectionId,
|
||||
file: &'file O,
|
||||
endian: Endian,
|
||||
) -> Result<gimli::EndianArcSlice<Endian>, gimli::Error>
|
||||
where
|
||||
O: object::Object<'data, 'file>,
|
||||
Endian: gimli::Endianity,
|
||||
{
|
||||
use object::ObjectSection;
|
||||
|
||||
let data = file
|
||||
.section_by_name(id.name())
|
||||
.and_then(|section| section.uncompressed_data().ok())
|
||||
.unwrap_or(Cow::Borrowed(&[]));
|
||||
Ok(gimli::EndianArcSlice::new(Arc::from(&*data), endian))
|
||||
}
|
||||
|
||||
let dwarf = gimli::Dwarf::load(|id| load_section(id, file, endian)).unwrap();
|
||||
let ctx = Context::from_dwarf(dwarf).unwrap();
|
||||
let mut split_dwarf_loader = addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new(
|
||||
|data, endian| gimli::EndianArcSlice::new(Arc::from(&*data), endian),
|
||||
None,
|
||||
);
|
||||
|
||||
let mut bias = None;
|
||||
TargetSharedLibrary::each(|lib| {
|
||||
bias = Some((lib.virtual_memory_bias().0 as u64).wrapping_sub(module_base));
|
||||
IterationControl::Break
|
||||
});
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut test = |sym: u64, expected_prefix: &str| {
|
||||
let ip = sym.wrapping_sub(bias.unwrap());
|
||||
|
||||
let frames = ctx.find_frames(ip);
|
||||
let frames = split_dwarf_loader.run(frames).unwrap();
|
||||
let frame = frames.last().unwrap().unwrap();
|
||||
let name = frame.function.as_ref().unwrap().demangle().unwrap();
|
||||
// Old rust versions generate DWARF with wrong linkage name,
|
||||
// so only check the start.
|
||||
if !name.starts_with(expected_prefix) {
|
||||
panic!("incorrect name '{}', expected {:?}", name, expected_prefix);
|
||||
}
|
||||
};
|
||||
|
||||
test(test_function as u64, "correctness::test_function");
|
||||
test(
|
||||
small::test_function as u64,
|
||||
"correctness::small::test_function",
|
||||
);
|
||||
test(auxiliary::foo as u64, "auxiliary::foo");
|
||||
}
|
||||
|
||||
mod small {
|
||||
pub fn test_function() {
|
||||
println!("y");
|
||||
}
|
||||
}
|
||||
|
||||
fn test_function() {
|
||||
println!("x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_function() {
|
||||
let map = find_debuginfo();
|
||||
let file = &object::File::parse(&*map).unwrap();
|
||||
let ctx = Context::new(file).unwrap();
|
||||
for probe in 0..10 {
|
||||
assert!(
|
||||
ctx.find_frames(probe)
|
||||
.skip_all_loads()
|
||||
.unwrap()
|
||||
.count()
|
||||
.unwrap()
|
||||
< 10
|
||||
);
|
||||
}
|
||||
}
|
||||
135
vendor/addr2line/tests/output_equivalence.rs
vendored
Normal file
135
vendor/addr2line/tests/output_equivalence.rs
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use backtrace::Backtrace;
|
||||
use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary};
|
||||
use libtest_mimic::{Arguments, Failed, Trial};
|
||||
|
||||
#[inline(never)]
|
||||
fn make_trace() -> Vec<String> {
|
||||
fn foo() -> Backtrace {
|
||||
bar()
|
||||
}
|
||||
#[inline(never)]
|
||||
fn bar() -> Backtrace {
|
||||
baz()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn baz() -> Backtrace {
|
||||
Backtrace::new_unresolved()
|
||||
}
|
||||
|
||||
let mut base_addr = None;
|
||||
TargetSharedLibrary::each(|lib| {
|
||||
base_addr = Some(lib.virtual_memory_bias().0 as isize);
|
||||
IterationControl::Break
|
||||
});
|
||||
let addrfix = -base_addr.unwrap();
|
||||
|
||||
let trace = foo();
|
||||
trace
|
||||
.frames()
|
||||
.iter()
|
||||
.take(5)
|
||||
.map(|x| format!("{:p}", (x.ip() as *const u8).wrapping_offset(addrfix)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn run_cmd<P: AsRef<OsStr>>(exe: P, me: &Path, flags: Option<&str>, trace: &str) -> String {
|
||||
let mut cmd = Command::new(exe);
|
||||
cmd.env("LC_ALL", "C"); // GNU addr2line is localized, we aren't
|
||||
cmd.env("RUST_BACKTRACE", "1"); // if a child crashes, we want to know why
|
||||
|
||||
if let Some(flags) = flags {
|
||||
cmd.arg(flags);
|
||||
}
|
||||
cmd.arg("--exe").arg(me).arg(trace);
|
||||
|
||||
let output = cmd.output().unwrap();
|
||||
|
||||
assert!(output.status.success());
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
fn run_test(flags: Option<&str>) -> Result<(), Failed> {
|
||||
let me = env::current_exe().unwrap();
|
||||
let mut exe = me.clone();
|
||||
assert!(exe.pop());
|
||||
if exe.file_name().unwrap().to_str().unwrap() == "deps" {
|
||||
assert!(exe.pop());
|
||||
}
|
||||
exe.push("examples");
|
||||
exe.push("addr2line");
|
||||
|
||||
assert!(exe.is_file());
|
||||
|
||||
let trace = make_trace();
|
||||
|
||||
// HACK: GNU addr2line has a bug where looking up multiple addresses can cause the second
|
||||
// lookup to fail. Workaround by doing one address at a time.
|
||||
for addr in &trace {
|
||||
let theirs = run_cmd("addr2line", &me, flags, addr);
|
||||
let ours = run_cmd(&exe, &me, flags, addr);
|
||||
|
||||
// HACK: GNU addr2line does not tidy up paths properly, causing double slashes to be printed.
|
||||
// We consider our behavior to be correct, so we fix their output to match ours.
|
||||
let theirs = theirs.replace("//", "/");
|
||||
|
||||
assert!(
|
||||
theirs == ours,
|
||||
"Output not equivalent:
|
||||
|
||||
$ addr2line {0} --exe {1} {2}
|
||||
{4}
|
||||
$ {3} {0} --exe {1} {2}
|
||||
{5}
|
||||
|
||||
|
||||
",
|
||||
flags.unwrap_or(""),
|
||||
me.display(),
|
||||
trace.join(" "),
|
||||
exe.display(),
|
||||
theirs,
|
||||
ours
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static FLAGS: &str = "aipsf";
|
||||
|
||||
fn make_tests() -> Vec<Trial> {
|
||||
(0..(1 << FLAGS.len()))
|
||||
.map(|bits| {
|
||||
if bits == 0 {
|
||||
None
|
||||
} else {
|
||||
let mut param = String::new();
|
||||
param.push('-');
|
||||
for (i, flag) in FLAGS.chars().enumerate() {
|
||||
if (bits & (1 << i)) != 0 {
|
||||
param.push(flag);
|
||||
}
|
||||
}
|
||||
Some(param)
|
||||
}
|
||||
})
|
||||
.map(|param| {
|
||||
Trial::test(
|
||||
format!("addr2line {}", param.as_ref().map_or("", String::as_str)),
|
||||
move || run_test(param.as_ref().map(String::as_str)),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if !cfg!(target_os = "linux") {
|
||||
return;
|
||||
}
|
||||
let args = Arguments::from_args();
|
||||
libtest_mimic::run(&args, make_tests()).exit();
|
||||
}
|
||||
114
vendor/addr2line/tests/parse.rs
vendored
Normal file
114
vendor/addr2line/tests/parse.rs
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::path::{self, PathBuf};
|
||||
|
||||
use object::Object;
|
||||
|
||||
fn release_fixture_path() -> PathBuf {
|
||||
if let Ok(p) = env::var("ADDR2LINE_FIXTURE_PATH") {
|
||||
return p.into();
|
||||
}
|
||||
|
||||
let mut path = PathBuf::new();
|
||||
if let Ok(dir) = env::var("CARGO_MANIFEST_DIR") {
|
||||
path.push(dir);
|
||||
}
|
||||
path.push("fixtures");
|
||||
path.push("addr2line-release");
|
||||
path
|
||||
}
|
||||
|
||||
fn with_file<F: FnOnce(&object::File<'_>)>(target: &path::Path, f: F) {
|
||||
let file = File::open(target).unwrap();
|
||||
let map = unsafe { memmap2::Mmap::map(&file).unwrap() };
|
||||
let file = object::File::parse(&*map).unwrap();
|
||||
f(&file)
|
||||
}
|
||||
|
||||
fn dwarf_load<'a>(object: &object::File<'a>) -> gimli::Dwarf<Cow<'a, [u8]>> {
|
||||
let load_section = |id: gimli::SectionId| -> Result<Cow<'a, [u8]>, gimli::Error> {
|
||||
use object::ObjectSection;
|
||||
|
||||
let data = object
|
||||
.section_by_name(id.name())
|
||||
.and_then(|section| section.data().ok())
|
||||
.unwrap_or(&[][..]);
|
||||
Ok(Cow::Borrowed(data))
|
||||
};
|
||||
gimli::Dwarf::load(&load_section).unwrap()
|
||||
}
|
||||
|
||||
fn dwarf_borrow<'a>(
|
||||
dwarf: &'a gimli::Dwarf<Cow<'_, [u8]>>,
|
||||
) -> gimli::Dwarf<gimli::EndianSlice<'a, gimli::LittleEndian>> {
|
||||
let borrow_section: &dyn for<'b> Fn(
|
||||
&'b Cow<'_, [u8]>,
|
||||
) -> gimli::EndianSlice<'b, gimli::LittleEndian> =
|
||||
&|section| gimli::EndianSlice::new(section, gimli::LittleEndian);
|
||||
dwarf.borrow(&borrow_section)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_base_rc() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
addr2line::ObjectContext::new(file).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_base_slice() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
let dwarf = dwarf_load(file);
|
||||
let dwarf = dwarf_borrow(&dwarf);
|
||||
addr2line::Context::from_dwarf(dwarf).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_lines_rc() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
let context = addr2line::ObjectContext::new(file).unwrap();
|
||||
context.parse_lines().unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_lines_slice() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
let dwarf = dwarf_load(file);
|
||||
let dwarf = dwarf_borrow(&dwarf);
|
||||
let context = addr2line::Context::from_dwarf(dwarf).unwrap();
|
||||
context.parse_lines().unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_functions_rc() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
let context = addr2line::ObjectContext::new(file).unwrap();
|
||||
context.parse_functions().unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_functions_slice() {
|
||||
let target = release_fixture_path();
|
||||
|
||||
with_file(&target, |file| {
|
||||
let dwarf = dwarf_load(file);
|
||||
let dwarf = dwarf_borrow(&dwarf);
|
||||
let context = addr2line::Context::from_dwarf(dwarf).unwrap();
|
||||
context.parse_functions().unwrap();
|
||||
});
|
||||
}
|
||||
1
vendor/adler/.cargo-checksum.json
vendored
Normal file
1
vendor/adler/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"7ef3fd450a17facfa60d2fcc3225c6e5b9d020d299a31c50f64f6a1a0ba9a29e",".github/workflows/ci.yml":"a96e0ab5bf676757640fb93fefb0410221bf5d37b049c66101033e2710739f89","CHANGELOG.md":"737088e45fdf27fe2cfedce163332d8ce08c58fd86ca287de2de34c0fbaf63e7","Cargo.toml":"f410869f0f1a5697f65a8a77be03da7aeecc0be26e7cf3a1feb1acaa4f518770","Cargo.toml.orig":"67c7da0e25a1fb4e74a8f818af03acabaa73fdf31c362dc41db56b74524b6c6f","LICENSE-0BSD":"861399f8c21c042b110517e76dc6b63a2b334276c8cf17412fc3c8908ca8dc17","LICENSE-APACHE":"8ada45cd9f843acf64e4722ae262c622a2b3b3007c7310ef36ac1061a30f6adb","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"308c50cdb42b9573743068158339570b45ca3f895015ca3b87ba983edb0a21e6","RELEASE_PROCESS.md":"a86cd10fc70f167f8d00e9e4ce0c6b4ebdfa1865058390dffd1e0ad4d3e68d9d","benches/bench.rs":"c07ce370e3680c602e415f8d1ec4e543ea2163ab22a09b6b82d93e8a30adca82","src/algo.rs":"b664b131f724a809591394a10b9023f40ab5963e32a83fa3163c2668e59c8b66","src/lib.rs":"b55ba9c629b30360d08168b2ca0c96275432856a539737a105a6d6ae6bf7e88f"},"package":"f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"}
|
||||
5
vendor/adler/.cargo_vcs_info.json
vendored
Normal file
5
vendor/adler/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "a94f525f62698d699d1fb3cc9112db8c35662b16"
|
||||
}
|
||||
}
|
||||
81
vendor/adler/.github/workflows/ci.yml
vendored
Normal file
81
vendor/adler/.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- staging
|
||||
- trying
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUSTFLAGS: "--deny warnings"
|
||||
MSRV: 1.31.0
|
||||
NO_STD_TARGET: thumbv6m-none-eabi
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
rust:
|
||||
- stable
|
||||
- nightly
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macOS-latest
|
||||
- windows-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
- name: Build
|
||||
run: cargo build --all --all-targets
|
||||
- name: Run tests
|
||||
run: |
|
||||
cargo test --all --all-targets
|
||||
cargo test --all --no-default-features
|
||||
|
||||
no-std:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
target: ${{ env.NO_STD_TARGET }}
|
||||
- name: Build
|
||||
run: cargo build --verbose --no-default-features --target ${{ env.NO_STD_TARGET }}
|
||||
|
||||
msrv:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ env.MSRV }}
|
||||
override: true
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt
|
||||
- name: Check code formatting
|
||||
run: cargo fmt -- --check
|
||||
63
vendor/adler/CHANGELOG.md
vendored
Normal file
63
vendor/adler/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
No changes.
|
||||
|
||||
## [1.0.2 - 2021-02-26](https://github.com/jonas-schievink/adler/releases/tag/v1.0.2)
|
||||
|
||||
- Fix doctest on big-endian systems ([#9]).
|
||||
|
||||
[#9]: https://github.com/jonas-schievink/adler/pull/9
|
||||
|
||||
## [1.0.1 - 2020-11-08](https://github.com/jonas-schievink/adler/releases/tag/v1.0.1)
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix documentation on docs.rs.
|
||||
|
||||
## [1.0.0 - 2020-11-08](https://github.com/jonas-schievink/adler/releases/tag/v1.0.0)
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix `cargo test --no-default-features` ([#5]).
|
||||
|
||||
### Improvements
|
||||
|
||||
- Extended and clarified documentation.
|
||||
- Added more rustdoc examples.
|
||||
- Extended CI to test the crate with `--no-default-features`.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- `adler32_reader` now takes its generic argument by value instead of as a `&mut`.
|
||||
- Renamed `adler32_reader` to `adler32`.
|
||||
|
||||
## [0.2.3 - 2020-07-11](https://github.com/jonas-schievink/adler/releases/tag/v0.2.3)
|
||||
|
||||
- Process 4 Bytes at a time, improving performance by up to 50% ([#2]).
|
||||
|
||||
## [0.2.2 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.2)
|
||||
|
||||
- Bump MSRV to 1.31.0.
|
||||
|
||||
## [0.2.1 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.1)
|
||||
|
||||
- Add a few `#[inline]` annotations to small functions.
|
||||
- Fix CI badge.
|
||||
- Allow integration into libstd.
|
||||
|
||||
## [0.2.0 - 2020-06-27](https://github.com/jonas-schievink/adler/releases/tag/v0.2.0)
|
||||
|
||||
- Support `#![no_std]` when using `default-features = false`.
|
||||
- Improve performance by around 7x.
|
||||
- Support Rust 1.8.0.
|
||||
- Improve API naming.
|
||||
|
||||
## [0.1.0 - 2020-06-26](https://github.com/jonas-schievink/adler/releases/tag/v0.1.0)
|
||||
|
||||
Initial release.
|
||||
|
||||
|
||||
[#2]: https://github.com/jonas-schievink/adler/pull/2
|
||||
[#5]: https://github.com/jonas-schievink/adler/pull/5
|
||||
64
vendor/adler/Cargo.toml
vendored
Normal file
64
vendor/adler/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# 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 = "adler"
|
||||
version = "1.0.2"
|
||||
authors = ["Jonas Schievink <jonasschievink@gmail.com>"]
|
||||
description = "A simple clean-room implementation of the Adler-32 checksum"
|
||||
documentation = "https://docs.rs/adler/"
|
||||
readme = "README.md"
|
||||
keywords = ["checksum", "integrity", "hash", "adler32", "zlib"]
|
||||
categories = ["algorithms"]
|
||||
license = "0BSD OR MIT OR Apache-2.0"
|
||||
repository = "https://github.com/jonas-schievink/adler.git"
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = ["--cfg=docsrs"]
|
||||
|
||||
[package.metadata.release]
|
||||
no-dev-version = true
|
||||
pre-release-commit-message = "Release {{version}}"
|
||||
tag-message = "{{version}}"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "CHANGELOG.md"
|
||||
replace = "## Unreleased\n\nNo changes.\n\n## [{{version}} - {{date}}](https://github.com/jonas-schievink/adler/releases/tag/v{{version}})\n"
|
||||
search = "## Unreleased\n"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "README.md"
|
||||
replace = "adler = \"{{version}}\""
|
||||
search = "adler = \"[a-z0-9\\\\.-]+\""
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "src/lib.rs"
|
||||
replace = "https://docs.rs/adler/{{version}}"
|
||||
search = "https://docs.rs/adler/[a-z0-9\\.-]+"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
[dependencies.compiler_builtins]
|
||||
version = "0.1.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.core]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-core"
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3.2"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
rustc-dep-of-std = ["core", "compiler_builtins"]
|
||||
std = []
|
||||
68
vendor/adler/Cargo.toml.orig
generated
vendored
Normal file
68
vendor/adler/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
[package]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
authors = ["Jonas Schievink <jonasschievink@gmail.com>"]
|
||||
description = "A simple clean-room implementation of the Adler-32 checksum"
|
||||
documentation = "https://docs.rs/adler/"
|
||||
repository = "https://github.com/jonas-schievink/adler.git"
|
||||
keywords = ["checksum", "integrity", "hash", "adler32", "zlib"]
|
||||
categories = ["algorithms"]
|
||||
readme = "README.md"
|
||||
license = "0BSD OR MIT OR Apache-2.0"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
||||
[dependencies]
|
||||
# Internal features, only used when building as part of libstd, not part of the
|
||||
# stable interface of this crate.
|
||||
core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' }
|
||||
compiler_builtins = { version = '0.1.2', optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.2"
|
||||
|
||||
[features]
|
||||
# Disable default features to enable `#![no_std]` support.
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
||||
# Internal feature, only used when building as part of libstd, not part of the
|
||||
# stable interface of this crate.
|
||||
rustc-dep-of-std = ['core', 'compiler_builtins']
|
||||
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = [ "--cfg=docsrs" ]
|
||||
|
||||
# cargo-release configuration
|
||||
[package.metadata.release]
|
||||
tag-message = "{{version}}"
|
||||
no-dev-version = true
|
||||
pre-release-commit-message = "Release {{version}}"
|
||||
|
||||
# Change the changelog's `Unreleased` section to refer to this release and
|
||||
# prepend a new `Unreleased` section
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "CHANGELOG.md"
|
||||
search = "## Unreleased\n"
|
||||
replace = """
|
||||
## Unreleased
|
||||
|
||||
No changes.
|
||||
|
||||
## [{{version}} - {{date}}](https://github.com/jonas-schievink/adler/releases/tag/v{{version}})
|
||||
"""
|
||||
|
||||
# Bump the version inside the example manifest in `README.md`
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "README.md"
|
||||
search = 'adler = "[a-z0-9\\.-]+"'
|
||||
replace = 'adler = "{{version}}"'
|
||||
|
||||
# Bump the version referenced by the `html_root_url` attribute in `lib.rs`
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "src/lib.rs"
|
||||
search = "https://docs.rs/adler/[a-z0-9\\.-]+"
|
||||
replace = "https://docs.rs/adler/{{version}}"
|
||||
12
vendor/adler/LICENSE-0BSD
vendored
Normal file
12
vendor/adler/LICENSE-0BSD
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Copyright (C) Jonas Schievink <jonasschievink@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
201
vendor/adler/LICENSE-APACHE
vendored
Normal file
201
vendor/adler/LICENSE-APACHE
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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
|
||||
|
||||
https://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.
|
||||
23
vendor/adler/LICENSE-MIT
vendored
Normal file
23
vendor/adler/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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.
|
||||
39
vendor/adler/README.md
vendored
Normal file
39
vendor/adler/README.md
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Adler-32 checksums for Rust
|
||||
|
||||
[](https://crates.io/crates/adler)
|
||||
[](https://docs.rs/adler/)
|
||||

|
||||
|
||||
This crate provides a simple implementation of the Adler-32 checksum, used in
|
||||
the zlib compression format.
|
||||
|
||||
Please refer to the [changelog](CHANGELOG.md) to see what changed in the last
|
||||
releases.
|
||||
|
||||
## Features
|
||||
|
||||
- Permissively licensed (0BSD) clean-room implementation.
|
||||
- Zero dependencies.
|
||||
- Zero `unsafe`.
|
||||
- Decent performance (3-4 GB/s).
|
||||
- Supports `#![no_std]` (with `default-features = false`).
|
||||
|
||||
## Usage
|
||||
|
||||
Add an entry to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
adler = "1.0.2"
|
||||
```
|
||||
|
||||
Check the [API Documentation](https://docs.rs/adler/) for how to use the
|
||||
crate's functionality.
|
||||
|
||||
## Rust version support
|
||||
|
||||
Currently, this crate supports all Rust versions starting at Rust 1.31.0.
|
||||
|
||||
Bumping the Minimum Supported Rust Version (MSRV) is *not* considered a breaking
|
||||
change, but will not be done without good reasons. The latest 3 stable Rust
|
||||
versions will always be supported no matter what.
|
||||
13
vendor/adler/RELEASE_PROCESS.md
vendored
Normal file
13
vendor/adler/RELEASE_PROCESS.md
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# What to do to publish a new release
|
||||
|
||||
1. Ensure all notable changes are in the changelog under "Unreleased".
|
||||
|
||||
2. Execute `cargo release <level>` to bump version(s), tag and publish
|
||||
everything. External subcommand, must be installed with `cargo install
|
||||
cargo-release`.
|
||||
|
||||
`<level>` can be one of `major|minor|patch`. If this is the first release
|
||||
(`0.1.0`), use `minor`, since the version starts out as `0.0.0`.
|
||||
|
||||
3. Go to the GitHub releases, edit the just-pushed tag. Copy the release notes
|
||||
from the changelog.
|
||||
109
vendor/adler/benches/bench.rs
vendored
Normal file
109
vendor/adler/benches/bench.rs
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
extern crate adler;
|
||||
extern crate criterion;
|
||||
|
||||
use adler::{adler32_slice, Adler32};
|
||||
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
|
||||
|
||||
fn simple(c: &mut Criterion) {
|
||||
{
|
||||
const SIZE: usize = 100;
|
||||
|
||||
let mut group = c.benchmark_group("simple-100b");
|
||||
group.throughput(Throughput::Bytes(SIZE as u64));
|
||||
group.bench_function("zeroes-100", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0; SIZE]);
|
||||
});
|
||||
});
|
||||
group.bench_function("ones-100", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0xff; SIZE]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const SIZE: usize = 1024;
|
||||
|
||||
let mut group = c.benchmark_group("simple-1k");
|
||||
group.throughput(Throughput::Bytes(SIZE as u64));
|
||||
|
||||
group.bench_function("zeroes-1k", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0; SIZE]);
|
||||
});
|
||||
});
|
||||
|
||||
group.bench_function("ones-1k", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0xff; SIZE]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const SIZE: usize = 1024 * 1024;
|
||||
|
||||
let mut group = c.benchmark_group("simple-1m");
|
||||
group.throughput(Throughput::Bytes(SIZE as u64));
|
||||
group.bench_function("zeroes-1m", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0; SIZE]);
|
||||
});
|
||||
});
|
||||
|
||||
group.bench_function("ones-1m", |bencher| {
|
||||
bencher.iter(|| {
|
||||
adler32_slice(&[0xff; SIZE]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn chunked(c: &mut Criterion) {
|
||||
const SIZE: usize = 16 * 1024 * 1024;
|
||||
|
||||
let data = vec![0xAB; SIZE];
|
||||
|
||||
let mut group = c.benchmark_group("chunked-16m");
|
||||
group.throughput(Throughput::Bytes(SIZE as u64));
|
||||
group.bench_function("5552", |bencher| {
|
||||
bencher.iter(|| {
|
||||
let mut h = Adler32::new();
|
||||
for chunk in data.chunks(5552) {
|
||||
h.write_slice(chunk);
|
||||
}
|
||||
h.checksum()
|
||||
});
|
||||
});
|
||||
group.bench_function("8k", |bencher| {
|
||||
bencher.iter(|| {
|
||||
let mut h = Adler32::new();
|
||||
for chunk in data.chunks(8 * 1024) {
|
||||
h.write_slice(chunk);
|
||||
}
|
||||
h.checksum()
|
||||
});
|
||||
});
|
||||
group.bench_function("64k", |bencher| {
|
||||
bencher.iter(|| {
|
||||
let mut h = Adler32::new();
|
||||
for chunk in data.chunks(64 * 1024) {
|
||||
h.write_slice(chunk);
|
||||
}
|
||||
h.checksum()
|
||||
});
|
||||
});
|
||||
group.bench_function("1m", |bencher| {
|
||||
bencher.iter(|| {
|
||||
let mut h = Adler32::new();
|
||||
for chunk in data.chunks(1024 * 1024) {
|
||||
h.write_slice(chunk);
|
||||
}
|
||||
h.checksum()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, simple, chunked);
|
||||
criterion_main!(benches);
|
||||
146
vendor/adler/src/algo.rs
vendored
Normal file
146
vendor/adler/src/algo.rs
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
use crate::Adler32;
|
||||
use std::ops::{AddAssign, MulAssign, RemAssign};
|
||||
|
||||
impl Adler32 {
|
||||
pub(crate) fn compute(&mut self, bytes: &[u8]) {
|
||||
// The basic algorithm is, for every byte:
|
||||
// a = (a + byte) % MOD
|
||||
// b = (b + a) % MOD
|
||||
// where MOD = 65521.
|
||||
//
|
||||
// For efficiency, we can defer the `% MOD` operations as long as neither a nor b overflows:
|
||||
// - Between calls to `write`, we ensure that a and b are always in range 0..MOD.
|
||||
// - We use 32-bit arithmetic in this function.
|
||||
// - Therefore, a and b must not increase by more than 2^32-MOD without performing a `% MOD`
|
||||
// operation.
|
||||
//
|
||||
// According to Wikipedia, b is calculated as follows for non-incremental checksumming:
|
||||
// b = n×D1 + (n−1)×D2 + (n−2)×D3 + ... + Dn + n*1 (mod 65521)
|
||||
// Where n is the number of bytes and Di is the i-th Byte. We need to change this to account
|
||||
// for the previous values of a and b, as well as treat every input Byte as being 255:
|
||||
// b_inc = n×255 + (n-1)×255 + ... + 255 + n*65520
|
||||
// Or in other words:
|
||||
// b_inc = n*65520 + n(n+1)/2*255
|
||||
// The max chunk size is thus the largest value of n so that b_inc <= 2^32-65521.
|
||||
// 2^32-65521 = n*65520 + n(n+1)/2*255
|
||||
// Plugging this into an equation solver since I can't math gives n = 5552.18..., so 5552.
|
||||
//
|
||||
// On top of the optimization outlined above, the algorithm can also be parallelized with a
|
||||
// bit more work:
|
||||
//
|
||||
// Note that b is a linear combination of a vector of input bytes (D1, ..., Dn).
|
||||
//
|
||||
// If we fix some value k<N and rewrite indices 1, ..., N as
|
||||
//
|
||||
// 1_1, 1_2, ..., 1_k, 2_1, ..., 2_k, ..., (N/k)_k,
|
||||
//
|
||||
// then we can express a and b in terms of sums of smaller sequences kb and ka:
|
||||
//
|
||||
// ka(j) := D1_j + D2_j + ... + D(N/k)_j where j <= k
|
||||
// kb(j) := (N/k)*D1_j + (N/k-1)*D2_j + ... + D(N/k)_j where j <= k
|
||||
//
|
||||
// a = ka(1) + ka(2) + ... + ka(k) + 1
|
||||
// b = k*(kb(1) + kb(2) + ... + kb(k)) - 1*ka(2) - ... - (k-1)*ka(k) + N
|
||||
//
|
||||
// We use this insight to unroll the main loop and process k=4 bytes at a time.
|
||||
// The resulting code is highly amenable to SIMD acceleration, although the immediate speedups
|
||||
// stem from increased pipeline parallelism rather than auto-vectorization.
|
||||
//
|
||||
// This technique is described in-depth (here:)[https://software.intel.com/content/www/us/\
|
||||
// en/develop/articles/fast-computation-of-fletcher-checksums.html]
|
||||
|
||||
const MOD: u32 = 65521;
|
||||
const CHUNK_SIZE: usize = 5552 * 4;
|
||||
|
||||
let mut a = u32::from(self.a);
|
||||
let mut b = u32::from(self.b);
|
||||
let mut a_vec = U32X4([0; 4]);
|
||||
let mut b_vec = a_vec;
|
||||
|
||||
let (bytes, remainder) = bytes.split_at(bytes.len() - bytes.len() % 4);
|
||||
|
||||
// iterate over 4 bytes at a time
|
||||
let chunk_iter = bytes.chunks_exact(CHUNK_SIZE);
|
||||
let remainder_chunk = chunk_iter.remainder();
|
||||
for chunk in chunk_iter {
|
||||
for byte_vec in chunk.chunks_exact(4) {
|
||||
let val = U32X4::from(byte_vec);
|
||||
a_vec += val;
|
||||
b_vec += a_vec;
|
||||
}
|
||||
b += CHUNK_SIZE as u32 * a;
|
||||
a_vec %= MOD;
|
||||
b_vec %= MOD;
|
||||
b %= MOD;
|
||||
}
|
||||
// special-case the final chunk because it may be shorter than the rest
|
||||
for byte_vec in remainder_chunk.chunks_exact(4) {
|
||||
let val = U32X4::from(byte_vec);
|
||||
a_vec += val;
|
||||
b_vec += a_vec;
|
||||
}
|
||||
b += remainder_chunk.len() as u32 * a;
|
||||
a_vec %= MOD;
|
||||
b_vec %= MOD;
|
||||
b %= MOD;
|
||||
|
||||
// combine the sub-sum results into the main sum
|
||||
b_vec *= 4;
|
||||
b_vec.0[1] += MOD - a_vec.0[1];
|
||||
b_vec.0[2] += (MOD - a_vec.0[2]) * 2;
|
||||
b_vec.0[3] += (MOD - a_vec.0[3]) * 3;
|
||||
for &av in a_vec.0.iter() {
|
||||
a += av;
|
||||
}
|
||||
for &bv in b_vec.0.iter() {
|
||||
b += bv;
|
||||
}
|
||||
|
||||
// iterate over the remaining few bytes in serial
|
||||
for &byte in remainder.iter() {
|
||||
a += u32::from(byte);
|
||||
b += a;
|
||||
}
|
||||
|
||||
self.a = (a % MOD) as u16;
|
||||
self.b = (b % MOD) as u16;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct U32X4([u32; 4]);
|
||||
|
||||
impl U32X4 {
|
||||
fn from(bytes: &[u8]) -> Self {
|
||||
U32X4([
|
||||
u32::from(bytes[0]),
|
||||
u32::from(bytes[1]),
|
||||
u32::from(bytes[2]),
|
||||
u32::from(bytes[3]),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Self> for U32X4 {
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
for (s, o) in self.0.iter_mut().zip(other.0.iter()) {
|
||||
*s += o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RemAssign<u32> for U32X4 {
|
||||
fn rem_assign(&mut self, quotient: u32) {
|
||||
for s in self.0.iter_mut() {
|
||||
*s %= quotient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MulAssign<u32> for U32X4 {
|
||||
fn mul_assign(&mut self, rhs: u32) {
|
||||
for s in self.0.iter_mut() {
|
||||
*s *= rhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
287
vendor/adler/src/lib.rs
vendored
Normal file
287
vendor/adler/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
//! Adler-32 checksum implementation.
|
||||
//!
|
||||
//! This implementation features:
|
||||
//!
|
||||
//! - Permissively licensed (0BSD) clean-room implementation.
|
||||
//! - Zero dependencies.
|
||||
//! - Zero `unsafe`.
|
||||
//! - Decent performance (3-4 GB/s).
|
||||
//! - `#![no_std]` support (with `default-features = false`).
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/adler/1.0.2")]
|
||||
// Deny a few warnings in doctests, since rustdoc `allow`s many warnings by default
|
||||
#![doc(test(attr(deny(unused_imports, unused_must_use))))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate core as std;
|
||||
|
||||
mod algo;
|
||||
|
||||
use std::hash::Hasher;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
/// Adler-32 checksum calculator.
|
||||
///
|
||||
/// An instance of this type is equivalent to an Adler-32 checksum: It can be created in the default
|
||||
/// state via [`new`] (or the provided `Default` impl), or from a precalculated checksum via
|
||||
/// [`from_checksum`], and the currently stored checksum can be fetched via [`checksum`].
|
||||
///
|
||||
/// This type also implements `Hasher`, which makes it easy to calculate Adler-32 checksums of any
|
||||
/// type that implements or derives `Hash`. This also allows using Adler-32 in a `HashMap`, although
|
||||
/// that is not recommended (while every checksum is a hash function, they are not necessarily a
|
||||
/// good one).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic, piecewise checksum calculation:
|
||||
///
|
||||
/// ```
|
||||
/// use adler::Adler32;
|
||||
///
|
||||
/// let mut adler = Adler32::new();
|
||||
///
|
||||
/// adler.write_slice(&[0, 1, 2]);
|
||||
/// adler.write_slice(&[3, 4, 5]);
|
||||
///
|
||||
/// assert_eq!(adler.checksum(), 0x00290010);
|
||||
/// ```
|
||||
///
|
||||
/// Using `Hash` to process structures:
|
||||
///
|
||||
/// ```
|
||||
/// use std::hash::Hash;
|
||||
/// use adler::Adler32;
|
||||
///
|
||||
/// #[derive(Hash)]
|
||||
/// struct Data {
|
||||
/// byte: u8,
|
||||
/// word: u16,
|
||||
/// big: u64,
|
||||
/// }
|
||||
///
|
||||
/// let mut adler = Adler32::new();
|
||||
///
|
||||
/// let data = Data { byte: 0x1F, word: 0xABCD, big: !0 };
|
||||
/// data.hash(&mut adler);
|
||||
///
|
||||
/// // hash value depends on architecture endianness
|
||||
/// if cfg!(target_endian = "little") {
|
||||
/// assert_eq!(adler.checksum(), 0x33410990);
|
||||
/// }
|
||||
/// if cfg!(target_endian = "big") {
|
||||
/// assert_eq!(adler.checksum(), 0x331F0990);
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// [`new`]: #method.new
|
||||
/// [`from_checksum`]: #method.from_checksum
|
||||
/// [`checksum`]: #method.checksum
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Adler32 {
|
||||
a: u16,
|
||||
b: u16,
|
||||
}
|
||||
|
||||
impl Adler32 {
|
||||
/// Creates a new Adler-32 instance with default state.
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Creates an `Adler32` instance from a precomputed Adler-32 checksum.
|
||||
///
|
||||
/// This allows resuming checksum calculation without having to keep the `Adler32` instance
|
||||
/// around.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use adler::Adler32;
|
||||
/// let parts = [
|
||||
/// "rust",
|
||||
/// "acean",
|
||||
/// ];
|
||||
/// let whole = adler::adler32_slice(b"rustacean");
|
||||
///
|
||||
/// let mut sum = Adler32::new();
|
||||
/// sum.write_slice(parts[0].as_bytes());
|
||||
/// let partial = sum.checksum();
|
||||
///
|
||||
/// // ...later
|
||||
///
|
||||
/// let mut sum = Adler32::from_checksum(partial);
|
||||
/// sum.write_slice(parts[1].as_bytes());
|
||||
/// assert_eq!(sum.checksum(), whole);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn from_checksum(sum: u32) -> Self {
|
||||
Adler32 {
|
||||
a: sum as u16,
|
||||
b: (sum >> 16) as u16,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the calculated checksum at this point in time.
|
||||
#[inline]
|
||||
pub fn checksum(&self) -> u32 {
|
||||
(u32::from(self.b) << 16) | u32::from(self.a)
|
||||
}
|
||||
|
||||
/// Adds `bytes` to the checksum calculation.
|
||||
///
|
||||
/// If efficiency matters, this should be called with Byte slices that contain at least a few
|
||||
/// thousand Bytes.
|
||||
pub fn write_slice(&mut self, bytes: &[u8]) {
|
||||
self.compute(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Adler32 {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Adler32 { a: 1, b: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for Adler32 {
|
||||
#[inline]
|
||||
fn finish(&self) -> u64 {
|
||||
u64::from(self.checksum())
|
||||
}
|
||||
|
||||
fn write(&mut self, bytes: &[u8]) {
|
||||
self.write_slice(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the Adler-32 checksum of a byte slice.
|
||||
///
|
||||
/// This is a convenience function around the [`Adler32`] type.
|
||||
///
|
||||
/// [`Adler32`]: struct.Adler32.html
|
||||
pub fn adler32_slice(data: &[u8]) -> u32 {
|
||||
let mut h = Adler32::new();
|
||||
h.write_slice(data);
|
||||
h.checksum()
|
||||
}
|
||||
|
||||
/// Calculates the Adler-32 checksum of a `BufRead`'s contents.
|
||||
///
|
||||
/// The passed `BufRead` implementor will be read until it reaches EOF (or until it reports an
|
||||
/// error).
|
||||
///
|
||||
/// If you only have a `Read` implementor, you can wrap it in `std::io::BufReader` before calling
|
||||
/// this function.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Any error returned by the reader are bubbled up by this function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// use adler::adler32;
|
||||
///
|
||||
/// use std::fs::File;
|
||||
/// use std::io::BufReader;
|
||||
///
|
||||
/// let file = File::open("input.txt")?;
|
||||
/// let mut file = BufReader::new(file);
|
||||
///
|
||||
/// adler32(&mut file)?;
|
||||
/// # Ok(()) }
|
||||
/// # fn main() { run().unwrap() }
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub fn adler32<R: BufRead>(mut reader: R) -> io::Result<u32> {
|
||||
let mut h = Adler32::new();
|
||||
loop {
|
||||
let len = {
|
||||
let buf = reader.fill_buf()?;
|
||||
if buf.is_empty() {
|
||||
return Ok(h.checksum());
|
||||
}
|
||||
|
||||
h.write_slice(buf);
|
||||
buf.len()
|
||||
};
|
||||
reader.consume(len);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn zeroes() {
|
||||
assert_eq!(adler32_slice(&[]), 1);
|
||||
assert_eq!(adler32_slice(&[0]), 1 | 1 << 16);
|
||||
assert_eq!(adler32_slice(&[0, 0]), 1 | 2 << 16);
|
||||
assert_eq!(adler32_slice(&[0; 100]), 0x00640001);
|
||||
assert_eq!(adler32_slice(&[0; 1024]), 0x04000001);
|
||||
assert_eq!(adler32_slice(&[0; 1024 * 1024]), 0x00f00001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ones() {
|
||||
assert_eq!(adler32_slice(&[0xff; 1024]), 0x79a6fc2e);
|
||||
assert_eq!(adler32_slice(&[0xff; 1024 * 1024]), 0x8e88ef11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mixed() {
|
||||
assert_eq!(adler32_slice(&[1]), 2 | 2 << 16);
|
||||
assert_eq!(adler32_slice(&[40]), 41 | 41 << 16);
|
||||
|
||||
assert_eq!(adler32_slice(&[0xA5; 1024 * 1024]), 0xd5009ab1);
|
||||
}
|
||||
|
||||
/// Example calculation from https://en.wikipedia.org/wiki/Adler-32.
|
||||
#[test]
|
||||
fn wiki() {
|
||||
assert_eq!(adler32_slice(b"Wikipedia"), 0x11E60398);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resume() {
|
||||
let mut adler = Adler32::new();
|
||||
adler.write_slice(&[0xff; 1024]);
|
||||
let partial = adler.checksum();
|
||||
assert_eq!(partial, 0x79a6fc2e); // from above
|
||||
adler.write_slice(&[0xff; 1024 * 1024 - 1024]);
|
||||
assert_eq!(adler.checksum(), 0x8e88ef11); // from above
|
||||
|
||||
// Make sure that we can resume computing from the partial checksum via `from_checksum`.
|
||||
let mut adler = Adler32::from_checksum(partial);
|
||||
adler.write_slice(&[0xff; 1024 * 1024 - 1024]);
|
||||
assert_eq!(adler.checksum(), 0x8e88ef11); // from above
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn bufread() {
|
||||
use std::io::BufReader;
|
||||
fn test(data: &[u8], checksum: u32) {
|
||||
// `BufReader` uses an 8 KB buffer, so this will test buffer refilling.
|
||||
let mut buf = BufReader::new(data);
|
||||
let real_sum = adler32(&mut buf).unwrap();
|
||||
assert_eq!(checksum, real_sum);
|
||||
}
|
||||
|
||||
test(&[], 1);
|
||||
test(&[0; 1024], 0x04000001);
|
||||
test(&[0; 1024 * 1024], 0x00f00001);
|
||||
test(&[0xA5; 1024 * 1024], 0xd5009ab1);
|
||||
}
|
||||
}
|
||||
1
vendor/android-tzdata/.cargo-checksum.json
vendored
Normal file
1
vendor/android-tzdata/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"6846a0ea8f7eba50594e2ad628b52cb3b450f361eae3734f8b3dd2001fee91b5","Cargo.toml":"a87d9acc9827a50c7a96a88720c5dd055cbc08b1144dff95bd572ff977d4a79a","Cargo.toml.orig":"9cf5570fbbad8241eb368f96f3e3d4982c93342143cd9e1c849a461167f8c18a","LICENSE-APACHE":"4458503dd48e88c4e0b945fb252a08b93c40ec757309b8ffa7c594dfa1e35104","LICENSE-MIT":"002c2696d92b5c8cf956c11072baa58eaf9f6ade995c031ea635c6a1ee342ad1","README.md":"6dfe0c602dc61eebe118900ed66a2c1f7887b9fe95b36e1c2974c4e8fa7ebd4b","src/lib.rs":"8f421233df83f82e737930ca8a2ad254966334183148bcc170f9c405df230de2","src/tzdata.rs":"78920925b04219910511e9a1f036f468cd2925c0054f280d6a00b106529046e7"},"package":"e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"}
|
||||
6
vendor/android-tzdata/.cargo_vcs_info.json
vendored
Normal file
6
vendor/android-tzdata/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "230368ebd6aa911bc56401202808d11019411dc4"
|
||||
},
|
||||
"path_in_vcs": ""
|
||||
}
|
||||
34
vendor/android-tzdata/Cargo.toml
vendored
Normal file
34
vendor/android-tzdata/Cargo.toml
vendored
Normal file
|
|
@ -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 are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
authors = ["RumovZ"]
|
||||
include = [
|
||||
"src/**/*",
|
||||
"LICENSE-*",
|
||||
"README.md",
|
||||
]
|
||||
description = "Parser for the Android-specific tzdata file"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"parser",
|
||||
"android",
|
||||
"timezone",
|
||||
]
|
||||
categories = ["date-and-time"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/RumovZ/android-tzdata"
|
||||
|
||||
[dev-dependencies.zip]
|
||||
version = "0.6.4"
|
||||
15
vendor/android-tzdata/Cargo.toml.orig
generated
vendored
Normal file
15
vendor/android-tzdata/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
authors = ["RumovZ"]
|
||||
edition = "2018"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Parser for the Android-specific tzdata file"
|
||||
repository = "https://github.com/RumovZ/android-tzdata"
|
||||
readme = "README.md"
|
||||
categories = ["date-and-time"]
|
||||
keywords = ["parser", "android", "timezone"]
|
||||
include = ["src/**/*", "LICENSE-*", "README.md"]
|
||||
|
||||
[dev-dependencies]
|
||||
zip = "0.6.4"
|
||||
201
vendor/android-tzdata/LICENSE-APACHE
vendored
Normal file
201
vendor/android-tzdata/LICENSE-APACHE
vendored
Normal file
|
|
@ -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.
|
||||
21
vendor/android-tzdata/LICENSE-MIT
vendored
Normal file
21
vendor/android-tzdata/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
|
||||
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.
|
||||
20
vendor/android-tzdata/README.md
vendored
Normal file
20
vendor/android-tzdata/README.md
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# android-tzdata
|
||||
|
||||
Parser for the Android-specific tzdata file.
|
||||
|
||||
## License
|
||||
|
||||
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.
|
||||
|
||||
## 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.
|
||||
29
vendor/android-tzdata/src/lib.rs
vendored
Normal file
29
vendor/android-tzdata/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! Parser for the Android-specific tzdata file.
|
||||
|
||||
mod tzdata;
|
||||
|
||||
/// Tries to locate the `tzdata` file, parse it, and return the entry for the
|
||||
/// requested time zone.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an [std::io::Error] if the `tzdata` file cannot be found and parsed, or
|
||||
/// if it does not contain the requested timezone entry.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::error::Error;
|
||||
/// # use android_tzdata::find_tz_data;
|
||||
/// #
|
||||
/// # fn main() -> Result<(), Box<dyn Error>> {
|
||||
/// let tz_data = find_tz_data("Europe/Kiev")?;
|
||||
/// // Check it's version 2 of the [Time Zone Information Format](https://www.ietf.org/archive/id/draft-murchison-rfc8536bis-02.html).
|
||||
/// assert!(tz_data.starts_with(b"TZif2"));
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn find_tz_data(tz_name: impl AsRef<str>) -> Result<Vec<u8>, std::io::Error> {
|
||||
let mut file = tzdata::find_file()?;
|
||||
tzdata::find_tz_data_in_file(&mut file, tz_name.as_ref())
|
||||
}
|
||||
166
vendor/android-tzdata/src/tzdata.rs
vendored
Normal file
166
vendor/android-tzdata/src/tzdata.rs
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
//! Logic was mainly ported from https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/util/ZoneInfoDB.java
|
||||
|
||||
use core::{cmp::Ordering, convert::TryInto};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, ErrorKind, Read, Seek, SeekFrom},
|
||||
};
|
||||
|
||||
// The database uses 32-bit (4 byte) integers.
|
||||
const TZ_INT_SIZE: usize = 4;
|
||||
// The first 12 bytes contain a special version string.
|
||||
const MAGIC_SIZE: usize = 12;
|
||||
const HEADER_SIZE: usize = MAGIC_SIZE + 3 * TZ_INT_SIZE;
|
||||
// The database reserves 40 bytes for each id.
|
||||
const TZ_NAME_SIZE: usize = 40;
|
||||
const INDEX_ENTRY_SIZE: usize = TZ_NAME_SIZE + 3 * TZ_INT_SIZE;
|
||||
const TZDATA_LOCATIONS: [TzdataLocation; 2] = [
|
||||
TzdataLocation {
|
||||
env_var: "ANDROID_DATA",
|
||||
path: "/misc/zoneinfo/",
|
||||
},
|
||||
TzdataLocation {
|
||||
env_var: "ANDROID_ROOT",
|
||||
path: "/usr/share/zoneinfo/",
|
||||
},
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TzdataLocation {
|
||||
env_var: &'static str,
|
||||
path: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Header {
|
||||
index_offset: usize,
|
||||
data_offset: usize,
|
||||
_zonetab_offset: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Index(Vec<u8>);
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct IndexEntry<'a> {
|
||||
_name: &'a [u8],
|
||||
offset: usize,
|
||||
length: usize,
|
||||
_raw_utc_offset: usize,
|
||||
}
|
||||
|
||||
pub(super) fn find_file() -> Result<File, io::Error> {
|
||||
for location in &TZDATA_LOCATIONS {
|
||||
if let Ok(env_value) = std::env::var(location.env_var) {
|
||||
if let Ok(file) = File::open(format!("{}{}tzdata", env_value, location.path)) {
|
||||
return Ok(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(io::Error::from(io::ErrorKind::NotFound))
|
||||
}
|
||||
|
||||
pub(super) fn find_tz_data_in_file(
|
||||
mut file: impl Read + Seek,
|
||||
tz_name: &str,
|
||||
) -> Result<Vec<u8>, io::Error> {
|
||||
let header = Header::new(&mut file)?;
|
||||
let index = Index::new(&mut file, header)?;
|
||||
if let Some(entry) = index.find_entry(tz_name) {
|
||||
file.seek(SeekFrom::Start((entry.offset + header.data_offset) as u64))?;
|
||||
let mut tz_data = vec![0u8; entry.length];
|
||||
file.read_exact(&mut tz_data)?;
|
||||
Ok(tz_data)
|
||||
} else {
|
||||
Err(io::Error::from(ErrorKind::NotFound))
|
||||
}
|
||||
}
|
||||
|
||||
impl Header {
|
||||
fn new(mut file: impl Read + Seek) -> Result<Self, io::Error> {
|
||||
let mut buf = [0; HEADER_SIZE];
|
||||
file.read_exact(&mut buf)?;
|
||||
if !buf.starts_with(b"tzdata") || buf[MAGIC_SIZE - 1] != 0u8 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"invalid magic number",
|
||||
));
|
||||
}
|
||||
Ok(Self {
|
||||
index_offset: parse_tz_int(&buf, MAGIC_SIZE) as usize,
|
||||
data_offset: parse_tz_int(&buf, MAGIC_SIZE + TZ_INT_SIZE) as usize,
|
||||
_zonetab_offset: parse_tz_int(&buf, MAGIC_SIZE + 2 * TZ_INT_SIZE) as usize,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Index {
|
||||
fn new(mut file: impl Read + Seek, header: Header) -> Result<Self, io::Error> {
|
||||
file.seek(SeekFrom::Start(header.index_offset as u64))?;
|
||||
let size = header.data_offset - header.index_offset;
|
||||
let mut bytes = vec![0; size];
|
||||
file.read_exact(&mut bytes)?;
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
||||
fn find_entry(&self, name: &str) -> Option<IndexEntry> {
|
||||
let name_bytes = name.as_bytes();
|
||||
let name_len = name_bytes.len();
|
||||
if name_len > TZ_NAME_SIZE {
|
||||
return None;
|
||||
}
|
||||
|
||||
let zeros = [0u8; TZ_NAME_SIZE];
|
||||
let cmp = |chunk: &&[u8]| -> Ordering {
|
||||
// tz names always have TZ_NAME_SIZE bytes and are right-padded with 0s
|
||||
// so we check that a chunk starts with `name` and the remaining bytes are 0
|
||||
chunk[..name_len]
|
||||
.cmp(name_bytes)
|
||||
.then_with(|| chunk[name_len..TZ_NAME_SIZE].cmp(&zeros[name_len..]))
|
||||
};
|
||||
|
||||
let chunks: Vec<_> = self.0.chunks_exact(INDEX_ENTRY_SIZE).collect();
|
||||
chunks
|
||||
.binary_search_by(cmp)
|
||||
.map(|idx| IndexEntry::new(chunks[idx]))
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IndexEntry<'a> {
|
||||
fn new(bytes: &'a [u8]) -> Self {
|
||||
Self {
|
||||
_name: bytes[..TZ_NAME_SIZE]
|
||||
.splitn(2, |&b| b == 0u8)
|
||||
.next()
|
||||
.unwrap(),
|
||||
offset: parse_tz_int(bytes, TZ_NAME_SIZE) as usize,
|
||||
length: parse_tz_int(bytes, TZ_NAME_SIZE + TZ_INT_SIZE) as usize,
|
||||
_raw_utc_offset: parse_tz_int(bytes, TZ_NAME_SIZE + 2 * TZ_INT_SIZE) as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Panics if slice does not contain [TZ_INT_SIZE] bytes beginning at start.
|
||||
fn parse_tz_int(slice: &[u8], start: usize) -> u32 {
|
||||
u32::from_be_bytes(slice[start..start + TZ_INT_SIZE].try_into().unwrap())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use std::fs::File;
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
let mut archive = File::open("tests/resources/tzdata.zip").unwrap();
|
||||
let mut zip = zip::ZipArchive::new(&mut archive).unwrap();
|
||||
let mut file = zip.by_index(0).unwrap();
|
||||
let mut data = Vec::new();
|
||||
file.read_to_end(&mut data).unwrap();
|
||||
let cursor = Cursor::new(data);
|
||||
let tz = find_tz_data_in_file(cursor, "Europe/Kiev").unwrap();
|
||||
assert!(tz.starts_with(b"TZif2"));
|
||||
}
|
||||
}
|
||||
1
vendor/android_system_properties/.cargo-checksum.json
vendored
Normal file
1
vendor/android_system_properties/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"86f505a9258ea3098b18bb2b6c02cb45a2e0c368a9bef6814ee8865a3f169797","CONTRIBUTING.md":"0834cb3b5e092977688d73d219a05bed23ae0ecb54b6d6e5d866ce07f6583b5e","Cargo.lock":"37ffc00dbbbec58fd27b4f4cb597e5402d6cf615ce0458f62a73a7f0d987e5bd","Cargo.toml":"e9e8c037cdef7adc9794b17c13e5a014421524d67ea5048bc09cf70ef13c782c","Cargo.toml.orig":"749ab935be1cb6485115a677e36d680c2be95dcea8eb00c7b115006224ff926a","LICENSE-APACHE":"216486f29671a4262efe32af6d84a75bef398127f8c5f369b5c8305983887a06","LICENSE-MIT":"80f275e90d799911ed3830a7f242a2ef5a4ade2092fe0aa07bfb2d2cf2f2b95e","README.md":"aba8ff5dbd0712326d97d32bc6a3b66b24d1980a446c238f7e14b96784766cd1","examples/time_zone.rs":"8edb32a946ef2680146ba9ac16c233dd94391ac9f98464e9fb6f87d3954b72a9","src/lib.rs":"0004133d6c3805bf449e7183d2931e9640167511bea6cd12b400805073c4305d"},"package":"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"}
|
||||
6
vendor/android_system_properties/.cargo_vcs_info.json
vendored
Normal file
6
vendor/android_system_properties/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "fb87625f1807dff7623db2d80df682a199358515"
|
||||
},
|
||||
"path_in_vcs": ""
|
||||
}
|
||||
40
vendor/android_system_properties/CONTRIBUTING.md
vendored
Normal file
40
vendor/android_system_properties/CONTRIBUTING.md
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Contributing
|
||||
|
||||
Contributions are very much welcome. Here are the guidelines if you are thinking of helping us:
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions should be made in the form of GitHub pull requests.
|
||||
Each pull request will be reviewed by a core contributor (someone with
|
||||
permission to land patches) and either landed in the main tree or
|
||||
given feedback for changes that would be required.
|
||||
|
||||
Should you wish to work on an issue, please claim it first by commenting on
|
||||
the GitHub issue that you want to work on it. This is to prevent duplicated
|
||||
efforts from contributors on the same issue.
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- Branch from the master branch and, if needed, rebase to the current master
|
||||
branch before submitting your pull request. If it doesn't merge cleanly with
|
||||
master you may be asked to rebase your changes.
|
||||
|
||||
- Commits should be as small as possible, while ensuring that each commit is
|
||||
correct independently (i.e., each commit should compile and pass tests).
|
||||
|
||||
- If your patch is not getting reviewed or you need a specific person to review
|
||||
it, you can @-reply a reviewer asking for a review in the pull request or a
|
||||
comment.
|
||||
|
||||
- Whenever applicable, add tests relevant to the fixed bug or new feature.
|
||||
|
||||
For specific git instructions, see [GitHub workflow 101](https://github.com/servo/servo/wiki/Github-workflow).
|
||||
|
||||
## Conduct
|
||||
|
||||
We follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html).
|
||||
For escalation or moderation issues, please contact Nical (nical@fastmail.com) instead of the Rust moderation team.
|
||||
|
||||
## License
|
||||
|
||||
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 licensed dual MIT/Apache 2, without any additional terms or conditions.
|
||||
16
vendor/android_system_properties/Cargo.lock
generated
vendored
Normal file
16
vendor/android_system_properties/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
36
vendor/android_system_properties/Cargo.toml
vendored
Normal file
36
vendor/android_system_properties/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# 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 are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
authors = ["Nicolas Silva <nical@fastmail.com>"]
|
||||
description = "Minimal Android system properties wrapper"
|
||||
homepage = "https://github.com/nical/android_system_properties"
|
||||
documentation = "https://docs.rs/android_system_properties"
|
||||
readme = "README.md"
|
||||
keywords = ["android"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/nical/android_system_properties"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = [
|
||||
"arm-linux-androideabi",
|
||||
"armv7-linux-androideabi",
|
||||
"aarch64-linux-android",
|
||||
"i686-linux-android",
|
||||
"x86_64-linux-android",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
]
|
||||
|
||||
[dependencies.libc]
|
||||
version = "0.2.126"
|
||||
20
vendor/android_system_properties/Cargo.toml.orig
generated
vendored
Normal file
20
vendor/android_system_properties/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "android_system_properties"
|
||||
description = "Minimal Android system properties wrapper"
|
||||
version = "0.1.5"
|
||||
authors = ["Nicolas Silva <nical@fastmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/nical/android_system_properties"
|
||||
homepage = "https://github.com/nical/android_system_properties"
|
||||
documentation = "https://docs.rs/android_system_properties"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"android",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.126"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["arm-linux-androideabi", "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android", "x86_64-linux-android", "x86_64-unknown-linux-gnu"]
|
||||
13
vendor/android_system_properties/LICENSE-APACHE
vendored
Normal file
13
vendor/android_system_properties/LICENSE-APACHE
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright 2016 Nicolas Silva
|
||||
|
||||
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.
|
||||
20
vendor/android_system_properties/LICENSE-MIT
vendored
Normal file
20
vendor/android_system_properties/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Nicolas Silva
|
||||
|
||||
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.
|
||||
36
vendor/android_system_properties/README.md
vendored
Normal file
36
vendor/android_system_properties/README.md
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# android_system_properties
|
||||
|
||||
A thin rust wrapper for Android system properties.
|
||||
|
||||
This crate is similar to the `android-properties` crate with the exception that
|
||||
the necessary Android libc symbols are loaded dynamically instead of linked
|
||||
statically. In practice this means that the same binary will work with old and
|
||||
new versions of Android, even though the API for reading system properties changed
|
||||
around Android L.
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
use android_system_properties::AndroidSystemProperties;
|
||||
|
||||
let properties = AndroidSystemProperties::new();
|
||||
|
||||
if let Some(value) = properties.get("persist.sys.timezone") {
|
||||
println!("{}", value);
|
||||
}
|
||||
```
|
||||
|
||||
## Listing and setting properties
|
||||
|
||||
For the sake of simplicity this crate currently only contains what's needed by wgpu.
|
||||
The implementations for listing and setting properties can be added back if anyone needs
|
||||
them (let me know by filing an issue).
|
||||
|
||||
## License
|
||||
|
||||
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.
|
||||
9
vendor/android_system_properties/examples/time_zone.rs
vendored
Normal file
9
vendor/android_system_properties/examples/time_zone.rs
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/// Prints the current time zone, e.g. "Europe/Paris".
|
||||
|
||||
use android_system_properties::AndroidSystemProperties;
|
||||
|
||||
fn main() {
|
||||
let android_system_properties = AndroidSystemProperties::new();
|
||||
let tz = android_system_properties.get("persist.sys.timezone");
|
||||
println!("Your time zone is: {}", tz.as_deref().unwrap_or("<unknown>"));
|
||||
}
|
||||
221
vendor/android_system_properties/src/lib.rs
vendored
Normal file
221
vendor/android_system_properties/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
//! A thin rust wrapper for Android system properties.
|
||||
//!
|
||||
//! This crate is similar to the `android-properties` crate with the exception that
|
||||
//! the necessary Android libc symbols are loaded dynamically instead of linked
|
||||
//! statically. In practice this means that the same binary will work with old and
|
||||
//! new versions of Android, even though the API for reading system properties changed
|
||||
//! around Android L.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```rust
|
||||
//! use android_system_properties::AndroidSystemProperties;
|
||||
//!
|
||||
//! let properties = AndroidSystemProperties::new();
|
||||
//!
|
||||
//! if let Some(value) = properties.get("persist.sys.timezone") {
|
||||
//! println!("{}", value);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Listing and setting properties
|
||||
//!
|
||||
//! For the sake of simplicity this crate currently only contains what's needed by wgpu.
|
||||
//! The implementations for listing and setting properties can be added back if anyone needs
|
||||
//! them (let me know by filing an issue).
|
||||
//!
|
||||
//! ## License
|
||||
//!
|
||||
//! Licensed under either of
|
||||
//!
|
||||
//! * Apache License, Version 2.0 ([LICENSE-APACHE] or <http://www.apache.org/licenses/LICENSE-2.0>)
|
||||
//! * MIT license ([LICENSE-MIT] or <http://opensource.org/licenses/MIT>)
|
||||
//!
|
||||
//! at your option.
|
||||
//!
|
||||
//! [LICENSE-APACHE]: https://github.com/nical/android_system_properties/blob/804681c5c1c93d4fab29c1a2f47b7d808dc70fd3/LICENSE-APACHE
|
||||
//! [LICENSE-MIT]: https://github.com/nical/android_system_properties/blob/804681c5c1c93d4fab29c1a2f47b7d808dc70fd3/LICENSE-MIT
|
||||
|
||||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
os::raw::{c_char, c_int, c_void},
|
||||
};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
use std::mem;
|
||||
|
||||
unsafe fn property_callback(payload: *mut String, _name: *const c_char, value: *const c_char, _serial: u32) {
|
||||
let cvalue = CStr::from_ptr(value);
|
||||
(*payload) = cvalue.to_str().unwrap().to_string();
|
||||
}
|
||||
|
||||
type Callback = unsafe fn(*mut String, *const c_char, *const c_char, u32);
|
||||
|
||||
type SystemPropertyGetFn = unsafe extern "C" fn(*const c_char, *mut c_char) -> c_int;
|
||||
type SystemPropertyFindFn = unsafe extern "C" fn(*const c_char) -> *const c_void;
|
||||
type SystemPropertyReadCallbackFn = unsafe extern "C" fn(*const c_void, Callback, *mut String) -> *const c_void;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// An object that can retrieve android system properties.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// use android_system_properties::AndroidSystemProperties;
|
||||
///
|
||||
/// let properties = AndroidSystemProperties::new();
|
||||
///
|
||||
/// if let Some(value) = properties.get("persist.sys.timezone") {
|
||||
/// println!("{}", value);
|
||||
/// }
|
||||
/// ```
|
||||
pub struct AndroidSystemProperties {
|
||||
libc_so: *mut c_void,
|
||||
get_fn: Option<SystemPropertyGetFn>,
|
||||
find_fn: Option<SystemPropertyFindFn>,
|
||||
read_callback_fn: Option<SystemPropertyReadCallbackFn>,
|
||||
}
|
||||
|
||||
unsafe impl Send for AndroidSystemProperties {}
|
||||
unsafe impl Sync for AndroidSystemProperties {}
|
||||
|
||||
impl AndroidSystemProperties {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
/// Create an entry point for accessing Android properties.
|
||||
pub fn new() -> Self {
|
||||
AndroidSystemProperties {
|
||||
libc_so: std::ptr::null_mut(),
|
||||
find_fn: None,
|
||||
read_callback_fn: None,
|
||||
get_fn: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
/// Create an entry point for accessing Android properties.
|
||||
pub fn new() -> Self {
|
||||
let libc_so = unsafe { libc::dlopen(b"libc.so\0".as_ptr().cast(), libc::RTLD_NOLOAD) };
|
||||
|
||||
let mut properties = AndroidSystemProperties {
|
||||
libc_so,
|
||||
find_fn: None,
|
||||
read_callback_fn: None,
|
||||
get_fn: None,
|
||||
};
|
||||
|
||||
if libc_so.is_null() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
unsafe fn load_fn(libc_so: *mut c_void, name: &[u8]) -> Option<*const c_void> {
|
||||
let fn_ptr = libc::dlsym(libc_so, name.as_ptr().cast());
|
||||
|
||||
if fn_ptr.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(fn_ptr)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
properties.read_callback_fn = load_fn(libc_so, b"__system_property_read_callback\0")
|
||||
.map(|raw| mem::transmute::<*const c_void, SystemPropertyReadCallbackFn>(raw));
|
||||
|
||||
properties.find_fn = load_fn(libc_so, b"__system_property_find\0")
|
||||
.map(|raw| mem::transmute::<*const c_void, SystemPropertyFindFn>(raw));
|
||||
|
||||
// Fallback for old versions of Android.
|
||||
if properties.read_callback_fn.is_none() || properties.find_fn.is_none() {
|
||||
properties.get_fn = load_fn(libc_so, b"__system_property_get\0")
|
||||
.map(|raw| mem::transmute::<*const c_void, SystemPropertyGetFn>(raw));
|
||||
}
|
||||
}
|
||||
|
||||
properties
|
||||
}
|
||||
|
||||
/// Retrieve a system property.
|
||||
///
|
||||
/// Returns None if the operation fails.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use android_system_properties::AndroidSystemProperties;
|
||||
/// let properties = AndroidSystemProperties::new();
|
||||
///
|
||||
/// if let Some(value) = properties.get("persist.sys.timezone") {
|
||||
/// println!("{}", value);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn get(&self, name: &str) -> Option<String> {
|
||||
let cname = CString::new(name).ok()?;
|
||||
self.get_from_cstr(&cname)
|
||||
}
|
||||
|
||||
/// Retrieve a system property using a [`CStr`] key.
|
||||
///
|
||||
/// Returns None if the operation fails.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use android_system_properties::AndroidSystemProperties;
|
||||
/// # use std::ffi::CStr;
|
||||
/// let properties = AndroidSystemProperties::new();
|
||||
///
|
||||
/// let key = unsafe { CStr::from_bytes_with_nul_unchecked(b"persist.sys.timezone\0") };
|
||||
/// if let Some(value) = properties.get_from_cstr(key) {
|
||||
/// println!("{}", value);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn get_from_cstr(&self, cname: &std::ffi::CStr) -> Option<String> {
|
||||
// If available, use the recommended approach to accessing properties (Android L and onward).
|
||||
if let (Some(find_fn), Some(read_callback_fn)) = (self.find_fn, self.read_callback_fn) {
|
||||
let info = unsafe { (find_fn)(cname.as_ptr()) };
|
||||
|
||||
if info.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut result = String::new();
|
||||
|
||||
unsafe {
|
||||
(read_callback_fn)(info, property_callback, &mut result);
|
||||
}
|
||||
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
// Fall back to the older approach.
|
||||
if let Some(get_fn) = self.get_fn {
|
||||
// The constant is PROP_VALUE_MAX in Android's libc/include/sys/system_properties.h
|
||||
const PROPERTY_VALUE_MAX: usize = 92;
|
||||
let mut buffer: Vec<u8> = Vec::with_capacity(PROPERTY_VALUE_MAX);
|
||||
let raw = buffer.as_mut_ptr() as *mut c_char;
|
||||
|
||||
let len = unsafe { (get_fn)(cname.as_ptr(), raw) };
|
||||
|
||||
if len > 0 {
|
||||
assert!(len as usize <= buffer.capacity());
|
||||
unsafe { buffer.set_len(len as usize); }
|
||||
String::from_utf8(buffer).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AndroidSystemProperties {
|
||||
fn drop(&mut self) {
|
||||
if !self.libc_so.is_null() {
|
||||
unsafe {
|
||||
libc::dlclose(self.libc_so);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
162
vendor/ansi_term/.appveyor.yml
vendored
Normal file
162
vendor/ansi_term/.appveyor.yml
vendored
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# spell-checker:words POSIX repo SDK SDKs toolchain toolchains
|
||||
# spell-checker:ignore ARCH ABI BACKTRACE BINDIR cl COMNTOOLS dllcrt findstr maint MINGW MINGWDIR mkdir MSVC MSYS rustc rustlib rustup targetting USERPROFILE vcvarsall
|
||||
|
||||
version: "{build} ~ {branch}"
|
||||
|
||||
branches:
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
artifacts:
|
||||
# - path: target\%TARGET%\debug\....exe
|
||||
# name: ....exe
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- CHANNEL: nightly
|
||||
# - ABI: gnu
|
||||
|
||||
environment:
|
||||
global:
|
||||
FEATURES:
|
||||
BUILD_OPTIONS:
|
||||
TEST_OPTIONS: "--no-fail-fast"
|
||||
|
||||
matrix:
|
||||
# minimum version
|
||||
- CHANNEL: 1.28.0
|
||||
ARCH: i686
|
||||
ABI: msvc
|
||||
# "msvc" ABI
|
||||
- CHANNEL: stable
|
||||
ARCH: i686
|
||||
ABI: msvc
|
||||
- CHANNEL: stable
|
||||
ARCH: x86_64
|
||||
ABI: msvc
|
||||
# - CHANNEL: beta
|
||||
# ARCH: i686
|
||||
# ABI: msvc
|
||||
# - CHANNEL: beta
|
||||
# ARCH: x86_64
|
||||
# ABI: msvc
|
||||
- CHANNEL: nightly
|
||||
ARCH: i686
|
||||
ABI: msvc
|
||||
- CHANNEL: nightly
|
||||
ARCH: x86_64
|
||||
ABI: msvc
|
||||
# "gnu" ABI
|
||||
- CHANNEL: stable
|
||||
ARCH: i686
|
||||
ABI: gnu
|
||||
- CHANNEL: stable
|
||||
ARCH: x86_64
|
||||
ABI: gnu
|
||||
# - CHANNEL: beta
|
||||
# ARCH: i686
|
||||
# ABI: gnu
|
||||
# - CHANNEL: beta
|
||||
# ARCH: x86_64
|
||||
# ABI: gnu
|
||||
# - CHANNEL: nightly
|
||||
# ARCH: i686
|
||||
# ABI: gnu
|
||||
# - CHANNEL: nightly
|
||||
# ARCH: x86_64
|
||||
# ABI: gnu
|
||||
# # * specific gnu compilers
|
||||
# - CHANNEL: stable
|
||||
# ARCH: i686
|
||||
# ABI: gnu
|
||||
# MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/dwarf/i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z/download
|
||||
# MINGW_ARCHIVE: i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z
|
||||
# - CHANNEL: stable
|
||||
# ARCH: x86_64
|
||||
# ABI: gnu
|
||||
# MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z/download#mingw-w64-x86_64-7.3.0-posix-seh.7z
|
||||
|
||||
install:
|
||||
# force branch checkout (if knowable), then reset to the specific commit ## (can be needed for accurate code coverage info)
|
||||
# * this allows later apps to see the branch name using standard `git branch` operations, yet always builds the correct specific commit
|
||||
# * ref: <https://github.com/appveyor/ci/issues/1606>[`@`](https://archive.is/RVpnF)
|
||||
- if DEFINED APPVEYOR_REPO_BRANCH if /I "%APPVEYOR_REPO_SCM%"=="git" ( git checkout "%APPVEYOR_REPO_BRANCH%" 2>NUL & git reset --hard "%APPVEYOR_REPO_COMMIT%" )
|
||||
# ensure CWD is project main directory
|
||||
- cd "%APPVEYOR_BUILD_FOLDER%"
|
||||
# create a working area
|
||||
- ps: if ( ! $env:CI_TEMP_DIR ) { $env:CI_TEMP_DIR = "${env:TEMP}\${env:APPVEYOR_JOB_ID}" ; mkdir -force $env:CI_TEMP_DIR | out-null }
|
||||
|
||||
# define the TARGET host
|
||||
- set "TARGET=%ARCH%-pc-windows-%ABI%"
|
||||
|
||||
# show relevant environment settings
|
||||
- ps: ('CHANNEL', 'ARCH', 'ABI', 'FEATURES', 'BUILD_OPTIONS', 'TEST_OPTIONS', 'TARGET') |% { write-host -f yellow "$_=$(get-content -ea silent env:/$_)" }
|
||||
|
||||
# rust installation
|
||||
# * install `rust` via `rustup`
|
||||
- appveyor DownloadFile "https://win.rustup.rs/" -FileName "%CI_TEMP_DIR%\rustup-init.exe"
|
||||
- call "%CI_TEMP_DIR%\rustup-init.exe" -y --default-toolchain %CHANNEL% --default-host %TARGET% --no-modify-path >NUL
|
||||
- set "PATH=%PATH%;%USERPROFILE%\.cargo\bin"
|
||||
- ps: $env:TOOLCHAIN = $("$(rustup show active-toolchain)" -split '\s+')[0]
|
||||
# * set RUST_BACKTRACE for enhanced error messages
|
||||
- set RUST_BACKTRACE=1
|
||||
# * show rust versions
|
||||
- rustc -vV
|
||||
- cargo -vV
|
||||
|
||||
# "gnu" ABI setup
|
||||
# * use the system MinGW/MSYS if we can
|
||||
- if /i "%ABI%"=="gnu" set MSYS_BINDIR=C:\msys64\usr\bin
|
||||
- if /i "%ABI%"=="gnu" if /i "%ARCH%"=="i686" set "MSYS_BITS=32"
|
||||
- if /i "%ABI%"=="gnu" if /i "%ARCH%"=="x86_64" set "MSYS_BITS=64"
|
||||
- if defined MSYS_BITS set "MSYS_MINGWDIR=C:\msys64\mingw%MSYS_BITS%"
|
||||
- if defined MSYS_MINGWDIR set "MSYS_BINDIR=C:\msys64\usr\bin"
|
||||
## * workaround for rust-lang/rust#47048 / rust-lang/rust#53454 ## !maint: remove when resolved
|
||||
- if /i "%ABI%"=="gnu" if /i "%ARCH%"=="i686" if not DEFINED MINGW_URL set "MINGW_URL=https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win32/Personal Builds/mingw-builds/8.1.0/threads-posix/dwarf/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z"
|
||||
- if /i "%ABI%"=="gnu" if /i "%ARCH%"=="x86_64" if not DEFINED MINGW_URL set "MINGW_URL=https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win64/Personal Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z"
|
||||
## (end workaround)
|
||||
# * specific MinGW, if specified
|
||||
- ps: if ( ! $env:MINGW_ARCHIVE -and $env:MINGW_URL ) { $env:MINGW_ARCHIVE = $($([URI]$env:MINGW_URL).fragment).TrimStart('#') }
|
||||
- ps: if ( ! $env:MINGW_ARCHIVE -and $env:MINGW_URL ) { $env:MINGW_ARCHIVE = $([URI]$env:MINGW_URL).segments[-1] }
|
||||
- if defined MINGW_ARCHIVE curl --insecure -fsSL "%MINGW_URL%" -o "%CI_TEMP_DIR%\%MINGW_ARCHIVE%"
|
||||
- if defined MINGW_ARCHIVE mkdir "%CI_TEMP_DIR%\MinGW" >NUL
|
||||
- if defined MINGW_ARCHIVE 7z x -y "%CI_TEMP_DIR%\%MINGW_ARCHIVE%" -o"%CI_TEMP_DIR%\MinGW" >NUL
|
||||
- if defined MINGW_ARCHIVE set "MSYS_MINGWDIR=%CI_TEMP_DIR%\MinGW\mingw%MSYS_BITS%"
|
||||
- if defined MINGW_ARCHIVE set "MSYS_BINDIR=%MSYS_MINGWDIR%\bin"
|
||||
# * MinGW/MSYS PATH setup
|
||||
- if defined MSYS_MINGWDIR set PATH=%MSYS_MINGWDIR%\%ARCH%-w64-mingw32\bin;%MSYS_BINDIR%;%PATH%
|
||||
## * workaround for rust-lang/rust#47048 / rust-lang/rust#53454 ## !maint: remove when resolved
|
||||
# ** ref: <https://github.com/rust-lang/rust/issues/47048>, <https://github.com/rust-lang/rust/issues/53454>
|
||||
# ** egs: <https://github.com/pkgw/tectonic/commit/29686db533d8732d7d97fc94270ed33b77f29295>, <https://github.com/rukai/PF_Sandbox/blob/e842613cf9ff102dfb3fbd87381319e6e6dfe3ae/appveyor.yml>
|
||||
- if /i "%ABI%"=="gnu" rustup install %CHANNEL%-%ARCH%-pc-windows-msvc
|
||||
- if /i "%ABI%"=="gnu" rustup default %CHANNEL%-%ARCH%-pc-windows-msvc
|
||||
- if /i "%ABI%"=="gnu" rustup target add %TARGET%
|
||||
- ps: $env:TOOLCHAIN = $("$(rustup show active-toolchain)" -split '\s+')[0]
|
||||
- if /i "%ABI%"=="gnu" rustup show
|
||||
- if /i "%ABI%"=="gnu" rustc -vV
|
||||
# ** copy libs from gcc toolchain to rust toolchain (more specifically, "crt2.o" and "dllcrt2.o" are needed)
|
||||
- if defined MSYS_MINGWDIR copy /y "%MSYS_MINGWDIR%\%ARCH%-w64-mingw32\lib\*.o" "%USERPROFILE%\.rustup\toolchains\%TOOLCHAIN%\lib\rustlib\%TARGET%\lib" >NUL
|
||||
## (end workaround)
|
||||
# * show `gcc` info
|
||||
- if /i "%ABI%"=="gnu" ( where gcc && gcc --version )
|
||||
|
||||
# "msvc" ABI setup
|
||||
- if /i "%ABI%" == "msvc" if /i "%ARCH%" == "i686" call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat"
|
||||
- if /i "%ABI%" == "msvc" if /i "%ARCH%" == "x86_64" call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64
|
||||
- if /i "%ABI%" == "msvc" if /i "%ARCH%" == "x86_64" call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
|
||||
# * show `cl` info
|
||||
- if /i "%ABI%"=="msvc" ( where cl && cl 2>&1 | findstr /i /c:"version" )
|
||||
|
||||
# finalize options
|
||||
- ps: if ("$env:FEATURES".length) { $env:BUILD_OPTIONS = $(($env:BUILD_OPTIONS, "--features `"${env:FEATURES}`"")|?{$_}) -join ' ' }
|
||||
- ps: if ("$env:FEATURES".length) { $env:TEST_OPTIONS = $(($env:TEST_OPTIONS, "--features `"${env:FEATURES}`"")|?{$_}) -join ' ' }
|
||||
|
||||
build_script:
|
||||
- ps: $env:BUILD_CMD = $(("cargo +${env:TOOLCHAIN} build --target=${env:TARGET}", $env:BUILD_OPTIONS)|?{$_}) -join ' '
|
||||
- echo [ `%BUILD_CMD%` ] & %BUILD_CMD%
|
||||
|
||||
test_script:
|
||||
- ps: $env:TEST_CMD = $(("cargo +${env:TOOLCHAIN} test --target=${env:TARGET}", $env:TEST_OPTIONS)|?{$_}) -join ' '
|
||||
- echo [ `%TEST_CMD%` ] & %TEST_CMD%
|
||||
1
vendor/ansi_term/.cargo-checksum.json
vendored
Normal file
1
vendor/ansi_term/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".appveyor.yml":"dc18e08f20a732eadcc795e8415d3f1c3db42cb53e08a37a3c3fc2e491e13126",".cargo_vcs_info.json":"c50b5a1bf1149608ba4d9d7a4ef07c84fc56ef16831f90ce4c1597d2231dc102",".rustfmt.toml":"67eadc5b3de4ec436094e2a0cd2615180521a835fe2c74a69fa08a93735aefc0",".travis.yml":"2c8011ac77dbefaada1c4fa9e4556bfa48ac6b8fd62f332a4ba4e63eb61412a4","Cargo.lock":"31bb7b361278d99a00595cbd916c444e6fd193b5f0b1ea0cf2d9454440739501","Cargo.toml":"4ca681d6949661455ac88541ffa68ebc7db50cb2b6e9a2134e6d0687da4997c3","Cargo.toml.orig":"8fef8834a60c530d2d948340fd43d8faf711650ff23abcc9b8eed0fb9a6b73ae","LICENCE":"2762990c7fbba9d550802a2593c1d857dcd52596bb0f9f192a97e9a7ac5f4f9e","README.md":"8d983e1bb3cc99724010d9073a5be6452cd49bd57a877525fd0a5dd41e6591d5","examples/256_colours.rs":"5f2845068bc2d93cff4a61f18ffa44fbbbc91be771dfd686d537d343f37041da","examples/basic_colours.rs":"d610795f3743d10d90ec4e5ab32cc09fb16640896cecd2f93fca434a0920397c","examples/rgb_colours.rs":"8399e5131e959a56c932036b790e601fb4ad658856112daf87f933889b443f2c","src/ansi.rs":"988fb87936064fa006fcc9474ac62099c8d6e98d38bb80cec2cd864066482a08","src/debug.rs":"61343f8bf13695020102c033aeaacd9ccd3ec830eacbf9011127e61829451d20","src/difference.rs":"9b4b8f91c72932bfda262abdceff0ec124a5a8dd27d07bd4d2e5e7889135c6c9","src/display.rs":"c04f2397d1d1d86a5e2188c2840c505cb0baeaf9706a88d4bbe56eadc67811b9","src/lib.rs":"b85df4b9b8832cda777db049efa2ec84b9847438fa3feaf8540e597ce2532a47","src/style.rs":"1042fc973f5ea8bbb2a2faec334aad530520b53edc9b3296174ae38c1060490b","src/util.rs":"07c127f732887573a1c9126fc0288e13e7a8f1f803513b95e50aac2905171b0d","src/windows.rs":"7ce7dd6738b9728fcd3908c284b6f29a9bdfb34af761b4c7385cf7e3e1b20e64","src/write.rs":"c9ec03764ad1ecea8b680243c9cafc5e70919fcea7500cc18246ffd8f6bb4b33"},"package":"d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"}
|
||||
5
vendor/ansi_term/.cargo_vcs_info.json
vendored
Normal file
5
vendor/ansi_term/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "ff7eba98d55ad609c7fcc8c7bb0859b37c7545cc"
|
||||
}
|
||||
}
|
||||
2
vendor/ansi_term/.rustfmt.toml
vendored
Normal file
2
vendor/ansi_term/.rustfmt.toml
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
disable_all_formatting = true
|
||||
# For now...
|
||||
34
vendor/ansi_term/.travis.yml
vendored
Normal file
34
vendor/ansi_term/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
language: rust
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
|
||||
# load travis-cargo
|
||||
before_script:
|
||||
- |
|
||||
pip install 'travis-cargo<0.2' --user &&
|
||||
export PATH=$HOME/.local/bin:$PATH
|
||||
|
||||
script:
|
||||
- |
|
||||
travis-cargo build
|
||||
travis-cargo build --examples
|
||||
travis-cargo test
|
||||
travis-cargo --only stable doc
|
||||
after_success:
|
||||
# measure code coverage and upload to coveralls.io
|
||||
- travis-cargo coveralls --no-sudo
|
||||
|
||||
env:
|
||||
global:
|
||||
# override the default `--features unstable` used for the nightly branch (optional)
|
||||
- TRAVIS_CARGO_NIGHTLY_FEATURE=nightly
|
||||
168
vendor/ansi_term/Cargo.lock
generated
vendored
Normal file
168
vendor/ansi_term/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
dependencies = [
|
||||
"doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26"
|
||||
"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "076a696fdea89c19d3baed462576b8f6d663064414b5c793642da8dfeb99475b"
|
||||
"checksum serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "ef45eb79d6463b22f5f9e16d283798b7c0175ba6050bc25c1a946c122727fe7b"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
43
vendor/ansi_term/Cargo.toml
vendored
Normal file
43
vendor/ansi_term/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# 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 = "ansi_term"
|
||||
version = "0.12.1"
|
||||
authors = ["ogham@bsago.me", "Ryan Scheel (Havvy) <ryan.havvy@gmail.com>", "Josh Triplett <josh@joshtriplett.org>"]
|
||||
description = "Library for ANSI terminal colours and styles (bold, underline)"
|
||||
homepage = "https://github.com/ogham/rust-ansi-term"
|
||||
documentation = "https://docs.rs/ansi_term"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/ogham/rust-ansi-term"
|
||||
|
||||
[lib]
|
||||
name = "ansi_term"
|
||||
[dependencies.serde]
|
||||
version = "1.0.90"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
[dev-dependencies.doc-comment]
|
||||
version = "0.3"
|
||||
|
||||
[dev-dependencies.regex]
|
||||
version = "1.1.9"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0.39"
|
||||
|
||||
[features]
|
||||
derive_serde_style = ["serde"]
|
||||
[target."cfg(target_os=\"windows\")".dependencies.winapi]
|
||||
version = "0.3.4"
|
||||
features = ["consoleapi", "errhandlingapi", "fileapi", "handleapi", "processenv"]
|
||||
33
vendor/ansi_term/Cargo.toml.orig
generated
vendored
Normal file
33
vendor/ansi_term/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
[package]
|
||||
name = "ansi_term"
|
||||
description = "Library for ANSI terminal colours and styles (bold, underline)"
|
||||
|
||||
authors = [ "ogham@bsago.me", "Ryan Scheel (Havvy) <ryan.havvy@gmail.com>", "Josh Triplett <josh@joshtriplett.org>" ]
|
||||
documentation = "https://docs.rs/ansi_term"
|
||||
homepage = "https://github.com/ogham/rust-ansi-term"
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
version = "0.12.1"
|
||||
repository = "https://github.com/ogham/rust-ansi-term"
|
||||
|
||||
[lib]
|
||||
name = "ansi_term"
|
||||
|
||||
[features]
|
||||
derive_serde_style = ["serde"]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.90"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[target.'cfg(target_os="windows")'.dependencies.winapi]
|
||||
version = "0.3.4"
|
||||
features = ["consoleapi", "errhandlingapi", "fileapi", "handleapi", "processenv"]
|
||||
|
||||
[dev-dependencies]
|
||||
doc-comment = "0.3"
|
||||
regex = "1.1.9"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0.39"
|
||||
21
vendor/ansi_term/LICENCE
vendored
Normal file
21
vendor/ansi_term/LICENCE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Benjamin Sago
|
||||
|
||||
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.
|
||||
183
vendor/ansi_term/README.md
vendored
Normal file
183
vendor/ansi_term/README.md
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
# rust-ansi-term [](https://crates.io/crates/ansi_term) [](https://travis-ci.org/ogham/rust-ansi-term) [](https://ci.appveyor.com/project/ogham/rust-ansi-term) [](https://coveralls.io/github/ogham/rust-ansi-term?branch=master)
|
||||
|
||||
This is a library for controlling colours and formatting, such as red bold text or blue underlined text, on ANSI terminals.
|
||||
|
||||
### [View the Rustdoc](https://docs.rs/ansi_term/)
|
||||
|
||||
|
||||
# Installation
|
||||
|
||||
This crate works with [Cargo](http://crates.io). Add the following to your `Cargo.toml` dependencies section:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ansi_term = "0.12"
|
||||
```
|
||||
|
||||
|
||||
## Basic usage
|
||||
|
||||
There are three main types in this crate that you need to be concerned with: `ANSIString`, `Style`, and `Colour`.
|
||||
|
||||
A `Style` holds stylistic information: foreground and background colours, whether the text should be bold, or blinking, or other properties.
|
||||
The `Colour` enum represents the available colours.
|
||||
And an `ANSIString` is a string paired with a `Style`.
|
||||
|
||||
`Color` is also available as an alias to `Colour`.
|
||||
|
||||
To format a string, call the `paint` method on a `Style` or a `Colour`, passing in the string you want to format as the argument.
|
||||
For example, here’s how to get some red text:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Red;
|
||||
|
||||
println!("This is in red: {}", Red.paint("a red string"));
|
||||
```
|
||||
|
||||
It’s important to note that the `paint` method does *not* actually return a string with the ANSI control characters surrounding it.
|
||||
Instead, it returns an `ANSIString` value that has a `Display` implementation that, when formatted, returns the characters.
|
||||
This allows strings to be printed with a minimum of `String` allocations being performed behind the scenes.
|
||||
|
||||
If you *do* want to get at the escape codes, then you can convert the `ANSIString` to a string as you would any other `Display` value:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Red;
|
||||
|
||||
let red_string = Red.paint("a red string").to_string();
|
||||
```
|
||||
|
||||
**Note for Windows 10 users:** On Windows 10, the application must enable ANSI support first:
|
||||
|
||||
```rust,ignore
|
||||
let enabled = ansi_term::enable_ansi_support();
|
||||
```
|
||||
|
||||
## Bold, underline, background, and other styles
|
||||
|
||||
For anything more complex than plain foreground colour changes, you need to construct `Style` values themselves, rather than beginning with a `Colour`.
|
||||
You can do this by chaining methods based on a new `Style`, created with `Style::new()`.
|
||||
Each method creates a new style that has that specific property set.
|
||||
For example:
|
||||
|
||||
```rust
|
||||
use ansi_term::Style;
|
||||
|
||||
println!("How about some {} and {}?",
|
||||
Style::new().bold().paint("bold"),
|
||||
Style::new().underline().paint("underline"));
|
||||
```
|
||||
|
||||
For brevity, these methods have also been implemented for `Colour` values, so you can give your styles a foreground colour without having to begin with an empty `Style` value:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::{Blue, Yellow};
|
||||
|
||||
println!("Demonstrating {} and {}!",
|
||||
Blue.bold().paint("blue bold"),
|
||||
Yellow.underline().paint("yellow underline"));
|
||||
|
||||
println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!"));
|
||||
```
|
||||
|
||||
The complete list of styles you can use are:
|
||||
`bold`, `dimmed`, `italic`, `underline`, `blink`, `reverse`, `hidden`, and `on` for background colours.
|
||||
|
||||
In some cases, you may find it easier to change the foreground on an existing `Style` rather than starting from the appropriate `Colour`.
|
||||
You can do this using the `fg` method:
|
||||
|
||||
```rust
|
||||
use ansi_term::Style;
|
||||
use ansi_term::Colour::{Blue, Cyan, Yellow};
|
||||
|
||||
println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!"));
|
||||
println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!"));
|
||||
```
|
||||
|
||||
You can turn a `Colour` into a `Style` with the `normal` method.
|
||||
This will produce the exact same `ANSIString` as if you just used the `paint` method on the `Colour` directly, but it’s useful in certain cases: for example, you may have a method that returns `Styles`, and need to represent both the “red bold” and “red, but not bold” styles with values of the same type. The `Style` struct also has a `Default` implementation if you want to have a style with *nothing* set.
|
||||
|
||||
```rust
|
||||
use ansi_term::Style;
|
||||
use ansi_term::Colour::Red;
|
||||
|
||||
Red.normal().paint("yet another red string");
|
||||
Style::default().paint("a completely regular string");
|
||||
```
|
||||
|
||||
|
||||
## Extended colours
|
||||
|
||||
You can access the extended range of 256 colours by using the `Colour::Fixed` variant, which takes an argument of the colour number to use.
|
||||
This can be included wherever you would use a `Colour`:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Fixed;
|
||||
|
||||
Fixed(134).paint("A sort of light purple");
|
||||
Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup");
|
||||
```
|
||||
|
||||
The first sixteen of these values are the same as the normal and bold standard colour variants.
|
||||
There’s nothing stopping you from using these as `Fixed` colours instead, but there’s nothing to be gained by doing so either.
|
||||
|
||||
You can also access full 24-bit colour by using the `Colour::RGB` variant, which takes separate `u8` arguments for red, green, and blue:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::RGB;
|
||||
|
||||
RGB(70, 130, 180).paint("Steel blue");
|
||||
```
|
||||
|
||||
## Combining successive coloured strings
|
||||
|
||||
The benefit of writing ANSI escape codes to the terminal is that they *stack*: you do not need to end every coloured string with a reset code if the text that follows it is of a similar style.
|
||||
For example, if you want to have some blue text followed by some blue bold text, it’s possible to send the ANSI code for blue, followed by the ANSI code for bold, and finishing with a reset code without having to have an extra one between the two strings.
|
||||
|
||||
This crate can optimise the ANSI codes that get printed in situations like this, making life easier for your terminal renderer.
|
||||
The `ANSIStrings` struct takes a slice of several `ANSIString` values, and will iterate over each of them, printing only the codes for the styles that need to be updated as part of its formatting routine.
|
||||
|
||||
The following code snippet uses this to enclose a binary number displayed in red bold text inside some red, but not bold, brackets:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Red;
|
||||
use ansi_term::{ANSIString, ANSIStrings};
|
||||
|
||||
let some_value = format!("{:b}", 42);
|
||||
let strings: &[ANSIString<'static>] = &[
|
||||
Red.paint("["),
|
||||
Red.bold().paint(some_value),
|
||||
Red.paint("]"),
|
||||
];
|
||||
|
||||
println!("Value: {}", ANSIStrings(strings));
|
||||
```
|
||||
|
||||
There are several things to note here.
|
||||
Firstly, the `paint` method can take *either* an owned `String` or a borrowed `&str`.
|
||||
Internally, an `ANSIString` holds a copy-on-write (`Cow`) string value to deal with both owned and borrowed strings at the same time.
|
||||
This is used here to display a `String`, the result of the `format!` call, using the same mechanism as some statically-available `&str` slices.
|
||||
Secondly, that the `ANSIStrings` value works in the same way as its singular counterpart, with a `Display` implementation that only performs the formatting when required.
|
||||
|
||||
## Byte strings
|
||||
|
||||
This library also supports formatting `[u8]` byte strings; this supports applications working with text in an unknown encoding.
|
||||
`Style` and `Colour` support painting `[u8]` values, resulting in an `ANSIByteString`.
|
||||
This type does not implement `Display`, as it may not contain UTF-8, but it does provide a method `write_to` to write the result to any value that implements `Write`:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Green;
|
||||
|
||||
Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap();
|
||||
```
|
||||
|
||||
Similarly, the type `ANSIByteStrings` supports writing a list of `ANSIByteString` values with minimal escape sequences:
|
||||
|
||||
```rust
|
||||
use ansi_term::Colour::Green;
|
||||
use ansi_term::ANSIByteStrings;
|
||||
|
||||
ANSIByteStrings(&[
|
||||
Green.paint("user data 1\n".as_bytes()),
|
||||
Green.bold().paint("user data 2\n".as_bytes()),
|
||||
]).write_to(&mut std::io::stdout()).unwrap();
|
||||
```
|
||||
73
vendor/ansi_term/examples/256_colours.rs
vendored
Normal file
73
vendor/ansi_term/examples/256_colours.rs
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
extern crate ansi_term;
|
||||
use ansi_term::Colour;
|
||||
|
||||
// This example prints out the 256 colours.
|
||||
// They're arranged like this:
|
||||
//
|
||||
// - 0 to 8 are the eight standard colours.
|
||||
// - 9 to 15 are the eight bold colours.
|
||||
// - 16 to 231 are six blocks of six-by-six colour squares.
|
||||
// - 232 to 255 are shades of grey.
|
||||
|
||||
fn main() {
|
||||
|
||||
// First two lines
|
||||
for c in 0..8 {
|
||||
glow(c, c != 0);
|
||||
print!(" ");
|
||||
}
|
||||
print!("\n");
|
||||
for c in 8..16 {
|
||||
glow(c, c != 8);
|
||||
print!(" ");
|
||||
}
|
||||
print!("\n\n");
|
||||
|
||||
// Six lines of the first three squares
|
||||
for row in 0..6 {
|
||||
for square in 0..3 {
|
||||
for column in 0..6 {
|
||||
glow(16 + square * 36 + row * 6 + column, row >= 3);
|
||||
print!(" ");
|
||||
}
|
||||
|
||||
print!(" ");
|
||||
}
|
||||
|
||||
print!("\n");
|
||||
}
|
||||
print!("\n");
|
||||
|
||||
// Six more lines of the other three squares
|
||||
for row in 0..6 {
|
||||
for square in 0..3 {
|
||||
for column in 0..6 {
|
||||
glow(124 + square * 36 + row * 6 + column, row >= 3);
|
||||
print!(" ");
|
||||
}
|
||||
|
||||
print!(" ");
|
||||
}
|
||||
|
||||
print!("\n");
|
||||
}
|
||||
print!("\n");
|
||||
|
||||
// The last greyscale lines
|
||||
for c in 232..=243 {
|
||||
glow(c, false);
|
||||
print!(" ");
|
||||
}
|
||||
print!("\n");
|
||||
for c in 244..=255 {
|
||||
glow(c, true);
|
||||
print!(" ");
|
||||
}
|
||||
print!("\n");
|
||||
}
|
||||
|
||||
fn glow(c: u8, light_bg: bool) {
|
||||
let base = if light_bg { Colour::Black } else { Colour::White };
|
||||
let style = base.on(Colour::Fixed(c));
|
||||
print!("{}", style.paint(&format!(" {:3} ", c)));
|
||||
}
|
||||
18
vendor/ansi_term/examples/basic_colours.rs
vendored
Normal file
18
vendor/ansi_term/examples/basic_colours.rs
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
extern crate ansi_term;
|
||||
use ansi_term::{Style, Colour::*};
|
||||
|
||||
// This example prints out the 16 basic colours.
|
||||
|
||||
fn main() {
|
||||
let normal = Style::default();
|
||||
|
||||
println!("{} {}", normal.paint("Normal"), normal.bold().paint("bold"));
|
||||
println!("{} {}", Black.paint("Black"), Black.bold().paint("bold"));
|
||||
println!("{} {}", Red.paint("Red"), Red.bold().paint("bold"));
|
||||
println!("{} {}", Green.paint("Green"), Green.bold().paint("bold"));
|
||||
println!("{} {}", Yellow.paint("Yellow"), Yellow.bold().paint("bold"));
|
||||
println!("{} {}", Blue.paint("Blue"), Blue.bold().paint("bold"));
|
||||
println!("{} {}", Purple.paint("Purple"), Purple.bold().paint("bold"));
|
||||
println!("{} {}", Cyan.paint("Cyan"), Cyan.bold().paint("bold"));
|
||||
println!("{} {}", White.paint("White"), White.bold().paint("bold"));
|
||||
}
|
||||
23
vendor/ansi_term/examples/rgb_colours.rs
vendored
Normal file
23
vendor/ansi_term/examples/rgb_colours.rs
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
extern crate ansi_term;
|
||||
use ansi_term::{Style, Colour};
|
||||
|
||||
// This example prints out a colour gradient in a grid by calculating each
|
||||
// character’s red, green, and blue components, and using 24-bit colour codes
|
||||
// to display them.
|
||||
|
||||
const WIDTH: i32 = 80;
|
||||
const HEIGHT: i32 = 24;
|
||||
|
||||
fn main() {
|
||||
for row in 0 .. HEIGHT {
|
||||
for col in 0 .. WIDTH {
|
||||
let r = (row * 255 / HEIGHT) as u8;
|
||||
let g = (col * 255 / WIDTH) as u8;
|
||||
let b = 128;
|
||||
|
||||
print!("{}", Style::default().on(Colour::RGB(r, g, b)).paint(" "));
|
||||
}
|
||||
|
||||
print!("\n");
|
||||
}
|
||||
}
|
||||
374
vendor/ansi_term/src/ansi.rs
vendored
Normal file
374
vendor/ansi_term/src/ansi.rs
vendored
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
use style::{Colour, Style};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use write::AnyWrite;
|
||||
|
||||
|
||||
// ---- generating ANSI codes ----
|
||||
|
||||
impl Style {
|
||||
|
||||
/// Write any bytes that go *before* a piece of text to the given writer.
|
||||
fn write_prefix<W: AnyWrite + ?Sized>(&self, f: &mut W) -> Result<(), W::Error> {
|
||||
|
||||
// If there are actually no styles here, then don’t write *any* codes
|
||||
// as the prefix. An empty ANSI code may not affect the terminal
|
||||
// output at all, but a user may just want a code-free string.
|
||||
if self.is_plain() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Write the codes’ prefix, then write numbers, separated by
|
||||
// semicolons, for each text style we want to apply.
|
||||
write!(f, "\x1B[")?;
|
||||
let mut written_anything = false;
|
||||
|
||||
{
|
||||
let mut write_char = |c| {
|
||||
if written_anything { write!(f, ";")?; }
|
||||
written_anything = true;
|
||||
write!(f, "{}", c)?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if self.is_bold { write_char('1')? }
|
||||
if self.is_dimmed { write_char('2')? }
|
||||
if self.is_italic { write_char('3')? }
|
||||
if self.is_underline { write_char('4')? }
|
||||
if self.is_blink { write_char('5')? }
|
||||
if self.is_reverse { write_char('7')? }
|
||||
if self.is_hidden { write_char('8')? }
|
||||
if self.is_strikethrough { write_char('9')? }
|
||||
}
|
||||
|
||||
// The foreground and background colours, if specified, need to be
|
||||
// handled specially because the number codes are more complicated.
|
||||
// (see `write_background_code` and `write_foreground_code`)
|
||||
if let Some(bg) = self.background {
|
||||
if written_anything { write!(f, ";")?; }
|
||||
written_anything = true;
|
||||
bg.write_background_code(f)?;
|
||||
}
|
||||
|
||||
if let Some(fg) = self.foreground {
|
||||
if written_anything { write!(f, ";")?; }
|
||||
fg.write_foreground_code(f)?;
|
||||
}
|
||||
|
||||
// All the codes end with an `m`, because reasons.
|
||||
write!(f, "m")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write any bytes that go *after* a piece of text to the given writer.
|
||||
fn write_suffix<W: AnyWrite + ?Sized>(&self, f: &mut W) -> Result<(), W::Error> {
|
||||
if self.is_plain() {
|
||||
Ok(())
|
||||
}
|
||||
else {
|
||||
write!(f, "{}", RESET)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The code to send to reset all styles and return to `Style::default()`.
|
||||
pub static RESET: &str = "\x1B[0m";
|
||||
|
||||
|
||||
|
||||
impl Colour {
|
||||
fn write_foreground_code<W: AnyWrite + ?Sized>(&self, f: &mut W) -> Result<(), W::Error> {
|
||||
match *self {
|
||||
Colour::Black => write!(f, "30"),
|
||||
Colour::Red => write!(f, "31"),
|
||||
Colour::Green => write!(f, "32"),
|
||||
Colour::Yellow => write!(f, "33"),
|
||||
Colour::Blue => write!(f, "34"),
|
||||
Colour::Purple => write!(f, "35"),
|
||||
Colour::Cyan => write!(f, "36"),
|
||||
Colour::White => write!(f, "37"),
|
||||
Colour::Fixed(num) => write!(f, "38;5;{}", &num),
|
||||
Colour::RGB(r,g,b) => write!(f, "38;2;{};{};{}", &r, &g, &b),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_background_code<W: AnyWrite + ?Sized>(&self, f: &mut W) -> Result<(), W::Error> {
|
||||
match *self {
|
||||
Colour::Black => write!(f, "40"),
|
||||
Colour::Red => write!(f, "41"),
|
||||
Colour::Green => write!(f, "42"),
|
||||
Colour::Yellow => write!(f, "43"),
|
||||
Colour::Blue => write!(f, "44"),
|
||||
Colour::Purple => write!(f, "45"),
|
||||
Colour::Cyan => write!(f, "46"),
|
||||
Colour::White => write!(f, "47"),
|
||||
Colour::Fixed(num) => write!(f, "48;5;{}", &num),
|
||||
Colour::RGB(r,g,b) => write!(f, "48;2;{};{};{}", &r, &g, &b),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Like `ANSIString`, but only displays the style prefix.
|
||||
///
|
||||
/// This type implements the `Display` trait, meaning it can be written to a
|
||||
/// `std::fmt` formatting without doing any extra allocation, and written to a
|
||||
/// string with the `.to_string()` method. For examples, see
|
||||
/// [`Style::prefix`](struct.Style.html#method.prefix).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Prefix(Style);
|
||||
|
||||
/// Like `ANSIString`, but only displays the difference between two
|
||||
/// styles.
|
||||
///
|
||||
/// This type implements the `Display` trait, meaning it can be written to a
|
||||
/// `std::fmt` formatting without doing any extra allocation, and written to a
|
||||
/// string with the `.to_string()` method. For examples, see
|
||||
/// [`Style::infix`](struct.Style.html#method.infix).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Infix(Style, Style);
|
||||
|
||||
/// Like `ANSIString`, but only displays the style suffix.
|
||||
///
|
||||
/// This type implements the `Display` trait, meaning it can be written to a
|
||||
/// `std::fmt` formatting without doing any extra allocation, and written to a
|
||||
/// string with the `.to_string()` method. For examples, see
|
||||
/// [`Style::suffix`](struct.Style.html#method.suffix).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Suffix(Style);
|
||||
|
||||
|
||||
impl Style {
|
||||
|
||||
/// The prefix bytes for this style. These are the bytes that tell the
|
||||
/// terminal to use a different colour or font style.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour::Blue};
|
||||
///
|
||||
/// let style = Style::default().bold();
|
||||
/// assert_eq!("\x1b[1m",
|
||||
/// style.prefix().to_string());
|
||||
///
|
||||
/// let style = Blue.bold();
|
||||
/// assert_eq!("\x1b[1;34m",
|
||||
/// style.prefix().to_string());
|
||||
///
|
||||
/// let style = Style::default();
|
||||
/// assert_eq!("",
|
||||
/// style.prefix().to_string());
|
||||
/// ```
|
||||
pub fn prefix(self) -> Prefix {
|
||||
Prefix(self)
|
||||
}
|
||||
|
||||
/// The infix bytes between this style and `next` style. These are the bytes
|
||||
/// that tell the terminal to change the style to `next`. These may include
|
||||
/// a reset followed by the next colour and style, depending on the two styles.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour::Green};
|
||||
///
|
||||
/// let style = Style::default().bold();
|
||||
/// assert_eq!("\x1b[32m",
|
||||
/// style.infix(Green.bold()).to_string());
|
||||
///
|
||||
/// let style = Green.normal();
|
||||
/// assert_eq!("\x1b[1m",
|
||||
/// style.infix(Green.bold()).to_string());
|
||||
///
|
||||
/// let style = Style::default();
|
||||
/// assert_eq!("",
|
||||
/// style.infix(style).to_string());
|
||||
/// ```
|
||||
pub fn infix(self, next: Style) -> Infix {
|
||||
Infix(self, next)
|
||||
}
|
||||
|
||||
/// The suffix for this style. These are the bytes that tell the terminal
|
||||
/// to reset back to its normal colour and font style.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour::Green};
|
||||
///
|
||||
/// let style = Style::default().bold();
|
||||
/// assert_eq!("\x1b[0m",
|
||||
/// style.suffix().to_string());
|
||||
///
|
||||
/// let style = Green.normal().bold();
|
||||
/// assert_eq!("\x1b[0m",
|
||||
/// style.suffix().to_string());
|
||||
///
|
||||
/// let style = Style::default();
|
||||
/// assert_eq!("",
|
||||
/// style.suffix().to_string());
|
||||
/// ```
|
||||
pub fn suffix(self) -> Suffix {
|
||||
Suffix(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Colour {
|
||||
|
||||
/// The prefix bytes for this colour as a `Style`. These are the bytes
|
||||
/// that tell the terminal to use a different colour or font style.
|
||||
///
|
||||
/// See also [`Style::prefix`](struct.Style.html#method.prefix).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour::Green;
|
||||
///
|
||||
/// assert_eq!("\x1b[0m",
|
||||
/// Green.suffix().to_string());
|
||||
/// ```
|
||||
pub fn prefix(self) -> Prefix {
|
||||
Prefix(self.normal())
|
||||
}
|
||||
|
||||
/// The infix bytes between this colour and `next` colour. These are the bytes
|
||||
/// that tell the terminal to use the `next` colour, or to do nothing if
|
||||
/// the two colours are equal.
|
||||
///
|
||||
/// See also [`Style::infix`](struct.Style.html#method.infix).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour::{Red, Yellow};
|
||||
///
|
||||
/// assert_eq!("\x1b[33m",
|
||||
/// Red.infix(Yellow).to_string());
|
||||
/// ```
|
||||
pub fn infix(self, next: Colour) -> Infix {
|
||||
Infix(self.normal(), next.normal())
|
||||
}
|
||||
|
||||
/// The suffix for this colour as a `Style`. These are the bytes that
|
||||
/// tell the terminal to reset back to its normal colour and font style.
|
||||
///
|
||||
/// See also [`Style::suffix`](struct.Style.html#method.suffix).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour::Purple;
|
||||
///
|
||||
/// assert_eq!("\x1b[0m",
|
||||
/// Purple.suffix().to_string());
|
||||
/// ```
|
||||
pub fn suffix(self) -> Suffix {
|
||||
Suffix(self.normal())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Prefix {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let f: &mut fmt::Write = f;
|
||||
self.0.write_prefix(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Infix {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use difference::Difference;
|
||||
|
||||
match Difference::between(&self.0, &self.1) {
|
||||
Difference::ExtraStyles(style) => {
|
||||
let f: &mut fmt::Write = f;
|
||||
style.write_prefix(f)
|
||||
},
|
||||
Difference::Reset => {
|
||||
let f: &mut fmt::Write = f;
|
||||
write!(f, "{}{}", RESET, self.1.prefix())
|
||||
},
|
||||
Difference::NoDifference => {
|
||||
Ok(()) // nothing to write
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Suffix {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let f: &mut fmt::Write = f;
|
||||
self.0.write_suffix(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use style::Style;
|
||||
use style::Colour::*;
|
||||
|
||||
macro_rules! test {
|
||||
($name: ident: $style: expr; $input: expr => $result: expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
assert_eq!($style.paint($input).to_string(), $result.to_string());
|
||||
|
||||
let mut v = Vec::new();
|
||||
$style.paint($input.as_bytes()).write_to(&mut v).unwrap();
|
||||
assert_eq!(v.as_slice(), $result.as_bytes());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test!(plain: Style::default(); "text/plain" => "text/plain");
|
||||
test!(red: Red; "hi" => "\x1B[31mhi\x1B[0m");
|
||||
test!(black: Black.normal(); "hi" => "\x1B[30mhi\x1B[0m");
|
||||
test!(yellow_bold: Yellow.bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
|
||||
test!(yellow_bold_2: Yellow.normal().bold(); "hi" => "\x1B[1;33mhi\x1B[0m");
|
||||
test!(blue_underline: Blue.underline(); "hi" => "\x1B[4;34mhi\x1B[0m");
|
||||
test!(green_bold_ul: Green.bold().underline(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
|
||||
test!(green_bold_ul_2: Green.underline().bold(); "hi" => "\x1B[1;4;32mhi\x1B[0m");
|
||||
test!(purple_on_white: Purple.on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
|
||||
test!(purple_on_white_2: Purple.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m");
|
||||
test!(yellow_on_blue: Style::new().on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
|
||||
test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m");
|
||||
test!(cyan_bold_on_white: Cyan.bold().on(White); "hi" => "\x1B[1;47;36mhi\x1B[0m");
|
||||
test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[4;47;36mhi\x1B[0m");
|
||||
test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
|
||||
test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m");
|
||||
test!(fixed: Fixed(100); "hi" => "\x1B[38;5;100mhi\x1B[0m");
|
||||
test!(fixed_on_purple: Fixed(100).on(Purple); "hi" => "\x1B[45;38;5;100mhi\x1B[0m");
|
||||
test!(fixed_on_fixed: Fixed(100).on(Fixed(200)); "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m");
|
||||
test!(rgb: RGB(70,130,180); "hi" => "\x1B[38;2;70;130;180mhi\x1B[0m");
|
||||
test!(rgb_on_blue: RGB(70,130,180).on(Blue); "hi" => "\x1B[44;38;2;70;130;180mhi\x1B[0m");
|
||||
test!(blue_on_rgb: Blue.on(RGB(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m");
|
||||
test!(rgb_on_rgb: RGB(70,130,180).on(RGB(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m");
|
||||
test!(bold: Style::new().bold(); "hi" => "\x1B[1mhi\x1B[0m");
|
||||
test!(underline: Style::new().underline(); "hi" => "\x1B[4mhi\x1B[0m");
|
||||
test!(bunderline: Style::new().bold().underline(); "hi" => "\x1B[1;4mhi\x1B[0m");
|
||||
test!(dimmed: Style::new().dimmed(); "hi" => "\x1B[2mhi\x1B[0m");
|
||||
test!(italic: Style::new().italic(); "hi" => "\x1B[3mhi\x1B[0m");
|
||||
test!(blink: Style::new().blink(); "hi" => "\x1B[5mhi\x1B[0m");
|
||||
test!(reverse: Style::new().reverse(); "hi" => "\x1B[7mhi\x1B[0m");
|
||||
test!(hidden: Style::new().hidden(); "hi" => "\x1B[8mhi\x1B[0m");
|
||||
test!(stricken: Style::new().strikethrough(); "hi" => "\x1B[9mhi\x1B[0m");
|
||||
|
||||
#[test]
|
||||
fn test_infix() {
|
||||
assert_eq!(Style::new().dimmed().infix(Style::new()).to_string(), "\x1B[0m");
|
||||
assert_eq!(White.dimmed().infix(White.normal()).to_string(), "\x1B[0m\x1B[37m");
|
||||
assert_eq!(White.normal().infix(White.bold()).to_string(), "\x1B[1m");
|
||||
assert_eq!(White.normal().infix(Blue.normal()).to_string(), "\x1B[34m");
|
||||
assert_eq!(Blue.bold().infix(Blue.bold()).to_string(), "");
|
||||
}
|
||||
}
|
||||
134
vendor/ansi_term/src/debug.rs
vendored
Normal file
134
vendor/ansi_term/src/debug.rs
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
use std::fmt;
|
||||
|
||||
use style::Style;
|
||||
|
||||
/// Styles have a special `Debug` implementation that only shows the fields that
|
||||
/// are set. Fields that haven’t been touched aren’t included in the output.
|
||||
///
|
||||
/// This behaviour gets bypassed when using the alternate formatting mode
|
||||
/// `format!("{:#?}")`.
|
||||
///
|
||||
/// use ansi_term::Colour::{Red, Blue};
|
||||
/// assert_eq!("Style { fg(Red), on(Blue), bold, italic }",
|
||||
/// format!("{:?}", Red.on(Blue).bold().italic()));
|
||||
impl fmt::Debug for Style {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
if fmt.alternate() {
|
||||
fmt.debug_struct("Style")
|
||||
.field("foreground", &self.foreground)
|
||||
.field("background", &self.background)
|
||||
.field("blink", &self.is_blink)
|
||||
.field("bold", &self.is_bold)
|
||||
.field("dimmed", &self.is_dimmed)
|
||||
.field("hidden", &self.is_hidden)
|
||||
.field("italic", &self.is_italic)
|
||||
.field("reverse", &self.is_reverse)
|
||||
.field("strikethrough", &self.is_strikethrough)
|
||||
.field("underline", &self.is_underline)
|
||||
.finish()
|
||||
}
|
||||
else if self.is_plain() {
|
||||
fmt.write_str("Style {}")
|
||||
}
|
||||
else {
|
||||
fmt.write_str("Style { ")?;
|
||||
|
||||
let mut written_anything = false;
|
||||
|
||||
if let Some(fg) = self.foreground {
|
||||
if written_anything { fmt.write_str(", ")? }
|
||||
written_anything = true;
|
||||
write!(fmt, "fg({:?})", fg)?
|
||||
}
|
||||
|
||||
if let Some(bg) = self.background {
|
||||
if written_anything { fmt.write_str(", ")? }
|
||||
written_anything = true;
|
||||
write!(fmt, "on({:?})", bg)?
|
||||
}
|
||||
|
||||
{
|
||||
let mut write_flag = |name| {
|
||||
if written_anything { fmt.write_str(", ")? }
|
||||
written_anything = true;
|
||||
fmt.write_str(name)
|
||||
};
|
||||
|
||||
if self.is_blink { write_flag("blink")? }
|
||||
if self.is_bold { write_flag("bold")? }
|
||||
if self.is_dimmed { write_flag("dimmed")? }
|
||||
if self.is_hidden { write_flag("hidden")? }
|
||||
if self.is_italic { write_flag("italic")? }
|
||||
if self.is_reverse { write_flag("reverse")? }
|
||||
if self.is_strikethrough { write_flag("strikethrough")? }
|
||||
if self.is_underline { write_flag("underline")? }
|
||||
}
|
||||
|
||||
write!(fmt, " }}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use style::Colour::*;
|
||||
use style::Style;
|
||||
|
||||
fn style() -> Style {
|
||||
Style::new()
|
||||
}
|
||||
|
||||
macro_rules! test {
|
||||
($name: ident: $obj: expr => $result: expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
assert_eq!($result, format!("{:?}", $obj));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test!(empty: style() => "Style {}");
|
||||
test!(bold: style().bold() => "Style { bold }");
|
||||
test!(italic: style().italic() => "Style { italic }");
|
||||
test!(both: style().bold().italic() => "Style { bold, italic }");
|
||||
|
||||
test!(red: Red.normal() => "Style { fg(Red) }");
|
||||
test!(redblue: Red.normal().on(RGB(3, 2, 4)) => "Style { fg(Red), on(RGB(3, 2, 4)) }");
|
||||
|
||||
test!(everything:
|
||||
Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() =>
|
||||
"Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }");
|
||||
|
||||
#[test]
|
||||
fn long_and_detailed() {
|
||||
extern crate regex;
|
||||
let expected_debug = "Style { fg(Blue), bold }";
|
||||
let expected_pretty_repat = r##"(?x)
|
||||
Style\s+\{\s+
|
||||
foreground:\s+Some\(\s+
|
||||
Blue,?\s+
|
||||
\),\s+
|
||||
background:\s+None,\s+
|
||||
blink:\s+false,\s+
|
||||
bold:\s+true,\s+
|
||||
dimmed:\s+false,\s+
|
||||
hidden:\s+false,\s+
|
||||
italic:\s+false,\s+
|
||||
reverse:\s+false,\s+
|
||||
strikethrough:\s+
|
||||
false,\s+
|
||||
underline:\s+false,?\s+
|
||||
\}"##;
|
||||
let re = regex::Regex::new(expected_pretty_repat).unwrap();
|
||||
|
||||
let style = Blue.bold();
|
||||
let style_fmt_debug = format!("{:?}", style);
|
||||
let style_fmt_pretty = format!("{:#?}", style);
|
||||
println!("style_fmt_debug:\n{}", style_fmt_debug);
|
||||
println!("style_fmt_pretty:\n{}", style_fmt_pretty);
|
||||
|
||||
assert_eq!(expected_debug, style_fmt_debug);
|
||||
assert!(re.is_match(&style_fmt_pretty));
|
||||
}
|
||||
}
|
||||
179
vendor/ansi_term/src/difference.rs
vendored
Normal file
179
vendor/ansi_term/src/difference.rs
vendored
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
use super::Style;
|
||||
|
||||
|
||||
/// When printing out one coloured string followed by another, use one of
|
||||
/// these rules to figure out which *extra* control codes need to be sent.
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
pub enum Difference {
|
||||
|
||||
/// Print out the control codes specified by this style to end up looking
|
||||
/// like the second string's styles.
|
||||
ExtraStyles(Style),
|
||||
|
||||
/// Converting between these two is impossible, so just send a reset
|
||||
/// command and then the second string's styles.
|
||||
Reset,
|
||||
|
||||
/// The before style is exactly the same as the after style, so no further
|
||||
/// control codes need to be printed.
|
||||
NoDifference,
|
||||
}
|
||||
|
||||
|
||||
impl Difference {
|
||||
|
||||
/// Compute the 'style difference' required to turn an existing style into
|
||||
/// the given, second style.
|
||||
///
|
||||
/// For example, to turn green text into green bold text, it's redundant
|
||||
/// to write a reset command then a second green+bold command, instead of
|
||||
/// just writing one bold command. This method should see that both styles
|
||||
/// use the foreground colour green, and reduce it to a single command.
|
||||
///
|
||||
/// This method returns an enum value because it's not actually always
|
||||
/// possible to turn one style into another: for example, text could be
|
||||
/// made bold and underlined, but you can't remove the bold property
|
||||
/// without also removing the underline property. So when this has to
|
||||
/// happen, this function returns None, meaning that the entire set of
|
||||
/// styles should be reset and begun again.
|
||||
pub fn between(first: &Style, next: &Style) -> Difference {
|
||||
use self::Difference::*;
|
||||
|
||||
// XXX(Havvy): This algorithm is kind of hard to replicate without
|
||||
// having the Plain/Foreground enum variants, so I'm just leaving
|
||||
// it commented out for now, and defaulting to Reset.
|
||||
|
||||
if first == next {
|
||||
return NoDifference;
|
||||
}
|
||||
|
||||
// Cannot un-bold, so must Reset.
|
||||
if first.is_bold && !next.is_bold {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_dimmed && !next.is_dimmed {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_italic && !next.is_italic {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
// Cannot un-underline, so must Reset.
|
||||
if first.is_underline && !next.is_underline {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_blink && !next.is_blink {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_reverse && !next.is_reverse {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_hidden && !next.is_hidden {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
if first.is_strikethrough && !next.is_strikethrough {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
// Cannot go from foreground to no foreground, so must Reset.
|
||||
if first.foreground.is_some() && next.foreground.is_none() {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
// Cannot go from background to no background, so must Reset.
|
||||
if first.background.is_some() && next.background.is_none() {
|
||||
return Reset;
|
||||
}
|
||||
|
||||
let mut extra_styles = Style::default();
|
||||
|
||||
if first.is_bold != next.is_bold {
|
||||
extra_styles.is_bold = true;
|
||||
}
|
||||
|
||||
if first.is_dimmed != next.is_dimmed {
|
||||
extra_styles.is_dimmed = true;
|
||||
}
|
||||
|
||||
if first.is_italic != next.is_italic {
|
||||
extra_styles.is_italic = true;
|
||||
}
|
||||
|
||||
if first.is_underline != next.is_underline {
|
||||
extra_styles.is_underline = true;
|
||||
}
|
||||
|
||||
if first.is_blink != next.is_blink {
|
||||
extra_styles.is_blink = true;
|
||||
}
|
||||
|
||||
if first.is_reverse != next.is_reverse {
|
||||
extra_styles.is_reverse = true;
|
||||
}
|
||||
|
||||
if first.is_hidden != next.is_hidden {
|
||||
extra_styles.is_hidden = true;
|
||||
}
|
||||
|
||||
if first.is_strikethrough != next.is_strikethrough {
|
||||
extra_styles.is_strikethrough = true;
|
||||
}
|
||||
|
||||
if first.foreground != next.foreground {
|
||||
extra_styles.foreground = next.foreground;
|
||||
}
|
||||
|
||||
if first.background != next.background {
|
||||
extra_styles.background = next.background;
|
||||
}
|
||||
|
||||
ExtraStyles(extra_styles)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use super::Difference::*;
|
||||
use style::Colour::*;
|
||||
use style::Style;
|
||||
|
||||
fn style() -> Style {
|
||||
Style::new()
|
||||
}
|
||||
|
||||
macro_rules! test {
|
||||
($name: ident: $first: expr; $next: expr => $result: expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
assert_eq!($result, Difference::between(&$first, &$next));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test!(nothing: Green.normal(); Green.normal() => NoDifference);
|
||||
test!(uppercase: Green.normal(); Green.bold() => ExtraStyles(style().bold()));
|
||||
test!(lowercase: Green.bold(); Green.normal() => Reset);
|
||||
test!(nothing2: Green.bold(); Green.bold() => NoDifference);
|
||||
|
||||
test!(colour_change: Red.normal(); Blue.normal() => ExtraStyles(Blue.normal()));
|
||||
|
||||
test!(addition_of_blink: style(); style().blink() => ExtraStyles(style().blink()));
|
||||
test!(addition_of_dimmed: style(); style().dimmed() => ExtraStyles(style().dimmed()));
|
||||
test!(addition_of_hidden: style(); style().hidden() => ExtraStyles(style().hidden()));
|
||||
test!(addition_of_reverse: style(); style().reverse() => ExtraStyles(style().reverse()));
|
||||
test!(addition_of_strikethrough: style(); style().strikethrough() => ExtraStyles(style().strikethrough()));
|
||||
|
||||
test!(removal_of_strikethrough: style().strikethrough(); style() => Reset);
|
||||
test!(removal_of_reverse: style().reverse(); style() => Reset);
|
||||
test!(removal_of_hidden: style().hidden(); style() => Reset);
|
||||
test!(removal_of_dimmed: style().dimmed(); style() => Reset);
|
||||
test!(removal_of_blink: style().blink(); style() => Reset);
|
||||
}
|
||||
296
vendor/ansi_term/src/display.rs
vendored
Normal file
296
vendor/ansi_term/src/display.rs
vendored
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::ops::Deref;
|
||||
|
||||
use ansi::RESET;
|
||||
use difference::Difference;
|
||||
use style::{Style, Colour};
|
||||
use write::AnyWrite;
|
||||
|
||||
|
||||
/// An `ANSIGenericString` includes a generic string type and a `Style` to
|
||||
/// display that string. `ANSIString` and `ANSIByteString` are aliases for
|
||||
/// this type on `str` and `\[u8]`, respectively.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct ANSIGenericString<'a, S: 'a + ToOwned + ?Sized>
|
||||
where <S as ToOwned>::Owned: fmt::Debug {
|
||||
style: Style,
|
||||
string: Cow<'a, S>,
|
||||
}
|
||||
|
||||
|
||||
/// Cloning an `ANSIGenericString` will clone its underlying string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::ANSIString;
|
||||
///
|
||||
/// let plain_string = ANSIString::from("a plain string");
|
||||
/// let clone_string = plain_string.clone();
|
||||
/// assert_eq!(clone_string, plain_string);
|
||||
/// ```
|
||||
impl<'a, S: 'a + ToOwned + ?Sized> Clone for ANSIGenericString<'a, S>
|
||||
where <S as ToOwned>::Owned: fmt::Debug {
|
||||
fn clone(&self) -> ANSIGenericString<'a, S> {
|
||||
ANSIGenericString {
|
||||
style: self.style,
|
||||
string: self.string.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// You might think that the hand-written Clone impl above is the same as the
|
||||
// one that gets generated with #[derive]. But it’s not *quite* the same!
|
||||
//
|
||||
// `str` is not Clone, and the derived Clone implementation puts a Clone
|
||||
// constraint on the S type parameter (generated using --pretty=expanded):
|
||||
//
|
||||
// ↓_________________↓
|
||||
// impl <'a, S: ::std::clone::Clone + 'a + ToOwned + ?Sized> ::std::clone::Clone
|
||||
// for ANSIGenericString<'a, S> where
|
||||
// <S as ToOwned>::Owned: fmt::Debug { ... }
|
||||
//
|
||||
// This resulted in compile errors when you tried to derive Clone on a type
|
||||
// that used it:
|
||||
//
|
||||
// #[derive(PartialEq, Debug, Clone, Default)]
|
||||
// pub struct TextCellContents(Vec<ANSIString<'static>>);
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// error[E0277]: the trait `std::clone::Clone` is not implemented for `str`
|
||||
//
|
||||
// The hand-written impl above can ignore that constraint and still compile.
|
||||
|
||||
|
||||
|
||||
/// An ANSI String is a string coupled with the `Style` to display it
|
||||
/// in a terminal.
|
||||
///
|
||||
/// Although not technically a string itself, it can be turned into
|
||||
/// one with the `to_string` method.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::ANSIString;
|
||||
/// use ansi_term::Colour::Red;
|
||||
///
|
||||
/// let red_string = Red.paint("a red string");
|
||||
/// println!("{}", red_string);
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::ANSIString;
|
||||
///
|
||||
/// let plain_string = ANSIString::from("a plain string");
|
||||
/// assert_eq!(&*plain_string, "a plain string");
|
||||
/// ```
|
||||
pub type ANSIString<'a> = ANSIGenericString<'a, str>;
|
||||
|
||||
/// An `ANSIByteString` represents a formatted series of bytes. Use
|
||||
/// `ANSIByteString` when styling text with an unknown encoding.
|
||||
pub type ANSIByteString<'a> = ANSIGenericString<'a, [u8]>;
|
||||
|
||||
impl<'a, I, S: 'a + ToOwned + ?Sized> From<I> for ANSIGenericString<'a, S>
|
||||
where I: Into<Cow<'a, S>>,
|
||||
<S as ToOwned>::Owned: fmt::Debug {
|
||||
fn from(input: I) -> ANSIGenericString<'a, S> {
|
||||
ANSIGenericString {
|
||||
string: input.into(),
|
||||
style: Style::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericString<'a, S>
|
||||
where <S as ToOwned>::Owned: fmt::Debug {
|
||||
|
||||
/// Directly access the style
|
||||
pub fn style_ref(&self) -> &Style {
|
||||
&self.style
|
||||
}
|
||||
|
||||
/// Directly access the style mutably
|
||||
pub fn style_ref_mut(&mut self) -> &mut Style {
|
||||
&mut self.style
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: 'a + ToOwned + ?Sized> Deref for ANSIGenericString<'a, S>
|
||||
where <S as ToOwned>::Owned: fmt::Debug {
|
||||
type Target = S;
|
||||
|
||||
fn deref(&self) -> &S {
|
||||
self.string.deref()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A set of `ANSIGenericString`s collected together, in order to be
|
||||
/// written with a minimum of control characters.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ANSIGenericStrings<'a, S: 'a + ToOwned + ?Sized>
|
||||
(pub &'a [ANSIGenericString<'a, S>])
|
||||
where <S as ToOwned>::Owned: fmt::Debug, S: PartialEq;
|
||||
|
||||
/// A set of `ANSIString`s collected together, in order to be written with a
|
||||
/// minimum of control characters.
|
||||
pub type ANSIStrings<'a> = ANSIGenericStrings<'a, str>;
|
||||
|
||||
/// A function to construct an `ANSIStrings` instance.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn ANSIStrings<'a>(arg: &'a [ANSIString<'a>]) -> ANSIStrings<'a> {
|
||||
ANSIGenericStrings(arg)
|
||||
}
|
||||
|
||||
/// A set of `ANSIByteString`s collected together, in order to be
|
||||
/// written with a minimum of control characters.
|
||||
pub type ANSIByteStrings<'a> = ANSIGenericStrings<'a, [u8]>;
|
||||
|
||||
/// A function to construct an `ANSIByteStrings` instance.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn ANSIByteStrings<'a>(arg: &'a [ANSIByteString<'a>]) -> ANSIByteStrings<'a> {
|
||||
ANSIGenericStrings(arg)
|
||||
}
|
||||
|
||||
|
||||
// ---- paint functions ----
|
||||
|
||||
impl Style {
|
||||
|
||||
/// Paints the given text with this colour, returning an ANSI string.
|
||||
#[must_use]
|
||||
pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
|
||||
where I: Into<Cow<'a, S>>,
|
||||
<S as ToOwned>::Owned: fmt::Debug {
|
||||
ANSIGenericString {
|
||||
string: input.into(),
|
||||
style: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Colour {
|
||||
|
||||
/// Paints the given text with this colour, returning an ANSI string.
|
||||
/// This is a short-cut so you don’t have to use `Blue.normal()` just
|
||||
/// to get blue text.
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour::Blue;
|
||||
/// println!("{}", Blue.paint("da ba dee"));
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S>
|
||||
where I: Into<Cow<'a, S>>,
|
||||
<S as ToOwned>::Owned: fmt::Debug {
|
||||
ANSIGenericString {
|
||||
string: input.into(),
|
||||
style: self.normal(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- writers for individual ANSI strings ----
|
||||
|
||||
impl<'a> fmt::Display for ANSIString<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let w: &mut fmt::Write = f;
|
||||
self.write_to_any(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ANSIByteString<'a> {
|
||||
/// Write an `ANSIByteString` to an `io::Write`. This writes the escape
|
||||
/// sequences for the associated `Style` around the bytes.
|
||||
pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
let w: &mut io::Write = w;
|
||||
self.write_to_any(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericString<'a, S>
|
||||
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
|
||||
fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
|
||||
write!(w, "{}", self.style.prefix())?;
|
||||
w.write_str(self.string.as_ref())?;
|
||||
write!(w, "{}", self.style.suffix())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- writers for combined ANSI strings ----
|
||||
|
||||
impl<'a> fmt::Display for ANSIStrings<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let f: &mut fmt::Write = f;
|
||||
self.write_to_any(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ANSIByteStrings<'a> {
|
||||
/// Write `ANSIByteStrings` to an `io::Write`. This writes the minimal
|
||||
/// escape sequences for the associated `Style`s around each set of
|
||||
/// bytes.
|
||||
pub fn write_to<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
let w: &mut io::Write = w;
|
||||
self.write_to_any(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: 'a + ToOwned + ?Sized + PartialEq> ANSIGenericStrings<'a, S>
|
||||
where <S as ToOwned>::Owned: fmt::Debug, &'a S: AsRef<[u8]> {
|
||||
fn write_to_any<W: AnyWrite<wstr=S> + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> {
|
||||
use self::Difference::*;
|
||||
|
||||
let first = match self.0.first() {
|
||||
None => return Ok(()),
|
||||
Some(f) => f,
|
||||
};
|
||||
|
||||
write!(w, "{}", first.style.prefix())?;
|
||||
w.write_str(first.string.as_ref())?;
|
||||
|
||||
for window in self.0.windows(2) {
|
||||
match Difference::between(&window[0].style, &window[1].style) {
|
||||
ExtraStyles(style) => write!(w, "{}", style.prefix())?,
|
||||
Reset => write!(w, "{}{}", RESET, window[1].style.prefix())?,
|
||||
NoDifference => {/* Do nothing! */},
|
||||
}
|
||||
|
||||
w.write_str(&window[1].string)?;
|
||||
}
|
||||
|
||||
// Write the final reset string after all of the ANSIStrings have been
|
||||
// written, *except* if the last one has no styles, because it would
|
||||
// have already been written by this point.
|
||||
if let Some(last) = self.0.last() {
|
||||
if !last.style.is_plain() {
|
||||
write!(w, "{}", RESET)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- tests ----
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
pub use super::super::ANSIStrings;
|
||||
pub use style::Style;
|
||||
pub use style::Colour::*;
|
||||
|
||||
#[test]
|
||||
fn no_control_codes_for_plain() {
|
||||
let one = Style::default().paint("one");
|
||||
let two = Style::default().paint("two");
|
||||
let output = format!("{}", ANSIStrings( &[ one, two ] ));
|
||||
assert_eq!(&*output, "onetwo");
|
||||
}
|
||||
}
|
||||
271
vendor/ansi_term/src/lib.rs
vendored
Normal file
271
vendor/ansi_term/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
//! This is a library for controlling colours and formatting, such as
|
||||
//! red bold text or blue underlined text, on ANSI terminals.
|
||||
//!
|
||||
//!
|
||||
//! ## Basic usage
|
||||
//!
|
||||
//! There are three main types in this crate that you need to be
|
||||
//! concerned with: [`ANSIString`], [`Style`], and [`Colour`].
|
||||
//!
|
||||
//! A `Style` holds stylistic information: foreground and background colours,
|
||||
//! whether the text should be bold, or blinking, or other properties. The
|
||||
//! [`Colour`] enum represents the available colours. And an [`ANSIString`] is a
|
||||
//! string paired with a [`Style`].
|
||||
//!
|
||||
//! [`Color`] is also available as an alias to `Colour`.
|
||||
//!
|
||||
//! To format a string, call the `paint` method on a `Style` or a `Colour`,
|
||||
//! passing in the string you want to format as the argument. For example,
|
||||
//! here’s how to get some red text:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Red;
|
||||
//!
|
||||
//! println!("This is in red: {}", Red.paint("a red string"));
|
||||
//! ```
|
||||
//!
|
||||
//! It’s important to note that the `paint` method does *not* actually return a
|
||||
//! string with the ANSI control characters surrounding it. Instead, it returns
|
||||
//! an [`ANSIString`] value that has a [`Display`] implementation that, when
|
||||
//! formatted, returns the characters. This allows strings to be printed with a
|
||||
//! minimum of [`String`] allocations being performed behind the scenes.
|
||||
//!
|
||||
//! If you *do* want to get at the escape codes, then you can convert the
|
||||
//! [`ANSIString`] to a string as you would any other `Display` value:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Red;
|
||||
//!
|
||||
//! let red_string = Red.paint("a red string").to_string();
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ## Bold, underline, background, and other styles
|
||||
//!
|
||||
//! For anything more complex than plain foreground colour changes, you need to
|
||||
//! construct `Style` values themselves, rather than beginning with a `Colour`.
|
||||
//! You can do this by chaining methods based on a new `Style`, created with
|
||||
//! [`Style::new()`]. Each method creates a new style that has that specific
|
||||
//! property set. For example:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Style;
|
||||
//!
|
||||
//! println!("How about some {} and {}?",
|
||||
//! Style::new().bold().paint("bold"),
|
||||
//! Style::new().underline().paint("underline"));
|
||||
//! ```
|
||||
//!
|
||||
//! For brevity, these methods have also been implemented for `Colour` values,
|
||||
//! so you can give your styles a foreground colour without having to begin with
|
||||
//! an empty `Style` value:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::{Blue, Yellow};
|
||||
//!
|
||||
//! println!("Demonstrating {} and {}!",
|
||||
//! Blue.bold().paint("blue bold"),
|
||||
//! Yellow.underline().paint("yellow underline"));
|
||||
//!
|
||||
//! println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!"));
|
||||
//! ```
|
||||
//!
|
||||
//! The complete list of styles you can use are: [`bold`], [`dimmed`], [`italic`],
|
||||
//! [`underline`], [`blink`], [`reverse`], [`hidden`], [`strikethrough`], and [`on`] for
|
||||
//! background colours.
|
||||
//!
|
||||
//! In some cases, you may find it easier to change the foreground on an
|
||||
//! existing `Style` rather than starting from the appropriate `Colour`.
|
||||
//! You can do this using the [`fg`] method:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Style;
|
||||
//! use ansi_term::Colour::{Blue, Cyan, Yellow};
|
||||
//!
|
||||
//! println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!"));
|
||||
//! println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!"));
|
||||
//! ```
|
||||
//!
|
||||
//! You can turn a `Colour` into a `Style` with the [`normal`] method.
|
||||
//! This will produce the exact same `ANSIString` as if you just used the
|
||||
//! `paint` method on the `Colour` directly, but it’s useful in certain cases:
|
||||
//! for example, you may have a method that returns `Styles`, and need to
|
||||
//! represent both the “red bold” and “red, but not bold” styles with values of
|
||||
//! the same type. The `Style` struct also has a [`Default`] implementation if you
|
||||
//! want to have a style with *nothing* set.
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Style;
|
||||
//! use ansi_term::Colour::Red;
|
||||
//!
|
||||
//! Red.normal().paint("yet another red string");
|
||||
//! Style::default().paint("a completely regular string");
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! ## Extended colours
|
||||
//!
|
||||
//! You can access the extended range of 256 colours by using the `Colour::Fixed`
|
||||
//! variant, which takes an argument of the colour number to use. This can be
|
||||
//! included wherever you would use a `Colour`:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Fixed;
|
||||
//!
|
||||
//! Fixed(134).paint("A sort of light purple");
|
||||
//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup");
|
||||
//! ```
|
||||
//!
|
||||
//! The first sixteen of these values are the same as the normal and bold
|
||||
//! standard colour variants. There’s nothing stopping you from using these as
|
||||
//! `Fixed` colours instead, but there’s nothing to be gained by doing so
|
||||
//! either.
|
||||
//!
|
||||
//! You can also access full 24-bit colour by using the `Colour::RGB` variant,
|
||||
//! which takes separate `u8` arguments for red, green, and blue:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::RGB;
|
||||
//!
|
||||
//! RGB(70, 130, 180).paint("Steel blue");
|
||||
//! ```
|
||||
//!
|
||||
//! ## Combining successive coloured strings
|
||||
//!
|
||||
//! The benefit of writing ANSI escape codes to the terminal is that they
|
||||
//! *stack*: you do not need to end every coloured string with a reset code if
|
||||
//! the text that follows it is of a similar style. For example, if you want to
|
||||
//! have some blue text followed by some blue bold text, it’s possible to send
|
||||
//! the ANSI code for blue, followed by the ANSI code for bold, and finishing
|
||||
//! with a reset code without having to have an extra one between the two
|
||||
//! strings.
|
||||
//!
|
||||
//! This crate can optimise the ANSI codes that get printed in situations like
|
||||
//! this, making life easier for your terminal renderer. The [`ANSIStrings`]
|
||||
//! type takes a slice of several [`ANSIString`] values, and will iterate over
|
||||
//! each of them, printing only the codes for the styles that need to be updated
|
||||
//! as part of its formatting routine.
|
||||
//!
|
||||
//! The following code snippet uses this to enclose a binary number displayed in
|
||||
//! red bold text inside some red, but not bold, brackets:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Red;
|
||||
//! use ansi_term::{ANSIString, ANSIStrings};
|
||||
//!
|
||||
//! let some_value = format!("{:b}", 42);
|
||||
//! let strings: &[ANSIString<'static>] = &[
|
||||
//! Red.paint("["),
|
||||
//! Red.bold().paint(some_value),
|
||||
//! Red.paint("]"),
|
||||
//! ];
|
||||
//!
|
||||
//! println!("Value: {}", ANSIStrings(strings));
|
||||
//! ```
|
||||
//!
|
||||
//! There are several things to note here. Firstly, the [`paint`] method can take
|
||||
//! *either* an owned [`String`] or a borrowed [`&str`]. Internally, an [`ANSIString`]
|
||||
//! holds a copy-on-write ([`Cow`]) string value to deal with both owned and
|
||||
//! borrowed strings at the same time. This is used here to display a `String`,
|
||||
//! the result of the `format!` call, using the same mechanism as some
|
||||
//! statically-available `&str` slices. Secondly, that the [`ANSIStrings`] value
|
||||
//! works in the same way as its singular counterpart, with a [`Display`]
|
||||
//! implementation that only performs the formatting when required.
|
||||
//!
|
||||
//! ## Byte strings
|
||||
//!
|
||||
//! This library also supports formatting `\[u8]` byte strings; this supports
|
||||
//! applications working with text in an unknown encoding. [`Style`] and
|
||||
//! [`Colour`] support painting `\[u8]` values, resulting in an [`ANSIByteString`].
|
||||
//! This type does not implement [`Display`], as it may not contain UTF-8, but
|
||||
//! it does provide a method [`write_to`] to write the result to any value that
|
||||
//! implements [`Write`]:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Green;
|
||||
//!
|
||||
//! Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! Similarly, the type [`ANSIByteStrings`] supports writing a list of
|
||||
//! [`ANSIByteString`] values with minimal escape sequences:
|
||||
//!
|
||||
//! ```
|
||||
//! use ansi_term::Colour::Green;
|
||||
//! use ansi_term::ANSIByteStrings;
|
||||
//!
|
||||
//! ANSIByteStrings(&[
|
||||
//! Green.paint("user data 1\n".as_bytes()),
|
||||
//! Green.bold().paint("user data 2\n".as_bytes()),
|
||||
//! ]).write_to(&mut std::io::stdout()).unwrap();
|
||||
//! ```
|
||||
//!
|
||||
//! [`Cow`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html
|
||||
//! [`Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
|
||||
//! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
|
||||
//! [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
||||
//! [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
|
||||
//! [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||
//! [`Style`]: struct.Style.html
|
||||
//! [`Style::new()`]: struct.Style.html#method.new
|
||||
//! [`Color`]: enum.Color.html
|
||||
//! [`Colour`]: enum.Colour.html
|
||||
//! [`ANSIString`]: type.ANSIString.html
|
||||
//! [`ANSIStrings`]: type.ANSIStrings.html
|
||||
//! [`ANSIByteString`]: type.ANSIByteString.html
|
||||
//! [`ANSIByteStrings`]: type.ANSIByteStrings.html
|
||||
//! [`write_to`]: type.ANSIByteString.html#method.write_to
|
||||
//! [`paint`]: type.ANSIByteString.html#method.write_to
|
||||
//! [`normal`]: enum.Colour.html#method.normal
|
||||
//!
|
||||
//! [`bold`]: struct.Style.html#method.bold
|
||||
//! [`dimmed`]: struct.Style.html#method.dimmed
|
||||
//! [`italic`]: struct.Style.html#method.italic
|
||||
//! [`underline`]: struct.Style.html#method.underline
|
||||
//! [`blink`]: struct.Style.html#method.blink
|
||||
//! [`reverse`]: struct.Style.html#method.reverse
|
||||
//! [`hidden`]: struct.Style.html#method.hidden
|
||||
//! [`strikethrough`]: struct.Style.html#method.strikethrough
|
||||
//! [`fg`]: struct.Style.html#method.fg
|
||||
//! [`on`]: struct.Style.html#method.on
|
||||
|
||||
#![crate_name = "ansi_term"]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
#![warn(missing_copy_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(trivial_casts, trivial_numeric_casts)]
|
||||
#![warn(unused_extern_crates, unused_qualifications)]
|
||||
|
||||
#[cfg(target_os="windows")]
|
||||
extern crate winapi;
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate doc_comment;
|
||||
|
||||
#[cfg(test)]
|
||||
doctest!("../README.md");
|
||||
|
||||
mod ansi;
|
||||
pub use ansi::{Prefix, Infix, Suffix};
|
||||
|
||||
mod style;
|
||||
pub use style::{Colour, Style};
|
||||
|
||||
/// Color is a type alias for `Colour`.
|
||||
pub use Colour as Color;
|
||||
|
||||
mod difference;
|
||||
mod display;
|
||||
pub use display::*;
|
||||
|
||||
mod write;
|
||||
|
||||
mod windows;
|
||||
pub use windows::*;
|
||||
|
||||
mod util;
|
||||
pub use util::*;
|
||||
|
||||
mod debug;
|
||||
521
vendor/ansi_term/src/style.rs
vendored
Normal file
521
vendor/ansi_term/src/style.rs
vendored
Normal file
|
|
@ -0,0 +1,521 @@
|
|||
/// A style is a collection of properties that can format a string
|
||||
/// using ANSI escape codes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour};
|
||||
///
|
||||
/// let style = Style::new().bold().on(Colour::Black);
|
||||
/// println!("{}", style.paint("Bold on black"));
|
||||
/// ```
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
#[cfg_attr(feature = "derive_serde_style", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct Style {
|
||||
|
||||
/// The style's foreground colour, if it has one.
|
||||
pub foreground: Option<Colour>,
|
||||
|
||||
/// The style's background colour, if it has one.
|
||||
pub background: Option<Colour>,
|
||||
|
||||
/// Whether this style is bold.
|
||||
pub is_bold: bool,
|
||||
|
||||
/// Whether this style is dimmed.
|
||||
pub is_dimmed: bool,
|
||||
|
||||
/// Whether this style is italic.
|
||||
pub is_italic: bool,
|
||||
|
||||
/// Whether this style is underlined.
|
||||
pub is_underline: bool,
|
||||
|
||||
/// Whether this style is blinking.
|
||||
pub is_blink: bool,
|
||||
|
||||
/// Whether this style has reverse colours.
|
||||
pub is_reverse: bool,
|
||||
|
||||
/// Whether this style is hidden.
|
||||
pub is_hidden: bool,
|
||||
|
||||
/// Whether this style is struckthrough.
|
||||
pub is_strikethrough: bool
|
||||
}
|
||||
|
||||
impl Style {
|
||||
|
||||
/// Creates a new Style with no properties set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new();
|
||||
/// println!("{}", style.paint("hi"));
|
||||
/// ```
|
||||
pub fn new() -> Style {
|
||||
Style::default()
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the bold property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().bold();
|
||||
/// println!("{}", style.paint("hey"));
|
||||
/// ```
|
||||
pub fn bold(&self) -> Style {
|
||||
Style { is_bold: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the dimmed property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().dimmed();
|
||||
/// println!("{}", style.paint("sup"));
|
||||
/// ```
|
||||
pub fn dimmed(&self) -> Style {
|
||||
Style { is_dimmed: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the italic property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().italic();
|
||||
/// println!("{}", style.paint("greetings"));
|
||||
/// ```
|
||||
pub fn italic(&self) -> Style {
|
||||
Style { is_italic: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the underline property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().underline();
|
||||
/// println!("{}", style.paint("salutations"));
|
||||
/// ```
|
||||
pub fn underline(&self) -> Style {
|
||||
Style { is_underline: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the blink property set.
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().blink();
|
||||
/// println!("{}", style.paint("wazzup"));
|
||||
/// ```
|
||||
pub fn blink(&self) -> Style {
|
||||
Style { is_blink: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the reverse property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().reverse();
|
||||
/// println!("{}", style.paint("aloha"));
|
||||
/// ```
|
||||
pub fn reverse(&self) -> Style {
|
||||
Style { is_reverse: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the hidden property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().hidden();
|
||||
/// println!("{}", style.paint("ahoy"));
|
||||
/// ```
|
||||
pub fn hidden(&self) -> Style {
|
||||
Style { is_hidden: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the strikethrough property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// let style = Style::new().strikethrough();
|
||||
/// println!("{}", style.paint("yo"));
|
||||
/// ```
|
||||
pub fn strikethrough(&self) -> Style {
|
||||
Style { is_strikethrough: true, .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour};
|
||||
///
|
||||
/// let style = Style::new().fg(Colour::Yellow);
|
||||
/// println!("{}", style.paint("hi"));
|
||||
/// ```
|
||||
pub fn fg(&self, foreground: Colour) -> Style {
|
||||
Style { foreground: Some(foreground), .. *self }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the background colour property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour};
|
||||
///
|
||||
/// let style = Style::new().on(Colour::Blue);
|
||||
/// println!("{}", style.paint("eyyyy"));
|
||||
/// ```
|
||||
pub fn on(&self, background: Colour) -> Style {
|
||||
Style { background: Some(background), .. *self }
|
||||
}
|
||||
|
||||
/// Return true if this `Style` has no actual styles, and can be written
|
||||
/// without any control characters.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
///
|
||||
/// assert_eq!(true, Style::default().is_plain());
|
||||
/// assert_eq!(false, Style::default().bold().is_plain());
|
||||
/// ```
|
||||
pub fn is_plain(self) -> bool {
|
||||
self == Style::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Style {
|
||||
|
||||
/// Returns a style with *no* properties set. Formatting text using this
|
||||
/// style returns the exact same text.
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Style;
|
||||
/// assert_eq!(None, Style::default().foreground);
|
||||
/// assert_eq!(None, Style::default().background);
|
||||
/// assert_eq!(false, Style::default().is_bold);
|
||||
/// assert_eq!("txt", Style::default().paint("txt").to_string());
|
||||
/// ```
|
||||
fn default() -> Style {
|
||||
Style {
|
||||
foreground: None,
|
||||
background: None,
|
||||
is_bold: false,
|
||||
is_dimmed: false,
|
||||
is_italic: false,
|
||||
is_underline: false,
|
||||
is_blink: false,
|
||||
is_reverse: false,
|
||||
is_hidden: false,
|
||||
is_strikethrough: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---- colours ----
|
||||
|
||||
/// A colour is one specific type of ANSI escape code, and can refer
|
||||
/// to either the foreground or background colour.
|
||||
///
|
||||
/// These use the standard numeric sequences.
|
||||
/// See <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html>
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "derive_serde_style", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub enum Colour {
|
||||
|
||||
/// Colour #0 (foreground code `30`, background code `40`).
|
||||
///
|
||||
/// This is not necessarily the background colour, and using it as one may
|
||||
/// render the text hard to read on terminals with dark backgrounds.
|
||||
Black,
|
||||
|
||||
/// Colour #1 (foreground code `31`, background code `41`).
|
||||
Red,
|
||||
|
||||
/// Colour #2 (foreground code `32`, background code `42`).
|
||||
Green,
|
||||
|
||||
/// Colour #3 (foreground code `33`, background code `43`).
|
||||
Yellow,
|
||||
|
||||
/// Colour #4 (foreground code `34`, background code `44`).
|
||||
Blue,
|
||||
|
||||
/// Colour #5 (foreground code `35`, background code `45`).
|
||||
Purple,
|
||||
|
||||
/// Colour #6 (foreground code `36`, background code `46`).
|
||||
Cyan,
|
||||
|
||||
/// Colour #7 (foreground code `37`, background code `47`).
|
||||
///
|
||||
/// As above, this is not necessarily the foreground colour, and may be
|
||||
/// hard to read on terminals with light backgrounds.
|
||||
White,
|
||||
|
||||
/// A colour number from 0 to 255, for use in 256-colour terminal
|
||||
/// environments.
|
||||
///
|
||||
/// - Colours 0 to 7 are the `Black` to `White` variants respectively.
|
||||
/// These colours can usually be changed in the terminal emulator.
|
||||
/// - Colours 8 to 15 are brighter versions of the eight colours above.
|
||||
/// These can also usually be changed in the terminal emulator, or it
|
||||
/// could be configured to use the original colours and show the text in
|
||||
/// bold instead. It varies depending on the program.
|
||||
/// - Colours 16 to 231 contain several palettes of bright colours,
|
||||
/// arranged in six squares measuring six by six each.
|
||||
/// - Colours 232 to 255 are shades of grey from black to white.
|
||||
///
|
||||
/// It might make more sense to look at a [colour chart][cc].
|
||||
///
|
||||
/// [cc]: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
|
||||
Fixed(u8),
|
||||
|
||||
/// A 24-bit RGB color, as specified by ISO-8613-3.
|
||||
RGB(u8, u8, u8),
|
||||
}
|
||||
|
||||
|
||||
impl Colour {
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Red.normal();
|
||||
/// println!("{}", style.paint("hi"));
|
||||
/// ```
|
||||
pub fn normal(self) -> Style {
|
||||
Style { foreground: Some(self), .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// bold property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Green.bold();
|
||||
/// println!("{}", style.paint("hey"));
|
||||
/// ```
|
||||
pub fn bold(self) -> Style {
|
||||
Style { foreground: Some(self), is_bold: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// dimmed property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Yellow.dimmed();
|
||||
/// println!("{}", style.paint("sup"));
|
||||
/// ```
|
||||
pub fn dimmed(self) -> Style {
|
||||
Style { foreground: Some(self), is_dimmed: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// italic property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Blue.italic();
|
||||
/// println!("{}", style.paint("greetings"));
|
||||
/// ```
|
||||
pub fn italic(self) -> Style {
|
||||
Style { foreground: Some(self), is_italic: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// underline property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Purple.underline();
|
||||
/// println!("{}", style.paint("salutations"));
|
||||
/// ```
|
||||
pub fn underline(self) -> Style {
|
||||
Style { foreground: Some(self), is_underline: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// blink property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Cyan.blink();
|
||||
/// println!("{}", style.paint("wazzup"));
|
||||
/// ```
|
||||
pub fn blink(self) -> Style {
|
||||
Style { foreground: Some(self), is_blink: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// reverse property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Black.reverse();
|
||||
/// println!("{}", style.paint("aloha"));
|
||||
/// ```
|
||||
pub fn reverse(self) -> Style {
|
||||
Style { foreground: Some(self), is_reverse: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// hidden property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::White.hidden();
|
||||
/// println!("{}", style.paint("ahoy"));
|
||||
/// ```
|
||||
pub fn hidden(self) -> Style {
|
||||
Style { foreground: Some(self), is_hidden: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// strikethrough property set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::Fixed(244).strikethrough();
|
||||
/// println!("{}", style.paint("yo"));
|
||||
/// ```
|
||||
pub fn strikethrough(self) -> Style {
|
||||
Style { foreground: Some(self), is_strikethrough: true, .. Style::default() }
|
||||
}
|
||||
|
||||
/// Returns a `Style` with the foreground colour set to this colour and the
|
||||
/// background colour property set to the given colour.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::Colour;
|
||||
///
|
||||
/// let style = Colour::RGB(31, 31, 31).on(Colour::White);
|
||||
/// println!("{}", style.paint("eyyyy"));
|
||||
/// ```
|
||||
pub fn on(self, background: Colour) -> Style {
|
||||
Style { foreground: Some(self), background: Some(background), .. Style::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Colour> for Style {
|
||||
|
||||
/// You can turn a `Colour` into a `Style` with the foreground colour set
|
||||
/// with the `From` trait.
|
||||
///
|
||||
/// ```
|
||||
/// use ansi_term::{Style, Colour};
|
||||
/// let green_foreground = Style::default().fg(Colour::Green);
|
||||
/// assert_eq!(green_foreground, Colour::Green.normal());
|
||||
/// assert_eq!(green_foreground, Colour::Green.into());
|
||||
/// assert_eq!(green_foreground, Style::from(Colour::Green));
|
||||
/// ```
|
||||
fn from(colour: Colour) -> Style {
|
||||
colour.normal()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "derive_serde_style")]
|
||||
mod serde_json_tests {
|
||||
use super::{Style, Colour};
|
||||
|
||||
#[test]
|
||||
fn colour_serialization() {
|
||||
|
||||
let colours = &[
|
||||
Colour::Red,
|
||||
Colour::Blue,
|
||||
Colour::RGB(123, 123, 123),
|
||||
Colour::Fixed(255),
|
||||
];
|
||||
|
||||
assert_eq!(serde_json::to_string(&colours).unwrap(), String::from("[\"Red\",\"Blue\",{\"RGB\":[123,123,123]},{\"Fixed\":255}]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn colour_deserialization() {
|
||||
let colours = &[
|
||||
Colour::Red,
|
||||
Colour::Blue,
|
||||
Colour::RGB(123, 123, 123),
|
||||
Colour::Fixed(255),
|
||||
];
|
||||
|
||||
for colour in colours.into_iter() {
|
||||
let serialized = serde_json::to_string(&colour).unwrap();
|
||||
let deserialized: Colour = serde_json::from_str(&serialized).unwrap();
|
||||
|
||||
assert_eq!(colour, &deserialized);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn style_serialization() {
|
||||
let style = Style::default();
|
||||
|
||||
assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false}".to_string());
|
||||
}
|
||||
}
|
||||
81
vendor/ansi_term/src/util.rs
vendored
Normal file
81
vendor/ansi_term/src/util.rs
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
use display::*;
|
||||
use std::ops::Deref;
|
||||
|
||||
/// Return a substring of the given ANSIStrings sequence, while keeping the formatting.
|
||||
pub fn sub_string<'a>(start: usize, len: usize, strs: &ANSIStrings<'a>) -> Vec<ANSIString<'static>> {
|
||||
let mut vec = Vec::new();
|
||||
let mut pos = start;
|
||||
let mut len_rem = len;
|
||||
|
||||
for i in strs.0.iter() {
|
||||
let fragment = i.deref();
|
||||
let frag_len = fragment.len();
|
||||
if pos >= frag_len {
|
||||
pos -= frag_len;
|
||||
continue;
|
||||
}
|
||||
if len_rem <= 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let end = pos + len_rem;
|
||||
let pos_end = if end >= frag_len { frag_len } else { end };
|
||||
|
||||
vec.push(i.style_ref().paint(String::from(&fragment[pos..pos_end])));
|
||||
|
||||
if end <= frag_len {
|
||||
break;
|
||||
}
|
||||
|
||||
len_rem -= pos_end - pos;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
/// Return a concatenated copy of `strs` without the formatting, as an allocated `String`.
|
||||
pub fn unstyle(strs: &ANSIStrings) -> String {
|
||||
let mut s = String::new();
|
||||
|
||||
for i in strs.0.iter() {
|
||||
s += &i.deref();
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
/// Return the unstyled length of ANSIStrings. This is equaivalent to `unstyle(strs).len()`.
|
||||
pub fn unstyled_len(strs: &ANSIStrings) -> usize {
|
||||
let mut l = 0;
|
||||
for i in strs.0.iter() {
|
||||
l += i.deref().len();
|
||||
}
|
||||
l
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use Colour::*;
|
||||
use display::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let l = [
|
||||
Black.paint("first"),
|
||||
Red.paint("-second"),
|
||||
White.paint("-third"),
|
||||
];
|
||||
let a = ANSIStrings(&l);
|
||||
assert_eq!(unstyle(&a), "first-second-third");
|
||||
assert_eq!(unstyled_len(&a), 18);
|
||||
|
||||
let l2 = [
|
||||
Black.paint("st"),
|
||||
Red.paint("-second"),
|
||||
White.paint("-t"),
|
||||
];
|
||||
assert_eq!(sub_string(3, 11, &a).as_slice(), &l2);
|
||||
}
|
||||
}
|
||||
61
vendor/ansi_term/src/windows.rs
vendored
Normal file
61
vendor/ansi_term/src/windows.rs
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/// Enables ANSI code support on Windows 10.
|
||||
///
|
||||
/// This uses Windows API calls to alter the properties of the console that
|
||||
/// the program is running in.
|
||||
///
|
||||
/// https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
|
||||
///
|
||||
/// Returns a `Result` with the Windows error code if unsuccessful.
|
||||
#[cfg(windows)]
|
||||
pub fn enable_ansi_support() -> Result<(), u32> {
|
||||
// ref: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#EXAMPLE_OF_ENABLING_VIRTUAL_TERMINAL_PROCESSING @@ https://archive.is/L7wRJ#76%
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::iter::once;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::ptr::null_mut;
|
||||
use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode};
|
||||
use winapi::um::errhandlingapi::GetLastError;
|
||||
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
|
||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
||||
use winapi::um::winnt::{FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE};
|
||||
|
||||
const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
|
||||
|
||||
unsafe {
|
||||
// ref: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
|
||||
// Using `CreateFileW("CONOUT$", ...)` to retrieve the console handle works correctly even if STDOUT and/or STDERR are redirected
|
||||
let console_out_name: Vec<u16> = OsStr::new("CONOUT$").encode_wide().chain(once(0)).collect();
|
||||
let console_handle = CreateFileW(
|
||||
console_out_name.as_ptr(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE,
|
||||
null_mut(),
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
null_mut(),
|
||||
);
|
||||
if console_handle == INVALID_HANDLE_VALUE
|
||||
{
|
||||
return Err(GetLastError());
|
||||
}
|
||||
|
||||
// ref: https://docs.microsoft.com/en-us/windows/console/getconsolemode
|
||||
let mut console_mode: u32 = 0;
|
||||
if 0 == GetConsoleMode(console_handle, &mut console_mode)
|
||||
{
|
||||
return Err(GetLastError());
|
||||
}
|
||||
|
||||
// VT processing not already enabled?
|
||||
if console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 {
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
if 0 == SetConsoleMode(console_handle, console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
{
|
||||
return Err(GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
40
vendor/ansi_term/src/write.rs
vendored
Normal file
40
vendor/ansi_term/src/write.rs
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
|
||||
pub trait AnyWrite {
|
||||
type wstr: ?Sized;
|
||||
type Error;
|
||||
|
||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error>;
|
||||
|
||||
fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
|
||||
impl<'a> AnyWrite for fmt::Write + 'a {
|
||||
type wstr = str;
|
||||
type Error = fmt::Error;
|
||||
|
||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error> {
|
||||
fmt::Write::write_fmt(self, fmt)
|
||||
}
|
||||
|
||||
fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error> {
|
||||
fmt::Write::write_str(self, s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> AnyWrite for io::Write + 'a {
|
||||
type wstr = [u8];
|
||||
type Error = io::Error;
|
||||
|
||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error> {
|
||||
io::Write::write_fmt(self, fmt)
|
||||
}
|
||||
|
||||
fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error> {
|
||||
io::Write::write_all(self, s)
|
||||
}
|
||||
}
|
||||
1
vendor/atty/.cargo-checksum.json
vendored
Normal file
1
vendor/atty/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"35a894adf25f43d2e0f8788b1768bb632b9121cdfe34240100c6166c848a5b3e","CHANGELOG.md":"70db121262d72acc472ad1a90b78c42de570820e65b566c6b9339b62e636d572","Cargo.lock":"6868f02a96413bcba37a06f01c6bf87e6331dea9461681a47a561cec6acd2546","Cargo.toml":"3af88a07af6a4adb84373fc3cd4920884b0b12b338cdb55ef598fd512ee1a790","Cargo.toml.orig":"e1f972324e35b0de555afb18a8bb041bc092dbb4317f4c1e62a383b4dfb6d1bd","LICENSE":"99fa95ba4e4cdaf71c27d73260ea069fc4515b3d02fde3020c5b562280006cbc","README.md":"e559a69c0b2bd20bffcede64fd548df6c671b0d1504613c5e3e5d884d759caea","examples/atty.rs":"1551387a71474d9ac1b5153231f884e9e05213badcfaa3494ad2cb7ea958374a","rustfmt.toml":"8e6ea1bcb79c505490034020c98e9b472f4ac4113f245bae90f5e1217b1ec65a","src/lib.rs":"d5abf6a54e8c496c486572bdc91eef10480f6ad126c4287f039df5feff7a9bbb"},"package":"d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"}
|
||||
5
vendor/atty/.cargo_vcs_info.json
vendored
Normal file
5
vendor/atty/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "7b5df17888997d57c2c1c8f91da1db5691f49953"
|
||||
}
|
||||
}
|
||||
73
vendor/atty/CHANGELOG.md
vendored
Normal file
73
vendor/atty/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# 0.2.14
|
||||
|
||||
* add support for [RustyHermit](https://github.com/hermitcore/libhermit-rs), a Rust-based unikernel [#41](https://github.com/softprops/atty/pull/41)
|
||||
|
||||
# 0.2.13
|
||||
|
||||
* support older versions of rust that do now support 2018 edition
|
||||
|
||||
# 0.2.12
|
||||
|
||||
* Redox is now in the unix family so redox cfg is no longer needed [#35](https://github.com/softprops/atty/pull/35)
|
||||
|
||||
# 0.2.11
|
||||
|
||||
* fix msys detection with `winapi@0.3.5` [#28](https://github.com/softprops/atty/pull/28)
|
||||
|
||||
# 0.2.10
|
||||
|
||||
* fix wasm regression [#27](https://github.com/softprops/atty/pull/27)
|
||||
|
||||
# 0.2.9
|
||||
|
||||
* Fix fix pty detection [#25](https://github.com/softprops/atty/pull/25)
|
||||
|
||||
# 0.2.8
|
||||
|
||||
* Fix an inverted condition on MinGW [#22](https://github.com/softprops/atty/pull/22)
|
||||
|
||||
# 0.2.7
|
||||
|
||||
* Change `||` to `&&` for whether MSYS is a tty [#24](https://github.com/softprops/atty/pull/24/)
|
||||
|
||||
# 0.2.6
|
||||
|
||||
* updated winapi dependency to [0.3](https://retep998.github.io/blog/winapi-0.3/) [#18](https://github.com/softprops/atty/pull/18)
|
||||
|
||||
# 0.2.5
|
||||
|
||||
* added support for Wasm compile targets [#17](https://github.com/softprops/atty/pull/17)
|
||||
|
||||
# 0.2.4
|
||||
|
||||
* added support for Wasm compile targets [#17](https://github.com/softprops/atty/pull/17)
|
||||
|
||||
# 0.2.3
|
||||
|
||||
* added support for Redox OS [#14](https://github.com/softprops/atty/pull/14)
|
||||
|
||||
# 0.2.2
|
||||
|
||||
* use target specific dependencies [#11](https://github.com/softprops/atty/pull/11)
|
||||
* Add tty detection for MSYS terminals [#12](https://github.com/softprops/atty/pull/12)
|
||||
|
||||
# 0.2.1
|
||||
|
||||
* fix windows bug
|
||||
|
||||
# 0.2.0
|
||||
|
||||
* support for various stream types
|
||||
|
||||
# 0.1.2
|
||||
|
||||
* windows support (with automated testing)
|
||||
* automated code coverage
|
||||
|
||||
# 0.1.1
|
||||
|
||||
* bumped libc dep from `0.1` to `0.2`
|
||||
|
||||
# 0.1.0
|
||||
|
||||
* initial release
|
||||
49
vendor/atty/Cargo.lock
generated
vendored
Normal file
49
vendor/atty/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
|
||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
34
vendor/atty/Cargo.toml
vendored
Normal file
34
vendor/atty/Cargo.toml
vendored
Normal file
|
|
@ -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]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
authors = ["softprops <d.tangren@gmail.com>"]
|
||||
exclude = ["/.travis.yml", "/appveyor.yml"]
|
||||
description = "A simple interface for querying atty"
|
||||
homepage = "https://github.com/softprops/atty"
|
||||
documentation = "http://softprops.github.io/atty"
|
||||
readme = "README.md"
|
||||
keywords = ["terminal", "tty", "isatty"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/softprops/atty"
|
||||
[target."cfg(target_os = \"hermit\")".dependencies.hermit-abi]
|
||||
version = "0.1.6"
|
||||
[target."cfg(unix)".dependencies.libc]
|
||||
version = "0.2"
|
||||
default-features = false
|
||||
[target."cfg(windows)".dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["consoleapi", "processenv", "minwinbase", "minwindef", "winbase"]
|
||||
[badges.travis-ci]
|
||||
repository = "softprops/atty"
|
||||
26
vendor/atty/Cargo.toml.orig
generated
vendored
Normal file
26
vendor/atty/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
authors = ["softprops <d.tangren@gmail.com>"]
|
||||
description = "A simple interface for querying atty"
|
||||
documentation = "http://softprops.github.io/atty"
|
||||
homepage = "https://github.com/softprops/atty"
|
||||
repository = "https://github.com/softprops/atty"
|
||||
keywords = ["terminal", "tty", "isatty"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
exclude = ["/.travis.yml", "/appveyor.yml"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "softprops/atty" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = { version = "0.2", default-features = false }
|
||||
|
||||
[target.'cfg(target_os = "hermit")'.dependencies]
|
||||
hermit-abi = "0.1.6"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["consoleapi", "processenv", "minwinbase", "minwindef", "winbase"]
|
||||
|
||||
20
vendor/atty/LICENSE
vendored
Normal file
20
vendor/atty/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2015-2019 Doug Tangren
|
||||
|
||||
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.
|
||||
74
vendor/atty/README.md
vendored
Normal file
74
vendor/atty/README.md
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# atty
|
||||
|
||||
[](https://travis-ci.org/softprops/atty) [](https://ci.appveyor.com/project/softprops/atty) [](https://coveralls.io/github/softprops/atty?branch=master) [](https://crates.io/crates/atty) [](http://docs.rs/atty) [](https://softprops.github.io/atty)
|
||||
|
||||
> are you or are you not a tty?
|
||||
|
||||
|
||||
## install
|
||||
|
||||
Add the following to your `Cargo.toml`
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
atty = "0.2"
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```rust
|
||||
use atty::Stream;
|
||||
|
||||
fn main() {
|
||||
if atty::is(Stream::Stdout) {
|
||||
println!("I'm a terminal");
|
||||
} else {
|
||||
println!("I'm not");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## testing
|
||||
|
||||
This library has been unit tested on both unix and windows platforms (via appveyor).
|
||||
|
||||
|
||||
A simple example program is provided in this repo to test various tty's. By default.
|
||||
|
||||
It prints
|
||||
|
||||
```bash
|
||||
$ cargo run --example atty
|
||||
stdout? true
|
||||
stderr? true
|
||||
stdin? true
|
||||
```
|
||||
|
||||
To test std in, pipe some text to the program
|
||||
|
||||
```bash
|
||||
$ echo "test" | cargo run --example atty
|
||||
stdout? true
|
||||
stderr? true
|
||||
stdin? false
|
||||
```
|
||||
|
||||
To test std out, pipe the program to something
|
||||
|
||||
```bash
|
||||
$ cargo run --example atty | grep std
|
||||
stdout? false
|
||||
stderr? true
|
||||
stdin? true
|
||||
```
|
||||
|
||||
To test std err, pipe the program to something redirecting std err
|
||||
|
||||
```bash
|
||||
$ cargo run --example atty 2>&1 | grep std
|
||||
stdout? false
|
||||
stderr? false
|
||||
stdin? true
|
||||
```
|
||||
|
||||
Doug Tangren (softprops) 2015-2019
|
||||
9
vendor/atty/examples/atty.rs
vendored
Normal file
9
vendor/atty/examples/atty.rs
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
extern crate atty;
|
||||
|
||||
use atty::{is, Stream};
|
||||
|
||||
fn main() {
|
||||
println!("stdout? {}", is(Stream::Stdout));
|
||||
println!("stderr? {}", is(Stream::Stderr));
|
||||
println!("stdin? {}", is(Stream::Stdin));
|
||||
}
|
||||
4
vendor/atty/rustfmt.toml
vendored
Normal file
4
vendor/atty/rustfmt.toml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#fn_args_layout
|
||||
fn_args_layout = "Vertical"
|
||||
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#merge_imports
|
||||
merge_imports = true
|
||||
210
vendor/atty/src/lib.rs
vendored
Normal file
210
vendor/atty/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
//! atty is a simple utility that answers one question
|
||||
//! > is this a tty?
|
||||
//!
|
||||
//! usage is just as simple
|
||||
//!
|
||||
//! ```
|
||||
//! if atty::is(atty::Stream::Stdout) {
|
||||
//! println!("i'm a tty")
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ```
|
||||
//! if atty::isnt(atty::Stream::Stdout) {
|
||||
//! println!("i'm not a tty")
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(unix, no_std)]
|
||||
|
||||
#[cfg(unix)]
|
||||
extern crate libc;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
|
||||
#[cfg(windows)]
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
#[cfg(windows)]
|
||||
use winapi::shared::ntdef::WCHAR;
|
||||
|
||||
/// possible stream sources
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Stream {
|
||||
Stdout,
|
||||
Stderr,
|
||||
Stdin,
|
||||
}
|
||||
|
||||
/// returns true if this is a tty
|
||||
#[cfg(all(unix, not(target_arch = "wasm32")))]
|
||||
pub fn is(stream: Stream) -> bool {
|
||||
extern crate libc;
|
||||
|
||||
let fd = match stream {
|
||||
Stream::Stdout => libc::STDOUT_FILENO,
|
||||
Stream::Stderr => libc::STDERR_FILENO,
|
||||
Stream::Stdin => libc::STDIN_FILENO,
|
||||
};
|
||||
unsafe { libc::isatty(fd) != 0 }
|
||||
}
|
||||
|
||||
/// returns true if this is a tty
|
||||
#[cfg(target_os = "hermit")]
|
||||
pub fn is(stream: Stream) -> bool {
|
||||
extern crate hermit_abi;
|
||||
|
||||
let fd = match stream {
|
||||
Stream::Stdout => hermit_abi::STDOUT_FILENO,
|
||||
Stream::Stderr => hermit_abi::STDERR_FILENO,
|
||||
Stream::Stdin => hermit_abi::STDIN_FILENO,
|
||||
};
|
||||
hermit_abi::isatty(fd)
|
||||
}
|
||||
|
||||
/// returns true if this is a tty
|
||||
#[cfg(windows)]
|
||||
pub fn is(stream: Stream) -> bool {
|
||||
use winapi::um::winbase::{
|
||||
STD_ERROR_HANDLE as STD_ERROR, STD_INPUT_HANDLE as STD_INPUT,
|
||||
STD_OUTPUT_HANDLE as STD_OUTPUT,
|
||||
};
|
||||
|
||||
let (fd, others) = match stream {
|
||||
Stream::Stdin => (STD_INPUT, [STD_ERROR, STD_OUTPUT]),
|
||||
Stream::Stderr => (STD_ERROR, [STD_INPUT, STD_OUTPUT]),
|
||||
Stream::Stdout => (STD_OUTPUT, [STD_INPUT, STD_ERROR]),
|
||||
};
|
||||
if unsafe { console_on_any(&[fd]) } {
|
||||
// False positives aren't possible. If we got a console then
|
||||
// we definitely have a tty on stdin.
|
||||
return true;
|
||||
}
|
||||
|
||||
// At this point, we *could* have a false negative. We can determine that
|
||||
// this is true negative if we can detect the presence of a console on
|
||||
// any of the other streams. If another stream has a console, then we know
|
||||
// we're in a Windows console and can therefore trust the negative.
|
||||
if unsafe { console_on_any(&others) } {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we fall back to a very strange msys hack to see if we can
|
||||
// sneakily detect the presence of a tty.
|
||||
unsafe { msys_tty_on(fd) }
|
||||
}
|
||||
|
||||
/// returns true if this is _not_ a tty
|
||||
pub fn isnt(stream: Stream) -> bool {
|
||||
!is(stream)
|
||||
}
|
||||
|
||||
/// Returns true if any of the given fds are on a console.
|
||||
#[cfg(windows)]
|
||||
unsafe fn console_on_any(fds: &[DWORD]) -> bool {
|
||||
use winapi::um::{consoleapi::GetConsoleMode, processenv::GetStdHandle};
|
||||
|
||||
for &fd in fds {
|
||||
let mut out = 0;
|
||||
let handle = GetStdHandle(fd);
|
||||
if GetConsoleMode(handle, &mut out) != 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns true if there is an MSYS tty on the given handle.
|
||||
#[cfg(windows)]
|
||||
unsafe fn msys_tty_on(fd: DWORD) -> bool {
|
||||
use std::{mem, slice};
|
||||
|
||||
use winapi::{
|
||||
ctypes::c_void,
|
||||
shared::minwindef::MAX_PATH,
|
||||
um::{
|
||||
fileapi::FILE_NAME_INFO, minwinbase::FileNameInfo, processenv::GetStdHandle,
|
||||
winbase::GetFileInformationByHandleEx,
|
||||
},
|
||||
};
|
||||
|
||||
let size = mem::size_of::<FILE_NAME_INFO>();
|
||||
let mut name_info_bytes = vec![0u8; size + MAX_PATH * mem::size_of::<WCHAR>()];
|
||||
let res = GetFileInformationByHandleEx(
|
||||
GetStdHandle(fd),
|
||||
FileNameInfo,
|
||||
&mut *name_info_bytes as *mut _ as *mut c_void,
|
||||
name_info_bytes.len() as u32,
|
||||
);
|
||||
if res == 0 {
|
||||
return false;
|
||||
}
|
||||
let name_info: &FILE_NAME_INFO = &*(name_info_bytes.as_ptr() as *const FILE_NAME_INFO);
|
||||
let s = slice::from_raw_parts(
|
||||
name_info.FileName.as_ptr(),
|
||||
name_info.FileNameLength as usize / 2,
|
||||
);
|
||||
let name = String::from_utf16_lossy(s);
|
||||
// This checks whether 'pty' exists in the file name, which indicates that
|
||||
// a pseudo-terminal is attached. To mitigate against false positives
|
||||
// (e.g., an actual file name that contains 'pty'), we also require that
|
||||
// either the strings 'msys-' or 'cygwin-' are in the file name as well.)
|
||||
let is_msys = name.contains("msys-") || name.contains("cygwin-");
|
||||
let is_pty = name.contains("-pty");
|
||||
is_msys && is_pty
|
||||
}
|
||||
|
||||
/// returns true if this is a tty
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn is(_stream: Stream) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{is, Stream};
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn is_err() {
|
||||
// appveyor pipes its output
|
||||
assert!(!is(Stream::Stderr))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn is_out() {
|
||||
// appveyor pipes its output
|
||||
assert!(!is(Stream::Stdout))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn is_in() {
|
||||
assert!(is(Stream::Stdin))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn is_err() {
|
||||
assert!(is(Stream::Stderr))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn is_out() {
|
||||
assert!(is(Stream::Stdout))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn is_in() {
|
||||
// macos on travis seems to pipe its input
|
||||
assert!(is(Stream::Stdin))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(not(target_os = "macos"), unix))]
|
||||
fn is_in() {
|
||||
assert!(is(Stream::Stdin))
|
||||
}
|
||||
}
|
||||
1
vendor/autocfg/.cargo-checksum.json
vendored
Normal file
1
vendor/autocfg/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{".cargo_vcs_info.json":"e03dc300155573b79e299cb14e0c77acddbb97c035d6a319178f0b29bc962f08","Cargo.lock":"3d91565ed13de572a9ebde408a0c98e33f931d6ab52f212b0830a60b4ab26b77","Cargo.toml":"39f627122dceaad42146634719fde802fca3baa1b3908753af723074ae2a6d69","Cargo.toml.orig":"5edcfca33ce38a97f6fd53c9677ac14442b5a12a934e0ef1d9bfeead8966ee4e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac","README.md":"4c8f9b5016f2a0c3dbeca5bc41241f57db5568f803e58c1fa480ae2b3638d0a9","examples/integers.rs":"589ff4271566dfa322becddf3e2c7b592e6e0bc97b02892ce75619b7e452e930","examples/paths.rs":"1b30e466b824ce8df7ad0a55334424131d9d2573d6cf9f7d5d50c09c8901d526","examples/traits.rs":"cbee6a3e1f7db60b02ae25b714926517144a77cb492021f492774cf0e1865a9e","examples/versions.rs":"38535e6d9f5bfae0de474a3db79a40e8f5da8ba9334c5ff4c363de9bc99d4d12","src/error.rs":"12de7dafea4a35d1dc2f0fa79bfa038386bbbea72bf083979f4ddf227999eeda","src/lib.rs":"6fa01458e8f9258d84f83ead24fdb0cdf9aec10838b0262f1dfbdf79c530c537","src/tests.rs":"f0e6dc1ad9223c0336c02e215ea3940acb2af6c3bc8fd791e16cd4e786e6a608","src/version.rs":"175727d5f02f2fe2271ddc9b041db2a5b9c6fe0f95afd17c73a4d982612764a3","tests/rustflags.rs":"5c8169b88216055019db61b5d7baf4abdf675e3b14b54f5037bb1e3acd0a5d3f"},"package":"d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"}
|
||||
6
vendor/autocfg/.cargo_vcs_info.json
vendored
Normal file
6
vendor/autocfg/.cargo_vcs_info.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"git": {
|
||||
"sha1": "2dc4819c4a3d8856a1876dae546d1b082ea550f3"
|
||||
},
|
||||
"path_in_vcs": ""
|
||||
}
|
||||
7
vendor/autocfg/Cargo.lock
generated
vendored
Normal file
7
vendor/autocfg/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
24
vendor/autocfg/Cargo.toml
vendored
Normal file
24
vendor/autocfg/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# 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 are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
authors = ["Josh Stone <cuviper@gmail.com>"]
|
||||
exclude = ["/.github/**", "/bors.toml"]
|
||||
description = "Automatic cfg for Rust compiler features"
|
||||
readme = "README.md"
|
||||
keywords = ["rustc", "build", "autoconf"]
|
||||
categories = ["development-tools::build-utils"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/cuviper/autocfg"
|
||||
|
||||
[dependencies]
|
||||
13
vendor/autocfg/Cargo.toml.orig
generated
vendored
Normal file
13
vendor/autocfg/Cargo.toml.orig
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
authors = ["Josh Stone <cuviper@gmail.com>"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/cuviper/autocfg"
|
||||
description = "Automatic cfg for Rust compiler features"
|
||||
readme = "README.md"
|
||||
keywords = ["rustc", "build", "autoconf"]
|
||||
categories = ["development-tools::build-utils"]
|
||||
exclude = ["/.github/**", "/bors.toml"]
|
||||
|
||||
[dependencies]
|
||||
201
vendor/autocfg/LICENSE-APACHE
vendored
Normal file
201
vendor/autocfg/LICENSE-APACHE
vendored
Normal file
|
|
@ -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.
|
||||
25
vendor/autocfg/LICENSE-MIT
vendored
Normal file
25
vendor/autocfg/LICENSE-MIT
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2018 Josh Stone
|
||||
|
||||
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.
|
||||
95
vendor/autocfg/README.md
vendored
Normal file
95
vendor/autocfg/README.md
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
autocfg
|
||||
=======
|
||||
|
||||
[](https://crates.io/crates/autocfg)
|
||||
[](https://docs.rs/autocfg)
|
||||

|
||||

|
||||
|
||||
A Rust library for build scripts to automatically configure code based on
|
||||
compiler support. Code snippets are dynamically tested to see if the `rustc`
|
||||
will accept them, rather than hard-coding specific version support.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[build-dependencies]
|
||||
autocfg = "1"
|
||||
```
|
||||
|
||||
Then use it in your `build.rs` script to detect compiler features. For
|
||||
example, to test for 128-bit integer support, it might look like:
|
||||
|
||||
```rust
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
let ac = autocfg::new();
|
||||
ac.emit_has_type("i128");
|
||||
|
||||
// (optional) We don't need to rerun for anything external.
|
||||
autocfg::rerun_path("build.rs");
|
||||
}
|
||||
```
|
||||
|
||||
If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line
|
||||
for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the
|
||||
rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that
|
||||
should only be used when the compiler supports it.
|
||||
|
||||
|
||||
## Release Notes
|
||||
|
||||
- 1.1.0 (2022-02-07)
|
||||
- Use `CARGO_ENCODED_RUSTFLAGS` when it is set.
|
||||
|
||||
- 1.0.1 (2020-08-20)
|
||||
- Apply `RUSTFLAGS` for more `--target` scenarios, by @adamreichold.
|
||||
|
||||
- 1.0.0 (2020-01-08)
|
||||
- 🎉 Release 1.0! 🎉 (no breaking changes)
|
||||
- Add `probe_expression` and `emit_expression_cfg` to test arbitrary expressions.
|
||||
- Add `probe_constant` and `emit_constant_cfg` to test arbitrary constant expressions.
|
||||
|
||||
- 0.1.7 (2019-10-20)
|
||||
- Apply `RUSTFLAGS` when probing `$TARGET != $HOST`, mainly for sysroot, by @roblabla.
|
||||
|
||||
- 0.1.6 (2019-08-19)
|
||||
- Add `probe`/`emit_sysroot_crate`, by @leo60228.
|
||||
|
||||
- 0.1.5 (2019-07-16)
|
||||
- Mask some warnings from newer rustc.
|
||||
|
||||
- 0.1.4 (2019-05-22)
|
||||
- Relax `std`/`no_std` probing to a warning instead of an error.
|
||||
- Improve `rustc` bootstrap compatibility.
|
||||
|
||||
- 0.1.3 (2019-05-21)
|
||||
- Auto-detects if `#![no_std]` is needed for the `$TARGET`.
|
||||
|
||||
- 0.1.2 (2019-01-16)
|
||||
- Add `rerun_env(ENV)` to print `cargo:rerun-if-env-changed=ENV`.
|
||||
- Add `rerun_path(PATH)` to print `cargo:rerun-if-changed=PATH`.
|
||||
|
||||
|
||||
## Minimum Rust version policy
|
||||
|
||||
This crate's minimum supported `rustc` version is `1.0.0`. Compatibility is
|
||||
its entire reason for existence, so this crate will be extremely conservative
|
||||
about raising this requirement. If this is ever deemed necessary, it will be
|
||||
treated as a major breaking change for semver purposes.
|
||||
|
||||
|
||||
## 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.
|
||||
9
vendor/autocfg/examples/integers.rs
vendored
Normal file
9
vendor/autocfg/examples/integers.rs
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
for i in 3..8 {
|
||||
ac.emit_has_type(&format!("i{}", 1 << i));
|
||||
}
|
||||
}
|
||||
22
vendor/autocfg/examples/paths.rs
vendored
Normal file
22
vendor/autocfg/examples/paths.rs
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
|
||||
// since ancient times...
|
||||
ac.emit_has_path("std::vec::Vec");
|
||||
ac.emit_path_cfg("std::vec::Vec", "has_vec");
|
||||
|
||||
// rustc 1.10.0
|
||||
ac.emit_has_path("std::panic::PanicInfo");
|
||||
ac.emit_path_cfg("std::panic::PanicInfo", "has_panic_info");
|
||||
|
||||
// rustc 1.20.0
|
||||
ac.emit_has_path("std::mem::ManuallyDrop");
|
||||
ac.emit_path_cfg("std::mem::ManuallyDrop", "has_manually_drop");
|
||||
|
||||
// rustc 1.25.0
|
||||
ac.emit_has_path("std::ptr::NonNull");
|
||||
ac.emit_path_cfg("std::ptr::NonNull", "has_non_null");
|
||||
}
|
||||
26
vendor/autocfg/examples/traits.rs
vendored
Normal file
26
vendor/autocfg/examples/traits.rs
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
|
||||
// since ancient times...
|
||||
ac.emit_has_trait("std::ops::Add");
|
||||
ac.emit_trait_cfg("std::ops::Add", "has_ops");
|
||||
|
||||
// trait parameters have to be provided
|
||||
ac.emit_has_trait("std::borrow::Borrow<str>");
|
||||
ac.emit_trait_cfg("std::borrow::Borrow<str>", "has_borrow");
|
||||
|
||||
// rustc 1.8.0
|
||||
ac.emit_has_trait("std::ops::AddAssign");
|
||||
ac.emit_trait_cfg("std::ops::AddAssign", "has_assign_ops");
|
||||
|
||||
// rustc 1.12.0
|
||||
ac.emit_has_trait("std::iter::Sum");
|
||||
ac.emit_trait_cfg("std::iter::Sum", "has_sum");
|
||||
|
||||
// rustc 1.28.0
|
||||
ac.emit_has_trait("std::alloc::GlobalAlloc");
|
||||
ac.emit_trait_cfg("std::alloc::GlobalAlloc", "has_global_alloc");
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue