Bug 1485409 - update crates to dispense with winapi 0.2.8 requirement; r=glandium

winapi 0.2.8 is used by a number of crates in our dependency graph.  The
newest version of winapi is 0.3.4, which is a significant restructuring
and also more amenable to further development, e.g. adding AArch64
support.  This patch does the easy work of updating as many things as
possible to winapi 0.3.4 via a simple `cargo update`:

cargo update -p atty:0.2.2 -p fs2 -p msdos_time -p parking_lot_core -p aho-corasick

and then vendoring the results of those changes.
This commit is contained in:
Nathan Froyd 2018-08-28 21:37:30 -04:00
Родитель 9ca03066d9
Коммит 65e7b0bbd1
87 изменённых файлов: 3587 добавлений и 577 удалений

73
Cargo.lock сгенерированный
Просмотреть файл

@ -14,10 +14,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
version = "0.6.3"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -75,12 +75,12 @@ dependencies = [
[[package]]
name = "atty"
version = "0.2.2"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -316,7 +316,7 @@ version = "2.31.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -685,7 +685,7 @@ name = "env_logger"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -767,12 +767,11 @@ dependencies = [
[[package]]
name = "fs2"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1293,7 +1292,7 @@ name = "memmap"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1443,12 +1442,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "msdos_time"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1604,19 +1602,18 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.2.7"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1802,7 +1799,7 @@ dependencies = [
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1810,12 +1807,20 @@ name = "redox_syscall"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1827,7 +1832,7 @@ name = "regex"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2275,6 +2280,16 @@ dependencies = [
"wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.9.0"
@ -2812,7 +2827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2820,7 +2835,7 @@ dependencies = [
[metadata]
"checksum Inflector 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b33cd9b653730fc539c53c7b3c672d2f47108fa20c6df571fa5817178f5a14c"
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9dadc668390b373e73e4abbfc1f07238b09a25858f2f39c06cebc6d8e141d774"
"checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f"
@ -2828,7 +2843,7 @@ dependencies = [
"checksum ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b385d69402821a1c254533a011a312531cbcc0e3e24f19bbb4747a5a2daf37e2"
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fd4c0631f06448cc45a6bbb3b710ebb7ff8ccb96a0800c994afe23a70d5df2"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
@ -2896,7 +2911,7 @@ dependencies = [
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
"checksum freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b659e75b7a7338fe75afd7f909fc2b71937845cffb6ebe54ba2e50f13d8e903d"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
@ -2949,7 +2964,7 @@ dependencies = [
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum moz_cbor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c82a57087fd5990d7122dbff1607c3b20c3d2958e9d9ad9765aab415e2c91c"
"checksum mp4parse_fallible 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"
"checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"
"checksum msdos_time 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"
"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0"
"checksum new-ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ccbebba6fb53a6d2bdcfaf79cb339bc136dee3bfff54dc337a334bafe36476a"
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
@ -2966,7 +2981,7 @@ dependencies = [
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69376b761943787ebd5cc85a5bc95958651a22609c5c1c2b65de21786baec72b"
"checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum petgraph 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7e5234c228fbfa874c86a77f685886127f82e0aef602ad1d48333fcac6ad61"
@ -2990,6 +3005,7 @@ dependencies = [
"checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
@ -3032,6 +3048,7 @@ dependencies = [
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"

Просмотреть файл

@ -1 +1 @@
{"files":{".travis.yml":"e17babe5ba0bdd19ec59a37b4a099fd4313bff58be63a2ff506075f9a97dc172","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"b3fa06c2147a4749cd984ded69024ddcc8b7d578ab763b60227b3ba474c3ec70","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"9bc60d2cec222b50f87c85cf9475349bb228a36f89796c5d6481c52560ddde3a","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"acf4844efadeafc7bc396c2b16f2a184e140b6c17d1084dbaf454196de2090cd","benches/random.txt":"9386fb3efedc7ffbd09fb49088347f1056bc2d90a861009fa2f804cdb714efcb","ctags.rust":"3d128d3cc59f702e68953ba2fe6c3f46bc6991fc575308db060482d5da0c79f3","examples/dict-search.rs":"30eb44b1a0b599507db4c23a90f74199faabc64a8ae1d603ecdf3bba7428eb1e","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/autiter.rs":"98c31a7fbe21cfacaa858f90409f0d86edd46dda1b7651f4e800d929a50afb7b","src/full.rs":"b83a9c8ff3ef611c316b68650915df2d7f361a49b59dab103dc2c5476f2d8303","src/lib.rs":"68bf2ed02d58bebee6f7f7579038f1e4b60a2c4acc334263cb837bcbe15ffe94","src/main.rs":"fc867cb5f0b02d0f49ecab06b72c05a247cbcf3bf9228c235de8e787bda7bef5"},"package":"500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"}
{"files":{".travis.yml":"5749b97291a6f4e6cc0b308d2d410e1ae20530f0976575581270d3d4eb60ed19","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"64af7d0a0a299d3a05f52baed2ea87cc0d783c4fdeaa555a595aed92e5d780a6","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"9fb3256ce6fc5b25c9a92fe3b8f7a82a26d380fcf6121c934c2bb6f85102fede","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"c74b297ed2217e4784614573a8b44c61dfe5173985c43616e43a3f608973ff2e","benches/random.txt":"9386fb3efedc7ffbd09fb49088347f1056bc2d90a861009fa2f804cdb714efcb","ci/script.sh":"061b81cf1dba37d34063500117f5aa164919445472086665549ef2aa6a43bf77","ctags.rust":"3d128d3cc59f702e68953ba2fe6c3f46bc6991fc575308db060482d5da0c79f3","examples/dict-search.rs":"0dac88736039262dfb8df9ff85ece18de90dd4da9b8b895cf4d57bf33167b224","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/autiter.rs":"b3bd067bf6c25708109870afbb5d09e9a04d0f2f596f59c368e42ddbc7c65f93","src/full.rs":"acb6389d210e7bc4125f0ebb6f268b712e60ec50b58b9c4094a8083bb8f4caf2","src/lib.rs":"fdddbb688fbc71461242b94e1cfb3dfbf0a9f06b2c70a6e83de15a0e54804a28","src/main.rs":"fc867cb5f0b02d0f49ecab06b72c05a247cbcf3bf9228c235de8e787bda7bef5"},"package":"68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"}

13
third_party/rust/aho-corasick/.travis.yml поставляемый
Просмотреть файл

@ -1,13 +1,10 @@
language: rust
rust:
- 1.12.0
- 1.13.0
- stable
- beta
- nightly
script:
- cargo build --verbose
- cargo test --verbose
- cargo doc
- if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
cargo bench --verbose;
fi
script: ci/script.sh
branches:
only:
- master

87
third_party/rust/aho-corasick/Cargo.toml поставляемый
Просмотреть файл

@ -1,42 +1,26 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "aho-corasick"
version = "0.6.3" #:version
version = "0.6.8"
authors = ["Andrew Gallant <jamslam@gmail.com>"]
exclude = ["benches/sherlock.txt"]
description = "Fast multiple substring searching with finite state machines."
documentation = "http://burntsushi.net/rustdoc/aho_corasick/"
homepage = "https://github.com/BurntSushi/aho-corasick"
repository = "https://github.com/BurntSushi/aho-corasick"
readme = "README.md"
keywords = ["string", "search", "text", "aho", "corasick"]
license = "Unlicense/MIT"
exclude = ["benches/sherlock.txt"]
[lib]
name = "aho_corasick"
[[bin]]
name = "aho-corasick-dot"
test = false
doc = false
bench = false
[dependencies]
memchr = "1"
[dev-dependencies]
csv = "0.15"
docopt = "0.7"
memmap = "0.5"
quickcheck = { version = "0.4", default-features = false }
rand = "0.3"
rustc-serialize = "0.3"
[[bench]]
name = "bench"
path = "benches/bench.rs"
test = false
bench = true
repository = "https://github.com/BurntSushi/aho-corasick"
[profile.test]
debug = true
@ -45,3 +29,44 @@ debug = true
[profile.release]
debug = true
[lib]
name = "aho_corasick"
[[bin]]
name = "aho-corasick-dot"
path = "src/main.rs"
test = false
bench = false
doc = false
[[bench]]
name = "bench"
path = "benches/bench.rs"
test = false
bench = true
[dependencies.memchr]
version = "2"
[dev-dependencies.csv]
version = "1"
[dev-dependencies.docopt]
version = "1"
[dev-dependencies.memmap]
version = "0.6"
[dev-dependencies.quickcheck]
version = "0.7"
default-features = false
[dev-dependencies.rand]
version = "0.5"
[dev-dependencies.serde]
version = "1"
[dev-dependencies.serde_derive]
version = "1"
[badges.travis-ci]
repository = "BurntSushi/aho-corasick"

2
third_party/rust/aho-corasick/README.md поставляемый
Просмотреть файл

@ -17,7 +17,7 @@ Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
### Documentation
[http://burntsushi.net/rustdoc/aho_corasick/](http://burntsushi.net/rustdoc/aho_corasick/).
[https://docs.rs/aho-corasick/](https://docs.rs/aho-corasick/).
### Example

Просмотреть файл

@ -57,6 +57,40 @@ fn bench_naive_no_match<S>(b: &mut Bencher, needles: Vec<S>, haystack: &str)
b.iter(|| assert!(!naive_find(&needles, haystack)));
}
#[bench]
fn bench_construction(b: &mut Bencher) {
b.iter(|| {
AcAutomaton::new(test::black_box(
[
"ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BA", "BaK", "Bak", "Ba", "HOL",
"HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh", "JoH", "Joh", "SHE",
"SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat", "aDL", "aDl", "adL", "adl", "bAK",
"bAk", "bA", "baK", "bak", "ba", "hOL", "hOl", "hoL", "hol", "iRE", "iRe",
"irE", "ire", "jOH", "jOh", "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt",
"waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe",
].iter()
.map(|x| *x),
))
})
}
#[bench]
fn bench_full_construction(b: &mut Bencher) {
b.iter(|| {
AcAutomaton::new(test::black_box(
[
"ADL", "ADl", "AdL", "Adl", "BAK", "BAk", "BA", "BaK", "Bak", "Ba", "HOL",
"HOl", "HoL", "Hol", "IRE", "IRe", "IrE", "Ire", "JOH", "JOh", "JoH", "Joh", "SHE",
"SHe", "ShE", "She", "WAT", "WAt", "WaT", "Wat", "aDL", "aDl", "adL", "adl", "bAK",
"bAk", "bA", "baK", "bak", "ba", "hOL", "hOl", "hoL", "hol", "iRE", "iRe",
"irE", "ire", "jOH", "jOh", "joH", "joh", "sHE", "sHe", "shE", "she", "wAT", "wAt",
"waT", "wat", "ſHE", "ſHe", "ſhE", "ſhe",
].iter()
.map(|x| *x),
)).into_full()
})
}
fn haystack_same(letter: char) -> String {
iter::repeat(letter).take(10000).collect()
}

20
third_party/rust/aho-corasick/ci/script.sh поставляемый Executable file
Просмотреть файл

@ -0,0 +1,20 @@
#!/bin/sh
set -ex
cargo build --verbose
cargo doc --verbose
# If we're testing on an older version of Rust, then only check that we
# can build the crate. This is because the dev dependencies might be updated
# more frequently, and therefore might require a newer version of Rust.
#
# This isn't ideal. It's a compromise.
if [ "$TRAVIS_RUST_VERSION" = "1.13.0" ]; then
exit
fi
cargo test --verbose
if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
cargo bench --verbose --no-run
fi

Просмотреть файл

@ -5,7 +5,9 @@ extern crate aho_corasick;
extern crate csv;
extern crate docopt;
extern crate memmap;
extern crate rustc_serialize;
extern crate serde;
#[macro_use]
extern crate serde_derive;
use std::error::Error;
use std::fs::File;
@ -14,7 +16,7 @@ use std::process;
use aho_corasick::{Automaton, AcAutomaton, Match};
use docopt::Docopt;
use memmap::{Mmap, Protection};
use memmap::Mmap;
static USAGE: &'static str = "
Usage: dict-search [options] <input>
@ -33,7 +35,7 @@ Options:
-h, --help Show this usage message.
";
#[derive(Clone, Debug, RustcDecodable)]
#[derive(Clone, Debug, Deserialize)]
struct Args {
arg_input: String,
flag_dict: String,
@ -46,7 +48,7 @@ struct Args {
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.decode())
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
match run(&args) {
Ok(()) => {}
@ -70,48 +72,37 @@ fn run(args: &Args) -> Result<(), Box<Error>> {
return Ok(());
}
let rdr = try!(File::open(&args.arg_input));
if args.flag_full {
let aut = aut.into_full();
if args.flag_overlapping {
if args.flag_count {
let mmap = Mmap::open_path(
&args.arg_input, Protection::Read).unwrap();
let text = unsafe { mmap.as_slice() };
println!("{}", aut.find_overlapping(text).count());
let mmap = unsafe { try!(Mmap::map(&rdr)) };
println!("{}", aut.find_overlapping(&*mmap).count());
} else {
let rdr = try!(File::open(&args.arg_input));
try!(write_matches(&aut, aut.stream_find_overlapping(rdr)));
}
} else {
if args.flag_count {
let mmap = Mmap::open_path(
&args.arg_input, Protection::Read).unwrap();
let text = unsafe { mmap.as_slice() };
println!("{}", aut.find(text).count());
let mmap = unsafe { try!(Mmap::map(&rdr)) };
println!("{}", aut.find(&*mmap).count());
} else {
let rdr = try!(File::open(&args.arg_input));
try!(write_matches(&aut, aut.stream_find(rdr)));
}
}
} else {
if args.flag_overlapping {
if args.flag_count {
let mmap = Mmap::open_path(
&args.arg_input, Protection::Read).unwrap();
let text = unsafe { mmap.as_slice() };
println!("{}", aut.find_overlapping(text).count());
let mmap = unsafe { try!(Mmap::map(&rdr)) };
println!("{}", aut.find_overlapping(&*mmap).count());
} else {
let rdr = try!(File::open(&args.arg_input));
try!(write_matches(&aut, aut.stream_find_overlapping(rdr)));
}
} else {
if args.flag_count {
let mmap = Mmap::open_path(
&args.arg_input, Protection::Read).unwrap();
let text = unsafe { mmap.as_slice() };
println!("{}", aut.find(text).count());
let mmap = unsafe { try!(Mmap::map(&rdr)) };
println!("{}", aut.find(&*mmap).count());
} else {
let rdr = try!(File::open(&args.arg_input));
try!(write_matches(&aut, aut.stream_find(rdr)));
}
}
@ -122,14 +113,10 @@ fn run(args: &Args) -> Result<(), Box<Error>> {
fn write_matches<A, I>(aut: &A, it: I) -> Result<(), Box<Error>>
where A: Automaton<String>, I: Iterator<Item=io::Result<Match>> {
let mut wtr = csv::Writer::from_writer(io::stdout());
try!(wtr.write(["pattern", "start", "end"].iter()));
try!(wtr.serialize(("pattern", "start", "end")));
for m in it {
let m = try!(m);
try!(wtr.write([
aut.pattern(m.pati),
&m.start.to_string(),
&m.end.to_string(),
].iter()));
try!(wtr.serialize((aut.pattern(m.pati), m.start, m.end)));
}
try!(wtr.flush());
Ok(())

Просмотреть файл

@ -42,7 +42,7 @@ pub trait Automaton<P> {
/// Returns true if the automaton has no patterns.
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
self.patterns().is_empty()
}
/// Returns an iterator of non-overlapping matches in `s`.
@ -381,7 +381,7 @@ impl<'a, R: io::Read, P, A: Automaton<P>>
self.buf.consume(consumed);
let bs = match self.buf.fill_buf() {
Err(err) => return Some(Err(err)),
Ok(bs) if bs.len() == 0 => break,
Ok(bs) if bs.is_empty() => break,
Ok(bs) => bs,
};
consumed = bs.len(); // is shortened if we find a match
@ -505,7 +505,7 @@ impl<'a, R: io::Read, P, A: Automaton<P> + ?Sized>
self.buf.consume(consumed);
let bs = match self.buf.fill_buf() {
Err(err) => return Some(Err(err)),
Ok(bs) if bs.len() == 0 => break,
Ok(bs) if bs.is_empty() => break,
Ok(bs) => bs,
};
consumed = bs.len(); // is shortened if we find a match

29
third_party/rust/aho-corasick/src/full.rs поставляемый
Просмотреть файл

@ -44,11 +44,11 @@ impl<P: AsRef<[u8]>> FullAcAutomaton<P> {
pub fn memory_usage(&self) -> usize {
self.pats.iter()
.map(|p| vec_bytes() + p.as_ref().len())
.fold(0, |a, b| a + b)
.sum::<usize>()
+ (4 * self.trans.len())
+ self.out.iter()
.map(|v| vec_bytes() + (usize_bytes() * v.len()))
.fold(0, |a, b| a + b)
.sum::<usize>()
+ self.start_bytes.len()
}
@ -56,11 +56,11 @@ impl<P: AsRef<[u8]>> FullAcAutomaton<P> {
pub fn heap_bytes(&self) -> usize {
self.pats.iter()
.map(|p| mem::size_of::<P>() + p.as_ref().len())
.fold(0, |a, b| a + b)
.sum::<usize>()
+ (4 * self.trans.len())
+ self.out.iter()
.map(|v| vec_bytes() + (usize_bytes() * v.len()))
.fold(0, |a, b| a + b)
.sum::<usize>()
+ self.start_bytes.len()
}
@ -119,14 +119,23 @@ impl<P: AsRef<[u8]>> Automaton<P> for FullAcAutomaton<P> {
impl<P: AsRef<[u8]>> FullAcAutomaton<P> {
fn build_matrix<T: Transitions>(&mut self, ac: &AcAutomaton<P, T>) {
for (si, s) in ac.states.iter().enumerate().skip(1) {
for b in (0..256).map(|b| b as u8) {
self.set(si as StateIdx, b, ac.next_state(si as StateIdx, b));
}
for &pati in &s.out {
self.out[si].push(pati);
}
self.set_states(ac, si as StateIdx);
self.out[si].extend_from_slice(&s.out);
}
}
fn set_states<T: Transitions>(&mut self, ac: &AcAutomaton<P, T>, si: StateIdx) {
let current_state = &ac.states[si as usize];
let first_fail_state = current_state.fail;
current_state.for_each_transition(move |b, maybe_si| {
let goto = if maybe_si == FAIL_STATE {
ac.memoized_next_state(self, si, first_fail_state, b)
} else {
maybe_si
};
self.set(si, b, goto);
});
}
}
impl<P: AsRef<[u8]> + fmt::Debug> fmt::Debug for FullAcAutomaton<P> {

241
third_party/rust/aho-corasick/src/lib.rs поставляемый
Просмотреть файл

@ -121,8 +121,10 @@ assert_eq!(matches, vec![Match { pati: 1, start: 0, end: 1}]);
#![deny(missing_docs)]
extern crate memchr;
#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate rand;
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
extern crate rand;
use std::collections::VecDeque;
use std::fmt;
@ -241,24 +243,47 @@ impl<P: AsRef<[u8]>, T: Transitions> AcAutomaton<P, T> {
pub fn heap_bytes(&self) -> usize {
self.pats.iter()
.map(|p| mem::size_of::<P>() + p.as_ref().len())
.fold(0, |a, b| a + b)
.sum::<usize>()
+ self.states.iter()
.map(|s| mem::size_of::<State<T>>() + s.heap_bytes())
.fold(0, |a, b| a + b)
.sum::<usize>()
+ self.start_bytes.len()
}
// The states of `full_automaton` should be set for all states < si
fn memoized_next_state(
&self,
full_automaton: &FullAcAutomaton<P>,
current_si: StateIdx,
mut si: StateIdx,
b: u8,
) -> StateIdx {
loop {
if si < current_si {
return full_automaton.next_state(si, b);
}
let state = &self.states[si as usize];
let maybe_si = state.goto(b);
if maybe_si != FAIL_STATE {
return maybe_si;
} else {
si = state.fail;
}
}
}
}
impl<P: AsRef<[u8]>, T: Transitions> Automaton<P> for AcAutomaton<P, T> {
#[inline]
fn next_state(&self, mut si: StateIdx, b: u8) -> StateIdx {
loop {
let maybe_si = self.states[si as usize].goto(b);
let state = &self.states[si as usize];
let maybe_si = state.goto(b);
if maybe_si != FAIL_STATE {
si = maybe_si;
break;
} else {
si = self.states[si as usize].fail;
si = state.fail;
}
}
si
@ -297,6 +322,29 @@ impl<P: AsRef<[u8]>, T: Transitions> Automaton<P> for AcAutomaton<P, T> {
}
}
// `(0..256).map(|b| b as u8)` optimizes poorly in debug builds so
// we use this small explicit iterator instead
struct AllBytesIter(i32);
impl Iterator for AllBytesIter {
type Item = u8;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.0 < 256 {
let b = self.0 as u8;
self.0 += 1;
Some(b)
} else {
None
}
}
}
impl AllBytesIter {
fn new() -> AllBytesIter {
AllBytesIter(0)
}
}
// Below contains code for *building* the automaton. It's a reasonably faithful
// translation of the description/psuedo-code from:
// http://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf
@ -321,11 +369,14 @@ impl<P: AsRef<[u8]>, T: Transitions> AcAutomaton<P, T> {
}
self.states[previ as usize].out.push(pati);
}
for c in (0..256).into_iter().map(|c| c as u8) {
if self.states[ROOT_STATE as usize].goto(c) == FAIL_STATE {
self.states[ROOT_STATE as usize].set_goto(c, ROOT_STATE);
} else {
self.start_bytes.push(c);
{
let root_state = &mut self.states[ROOT_STATE as usize];
for c in AllBytesIter::new() {
if root_state.goto(c) == FAIL_STATE {
root_state.set_goto(c, ROOT_STATE);
} else {
self.start_bytes.push(c);
}
}
}
// If any of the start bytes are non-ASCII, then remove them all,
@ -344,26 +395,45 @@ impl<P: AsRef<[u8]>, T: Transitions> AcAutomaton<P, T> {
// Fill up the queue with all non-root transitions out of the root
// node. Then proceed by breadth first traversal.
let mut q = VecDeque::new();
for c in (0..256).into_iter().map(|c| c as u8) {
let si = self.states[ROOT_STATE as usize].goto(c);
self.states[ROOT_STATE as usize].for_each_transition(|_, si| {
if si != ROOT_STATE {
q.push_front(si);
}
}
});
let mut transitions = Vec::new();
while let Some(si) = q.pop_back() {
for c in (0..256).into_iter().map(|c| c as u8) {
let u = self.states[si as usize].goto(c);
if u != FAIL_STATE {
q.push_front(u);
let mut v = self.states[si as usize].fail;
while self.states[v as usize].goto(c) == FAIL_STATE {
v = self.states[v as usize].fail;
self.states[si as usize].for_each_ok_transition(|c, u| {
transitions.push((c, u));
q.push_front(u);
});
for (c, u) in transitions.drain(..) {
let mut v = self.states[si as usize].fail;
loop {
let state = &self.states[v as usize];
if state.goto(c) == FAIL_STATE {
v = state.fail;
} else {
break;
}
let ufail = self.states[v as usize].goto(c);
self.states[u as usize].fail = ufail;
let ufail_out = self.states[ufail as usize].out.clone();
self.states[u as usize].out.extend(ufail_out);
}
let ufail = self.states[v as usize].goto(c);
self.states[u as usize].fail = ufail;
fn get_two<T>(xs: &mut [T], i: usize, j: usize) -> (&mut T, &mut T) {
if i < j {
let (before, after) = xs.split_at_mut(j);
(&mut before[i], &mut after[0])
} else {
let (before, after) = xs.split_at_mut(i);
(&mut after[0], &mut before[j])
}
}
let (ufail_out, out) = get_two(&mut self.states, ufail as usize, u as usize);
out.out.extend_from_slice(&ufail_out.out);
}
}
self
@ -398,6 +468,18 @@ impl<T: Transitions> State<T> {
(self.out.len() * usize_bytes())
+ self.goto.heap_bytes()
}
fn for_each_transition<F>(&self, f: F)
where F: FnMut(u8, StateIdx)
{
self.goto.for_each_transition(f)
}
fn for_each_ok_transition<F>(&self, f: F)
where F: FnMut(u8, StateIdx)
{
self.goto.for_each_ok_transition(f)
}
}
/// An abstraction over state transition strategies.
@ -416,6 +498,27 @@ pub trait Transitions {
fn set_goto(&mut self, alpha: u8, si: StateIdx);
/// The memory use in bytes (on the heap) of this set of transitions.
fn heap_bytes(&self) -> usize;
/// Iterates over each state
fn for_each_transition<F>(&self, mut f: F)
where F: FnMut(u8, StateIdx)
{
for b in AllBytesIter::new() {
f(b, self.goto(b));
}
}
/// Iterates over each non-fail state
fn for_each_ok_transition<F>(&self, mut f: F)
where
F: FnMut(u8, StateIdx),
{
self.for_each_transition(|b, si| {
if si != FAIL_STATE {
f(b, si);
}
});
}
}
/// State transitions that can be stored either sparsely or densely.
@ -426,14 +529,14 @@ pub struct Dense(DenseChoice);
#[derive(Clone, Debug)]
enum DenseChoice {
Sparse(Vec<StateIdx>), // indexed by alphabet
Sparse(Box<Sparse>),
Dense(Vec<(u8, StateIdx)>),
}
impl Transitions for Dense {
fn new(depth: u32) -> Dense {
if depth <= DENSE_DEPTH_THRESHOLD {
Dense(DenseChoice::Sparse(vec![0; 256]))
Dense(DenseChoice::Sparse(Box::new(Sparse::new(depth))))
} else {
Dense(DenseChoice::Dense(vec![]))
}
@ -441,7 +544,7 @@ impl Transitions for Dense {
fn goto(&self, b1: u8) -> StateIdx {
match self.0 {
DenseChoice::Sparse(ref m) => m[b1 as usize],
DenseChoice::Sparse(ref m) => m.goto(b1),
DenseChoice::Dense(ref m) => {
for &(b2, si) in m {
if b1 == b2 {
@ -455,29 +558,75 @@ impl Transitions for Dense {
fn set_goto(&mut self, b: u8, si: StateIdx) {
match self.0 {
DenseChoice::Sparse(ref mut m) => m[b as usize] = si,
DenseChoice::Sparse(ref mut m) => m.set_goto(b, si),
DenseChoice::Dense(ref mut m) => m.push((b, si)),
}
}
fn heap_bytes(&self) -> usize {
match self.0 {
DenseChoice::Sparse(ref m) => m.len() * 4,
DenseChoice::Sparse(_) => mem::size_of::<Sparse>(),
DenseChoice::Dense(ref m) => m.len() * (1 + 4),
}
}
fn for_each_transition<F>(&self, mut f: F)
where F: FnMut(u8, StateIdx)
{
match self.0 {
DenseChoice::Sparse(ref m) => m.for_each_transition(f),
DenseChoice::Dense(ref m) => {
let mut iter = m.iter();
let mut b = 0i32;
while let Some(&(next_b, next_si)) = iter.next() {
while (b as u8) < next_b {
f(b as u8, FAIL_STATE);
b += 1;
}
f(b as u8, next_si);
b += 1;
}
while b < 256 {
f(b as u8, FAIL_STATE);
b += 1;
}
}
}
}
fn for_each_ok_transition<F>(&self, mut f: F)
where
F: FnMut(u8, StateIdx),
{
match self.0 {
DenseChoice::Sparse(ref m) => m.for_each_ok_transition(f),
DenseChoice::Dense(ref m) => for &(b, si) in m {
f(b, si)
}
}
}
}
/// State transitions that are always sparse.
///
/// This can use enormous amounts of memory when there are many patterns,
/// but matching is very fast.
#[derive(Clone, Debug)]
pub struct Sparse(Vec<StateIdx>);
pub struct Sparse([StateIdx; 256]);
impl Clone for Sparse {
fn clone(&self) -> Sparse {
Sparse(self.0)
}
}
impl fmt::Debug for Sparse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Sparse").field(&&self.0[..]).finish()
}
}
impl Transitions for Sparse {
fn new(_: u32) -> Sparse {
Sparse(vec![0; 256])
Sparse([0; 256])
}
#[inline]
@ -490,7 +639,7 @@ impl Transitions for Sparse {
}
fn heap_bytes(&self) -> usize {
self.0.len() * 4
0
}
}
@ -525,15 +674,13 @@ impl<T: Transitions> State<T> {
}
fn goto_string(&self, root: bool) -> String {
use std::char::from_u32;
let mut goto = vec![];
for b in (0..256).map(|b| b as u8) {
for b in AllBytesIter::new() {
let si = self.goto(b);
if (!root && si == FAIL_STATE) || (root && si == ROOT_STATE) {
continue;
}
goto.push(format!("{} => {}", from_u32(b as u32).unwrap(), si));
goto.push(format!("{} => {}", b as char, si));
}
goto.join(", ")
}
@ -563,13 +710,13 @@ digraph automaton {{
"#, self.pats.join(", "));
for (i, s) in self.states.iter().enumerate().skip(1) {
let i = i as u32;
if s.out.len() == 0 {
if s.out.is_empty() {
w!(out, " {};\n", i);
} else {
w!(out, " {} [peripheries=2];\n", i);
}
w!(out, " {} -> {} [style=dashed];\n", i, s.fail);
for b in (0..256).map(|b| b as u8) {
for b in AllBytesIter::new() {
let si = s.goto(b);
if si == FAIL_STATE || (i == ROOT_STATE && si == ROOT_STATE) {
continue;
@ -597,8 +744,9 @@ mod tests {
use std::io;
use quickcheck::{Arbitrary, Gen, quickcheck};
use rand::Rng;
use super::{Automaton, AcAutomaton, Match};
use super::{AcAutomaton, Automaton, Match, AllBytesIter};
fn aut_find<S>(xs: &[S], haystack: &str) -> Vec<Match>
where S: Clone + AsRef<[u8]> {
@ -870,7 +1018,7 @@ mod tests {
let size = { let s = g.size(); g.gen_range(0, s) };
let mut s = String::with_capacity(size);
for _ in 0..size {
if g.gen_weighted_bool(3) {
if g.gen_bool(0.3) {
s.push(char::arbitrary(g));
} else {
for _ in 0..5 {
@ -922,4 +1070,13 @@ mod tests {
}
quickcheck(prop as fn(Vec<SmallAscii>, BiasAscii) -> bool);
}
#[test]
fn all_bytes_iter() {
let all_bytes = AllBytesIter::new().collect::<Vec<_>>();
assert_eq!(all_bytes[0], 0);
assert_eq!(all_bytes[255], 255);
assert!(AllBytesIter::new().enumerate().all(|(i, b)| b as usize == i));
}
}

2
third_party/rust/atty/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{".travis.yml":"4752c993a36dc8b271f25998b2c0b34af65f82fb61f7d71d0e34612a8a7cd5b0","CHANGELOG.md":"a182831141a059342664a8aaf40b9fd7828e8004094fb42e1b17129a090899ec","Cargo.toml":"5fa1586ac82ee945f057b87c81acae6e588de2303536445b4a766028633347e0","LICENSE":"235760c32039b0a6b23207918b71c1aa5d8318ee651c0f245d290ba1f47631cf","README.md":"b23f66e15c8311e11cbc3b10bfc87a7cb10bc4d758c6a352b155127b48b970d7","appveyor.yml":"dfe3d3eddd762a3cc76174e03ea91c93f544ce7fa05fbca4975f1624757d65e4","examples/atty.rs":"1551387a71474d9ac1b5153231f884e9e05213badcfaa3494ad2cb7ea958374a","src/lib.rs":"4530fe39e123b042eb023e4cf98a81d5184d06c938d3604b002f418101beb524"},"package":"d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"}
{"files":{".travis.yml":"9002419ea748e146ea85fd5c2646aaa6649168d4baf2e23de834c7e13e5742d3","CHANGELOG.md":"7bd35273865921a87f96ea8d69bd98bde11a96001b74c79cdcdbc83bfbbee53c","Cargo.toml":"77b51a9746012bf939c0fd0a72daa9db816c26798c557c234213a2d38b8aae81","LICENSE":"f3f8d32084848316048c5a1e125a3c5003eb32145a5f5f2a0d5586377324f9ba","README.md":"a62d294c45c9d8b2e54fcf35d9ee1ba8b8e2ab6960fb3d3f4cc9d59e8aed0835","appveyor.yml":"dea9c8da309cbb02bce31c613b697256f4cfada20b2f7b0c8911b73d569daf58","examples/atty.rs":"1551387a71474d9ac1b5153231f884e9e05213badcfaa3494ad2cb7ea958374a","rustfmt.toml":"bd196700242d17913cf8adead6912f55e9347e52ab5a001729d6c18d169f05c4","src/lib.rs":"ec3428266e83b35a8714ab99d9962c9e29f78becb39e313846f042f5b176c723"},"package":"9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"}

81
third_party/rust/atty/.travis.yml поставляемый
Просмотреть файл

@ -4,41 +4,70 @@ matrix:
fast_finish: true
include:
- rust: nightly
- rust: nightly
os: osx
- rust: beta
- rust: beta
os: osx
- rust: stable
- rust: 1.8.0
os:
- linux
- osx
- rust: stable
os: osx
allow_failures:
- rust: nightly
before_cache:
# Travis can't cache files that are not readable by "others"
- chmod -R a+r $HOME/.cargo
before_install:
# install kcov
- >
if [ ! -d "$HOME/.kcov/bin" ]; then
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build &&
cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/.kcov .. && make && make install && cd ../..
fi
- export PATH=$HOME/.kcov/bin:$PATH
script:
- cargo build
- cargo test
cache:
cargo: true
apt: true
directories:
- target/debug/deps
- target/debug/build
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- binutils-dev # required for `kcov --verify`
- libbfd-dev # required for `kcov --verify`
after_success: |
[ $TRAVIS_RUST_VERSION = stable ] &&
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
ls target/debug &&
./kcov-master/tmp/usr/local/bin/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/atty-* &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo doc --no-deps &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
pip install --user ghp-import &&
/home/travis/.local/bin/ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
env:
global:
secure: acjXoBFG4yFklz/iW4q9PLaMmTgug0c8hOov4uiaXYjDkVGhnEePBozGc8ctKuFv2BVlwBSzvE1neE9dHcCS6il0x+G79sVTekfVN5dERja3UpwrC0/QodJuDmErIUpb6zylupPnUGq5pzZabRPNKyAnsFS5wYhLMSLxGPu4pfYdW0Eu8CEPIgPYsI6o2pfKgNpXbeizdHRLMeZCN4cbEPohO1odc+Z6WJvgKn2xEkpAcfhAuaroqGGxRtmDiJZ/JaBijAKY/O9Q3Xq1GSGOPT5lmwJSp3Fxw5dgmeX6LmN0ZODASdnEoYfoqUDUFzkCON3Sk4a7hugxlkZ7cx1tfqXxMg+0BgYIUdGQNloDJnuusWvXPBFdB2jxMsfcbrCjNsrJ8kjN6uBsW9yy0kqN7a8eOJckwh5fYRWfNta0R+BrveNXWmGp4u4aBq/85jEiHi30XKTzaEUbF0Y3cIONweWeWwBOcAvPBhO63Y07TRRe+SSk1NYm7QHGW9RsHhz89OSbaIXqn+r/o+6DZcw5XaO73DtZ62Kx48NErej9kVqcIJ6HnyvCJ/fJoT7h1ixSRI/WmS30l2S/q33Q2G4C/IZ4ZZRD/1thSltAxeA6OAUnr8ITZyW47CqOmyL1IUptrdAb9OLEedYV/QrOhcg2RJLXyP66xnItOwMp014bEp4=
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- binutils-dev
- libiberty-dev
after_success:
- '[ $TRAVIS_RUST_VERSION = stable ] &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
(ls target/debug &&
RUSTFLAGS="-C link-dead-code" cargo test --no-run &&
for file in target/debug/atty-*; do
if [[ "${file: -2}" != ".d" ]]; then
mkdir -p "target/cov/$(basename $file)";
kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file";
fi;
done &&
kcov --coveralls-id=$COVERALLS_REPO_TOKEN --merge target/cov target/cov/* &&
echo "covered") || true'
- '[ $TRAVIS_RUST_VERSION = stable ] &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ]
&& cargo doc --no-deps &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d / -f 2`/index.html>" > target/doc/index.html &&
pip install --user ghp-import &&
/home/travis/.local/bin/ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages &&
echo "documented"'

36
third_party/rust/atty/CHANGELOG.md поставляемый
Просмотреть файл

@ -1,3 +1,39 @@
# 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)

36
third_party/rust/atty/Cargo.toml поставляемый
Просмотреть файл

@ -1,17 +1,33 @@
# 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.2"
version = "0.2.11"
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"
documentation = "http://softprops.github.io/atty"
readme = "README.md"
keywords = ["terminal", "tty"]
license = "MIT"
[target.'cfg(not(windows))'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
kernel32-sys = "0.2"
winapi = "0.2"
repository = "https://github.com/softprops/atty"
[target."cfg(target_os = \"redox\")".dependencies.termion]
version = "1.5"
[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"

2
third_party/rust/atty/LICENSE поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
Copyright (c) 2015-2016 Doug Tangren
Copyright (c) 2015-2017 Doug Tangren
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

22
third_party/rust/atty/README.md поставляемый
Просмотреть файл

@ -1,11 +1,18 @@
# atty
[![Build Status](https://travis-ci.org/softprops/atty.svg?branch=master)](https://travis-ci.org/softprops/atty) [![Build status](https://ci.appveyor.com/api/projects/status/geggrsnsjsuse8cv?svg=true)](https://ci.appveyor.com/project/softprops/atty) [![Coverage Status](https://coveralls.io/repos/softprops/atty/badge.svg?branch=master&service=github)](https://coveralls.io/github/softprops/atty?branch=master) [![crates.io](http://meritbadge.herokuapp.com/atty)](https://crates.io/crates/atty)
[![Build Status](https://travis-ci.org/softprops/atty.svg?branch=master)](https://travis-ci.org/softprops/atty) [![Build status](https://ci.appveyor.com/api/projects/status/geggrsnsjsuse8cv?svg=true)](https://ci.appveyor.com/project/softprops/atty) [![Coverage Status](https://coveralls.io/repos/softprops/atty/badge.svg?branch=master&service=github)](https://coveralls.io/github/softprops/atty?branch=master) [![crates.io](https://img.shields.io/crates/v/atty.svg)](https://crates.io/crates/atty) [![Released API docs](https://docs.rs/atty/badge.svg)](http://docs.rs/atty) [![Master API docs](https://img.shields.io/badge/docs-master-green.svg)](https://softprops.github.io/atty)
> are you or are you not a tty?
[Api documentation](http://softprops.github.io/atty)
## install
Add the following to your `Cargo.toml`
```toml
[dependencies]
atty = "0.2"
```
## usage
@ -23,15 +30,6 @@ fn main() {
}
```
## install
Add the following to your `Cargo.toml`
```toml
[dependencies]
atty = "0.2"
```
## testing
This library has been unit tested on both unix and windows platforms (via appveyor).
@ -75,4 +73,4 @@ stderr? false
stdin? true
```
Doug Tangren (softprops) 2015
Doug Tangren (softprops) 2015-2017

3
third_party/rust/atty/appveyor.yml поставляемый
Просмотреть файл

@ -4,7 +4,6 @@ environment:
- TARGET: nightly-i686-pc-windows-msvc
- TARGET: nightly-x86_64-pc-windows-gnu
- TARGET: nightly-i686-pc-windows-gnu
- TARGET: 1.8.0-x86_64-pc-windows-gnu
install:
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe" -FileName "rust-install.exe"
- ps: .\rust-install.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null
@ -14,4 +13,4 @@ install:
- cargo -vV
build: false
test_script:
- cargo test --verbose
- cargo build

10
third_party/rust/atty/rustfmt.toml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
# keep imports tidy
reorder_imported_names = true
reorder_imports = true
reorder_imports_in_group = true
# there is no try!
use_try_shorthand = true
# don't create rustfmt artifacts
write_mode = "Replace"
# reduce wide load
max_width = 80

95
third_party/rust/atty/src/lib.rs поставляемый
Просмотреть файл

@ -15,15 +15,19 @@
//! }
//! ```
#[cfg(windows)]
extern crate kernel32;
#[cfg(not(windows))]
#![cfg_attr(unix, no_std)]
#[cfg(unix)]
extern crate libc;
#[cfg(windows)]
extern crate winapi;
#[cfg(target_os = "redox")]
extern crate termion;
#[cfg(windows)]
use winapi::minwindef::DWORD;
use winapi::shared::minwindef::DWORD;
#[cfg(windows)]
use winapi::shared::ntdef::WCHAR;
/// possible stream sources
#[derive(Clone, Copy, Debug)]
@ -34,7 +38,7 @@ pub enum Stream {
}
/// returns true if this is a tty
#[cfg(unix)]
#[cfg(all(unix, not(target_arch = "wasm32")))]
pub fn is(stream: Stream) -> bool {
extern crate libc;
@ -49,11 +53,8 @@ pub fn is(stream: Stream) -> bool {
/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
use winapi::{
STD_INPUT_HANDLE as STD_INPUT,
STD_ERROR_HANDLE as STD_ERROR,
STD_OUTPUT_HANDLE as STD_OUTPUT
};
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]),
@ -87,10 +88,13 @@ pub fn isnt(stream: Stream) -> bool {
/// 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;
use winapi::um::processenv::GetStdHandle;
for &fd in fds {
let mut out = 0;
let handle = kernel32::GetStdHandle(fd);
if kernel32::GetConsoleMode(handle, &mut out) != 0 {
let handle = GetStdHandle(fd);
if GetConsoleMode(handle, &mut out) != 0 {
return true;
}
}
@ -100,41 +104,64 @@ unsafe fn console_on_any(fds: &[DWORD]) -> bool {
/// Returns true if there is an MSYS tty on the given handle.
#[cfg(windows)]
unsafe fn msys_tty_on(fd: DWORD) -> bool {
use std::ffi::OsString;
use std::mem;
use std::os::raw::c_void;
use std::os::windows::ffi::OsStringExt;
use std::slice;
use kernel32::GetFileInformationByHandleEx;
use winapi::fileapi::FILE_NAME_INFO;
use winapi::minwinbase::FileNameInfo;
use winapi::minwindef::MAX_PATH;
use winapi::ctypes::c_void;
use winapi::um::winbase::GetFileInformationByHandleEx;
use winapi::um::fileapi::FILE_NAME_INFO;
use winapi::um::minwinbase::FileNameInfo;
use winapi::um::processenv::GetStdHandle;
use winapi::shared::minwindef::MAX_PATH;
let size = mem::size_of::<FILE_NAME_INFO>();
let mut name_info_bytes = vec![0u8; size + MAX_PATH];
let mut name_info_bytes = vec![0u8; size + MAX_PATH * mem::size_of::<WCHAR>()];
let res = GetFileInformationByHandleEx(
kernel32::GetStdHandle(fd),
GetStdHandle(fd),
FileNameInfo,
&mut *name_info_bytes as *mut _ as *mut c_void,
name_info_bytes.len() as u32);
name_info_bytes.len() as u32,
);
if res == 0 {
return true;
return false;
}
let name_info: FILE_NAME_INFO =
*(name_info_bytes[0..size].as_ptr() as *const FILE_NAME_INFO);
let name_bytes =
&name_info_bytes[size..size + name_info.FileNameLength as usize];
let name_u16 = slice::from_raw_parts(
name_bytes.as_ptr() as *const u16, name_bytes.len() / 2);
let name = OsString::from_wide(name_u16)
.as_os_str().to_string_lossy().into_owned();
name.contains("msys-") || name.contains("-pty")
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_os = "redox")]
pub fn is(stream: Stream) -> bool {
use std::io;
use termion::is_tty;
match stream {
Stream::Stdin => is_tty(&io::stdin()),
Stream::Stdout => is_tty(&io::stdout()),
Stream::Stderr => is_tty(&io::stderr()),
}
}
/// 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};
use super::{Stream, is};
#[test]
#[cfg(windows)]
@ -172,7 +199,7 @@ mod tests {
#[cfg(target_os = "macos")]
fn is_in() {
// macos on travis seems to pipe its input
assert!(!is(Stream::Stdin))
assert!(is(Stream::Stdin))
}
#[test]

2
third_party/rust/fs2/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{".appveyor.yml":"15c5548159ad6ebcc02960bb6a3269e729e772df2733b7d4c7cc1583c413ae45",".travis.yml":"5733d01f7cd27cbdd17a46399103e83eca528727e6cad7f355f6748e772ef916","Cargo.toml":"c257476252f17472f1a78c9fa92b137dc435873797ec1a137aa73043b3ad06a7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"7667acd3dfd050dadccf8b7815435b9108c24c5704944085281beed6a181e220","src/lib.rs":"106e402d1c5ae68558f4e8a3971b646c12f19762363d2cf15c13a1c2aeb1d1e7","src/unix.rs":"67f0244c118cff918f01b6c164dfe604039ce9160a099ba6e4ff86dcf8ec0097","src/windows.rs":"5767d923280998e341504f8d2a015b8b0c3f8b2b1188610aa4c1b6a343da5682"},"package":"9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"}
{"files":{".appveyor.yml":"15c5548159ad6ebcc02960bb6a3269e729e772df2733b7d4c7cc1583c413ae45",".travis.yml":"5733d01f7cd27cbdd17a46399103e83eca528727e6cad7f355f6748e772ef916","Cargo.toml":"c47bb59c1d58dc1eb439331bb140e3a4174370f83b0f0b702d41eb64b27cda3f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"4dda80a0599cc235f8eaf56c33117fcc7cbeb48aece7f7b262f374ee12e3f1f4","src/lib.rs":"38e0f03bb81d76ac8d71b73b00fae648359aa7e1c1b9ba7159cb1b19eb12b987","src/unix.rs":"67f0244c118cff918f01b6c164dfe604039ce9160a099ba6e4ff86dcf8ec0097","src/windows.rs":"4178e02fe48c1148a4d0edcdac6cec8fecf016e636064843b60e7a1d78c817a7"},"package":"9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"}

17
third_party/rust/fs2/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "fs2"
version = "0.4.2"
version = "0.4.3"
authors = ["Dan Burkert <dan@danburkert.com>"]
description = "Cross-platform file locks and file duplication."
documentation = "https://docs.rs/fs2"
@ -21,10 +21,13 @@ license = "MIT/Apache-2.0"
repository = "https://github.com/danburkert/fs2-rs"
[dev-dependencies.tempdir]
version = "0.3"
[target."cfg(windows)".dependencies.winapi]
version = "0.2"
[target."cfg(windows)".dependencies.kernel32-sys]
version = "0.2"
[target."cfg(unix)".dependencies.libc]
version = "0.2.2"
version = "0.2.30"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["handleapi", "processthreadsapi", "winerror", "fileapi", "winbase", "std"]
[badges.appveyor]
repository = "danburkert/fs2-rs"
[badges.travis-ci]
repository = "danburkert/fs2-rs"

8
third_party/rust/fs2/README.md поставляемый
Просмотреть файл

@ -3,10 +3,10 @@
Extended utilities for working with files and filesystems in Rust. `fs2`
requires Rust stable 1.8 or greater.
[Documentation](https://docs.rs/fs2)
[![Linux Status](https://travis-ci.org/danburkert/fs2-rs.svg?branch=master)](https://travis-ci.org/danburkert/fs2-rs)
[![Windows Status](https://ci.appveyor.com/api/projects/status/iuvjv1aaaml0rntt/branch/master?svg=true)](https://ci.appveyor.com/project/danburkert/fs2-rs)
[![Build Status](https://travis-ci.org/danburkert/fs2-rs.svg?branch=master)](https://travis-ci.org/danburkert/fs2-rs)
[![Windows Build status](https://ci.appveyor.com/api/projects/status/iuvjv1aaaml0rntt/branch/master?svg=true)](https://ci.appveyor.com/project/danburkert/fs2-rs/branch/master)
[![Documentation](https://docs.rs/fs2/badge.svg)](https://docs.rs/memmap)
[![Crate](https://img.shields.io/crates/v/fs2.svg)](https://crates.io/crates/memmap)
## Features

8
third_party/rust/fs2/src/lib.rs поставляемый
Просмотреть файл

@ -1,5 +1,11 @@
//! Extended utilities for working with files and filesystems in Rust.
#![doc(html_root_url = "https://docs.rs/fs2/0.4.3")]
#![cfg_attr(test, feature(test))]
#![deny(warnings)]
#[cfg(windows)]
extern crate winapi;
#[cfg(unix)]
mod unix;

80
third_party/rust/fs2/src/windows.rs поставляемый
Просмотреть файл

@ -1,6 +1,3 @@
extern crate kernel32;
extern crate winapi;
use std::fs::File;
use std::io::{Error, Result};
use std::mem;
@ -9,19 +6,30 @@ use std::os::windows::io::{AsRawHandle, FromRawHandle};
use std::path::Path;
use std::ptr;
use winapi::shared::minwindef::{BOOL, DWORD};
use winapi::shared::winerror::ERROR_LOCK_VIOLATION;
use winapi::um::fileapi::{FILE_ALLOCATION_INFO, FILE_STANDARD_INFO, GetDiskFreeSpaceW};
use winapi::um::fileapi::{GetVolumePathNameW, LockFileEx, UnlockFile, SetFileInformationByHandle};
use winapi::um::handleapi::DuplicateHandle;
use winapi::um::minwinbase::{FileAllocationInfo, FileStandardInfo};
use winapi::um::minwinbase::{LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK};
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::winbase::GetFileInformationByHandleEx;
use winapi::um::winnt::DUPLICATE_SAME_ACCESS;
use FsStats;
pub fn duplicate(file: &File) -> Result<File> {
unsafe {
let mut handle = ptr::null_mut();
let current_process = kernel32::GetCurrentProcess();
let ret = kernel32::DuplicateHandle(current_process,
file.as_raw_handle(),
current_process,
&mut handle,
0,
true as winapi::BOOL,
winapi::DUPLICATE_SAME_ACCESS);
let current_process = GetCurrentProcess();
let ret = DuplicateHandle(current_process,
file.as_raw_handle(),
current_process,
&mut handle,
0,
true as BOOL,
DUPLICATE_SAME_ACCESS);
if ret == 0 {
Err(Error::last_os_error())
} else {
@ -32,18 +40,18 @@ pub fn duplicate(file: &File) -> Result<File> {
pub fn allocated_size(file: &File) -> Result<u64> {
unsafe {
let mut info: winapi::FILE_STANDARD_INFO = mem::zeroed();
let mut info: FILE_STANDARD_INFO = mem::zeroed();
let ret = kernel32::GetFileInformationByHandleEx(
let ret = GetFileInformationByHandleEx(
file.as_raw_handle(),
winapi::FileStandardInfo,
FileStandardInfo,
&mut info as *mut _ as *mut _,
mem::size_of::<winapi::FILE_STANDARD_INFO>() as winapi::DWORD);
mem::size_of::<FILE_STANDARD_INFO>() as DWORD);
if ret == 0 {
Err(Error::last_os_error())
} else {
Ok(info.AllocationSize as u64)
Ok(*info.AllocationSize.QuadPart() as u64)
}
}
}
@ -51,13 +59,13 @@ pub fn allocated_size(file: &File) -> Result<u64> {
pub fn allocate(file: &File, len: u64) -> Result<()> {
if try!(allocated_size(file)) < len {
unsafe {
let mut info: winapi::FILE_ALLOCATION_INFO = mem::zeroed();
info.AllocationSize = len as i64;
let ret = kernel32::SetFileInformationByHandle(
let mut info: FILE_ALLOCATION_INFO = mem::zeroed();
*info.AllocationSize.QuadPart_mut() = len as i64;
let ret = SetFileInformationByHandle(
file.as_raw_handle(),
winapi::FileAllocationInfo,
FileAllocationInfo,
&mut info as *mut _ as *mut _,
mem::size_of::<winapi::FILE_ALLOCATION_INFO>() as winapi::DWORD);
mem::size_of::<FILE_ALLOCATION_INFO>() as DWORD);
if ret == 0 {
return Err(Error::last_os_error());
}
@ -75,32 +83,32 @@ pub fn lock_shared(file: &File) -> Result<()> {
}
pub fn lock_exclusive(file: &File) -> Result<()> {
lock_file(file, winapi::LOCKFILE_EXCLUSIVE_LOCK)
lock_file(file, LOCKFILE_EXCLUSIVE_LOCK)
}
pub fn try_lock_shared(file: &File) -> Result<()> {
lock_file(file, winapi::LOCKFILE_FAIL_IMMEDIATELY)
lock_file(file, LOCKFILE_FAIL_IMMEDIATELY)
}
pub fn try_lock_exclusive(file: &File) -> Result<()> {
lock_file(file, winapi::LOCKFILE_EXCLUSIVE_LOCK | winapi::LOCKFILE_FAIL_IMMEDIATELY)
lock_file(file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY)
}
pub fn unlock(file: &File) -> Result<()> {
unsafe {
let ret = kernel32::UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
let ret = UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
if ret == 0 { Err(Error::last_os_error()) } else { Ok(()) }
}
}
pub fn lock_error() -> Error {
Error::from_raw_os_error(winapi::ERROR_LOCK_VIOLATION as i32)
Error::from_raw_os_error(ERROR_LOCK_VIOLATION as i32)
}
fn lock_file(file: &File, flags: winapi::DWORD) -> Result<()> {
fn lock_file(file: &File, flags: DWORD) -> Result<()> {
unsafe {
let mut overlapped = mem::zeroed();
let ret = kernel32::LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
let ret = LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
if ret == 0 { Err(Error::last_os_error()) } else { Ok(()) }
}
}
@ -108,9 +116,9 @@ fn lock_file(file: &File, flags: winapi::DWORD) -> Result<()> {
fn volume_path(path: &Path, volume_path: &mut [u16]) -> Result<()> {
let path_utf8: Vec<u16> = path.as_os_str().encode_wide().chain(Some(0)).collect();
unsafe {
let ret = kernel32::GetVolumePathNameW(path_utf8.as_ptr(),
volume_path.as_mut_ptr(),
volume_path.len() as winapi::DWORD);
let ret = GetVolumePathNameW(path_utf8.as_ptr(),
volume_path.as_mut_ptr(),
volume_path.len() as DWORD);
if ret == 0 { Err(Error::last_os_error()) } else { Ok(())
}
}
@ -125,11 +133,11 @@ pub fn statvfs(path: &Path) -> Result<FsStats> {
let mut bytes_per_sector = 0;
let mut number_of_free_clusters = 0;
let mut total_number_of_clusters = 0;
let ret = kernel32::GetDiskFreeSpaceW(root_path.as_ptr(),
&mut sectors_per_cluster,
&mut bytes_per_sector,
&mut number_of_free_clusters,
&mut total_number_of_clusters);
let ret = GetDiskFreeSpaceW(root_path.as_ptr(),
&mut sectors_per_cluster,
&mut bytes_per_sector,
&mut number_of_free_clusters,
&mut total_number_of_clusters);
if ret == 0 {
Err(Error::last_os_error())
} else {

Просмотреть файл

@ -1 +1 @@
{"files":{".travis.yml":"f0902052851b9d4fec53cea56ce4075686365f0075d64a788fe7ba9f9b98fb8a","Cargo.toml":"b2dbd542893d6b03621c7c65c4fdd7ddb7e6e7c713c610ea3ef5ca88108d3644","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"0241727cb9f7e4ab1ad206ff89ec1dc31034a69b146f076237e8c1b1534b6fe0","README.md":"11cdfba96992fcee089bdcad6682ba5357d8161304d35618ee76abad298ffba7","appveyor.yml":"266ca65d48f02c6a3ce1ba1c0772ef9afece737da03b3176e000b7c32a9ea748","script/doc-upload.cfg":"8cae598ef8592842fa8319b18d515e7a322296490cbdf909b29f5e042a95419e","src/lib.rs":"996474c9c88d9c79865b4923d9739f4c9bc650b29ea70db1c7af43fa59947ed1"},"package":"65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"}
{"files":{".travis.yml":"f0902052851b9d4fec53cea56ce4075686365f0075d64a788fe7ba9f9b98fb8a","Cargo.toml":"3faa730a95b1a21d63ca11b375e9e86793565a573db649df01562bb24a0b1b43","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"0241727cb9f7e4ab1ad206ff89ec1dc31034a69b146f076237e8c1b1534b6fe0","README.md":"11cdfba96992fcee089bdcad6682ba5357d8161304d35618ee76abad298ffba7","appveyor.yml":"266ca65d48f02c6a3ce1ba1c0772ef9afece737da03b3176e000b7c32a9ea748","script/doc-upload.cfg":"8cae598ef8592842fa8319b18d515e7a322296490cbdf909b29f5e042a95419e","src/lib.rs":"282e6beaef56932a3737e1b60e71ddfdf620d35a9cafdfaa1cc59b54f7d43009"},"package":"aad9dfe950c057b1bfe9c1f2aa51583a8468ef2a5baba2ebbe06d775efeb7729"}

34
third_party/rust/msdos_time/Cargo.toml поставляемый
Просмотреть файл

@ -1,20 +1,28 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "msdos_time"
version = "0.1.5"
version = "0.1.6"
authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
license = "MIT OR Apache-2.0"
description = """
Converts an MsDosDateTime (FAT time) to a Tm value
"""
repository = "https://github.com/mvdnes/msdos_time"
description = "Converts an MsDosDateTime (FAT time) to a Tm value\n"
documentation = "https://mvdnes.github.io/rust-docs/msdos_time/msdos_time/"
license = "MIT OR Apache-2.0"
repository = "https://github.com/mvdnes/msdos_time"
[lib]
name = "msdos_time"
[dependencies]
time = "0.1"
[target.'cfg(windows)'.dependencies]
winapi = "0.2"
kernel32-sys = "0.2"
[dependencies.time]
version = "0.1"
[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["winbase", "timezoneapi"]

7
third_party/rust/msdos_time/src/lib.rs поставляемый
Просмотреть файл

@ -6,7 +6,6 @@
//! It is currently mostly used in zip files.
extern crate time;
#[cfg(windows)] extern crate kernel32;
#[cfg(windows)] extern crate winapi;
use std::io;
@ -93,8 +92,10 @@ mod sys {
mod sys {
use super::MsDosDateTime;
use time::{self, Tm};
use winapi::*;
use kernel32::*;
use winapi::shared::minwindef::{WORD, FILETIME};
use winapi::um::minwinbase::SYSTEMTIME;
use winapi::um::timezoneapi::{FileTimeToSystemTime, SystemTimeToFileTime};
use winapi::um::winbase::{DosDateTimeToFileTime, FileTimeToDosDateTime};
use std::io;
pub fn msdos_to_tm(ms: MsDosDateTime) -> Result<Tm, io::Error> {

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"c8a7070b6801c4cc9f410d45819dab3c6efcbe77806a617415289d8de0fbb01b","src/lib.rs":"932b67d85b4176bfb1d7a78b70ec5dd356839158dad22d2e932b88be30925572","src/parking_lot.rs":"aabffbdf465648a1066b24e88c74fbff9cef636354e0bfdd125937f61d771449","src/spinwait.rs":"5aee4a6e8d33eec1b6a81b21ff3b223460d8fa2d37e633b31b8ca27fabe659cb","src/stable.rs":"4562ea9a408bd3917df6d30c8354bf51f46bc69b3360815813730743204adfdc","src/thread_parker/generic.rs":"0c30db3d1c96bd5ef284a4761a829aba8d21fc813b3d1d70b2baf5f00744e006","src/thread_parker/linux.rs":"4e0a142ce3ff59d37e5c452bf57b3481ef00274e8e489ac1a1d11b2f31b473ed","src/thread_parker/unix.rs":"ff5a543f21895c8114bd4f89b5764882beab1f3a37ddbd8fc31c783e1db3f1c1","src/thread_parker/windows/keyed_event.rs":"b54b0855b10ed2c188ce42094c6e4069e92e325f870d0c0f8244bfe2d7811b66","src/thread_parker/windows/mod.rs":"dc5359b10275a4aaee04024c202b115d267e4ea15917546b042c4035c0218136","src/thread_parker/windows/waitaddress.rs":"2da78bfe09e4262a6cd6271d6416a9debdb3fd3abb1993be1c68515952576874","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84","src/word_lock.rs":"6ab156a775c46423bbb7dae520f181dde1747140d52ba995850969498559c7b2"},"package":"6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"}
{"files":{"Cargo.toml":"220144666e4c0a4b3b3235e7d3b10f4f34cb3b8ca292ee19437f23c9a15758de","src/lib.rs":"e80f927665ef24660878e5e4a4ea3c26892c2849889d59aacee6beb59d02020d","src/parking_lot.rs":"2da388ff4c13003fc30531bb6110e4feedac30ad3ce905912e657711a6b0fdad","src/spinwait.rs":"cbd2d2464ef6fa5fb05109bdb3ca588467949dcd4ee9194deafef6004d10215e","src/thread_parker/generic.rs":"0c30db3d1c96bd5ef284a4761a829aba8d21fc813b3d1d70b2baf5f00744e006","src/thread_parker/linux.rs":"1c4c023ebb58fcc16451683c6c8b68311e87ab34537dc17a060ddf5aad02a215","src/thread_parker/unix.rs":"dc6f4af965618cc2d87d3bef6455ba78b44ffe5b38dff9d41fb86e1526cbbcd1","src/thread_parker/windows/keyed_event.rs":"efe64f7bcdfe03049a7b901d2573bc7db1bb73b8ab4a040245423d95c8f9514f","src/thread_parker/windows/mod.rs":"f31eed53f3e402477d80a70a7c6d474c01ba4c9ad952bbe562509448cd3cc1ad","src/thread_parker/windows/waitaddress.rs":"09d1e6a5a6c3f23f375ae4beee946290f7c66d183e69d476ce69b21a4a5aa7af","src/util.rs":"2d07c0c010a857790ae2ed6a1215eeed8af76859e076797ea1ba8dec82169e84","src/word_lock.rs":"692f443c52672c6e88c0cad259cf7c89dc2a1b54aa95eeeea582401b2a7d058d"},"package":"4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"}

12
third_party/rust/parking_lot_core/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "parking_lot_core"
version = "0.2.7"
version = "0.2.14"
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
description = "An advanced API for creating custom synchronization primitives."
documentation = "https://amanieu.github.io/parking_lot/parking_lot_core/index.html"
@ -28,7 +28,7 @@ version = "0.4.5"
optional = true
[dependencies.rand]
version = "0.3"
version = "0.4"
[dependencies.smallvec]
version = "0.6"
@ -41,9 +41,7 @@ optional = true
deadlock_detection = ["petgraph", "thread-id", "backtrace"]
nightly = []
[target."cfg(unix)".dependencies.libc]
version = "0.2.15"
[target."cfg(windows)".dependencies.kernel32-sys]
version = "0.2"
version = "0.2.27"
[target."cfg(windows)".dependencies.winapi]
version = "0.2"
version = "0.3"
features = ["winnt", "ntstatus", "minwindef", "winerror", "winbase", "errhandlingapi", "handleapi"]

22
third_party/rust/parking_lot_core/src/lib.rs поставляемый
Просмотреть файл

@ -11,15 +11,16 @@
//! # The parking lot
//!
//! To keep synchronization primitives small, all thread queuing and suspending
//! functionality is offloaded to the *parking lot*. The idea behind this is
//! based on the Webkit [`WTF::ParkingLot`]
//! (https://webkit.org/blog/6161/locking-in-webkit/) class, which essentially
//! consists of a hash table mapping of lock addresses to queues of parked
//! (sleeping) threads. The Webkit parking lot was itself inspired by Linux
//! [futexes](http://man7.org/linux/man-pages/man2/futex.2.html), but it is more
//! powerful since it allows invoking callbacks while holding a queue lock.
//! functionality is offloaded to the *parking lot*. The idea behind this is based
//! on the Webkit [`WTF::ParkingLot`](https://webkit.org/blog/6161/locking-in-webkit/)
//! class, which essentially consists of a hash table mapping of lock addresses
//! to queues of parked (sleeping) threads. The Webkit parking lot was itself
//! inspired by Linux [futexes](http://man7.org/linux/man-pages/man2/futex.2.html),
//! but it is more powerful since it allows invoking callbacks while holding a
//! queue lock.
//!
//! There are two main operations that can be performed on the parking lot:
//!
//! - *Parking* refers to suspending the thread while simultaneously enqueuing it
//! on a queue keyed by some address.
//! - *Unparking* refers to dequeuing a thread from a queue keyed by some address
@ -37,9 +38,7 @@
//! reference count and the two mutex bits in the same atomic word.
#![warn(missing_docs)]
#![cfg_attr(feature = "nightly", feature(const_fn, thread_local_state))]
#![cfg_attr(all(feature = "nightly", target_os = "linux"), feature(integer_atomics))]
#![cfg_attr(feature = "nightly", feature(asm))]
extern crate rand;
extern crate smallvec;
@ -54,8 +53,6 @@ extern crate thread_id;
#[cfg(unix)]
extern crate libc;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate winapi;
@ -72,9 +69,6 @@ mod thread_parker;
#[path = "thread_parker/generic.rs"]
mod thread_parker;
#[cfg(not(feature = "nightly"))]
mod stable;
mod util;
mod spinwait;
mod word_lock;

Просмотреть файл

@ -5,10 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(feature = "nightly")]
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
#[cfg(not(feature = "nightly"))]
use stable::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::{Duration, Instant};
use std::cell::{Cell, UnsafeCell};
use std::ptr;
@ -890,7 +887,7 @@ unsafe fn unpark_requeue_internal(
let mut link = &bucket_from.queue_head;
let mut current = bucket_from.queue_head.get();
let mut previous = ptr::null();
let mut requeue_threads = ptr::null();
let mut requeue_threads: *const ThreadData = ptr::null();
let mut requeue_threads_tail: *const ThreadData = ptr::null();
let mut wakeup_thread = None;
while !current.is_null() {

Просмотреть файл

@ -5,24 +5,39 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(windows)]
use kernel32;
#[cfg(unix)]
use libc;
#[cfg(windows)]
use winapi;
#[cfg(not(any(windows, unix)))]
use std::thread;
#[cfg(not(feature = "nightly"))]
use std::sync::atomic::{fence, Ordering};
use std::sync::atomic::spin_loop_hint;
// Yields the rest of the current timeslice to the OS
#[cfg(windows)]
#[inline]
fn thread_yield() {
// Note that this is manually defined here rather than using the definition
// through `winapi`. The `winapi` definition comes from the `synchapi`
// header which enables the "synchronization.lib" library. It turns out,
// however that `Sleep` comes from `kernel32.dll` so this activation isn't
// necessary.
//
// This was originally identified in rust-lang/rust where on MinGW the
// libsynchronization.a library pulls in a dependency on a newer DLL not
// present in older versions of Windows. (see rust-lang/rust#49438)
//
// This is a bit of a hack for now and ideally we'd fix MinGW's own import
// libraries, but that'll probably take a lot longer than patching this here
// and avoiding the `synchapi` feature entirely.
extern "system" {
fn Sleep(a: winapi::shared::minwindef::DWORD);
}
unsafe {
// We don't use SwitchToThread here because it doesn't consider all
// threads in the system and the thread we are waiting for may not get
// selected.
kernel32::Sleep(0);
Sleep(0);
}
}
#[cfg(unix)]
@ -38,43 +53,12 @@ fn thread_yield() {
thread::yield_now();
}
// Wastes some CPU time for the given number of iterations, preferably also
// Wastes some CPU time for the given number of iterations,
// using a hint to indicate to the CPU that we are spinning.
#[cfg(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64")))]
#[inline]
fn cpu_relax(iterations: u32) {
for _ in 0..iterations {
unsafe {
asm!("pause" ::: "memory" : "volatile");
}
}
}
#[cfg(all(feature = "nightly", target_arch = "aarch64"))]
#[inline]
fn cpu_relax(iterations: u32) {
for _ in 0..iterations {
unsafe {
asm!("yield" ::: "memory" : "volatile");
}
}
}
#[cfg(all(feature = "nightly",
not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"))))]
#[inline]
fn cpu_relax(iterations: u32) {
for _ in 0..iterations {
unsafe {
asm!("" ::: "memory" : "volatile");
}
}
}
#[cfg(not(feature = "nightly"))]
#[inline]
fn cpu_relax(iterations: u32) {
// This is a bit tricky: we rely on the fact that LLVM doesn't optimize
// atomic operations and effectively treats them as volatile.
for _ in 0..iterations {
fence(Ordering::SeqCst);
spin_loop_hint()
}
}
@ -85,14 +69,6 @@ pub struct SpinWait {
impl SpinWait {
/// Creates a new `SpinWait`.
#[cfg(feature = "nightly")]
#[inline]
pub const fn new() -> SpinWait {
SpinWait { counter: 0 }
}
/// Creates a new `SpinWait`.
#[cfg(not(feature = "nightly"))]
#[inline]
pub fn new() -> SpinWait {
SpinWait { counter: 0 }

Просмотреть файл

@ -1,87 +0,0 @@
// Copyright 2016 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#![allow(dead_code)]
use std::sync::atomic;
// Re-export this for convenience
pub use std::sync::atomic::{fence, Ordering};
// Wrapper around AtomicUsize for non-nightly which has usable compare_exchange
// and compare_exchange_weak methods.
pub struct AtomicUsize(atomic::AtomicUsize);
pub use self::AtomicUsize as AtomicU8;
// Constants for static initialization
pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize(atomic::ATOMIC_USIZE_INIT);
pub use self::ATOMIC_USIZE_INIT as ATOMIC_U8_INIT;
impl AtomicUsize {
#[inline]
pub fn new(val: usize) -> AtomicUsize {
AtomicUsize(atomic::AtomicUsize::new(val))
}
#[inline]
pub fn load(&self, order: Ordering) -> usize {
self.0.load(order)
}
#[inline]
pub fn store(&self, val: usize, order: Ordering) {
self.0.store(val, order);
}
#[inline]
pub fn swap(&self, val: usize, order: Ordering) -> usize {
self.0.swap(val, order)
}
#[inline]
pub fn fetch_add(&self, val: usize, order: Ordering) -> usize {
self.0.fetch_add(val, order)
}
#[inline]
pub fn fetch_sub(&self, val: usize, order: Ordering) -> usize {
self.0.fetch_sub(val, order)
}
#[inline]
pub fn fetch_and(&self, val: usize, order: Ordering) -> usize {
self.0.fetch_and(val, order)
}
#[inline]
pub fn fetch_or(&self, val: usize, order: Ordering) -> usize {
self.0.fetch_or(val, order)
}
#[inline]
pub fn compare_exchange(
&self,
old: usize,
new: usize,
order: Ordering,
_: Ordering,
) -> Result<usize, usize> {
let res = self.0.compare_and_swap(old, new, order);
if res == old {
Ok(res)
} else {
Err(res)
}
}
#[inline]
pub fn compare_exchange_weak(
&self,
old: usize,
new: usize,
order: Ordering,
_: Ordering,
) -> Result<usize, usize> {
let res = self.0.compare_and_swap(old, new, order);
if res == old {
Ok(res)
} else {
Err(res)
}
}
}

Просмотреть файл

@ -9,19 +9,19 @@ use std::sync::atomic::{AtomicI32, Ordering};
use std::time::Instant;
use libc;
#[cfg(target_arch = "x86")]
const SYS_FUTEX: libc::c_long = 240;
#[cfg(target_arch = "x86_64")]
const SYS_FUTEX: libc::c_long = 202;
#[cfg(target_arch = "arm")]
const SYS_FUTEX: libc::c_long = 240;
#[cfg(target_arch = "aarch64")]
const SYS_FUTEX: libc::c_long = 98;
const FUTEX_WAIT: i32 = 0;
const FUTEX_WAKE: i32 = 1;
const FUTEX_PRIVATE: i32 = 128;
// x32 Linux uses a non-standard type for tv_nsec in timespec.
// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437
#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
#[allow(non_camel_case_types)]
type tv_nsec_t = i64;
#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
#[allow(non_camel_case_types)]
type tv_nsec_t = libc::c_long;
// Helper type for putting a thread to sleep until some other thread wakes it up
pub struct ThreadParker {
futex: AtomicI32,
@ -49,7 +49,13 @@ impl ThreadParker {
// been added to the queue, after unlocking the queue.
pub unsafe fn park(&self) {
while self.futex.load(Ordering::Acquire) != 0 {
let r = libc::syscall(SYS_FUTEX, &self.futex, FUTEX_WAIT | FUTEX_PRIVATE, 1, 0);
let r = libc::syscall(
libc::SYS_futex,
&self.futex,
FUTEX_WAIT | FUTEX_PRIVATE,
1,
0,
);
debug_assert!(r == 0 || r == -1);
if r == -1 {
debug_assert!(
@ -77,9 +83,15 @@ impl ThreadParker {
}
let ts = libc::timespec {
tv_sec: diff.as_secs() as libc::time_t,
tv_nsec: diff.subsec_nanos() as libc::c_long,
tv_nsec: diff.subsec_nanos() as tv_nsec_t,
};
let r = libc::syscall(SYS_FUTEX, &self.futex, FUTEX_WAIT | FUTEX_PRIVATE, 1, &ts);
let r = libc::syscall(
libc::SYS_futex,
&self.futex,
FUTEX_WAIT | FUTEX_PRIVATE,
1,
&ts,
);
debug_assert!(r == 0 || r == -1);
if r == -1 {
debug_assert!(
@ -116,7 +128,7 @@ impl UnparkHandle {
pub unsafe fn unpark(self) {
// The thread data may have been freed at this point, but it doesn't
// matter since the syscall will just return EFAULT in that case.
let r = libc::syscall(SYS_FUTEX, self.futex, FUTEX_WAKE | FUTEX_PRIVATE, 1);
let r = libc::syscall(libc::SYS_futex, self.futex, FUTEX_WAKE | FUTEX_PRIVATE, 1);
debug_assert!(r == 0 || r == 1 || r == -1);
if r == -1 {
debug_assert_eq!(*libc::__errno_location(), libc::EFAULT);

Просмотреть файл

@ -218,10 +218,8 @@ unsafe fn timeout_to_timespec(timeout: Duration) -> Option<libc::timespec> {
sec = sec.and_then(|sec| sec.checked_add(1));
}
sec.map(|sec| {
libc::timespec {
tv_nsec: nsec,
tv_sec: sec,
}
sec.map(|sec| libc::timespec {
tv_nsec: nsec,
tv_sec: sec,
})
}

Просмотреть файл

@ -5,15 +5,18 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(feature = "nightly")]
use std::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(feature = "nightly"))]
use stable::{AtomicUsize, Ordering};
use std::time::Instant;
use std::ptr;
use std::mem;
use winapi;
use kernel32;
use winapi::shared::minwindef::{TRUE, ULONG};
use winapi::shared::ntdef::NTSTATUS;
use winapi::shared::ntstatus::{STATUS_SUCCESS, STATUS_TIMEOUT};
use winapi::um::handleapi::CloseHandle;
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
use winapi::um::winnt::{ACCESS_MASK, GENERIC_READ, GENERIC_WRITE, LPCSTR};
use winapi::um::winnt::{BOOLEAN, HANDLE, LARGE_INTEGER, PHANDLE, PLARGE_INTEGER, PVOID};
const STATE_UNPARKED: usize = 0;
const STATE_PARKED: usize = 1;
@ -21,76 +24,71 @@ const STATE_TIMED_OUT: usize = 2;
#[allow(non_snake_case)]
pub struct KeyedEvent {
handle: winapi::HANDLE,
handle: HANDLE,
NtReleaseKeyedEvent: extern "system" fn(
EventHandle: winapi::HANDLE,
Key: winapi::PVOID,
Alertable: winapi::BOOLEAN,
Timeout: winapi::PLARGE_INTEGER,
) -> winapi::NTSTATUS,
EventHandle: HANDLE,
Key: PVOID,
Alertable: BOOLEAN,
Timeout: PLARGE_INTEGER,
) -> NTSTATUS,
NtWaitForKeyedEvent: extern "system" fn(
EventHandle: winapi::HANDLE,
Key: winapi::PVOID,
Alertable: winapi::BOOLEAN,
Timeout: winapi::PLARGE_INTEGER,
) -> winapi::NTSTATUS,
EventHandle: HANDLE,
Key: PVOID,
Alertable: BOOLEAN,
Timeout: PLARGE_INTEGER,
) -> NTSTATUS,
}
impl KeyedEvent {
unsafe fn wait_for(
&self,
key: winapi::PVOID,
timeout: winapi::PLARGE_INTEGER,
) -> winapi::NTSTATUS {
unsafe fn wait_for(&self, key: PVOID, timeout: PLARGE_INTEGER) -> NTSTATUS {
(self.NtWaitForKeyedEvent)(self.handle, key, 0, timeout)
}
unsafe fn release(&self, key: winapi::PVOID) -> winapi::NTSTATUS {
unsafe fn release(&self, key: PVOID) -> NTSTATUS {
(self.NtReleaseKeyedEvent)(self.handle, key, 0, ptr::null_mut())
}
#[allow(non_snake_case)]
pub unsafe fn create() -> Option<KeyedEvent> {
let ntdll = kernel32::GetModuleHandleA(b"ntdll.dll\0".as_ptr() as winapi::LPCSTR);
let ntdll = GetModuleHandleA(b"ntdll.dll\0".as_ptr() as LPCSTR);
if ntdll.is_null() {
return None;
}
let NtCreateKeyedEvent =
kernel32::GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr() as winapi::LPCSTR);
let NtCreateKeyedEvent = GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr() as LPCSTR);
if NtCreateKeyedEvent.is_null() {
return None;
}
let NtReleaseKeyedEvent =
kernel32::GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr() as winapi::LPCSTR);
GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr() as LPCSTR);
if NtReleaseKeyedEvent.is_null() {
return None;
}
let NtWaitForKeyedEvent =
kernel32::GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr() as winapi::LPCSTR);
GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr() as LPCSTR);
if NtWaitForKeyedEvent.is_null() {
return None;
}
let NtCreateKeyedEvent: extern "system" fn(
KeyedEventHandle: winapi::PHANDLE,
DesiredAccess: winapi::ACCESS_MASK,
ObjectAttributes: winapi::PVOID,
Flags: winapi::ULONG,
) -> winapi::NTSTATUS = mem::transmute(NtCreateKeyedEvent);
KeyedEventHandle: PHANDLE,
DesiredAccess: ACCESS_MASK,
ObjectAttributes: PVOID,
Flags: ULONG,
) -> NTSTATUS = mem::transmute(NtCreateKeyedEvent);
let mut handle = mem::uninitialized();
let status = NtCreateKeyedEvent(
&mut handle,
winapi::GENERIC_READ | winapi::GENERIC_WRITE,
GENERIC_READ | GENERIC_WRITE,
ptr::null_mut(),
0,
);
if status != winapi::STATUS_SUCCESS {
if status != STATUS_SUCCESS {
return None;
}
Some(KeyedEvent {
handle: handle,
handle,
NtReleaseKeyedEvent: mem::transmute(NtReleaseKeyedEvent),
NtWaitForKeyedEvent: mem::transmute(NtWaitForKeyedEvent),
})
@ -105,8 +103,8 @@ impl KeyedEvent {
}
pub unsafe fn park(&'static self, key: &AtomicUsize) {
let status = self.wait_for(key as *const _ as winapi::PVOID, ptr::null_mut());
debug_assert_eq!(status, winapi::STATUS_SUCCESS);
let status = self.wait_for(key as *const _ as PVOID, ptr::null_mut());
debug_assert_eq!(status, STATUS_SUCCESS);
}
pub unsafe fn park_until(&'static self, key: &AtomicUsize, timeout: Instant) -> bool {
@ -124,14 +122,14 @@ impl KeyedEvent {
// NT uses a timeout in units of 100ns. We use a negative value to
// indicate a relative timeout based on a monotonic clock.
let mut nt_timeout: LARGE_INTEGER = mem::zeroed();
let diff = timeout - now;
let nt_timeout = (diff.as_secs() as winapi::LARGE_INTEGER)
let value = (diff.as_secs() as i64)
.checked_mul(-10000000)
.and_then(|x| {
x.checked_sub((diff.subsec_nanos() as winapi::LARGE_INTEGER + 99) / 100)
});
let mut nt_timeout = match nt_timeout {
Some(x) => x,
.and_then(|x| x.checked_sub((diff.subsec_nanos() as i64 + 99) / 100));
match value {
Some(x) => *nt_timeout.QuadPart_mut() = x,
None => {
// Timeout overflowed, just sleep indefinitely
self.park(key);
@ -139,11 +137,11 @@ impl KeyedEvent {
}
};
let status = self.wait_for(key as *const _ as winapi::PVOID, &mut nt_timeout);
if status == winapi::STATUS_SUCCESS {
let status = self.wait_for(key as *const _ as PVOID, &mut nt_timeout);
if status == STATUS_SUCCESS {
return true;
}
debug_assert_eq!(status, winapi::STATUS_TIMEOUT);
debug_assert_eq!(status, STATUS_TIMEOUT);
// If another thread unparked us, we need to call NtWaitForKeyedEvent
// otherwise that thread will stay stuck at NtReleaseKeyedEvent.
@ -173,8 +171,8 @@ impl KeyedEvent {
impl Drop for KeyedEvent {
fn drop(&mut self) {
unsafe {
let ok = kernel32::CloseHandle(self.handle);
debug_assert_eq!(ok, winapi::TRUE);
let ok = CloseHandle(self.handle);
debug_assert_eq!(ok, TRUE);
}
}
}
@ -192,8 +190,8 @@ impl UnparkHandle {
// released to avoid blocking the queue for too long.
pub unsafe fn unpark(self) {
if !self.key.is_null() {
let status = self.keyed_event.release(self.key as winapi::PVOID);
debug_assert_eq!(status, winapi::STATUS_SUCCESS);
let status = self.keyed_event.release(self.key as PVOID);
debug_assert_eq!(status, STATUS_SUCCESS);
}
}
}

Просмотреть файл

@ -5,10 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(feature = "nightly")]
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
#[cfg(not(feature = "nightly"))]
use stable::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Instant;
mod keyed_event;

Просмотреть файл

@ -5,24 +5,27 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(feature = "nightly")]
use std::sync::atomic::{AtomicUsize, Ordering};
#[cfg(not(feature = "nightly"))]
use stable::{AtomicUsize, Ordering};
use std::time::Instant;
use std::mem;
use winapi;
use kernel32;
use winapi::shared::basetsd::SIZE_T;
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::shared::winerror::ERROR_TIMEOUT;
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
use winapi::um::winbase::INFINITE;
use winapi::um::winnt::{LPCSTR, PVOID};
#[allow(non_snake_case)]
pub struct WaitAddress {
WaitOnAddress: extern "system" fn(
Address: winapi::PVOID,
CompareAddress: winapi::PVOID,
AddressSize: winapi::SIZE_T,
dwMilliseconds: winapi::DWORD,
) -> winapi::BOOL,
WakeByAddressSingle: extern "system" fn(Address: winapi::PVOID),
Address: PVOID,
CompareAddress: PVOID,
AddressSize: SIZE_T,
dwMilliseconds: DWORD,
) -> BOOL,
WakeByAddressSingle: extern "system" fn(Address: PVOID),
}
impl WaitAddress {
@ -30,21 +33,17 @@ impl WaitAddress {
pub unsafe fn create() -> Option<WaitAddress> {
// MSDN claims that that WaitOnAddress and WakeByAddressSingle are
// located in kernel32.dll, but they are lying...
let synch_dll = kernel32::GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr()
as winapi::LPCSTR);
let synch_dll = GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr() as LPCSTR);
if synch_dll.is_null() {
return None;
}
let WaitOnAddress =
kernel32::GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr() as winapi::LPCSTR);
let WaitOnAddress = GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr() as LPCSTR);
if WaitOnAddress.is_null() {
return None;
}
let WakeByAddressSingle = kernel32::GetProcAddress(
synch_dll,
b"WakeByAddressSingle\0".as_ptr() as winapi::LPCSTR,
);
let WakeByAddressSingle =
GetProcAddress(synch_dll, b"WakeByAddressSingle\0".as_ptr() as LPCSTR);
if WakeByAddressSingle.is_null() {
return None;
}
@ -66,12 +65,12 @@ impl WaitAddress {
while key.load(Ordering::Acquire) != 0 {
let cmp = 1usize;
let r = (self.WaitOnAddress)(
key as *const _ as winapi::PVOID,
&cmp as *const _ as winapi::PVOID,
mem::size_of::<usize>() as winapi::SIZE_T,
winapi::INFINITE,
key as *const _ as PVOID,
&cmp as *const _ as PVOID,
mem::size_of::<usize>() as SIZE_T,
INFINITE,
);
debug_assert!(r == winapi::TRUE);
debug_assert!(r == TRUE);
}
}
@ -84,26 +83,24 @@ impl WaitAddress {
let diff = timeout - now;
let timeout = diff.as_secs()
.checked_mul(1000)
.and_then(|x| {
x.checked_add((diff.subsec_nanos() as u64 + 999999) / 1000000)
})
.and_then(|x| x.checked_add((diff.subsec_nanos() as u64 + 999999) / 1000000))
.map(|ms| {
if ms > <winapi::DWORD>::max_value() as u64 {
winapi::INFINITE
if ms > <DWORD>::max_value() as u64 {
INFINITE
} else {
ms as winapi::DWORD
ms as DWORD
}
})
.unwrap_or(winapi::INFINITE);
.unwrap_or(INFINITE);
let cmp = 1usize;
let r = (self.WaitOnAddress)(
key as *const _ as winapi::PVOID,
&cmp as *const _ as winapi::PVOID,
mem::size_of::<usize>() as winapi::SIZE_T,
key as *const _ as PVOID,
&cmp as *const _ as PVOID,
mem::size_of::<usize>() as SIZE_T,
timeout,
);
if r == winapi::FALSE {
debug_assert_eq!(kernel32::GetLastError(), winapi::ERROR_TIMEOUT);
if r == FALSE {
debug_assert_eq!(GetLastError(), ERROR_TIMEOUT);
}
}
true
@ -120,7 +117,6 @@ impl WaitAddress {
}
}
// Handle for a thread that is about to be unparked. We need to mark the thread
// as unparked while holding the queue lock, but we delay the actual unparking
// until after the queue lock is released.
@ -133,6 +129,6 @@ impl UnparkHandle {
// Wakes up the parked thread. This should be called after the queue lock is
// released to avoid blocking the queue for too long.
pub unsafe fn unpark(self) {
(self.waitaddress.WakeByAddressSingle)(self.key as winapi::PVOID);
(self.waitaddress.WakeByAddressSingle)(self.key as PVOID);
}
}

Просмотреть файл

@ -5,10 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#[cfg(feature = "nightly")]
use std::sync::atomic::{fence, AtomicUsize, Ordering};
#[cfg(not(feature = "nightly"))]
use stable::{fence, AtomicUsize, Ordering};
use std::ptr;
use std::mem;
use std::cell::Cell;

1
third_party/rust/redox_termios/.cargo-checksum.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"files":{"Cargo.toml":"e7d20b4132bf22e2c98a5f846f8c16e7628a9181d485fd131b97127ea8719130","LICENSE":"cb46b697c3fd9d27d7bfe1b1ad48f8a58a284984504c6eb215ae2164538df7cb","README.md":"c62ac3d33174db7977cfc7fc77605885f5445c0c9c7d1310dcbe3564c2854edb","src/lib.rs":"af5bc7c59c695880fef0352f9e0f9e9f8682c262a9b1c0fce725b10553647b4e"},"package":"7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"}

26
third_party/rust/redox_termios/Cargo.toml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,26 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "redox_termios"
version = "0.1.1"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
description = "A Rust library to access Redox termios functions"
documentation = "https://docs.rs/redox_termios"
license = "MIT"
repository = "https://github.com/redox-os/termios"
[lib]
name = "redox_termios"
path = "src/lib.rs"
[dependencies.redox_syscall]
version = "0.1"

21
third_party/rust/redox_termios/LICENSE поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Redox OS
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.

2
third_party/rust/redox_termios/README.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
# termios
Redox Rust termios library

218
third_party/rust/redox_termios/src/lib.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,218 @@
#![allow(non_camel_case_types)]
#![no_std]
extern crate syscall;
use core::{mem, slice};
use core::ops::{Deref, DerefMut};
pub type tcflag_t = u32;
pub type cc_t = u8;
/* c_cc { */
pub const VEOF: usize = 0;
pub const VEOL: usize = 1;
pub const VEOL2: usize = 2;
pub const VERASE: usize = 3;
pub const VWERASE: usize = 4;
pub const VKILL: usize = 5;
pub const VREPRINT: usize = 6;
pub const VSWTC: usize = 7;
pub const VINTR: usize = 8;
pub const VQUIT: usize = 9;
pub const VSUSP: usize = 10;
pub const VSTART: usize = 12;
pub const VSTOP: usize = 13;
pub const VLNEXT: usize = 14;
pub const VDISCARD: usize = 15;
pub const VMIN: usize = 16;
pub const VTIME: usize = 17;
pub const NCCS: usize = 32;
/* } c_cc */
/* c_iflag { */
pub const IGNBRK: tcflag_t = 0o000001;
pub const BRKINT: tcflag_t = 0o000002;
pub const IGNPAR: tcflag_t = 0o000004;
pub const PARMRK: tcflag_t = 0o000010;
pub const INPCK: tcflag_t = 0o000020;
pub const ISTRIP: tcflag_t = 0o000040;
pub const INLCR: tcflag_t = 0o000100;
pub const IGNCR: tcflag_t = 0o000200;
pub const ICRNL: tcflag_t = 0o000400;
pub const IXON: tcflag_t = 0o001000;
pub const IXOFF: tcflag_t = 0o002000;
/* } c_iflag */
/* c_oflag { */
pub const OPOST: tcflag_t = 0o000001;
pub const ONLCR: tcflag_t = 0o000002;
pub const OLCUC: tcflag_t = 0o000004;
pub const OCRNL: tcflag_t = 0o000010;
pub const ONOCR: tcflag_t = 0o000020;
pub const ONLRET: tcflag_t = 0o000040;
pub const OFILL: tcflag_t = 0o0000100;
pub const OFDEL: tcflag_t = 0o0000200;
/* } c_oflag */
/* c_cflag { */
pub const B0: tcflag_t = 0o000000;
pub const B50: tcflag_t = 0o000001;
pub const B75: tcflag_t = 0o000002;
pub const B110: tcflag_t = 0o000003;
pub const B134: tcflag_t = 0o000004;
pub const B150: tcflag_t = 0o000005;
pub const B200: tcflag_t = 0o000006;
pub const B300: tcflag_t = 0o000007;
pub const B600: tcflag_t = 0o000010;
pub const B1200: tcflag_t = 0o000011;
pub const B1800: tcflag_t = 0o000012;
pub const B2400: tcflag_t = 0o000013;
pub const B4800: tcflag_t = 0o000014;
pub const B9600: tcflag_t = 0o000015;
pub const B19200: tcflag_t = 0o000016;
pub const B38400: tcflag_t = 0o000017;
pub const B57600: tcflag_t = 0o0020;
pub const B115200: tcflag_t = 0o0021;
pub const B230400: tcflag_t = 0o0022;
pub const B460800: tcflag_t = 0o0023;
pub const B500000: tcflag_t = 0o0024;
pub const B576000: tcflag_t = 0o0025;
pub const B921600: tcflag_t = 0o0026;
pub const B1000000: tcflag_t = 0o0027;
pub const B1152000: tcflag_t = 0o0030;
pub const B1500000: tcflag_t = 0o0031;
pub const B2000000: tcflag_t = 0o0032;
pub const B2500000: tcflag_t = 0o0033;
pub const B3000000: tcflag_t = 0o0034;
pub const B3500000: tcflag_t = 0o0035;
pub const B4000000: tcflag_t = 0o0036;
pub const __MAX_BAUD: tcflag_t = B4000000;
pub const CSIZE: tcflag_t = 0o0001400;
pub const CS5: tcflag_t = 0o0000000;
pub const CS6: tcflag_t = 0o0000400;
pub const CS7: tcflag_t = 0o0001000;
pub const CS8: tcflag_t = 0o0001400;
pub const CSTOPB: tcflag_t = 0o0002000;
pub const CREAD: tcflag_t = 0o0004000;
pub const PARENB: tcflag_t = 0o0010000;
pub const PARODD: tcflag_t = 0o0020000;
pub const HUPCL: tcflag_t = 0o0040000;
pub const CLOCAL: tcflag_t = 0o0100000;
/* } c_clfag */
/* c_lflag { */
pub const ISIG: tcflag_t = 0x00000080;
pub const ICANON: tcflag_t = 0x00000100;
pub const ECHO: tcflag_t = 0x00000008;
pub const ECHOE: tcflag_t = 0x00000002;
pub const ECHOK: tcflag_t = 0x00000004;
pub const ECHONL: tcflag_t = 0x00000010;
pub const NOFLSH: tcflag_t = 0x80000000;
pub const TOSTOP: tcflag_t = 0x00400000;
pub const IEXTEN: tcflag_t = 0x00000400;
/* } c_lflag */
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Termios {
pub c_iflag: tcflag_t,
pub c_oflag: tcflag_t,
pub c_cflag: tcflag_t,
pub c_lflag: tcflag_t,
pub c_cc: [cc_t; 32]
}
impl Default for Termios {
fn default() -> Termios {
let mut termios = Termios {
c_iflag: ICRNL | IXON,
c_oflag: OPOST | ONLCR,
c_cflag: B38400 | CS8 | CREAD | HUPCL,
c_lflag: ISIG | ICANON | ECHO | ECHOE | ECHOK | IEXTEN,
c_cc: [0; 32]
};
{
let mut cc = |i: usize, b: cc_t| {
termios.c_cc[i] = b;
};
cc(VEOF, 0o004); // CTRL-D
cc(VEOL, 0o000); // NUL
cc(VEOL2, 0o000); // NUL
cc(VERASE, 0o177); // DEL
cc(VWERASE, 0o027); // CTRL-W
cc(VKILL, 0o025); // CTRL-U
cc(VREPRINT, 0o022);// CTRL-R
cc(VINTR, 0o003); // CTRL-C
cc(VQUIT, 0o034); // CTRL-\
cc(VSUSP, 0o032); // CTRL-Z
cc(VSTART, 0o021); // CTRL-Q
cc(VSTOP, 0o023); // CTRL-S
cc(VLNEXT, 0o026); // CTRL-V
cc(VDISCARD, 0o017);// CTRL-U
cc(VMIN, 1);
cc(VTIME, 0);
}
termios
}
}
impl Termios {
pub fn make_raw(&mut self) {
self.c_iflag &= !(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
self.c_oflag &= !OPOST;
self.c_cflag &= !(CSIZE | PARENB);
self.c_cflag |= CS8;
self.c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
}
}
impl Deref for Termios {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const Termios as *const u8, mem::size_of::<Termios>()) as &[u8]
}
}
}
impl DerefMut for Termios {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut Termios as *mut u8, mem::size_of::<Termios>()) as &mut [u8]
}
}
}
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct Winsize {
pub ws_row: u16,
pub ws_col: u16
}
impl Deref for Winsize {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const Winsize as *const u8, mem::size_of::<Winsize>()) as &[u8]
}
}
}
impl DerefMut for Winsize {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut Winsize as *mut u8, mem::size_of::<Winsize>()) as &mut [u8]
}
}
}

1
third_party/rust/termion/.cargo-checksum.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"files":{".travis.yml":"5ac96d0b7956730882c41fa620f04388ff3100205fac606ae3bd8353661794a9","Cargo.toml":"b061b09fc4bbf280c932f4b7d3c4641a5a2f0eb8c57029de7d0e4441888a1765","LICENSE":"6252f0c8d4a0df9b2dc0c6464cb2489dbe8859b0eb727e19c14e6af1ee432394","README.md":"71cac837cd6f1326865add7dd565ea2738756648de87fc2d35d0cf22a2512630","examples/alternate_screen.rs":"37978473e77331ad613843049b4f355e32a51a7b8ece9ee52efe02997391e4ec","examples/alternate_screen_raw.rs":"bfd68f86de929952aaed7e1e7175694d771be2a0b0943092fec4f58bf7473dc3","examples/async.rs":"2fdf5fe69edd3b407de3c1c8caf23f9e19a7f25b55578c84838e4305a9857c42","examples/click.rs":"bb3a76f4817292a82b00d92281a86a400038a8282b6c9d41a34dbaca84fb0caf","examples/color.rs":"808219c739677b9f2645e0ae7975a4bd8981255ed8bfc9df2413f8f8059bbda5","examples/commie.rs":"7bb00a7f669c74ccb3a9e9c8ff39fd01aa984f7c38983e5c1cfe6940f90b0c73","examples/detect_color.rs":"764d6465c6879efc38aca8d980a433bac058c1f03d578ac764437af289931824","examples/is_tty.rs":"9a76bdfb11ea84e7b25f6efc06c8d3a8d13a03448bd826bd283b935852f409c7","examples/keys.rs":"cd89f31a21062486e7c014843b360cee35dcee07d8022fc0282eddc48e46bdc7","examples/mouse.rs":"eeccab8043cec987e40e175f03b63c9c6cdc7bcd5808f51a57d0e970cae1c04e","examples/rainbow.rs":"c015176eba7c7a81c6d302d6fc41abea8817935ee804af59d64e3098b127c333","examples/read.rs":"b95fb9b02d2cbf978096825b18ffa25772467df3417c3f3cf5edfe811181a67a","examples/rustc_fun.rs":"f39bd8dbe224cb592d58a0084d15d1eb80d86eade72423fe51acc455e0e1ea68","examples/simple.rs":"eac1aab0d251f884a7d7d7d0d017b6ac4854b38ffcfb244d6a80102ed7a981ab","examples/size.rs":"ae89e7b98a29040f1b641d75226f5738770e2e043cee3f49649accaaeaabbeac","examples/truecolor.rs":"67128ef4870e9e742b1090fa129097484633d82fb015009b1760295f7a24e6af","logo.svg":"09b7a6bca3185acddc217d3d3baab23627c5e03a192f815116e71cf00cb31ddc","src/async.rs":"f0126ff1ee18c8c355bb86deb76e852c5f6bb47fbbaa286cce3d38cb656dfa28","src/clear.rs":"a9cf9a9f92cef2430239dc33d8ecb4e291c46b650f1f71b63248d0a0215768ba","src/color.rs":"2f2c8f6f572b22fc40a62d0502fc192c843dbeed21bb7ecc1954e881d41c9a1c","src/cursor.rs":"9132638902c4e42728efaac247ca363c1bda3e80d6c3cc20bc6928b9fe9a1d10","src/event.rs":"321c0a73cd6208a8ef17083d1bd907e308d5197cfd198a3f1ed1498b7e2b8055","src/input.rs":"a3e226a53b6536aef89d66a1e4974453389c86116c175c3efc4fc4bb9b41d60c","src/lib.rs":"549beee5f5a6fb7954af37df7fa598ba6c716f2287123e09d300e048af2a70ac","src/macros.rs":"8611f257ffc046ed25870611f1353a96e17a5671efbe2bbf33aae525b53a4df3","src/raw.rs":"6949b164cf1bd0a4146c169b948100ed626b3e0747df15a54b7f41853d348ea1","src/screen.rs":"19a9a2c42abe2afdb75d4850dc6ee54f33808f6da7f59644668e683418cbce4a","src/scroll.rs":"d0ba08663127e09e111fafc9f84c1fe42662b74f9acbca6b5d26d0b335ee4136","src/style.rs":"b2c805d710cf553835a01482f014aff7395f79d5f71f1e5029ae679e002ac010","src/sys/redox/attr.rs":"834d21cc17090fb7989906ce885f4efed252d65086c05e32ecc05792eb69151a","src/sys/redox/mod.rs":"4066ba97f10c8b87a6ebf32257c89d36338366e1230781aeb5fca98bd5f5bae0","src/sys/redox/size.rs":"b892d0053f40c343eeb40ea06a10fb77abd2758eecda6a7cccb0b07c07fff6eb","src/sys/redox/tty.rs":"3369a6ee3a21400053a023c01912bdd92b709915b833e25e557214dfad425224","src/sys/unix/attr.rs":"7b17e4841eab69533d2561764506211e2967cd4d7464a309e6d2832473b75dd7","src/sys/unix/mod.rs":"8ddebce9f5b2dbbd419519beb7d41f6d6a7eaed40a70cd0d0676ee893549f7a7","src/sys/unix/size.rs":"19f3de9ced2b329a50a9752ba1be406b25648b298c1a2b3e83582a34e21d2998","src/sys/unix/tty.rs":"eeea0279f76838aa4badd807325403d32ab359334cf59f9574191afcbe86c811"},"package":"689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"}

14
third_party/rust/termion/.travis.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
language: rust
cache: cargo
rust:
- stable
- beta
- nightly
os:
- linux
- osx
script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then FAKETTY="script -q /dev/null"; fi
- $FAKETTY cargo build --verbose
- $FAKETTY cargo test --verbose
- $FAKETTY cargo test --release --verbose

17
third_party/rust/termion/Cargo.toml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
[package]
name = "termion"
version = "1.5.1"
authors = ["ticki <Ticki@users.noreply.github.com>", "gycos <alexandre.bury@gmail.com>", "IGI-111 <igi-111@protonmail.com>"]
description = "A bindless library for manipulating terminals."
repository = "https://github.com/ticki/termion"
documentation = "https://docs.rs/termion"
license = "MIT"
keywords = ["tty", "color", "terminal", "password", "tui"]
exclude = ["target", "CHANGELOG.md", "image.png", "Cargo.lock"]
[target.'cfg(not(target_os = "redox"))'.dependencies]
libc = "0.2.8"
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"
redox_termios = "0.1"

21
third_party/rust/termion/LICENSE поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Ticki
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.

181
third_party/rust/termion/README.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,181 @@
<p align="center">
<img alt="Termion logo" src="https://rawgit.com/ticki/termion/master/logo.svg" />
</p>
[![Build Status](https://travis-ci.org/ticki/termion.svg?branch=master)](https://travis-ci.org/ticki/termion) [![Latest Version](https://img.shields.io/crates/v/termion.svg)](https://crates.io/crates/termion) | [Documentation](https://docs.rs/termion) | [Examples](https://github.com/Ticki/termion/tree/master/examples) | [Changelog](https://github.com/Ticki/termion/tree/master/CHANGELOG.md) | [Tutorial](http://ticki.github.io/blog/making-terminal-applications-in-rust-with-termion/)
|----|----|----|----|----
**Termion** is a pure Rust, bindless library for low-level handling, manipulating
and reading information about terminals. This provides a full-featured
alternative to Termbox.
Termion aims to be simple and yet expressive. It is bindless, meaning that it
is not a front-end to some other library (e.g., ncurses or termbox), but a
standalone library directly talking to the TTY.
Termion is quite convenient, due to its complete coverage of essential TTY
features, providing one consistent API. Termion is rather low-level containing
only abstraction aligned with what actually happens behind the scenes. For
something more high-level, refer to inquirer-rs, which uses Termion as backend.
Termion generates escapes and API calls for the user. This makes it a whole lot
cleaner to use escapes.
Supports Redox, Mac OS X, BSD, and Linux (or, in general, ANSI terminals).
## A note on stability
This crate is stable.
## Cargo.toml
```toml
[dependencies]
termion = "*"
```
## 0.1.0 to 1.0.0 guide
This sample table gives an idea of how to go about converting to the new major
version of Termion.
| 0.1.0 | 1.0.0
|--------------------------------|---------------------------
| `use termion::IntoRawMode` | `use termion::raw::IntoRawMode`
| `use termion::TermRead` | `use termion::input::TermRead`
| `stdout.color(color::Red);` | `write!(stdout, "{}", color::Fg(color::Red));`
| `stdout.color_bg(color::Red);` | `write!(stdout, "{}", color::Bg(color::Red));`
| `stdout.goto(x, y);` | `write!(stdout, "{}", cursor::Goto(x, y));`
| `color::rgb(r, g, b);` | `color::Rgb(r, g, b)` (truecolor)
| `x.with_mouse()` | `MouseTerminal::from(x)`
## Features
- Raw mode.
- TrueColor.
- 256-color mode.
- Cursor movement.
- Text formatting.
- Console size.
- TTY-only stream.
- Control sequences.
- Termios control.
- Password input.
- Redox support.
- Safe `isatty` wrapper.
- Panic-free error handling.
- Special keys events (modifiers, special keys, etc.).
- Allocation-free.
- Asynchronous key events.
- Mouse input.
- Carefully tested.
- Detailed documentation on every item.
and much more.
## Examples
### Style and colors.
```rust
extern crate termion;
use termion::{color, style};
use std::io;
fn main() {
println!("{}Red", color::Fg(color::Red));
println!("{}Blue", color::Fg(color::Blue));
println!("{}Blue'n'Bold{}", style::Bold, style::Reset);
println!("{}Just plain italic", style::Italic);
}
```
### Moving the cursor
```rust
extern crate termion;
fn main() {
print!("{}{}Stuff", termion::clear::All, termion::cursor::Goto(1, 1));
}
```
### Mouse
```rust
extern crate termion;
use termion::event::{Key, Event, MouseEvent};
use termion::input::{TermRead, MouseTerminal};
use termion::raw::IntoRawMode;
use std::io::{Write, stdout, stdin};
fn main() {
let stdin = stdin();
let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
write!(stdout, "{}{}q to exit. Click, click, click!", termion::clear::All, termion::cursor::Goto(1, 1)).unwrap();
stdout.flush().unwrap();
for c in stdin.events() {
let evt = c.unwrap();
match evt {
Event::Key(Key::Char('q')) => break,
Event::Mouse(me) => {
match me {
MouseEvent::Press(_, x, y) => {
write!(stdout, "{}x", termion::cursor::Goto(x, y)).unwrap();
},
_ => (),
}
}
_ => {}
}
stdout.flush().unwrap();
}
}
```
### Read a password
```rust
extern crate termion;
use termion::input::TermRead;
use std::io::{Write, stdout, stdin};
fn main() {
let stdout = stdout();
let mut stdout = stdout.lock();
let stdin = stdin();
let mut stdin = stdin.lock();
stdout.write_all(b"password: ").unwrap();
stdout.flush().unwrap();
let pass = stdin.read_passwd(&mut stdout);
if let Ok(Some(pass)) = pass {
stdout.write_all(pass.as_bytes()).unwrap();
stdout.write_all(b"\n").unwrap();
} else {
stdout.write_all(b"Error\n").unwrap();
}
}
```
## Usage
See `examples/`, and the documentation, which can be rendered using `cargo doc`.
For a more complete example, see [a minesweeper implementation](https://github.com/redox-os/games-for-redox/blob/master/src/minesweeper/main.rs), that I made for Redox using termion.
<img src="image.png" width="200">
## License
MIT/X11.

17
third_party/rust/termion/examples/alternate_screen.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
extern crate termion;
use termion::screen::*;
use std::io::{Write, stdout};
use std::{time, thread};
fn main() {
{
let mut screen = AlternateScreen::from(stdout());
write!(screen, "Welcome to the alternate screen.\n\nPlease wait patiently until we arrive back at the main screen in a about three seconds.").unwrap();
screen.flush().unwrap();
thread::sleep(time::Duration::from_secs(3));
}
println!("Phew! We are back.");
}

40
third_party/rust/termion/examples/alternate_screen_raw.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,40 @@
extern crate termion;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::screen::*;
use std::io::{Write, stdout, stdin};
fn write_alt_screen_msg<W: Write>(screen: &mut W) {
write!(screen, "{}{}Welcome to the alternate screen.{}Press '1' to switch to the main screen or '2' to switch to the alternate screen.{}Press 'q' to exit (and switch back to the main screen).",
termion::clear::All,
termion::cursor::Goto(1, 1),
termion::cursor::Goto(1, 3),
termion::cursor::Goto(1, 4)).unwrap();
}
fn main() {
let stdin = stdin();
let mut screen = AlternateScreen::from(stdout().into_raw_mode().unwrap());
write!(screen, "{}", termion::cursor::Hide).unwrap();
write_alt_screen_msg(&mut screen);
screen.flush().unwrap();
for c in stdin.keys() {
match c.unwrap() {
Key::Char('q') => break,
Key::Char('1') => {
write!(screen, "{}", ToMainScreen).unwrap();
}
Key::Char('2') => {
write!(screen, "{}", ToAlternateScreen).unwrap();
write_alt_screen_msg(&mut screen);
}
_ => {}
}
screen.flush().unwrap();
}
write!(screen, "{}", termion::cursor::Show).unwrap();
}

39
third_party/rust/termion/examples/async.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
extern crate termion;
use termion::raw::IntoRawMode;
use termion::async_stdin;
use std::io::{Read, Write, stdout};
use std::thread;
use std::time::Duration;
fn main() {
let stdout = stdout();
let mut stdout = stdout.lock().into_raw_mode().unwrap();
let mut stdin = async_stdin().bytes();
write!(stdout,
"{}{}",
termion::clear::All,
termion::cursor::Goto(1, 1))
.unwrap();
loop {
write!(stdout, "{}", termion::clear::CurrentLine).unwrap();
let b = stdin.next();
write!(stdout, "\r{:?} <- This demonstrates the async read input char. Between each update a 100 ms. is waited, simply to demonstrate the async fashion. \n\r", b).unwrap();
if let Some(Ok(b'q')) = b {
break;
}
stdout.flush().unwrap();
thread::sleep(Duration::from_millis(50));
stdout.write_all(b"# ").unwrap();
stdout.flush().unwrap();
thread::sleep(Duration::from_millis(50));
stdout.write_all(b"\r #").unwrap();
write!(stdout, "{}", termion::cursor::Goto(1, 1)).unwrap();
stdout.flush().unwrap();
}
}

35
third_party/rust/termion/examples/click.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,35 @@
extern crate termion;
use termion::event::{Key, Event, MouseEvent};
use termion::input::{TermRead, MouseTerminal};
use termion::raw::IntoRawMode;
use std::io::{Write, stdout, stdin};
fn main() {
let stdin = stdin();
let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
write!(stdout,
"{}{}q to exit. Click, click, click!",
termion::clear::All,
termion::cursor::Goto(1, 1))
.unwrap();
stdout.flush().unwrap();
for c in stdin.events() {
let evt = c.unwrap();
match evt {
Event::Key(Key::Char('q')) => break,
Event::Mouse(me) => {
match me {
MouseEvent::Press(_, x, y) => {
write!(stdout, "{}x", termion::cursor::Goto(x, y)).unwrap();
}
_ => (),
}
}
_ => {}
}
stdout.flush().unwrap();
}
}

10
third_party/rust/termion/examples/color.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
extern crate termion;
use termion::{color, style};
fn main() {
println!("{}Red", color::Fg(color::Red));
println!("{}Blue", color::Fg(color::Blue));
println!("{}Blue'n'Bold{}", style::Bold, style::Reset);
println!("{}Just plain italic", style::Italic);
}

51
third_party/rust/termion/examples/commie.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,51 @@
extern crate termion;
use termion::{clear, color, cursor};
use std::{time, thread};
const COMMUNISM: &'static str = r#"
!######### #
!########! ##!
!########! ###
!########## ####
######### ##### ######
!###! !####! ######
! ##### ######!
!####! #######
##### #######
!####! #######!
####!########
## ##########
,######! !#############
,#### ########################!####!
,####' ##################!' #####
,####' ####### !####!
####' #####
~## ##~
"#;
fn main() {
let mut state = 0;
println!("\n{}{}{}{}{}{}",
cursor::Hide,
clear::All,
cursor::Goto(1, 1),
color::Fg(color::Black),
color::Bg(color::Red),
COMMUNISM);
loop {
println!("{}{} ☭ GAY ☭ SPACE ☭ COMMUNISM ☭ ",
cursor::Goto(1, 1),
color::Bg(color::AnsiValue(state)));
println!("{}{} WILL PREVAIL, COMRADES! ",
cursor::Goto(1, 20),
color::Bg(color::AnsiValue(state)));
state += 1;
state %= 8;
thread::sleep(time::Duration::from_millis(90));
}
}

19
third_party/rust/termion/examples/detect_color.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
extern crate termion;
use termion::color::{DetectColors, AnsiValue, Bg};
use termion::raw::IntoRawMode;
use std::io::stdout;
fn main() {
let count;
{
let mut term = stdout().into_raw_mode().unwrap();
count = term.available_colors().unwrap();
}
println!("This terminal supports {} colors.", count);
for i in 0..count {
print!("{} {}", Bg(AnsiValue(i as u8)), Bg(AnsiValue(0)));
}
println!();
}

11
third_party/rust/termion/examples/is_tty.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,11 @@
extern crate termion;
use std::fs;
fn main() {
if termion::is_tty(&fs::File::create("/dev/stdout").unwrap()) {
println!("This is a TTY!");
} else {
println!("This is not a TTY :(");
}
}

44
third_party/rust/termion/examples/keys.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,44 @@
extern crate termion;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{Write, stdout, stdin};
fn main() {
let stdin = stdin();
let mut stdout = stdout().into_raw_mode().unwrap();
write!(stdout,
"{}{}q to exit. Type stuff, use alt, and so on.{}",
termion::clear::All,
termion::cursor::Goto(1, 1),
termion::cursor::Hide)
.unwrap();
stdout.flush().unwrap();
for c in stdin.keys() {
write!(stdout,
"{}{}",
termion::cursor::Goto(1, 1),
termion::clear::CurrentLine)
.unwrap();
match c.unwrap() {
Key::Char('q') => break,
Key::Char(c) => println!("{}", c),
Key::Alt(c) => println!("^{}", c),
Key::Ctrl(c) => println!("*{}", c),
Key::Esc => println!("ESC"),
Key::Left => println!(""),
Key::Right => println!(""),
Key::Up => println!(""),
Key::Down => println!(""),
Key::Backspace => println!("×"),
_ => {}
}
stdout.flush().unwrap();
}
write!(stdout, "{}", termion::cursor::Show).unwrap();
}

46
third_party/rust/termion/examples/mouse.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,46 @@
extern crate termion;
use termion::event::*;
use termion::cursor::{self, DetectCursorPos};
use termion::input::{TermRead, MouseTerminal};
use termion::raw::IntoRawMode;
use std::io::{self, Write};
fn main() {
let stdin = io::stdin();
let mut stdout = MouseTerminal::from(io::stdout().into_raw_mode().unwrap());
writeln!(stdout,
"{}{}q to exit. Type stuff, use alt, click around...",
termion::clear::All,
termion::cursor::Goto(1, 1))
.unwrap();
for c in stdin.events() {
let evt = c.unwrap();
match evt {
Event::Key(Key::Char('q')) => break,
Event::Mouse(me) => {
match me {
MouseEvent::Press(_, a, b) |
MouseEvent::Release(a, b) |
MouseEvent::Hold(a, b) => {
write!(stdout, "{}", cursor::Goto(a, b)).unwrap();
let (x, y) = stdout.cursor_pos().unwrap();
write!(stdout,
"{}{}Cursor is at: ({},{}){}",
cursor::Goto(5, 5),
termion::clear::UntilNewline,
x,
y,
cursor::Goto(a, b))
.unwrap();
}
}
}
_ => {}
}
stdout.flush().unwrap();
}
}

60
third_party/rust/termion/examples/rainbow.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,60 @@
extern crate termion;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use std::io::{Write, stdout, stdin};
fn rainbow<W: Write>(stdout: &mut W, blue: u8) {
write!(stdout,
"{}{}",
termion::cursor::Goto(1, 1),
termion::clear::All)
.unwrap();
for red in 0..32 {
let red = red * 8;
for green in 0..64 {
let green = green * 4;
write!(stdout,
"{} ",
termion::color::Bg(termion::color::Rgb(red, green, blue)))
.unwrap();
}
write!(stdout, "\n\r").unwrap();
}
writeln!(stdout, "{}b = {}", termion::style::Reset, blue).unwrap();
}
fn main() {
let stdin = stdin();
let mut stdout = stdout().into_raw_mode().unwrap();
writeln!(stdout,
"{}{}{}Use the up/down arrow keys to change the blue in the rainbow.",
termion::clear::All,
termion::cursor::Goto(1, 1),
termion::cursor::Hide)
.unwrap();
let mut blue = 172u8;
for c in stdin.keys() {
match c.unwrap() {
Key::Up => {
blue = blue.saturating_add(4);
rainbow(&mut stdout, blue);
}
Key::Down => {
blue = blue.saturating_sub(4);
rainbow(&mut stdout, blue);
}
Key::Char('q') => break,
_ => {}
}
stdout.flush().unwrap();
}
write!(stdout, "{}", termion::cursor::Show).unwrap();
}

23
third_party/rust/termion/examples/read.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
extern crate termion;
use termion::input::TermRead;
use std::io::{Write, stdout, stdin};
fn main() {
let stdout = stdout();
let mut stdout = stdout.lock();
let stdin = stdin();
let mut stdin = stdin.lock();
stdout.write_all(b"password: ").unwrap();
stdout.flush().unwrap();
let pass = stdin.read_passwd(&mut stdout);
if let Ok(Some(pass)) = pass {
stdout.write_all(pass.as_bytes()).unwrap();
stdout.write_all(b"\n").unwrap();
} else {
stdout.write_all(b"Error\n").unwrap();
}
}

24
third_party/rust/termion/examples/rustc_fun.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,24 @@
extern crate termion;
use termion::{color, style};
fn main() {
println!("{lighgreen}-- src/test/ui/borrow-errors.rs at 82:18 --\n\
{red}error: {reset}{bold}two closures require unique access to `vec` at the same time {reset}{bold}{magenta}[E0524]{reset}\n\
{line_num_fg}{line_num_bg}79 {reset} let append = |e| {{\n\
{line_num_fg}{line_num_bg}{info_line}{reset} {red}^^^{reset} {error_fg}first closure is constructed here\n\
{line_num_fg}{line_num_bg}80 {reset} vec.push(e)\n\
{line_num_fg}{line_num_bg}{info_line}{reset} {red}^^^{reset} {error_fg}previous borrow occurs due to use of `vec` in closure\n\
{line_num_fg}{line_num_bg}84 {reset} }};\n\
{line_num_fg}{line_num_bg}85 {reset} }}\n\
{line_num_fg}{line_num_bg}{info_line}{reset} {red}^{reset} {error_fg}borrow from first closure ends here",
lighgreen = color::Fg(color::LightGreen),
red = color::Fg(color::Red),
bold = style::Bold,
reset = style::Reset,
magenta = color::Fg(color::Magenta),
line_num_bg = color::Bg(color::AnsiValue::grayscale(3)),
line_num_fg = color::Fg(color::AnsiValue::grayscale(18)),
info_line = "| ",
error_fg = color::Fg(color::AnsiValue::grayscale(17)))
}

42
third_party/rust/termion/examples/simple.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,42 @@
extern crate termion;
use termion::color;
use termion::raw::IntoRawMode;
use std::io::{Read, Write, stdout, stdin};
fn main() {
// Initialize 'em all.
let stdout = stdout();
let mut stdout = stdout.lock().into_raw_mode().unwrap();
let stdin = stdin();
let stdin = stdin.lock();
write!(stdout,
"{}{}{}yo, 'q' will exit.{}{}",
termion::clear::All,
termion::cursor::Goto(5, 5),
termion::style::Bold,
termion::style::Reset,
termion::cursor::Goto(20, 10))
.unwrap();
stdout.flush().unwrap();
let mut bytes = stdin.bytes();
loop {
let b = bytes.next().unwrap().unwrap();
match b {
// Quit
b'q' => return,
// Clear the screen
b'c' => write!(stdout, "{}", termion::clear::All),
// Set red color
b'r' => write!(stdout, "{}", color::Fg(color::Rgb(5, 0, 0))),
// Write it to stdout.
a => write!(stdout, "{}", a),
}
.unwrap();
stdout.flush().unwrap();
}
}

7
third_party/rust/termion/examples/size.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
extern crate termion;
use termion::terminal_size;
fn main() {
println!("Size is {:?}", terminal_size().unwrap())
}

12
third_party/rust/termion/examples/truecolor.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
extern crate termion;
use termion::{color, cursor, clear};
use std::{thread, time};
fn main() {
for r in 0..255 {
let c = color::Rgb(r, !r, 2 * ((r % 128) as i8 - 64).abs() as u8);
println!("{}{}{}wow", cursor::Goto(1, 1), color::Bg(c), clear::All);
thread::sleep(time::Duration::from_millis(100));
}
}

9
third_party/rust/termion/logo.svg поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60.099598mm" height="18.291185mm" viewBox="0 0 212.95 64.81">
<style>
.blink { animation: blinker 3s linear infinite; } @keyframes blinker { 50% { opacity: 0; } }
</style>
<path d="M0 0h212.95v64.82H0z" opacity=".71"/>
<path fill="#f9f9f9" d="M12.24 17.8H34.5v3.33h-9.13v25.84H21.4V21.13h-9.16V17.8zm27 0h17.3v3.33H43.2v8.63h12.77v3.32h-12.8v10.57H56.9v3.32H39.24V17.8zM74.3 33.2q1.5.4 2.6 1.48 1.06 1.08 2.66 4.32l3.97 7.97H79.3l-3.5-7.37q-1.5-3.14-2.7-4.04-1.2-.92-3.13-.92H66.2v12.33h-3.96V17.8h8.13q4.8 0 7.36 2.17 2.56 2.17 2.56 6.27 0 2.9-1.6 4.73-1.6 1.82-4.4 2.23zm-8.1-12.15V31.4h4.32q2.83 0 4.22-1.27 1.4-1.27 1.4-3.9 0-2.5-1.5-3.83-1.46-1.35-4.27-1.35H66.2zm19-3.25h5.26l5.04 14.85 5.08-14.84h5.3V47h-3.66V21.2l-5.2 15.38h-2.98L88.82 21.2v25.77H85.2V17.8zm26.3 0h16.2v3.33h-6.12v22.52h6.1v3.32H111.5v-3.32h6.1V21.13h-6.1V17.8zm37.8 14.62q0-6.43-1.32-9.18-1.3-2.76-4.3-2.76t-4.33 2.76q-1.3 2.75-1.3 9.18 0 6.4 1.3 9.16 1.33 2.75 4.32 2.75 3 0 4.3-2.73 1.34-2.76 1.34-9.18zm4.13 0q0 7.6-2.42 11.36-2.4 3.75-7.3 3.75t-7.3-3.73q-2.4-3.73-2.4-11.38 0-7.64 2.4-11.4 2.4-3.74 7.35-3.74t7.34 3.75q2.42 3.75 2.42 11.4zm4.97-14.62h5l9.86 24v-24h3.8v29.17h-5l-9.84-24v24h-3.8V17.8z"/>
<path fill="#f9f9f9" d="M192.7 8.66v47.5h-3.93V8.66h3.94z" class="blink"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

78
third_party/rust/termion/src/async.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,78 @@
use std::io::{self, Read};
use std::sync::mpsc;
use std::thread;
use sys::tty::get_tty;
/// Construct an asynchronous handle to the TTY standard input.
///
/// This allows you to read from standard input _without blocking_ the current thread.
/// Specifically, it works by firing up another thread to handle the event stream, which will then
/// be buffered in a mpsc queue, which will eventually be read by the current thread.
///
/// This will not read the piped standard input, but rather read from the TTY device, since reading
/// asyncronized from piped input would rarely make sense. In other words, if you pipe standard
/// output from another process, it won't be reflected in the stream returned by this function, as
/// this represents the TTY device, and not the piped standard input.
pub fn async_stdin() -> AsyncReader {
let (send, recv) = mpsc::channel();
thread::spawn(move || for i in get_tty().unwrap().bytes() {
if send.send(i).is_err() {
return;
}
});
AsyncReader { recv: recv }
}
/// An asynchronous reader.
///
/// This acts as any other stream, with the exception that reading from it won't block. Instead,
/// the buffer will only be partially updated based on how much the internal buffer holds.
pub struct AsyncReader {
/// The underlying mpsc receiver.
recv: mpsc::Receiver<io::Result<u8>>,
}
// FIXME: Allow constructing an async reader from an arbitrary stream.
impl Read for AsyncReader {
/// Read from the byte stream.
///
/// This will never block, but try to drain the event queue until empty. If the total number of
/// bytes written is lower than the buffer's length, the event queue is empty or that the event
/// stream halted.
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut total = 0;
loop {
if total >= buf.len() {
break;
}
match self.recv.try_recv() {
Ok(Ok(b)) => {
buf[total] = b;
total += 1;
}
Ok(Err(e)) => return Err(e),
Err(_) => break,
}
}
Ok(total)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Read;
#[test]
fn test_async_stdin() {
let stdin = async_stdin();
stdin.bytes().next();
}
}

9
third_party/rust/termion/src/clear.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
//! Clearing the screen.
use std::fmt;
derive_csi_sequence!("Clear the entire screen.", All, "2J");
derive_csi_sequence!("Clear everything after the cursor.", AfterCursor, "J");
derive_csi_sequence!("Clear everything before the cursor.", BeforeCursor, "1J");
derive_csi_sequence!("Clear the current line.", CurrentLine, "2K");
derive_csi_sequence!("Clear from cursor to newline.", UntilNewline, "K");

242
third_party/rust/termion/src/color.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,242 @@
//! Color managemement.
//!
//! # Example
//!
//! ```rust
//! use termion::color;
//!
//! fn main() {
//! println!("{}Red", color::Fg(color::Red));
//! println!("{}Blue", color::Fg(color::Blue));
//! println!("{}Back again", color::Fg(color::Reset));
//! }
//! ```
use std::fmt;
use raw::CONTROL_SEQUENCE_TIMEOUT;
use std::io::{self, Write, Read};
use std::time::{SystemTime, Duration};
use async::async_stdin;
use std::env;
/// A terminal color.
pub trait Color {
/// Write the foreground version of this color.
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result;
/// Write the background version of this color.
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result;
}
macro_rules! derive_color {
($doc:expr, $name:ident, $value:expr) => {
#[doc = $doc]
#[derive(Copy, Clone, Debug)]
pub struct $name;
impl Color for $name {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("38;5;", $value, "m"))
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("48;5;", $value, "m"))
}
}
};
}
derive_color!("Black.", Black, "0");
derive_color!("Red.", Red, "1");
derive_color!("Green.", Green, "2");
derive_color!("Yellow.", Yellow, "3");
derive_color!("Blue.", Blue, "4");
derive_color!("Magenta.", Magenta, "5");
derive_color!("Cyan.", Cyan, "6");
derive_color!("White.", White, "7");
derive_color!("High-intensity light black.", LightBlack, "8");
derive_color!("High-intensity light red.", LightRed, "9");
derive_color!("High-intensity light green.", LightGreen, "10");
derive_color!("High-intensity light yellow.", LightYellow, "11");
derive_color!("High-intensity light blue.", LightBlue, "12");
derive_color!("High-intensity light magenta.", LightMagenta, "13");
derive_color!("High-intensity light cyan.", LightCyan, "14");
derive_color!("High-intensity light white.", LightWhite, "15");
impl<'a> Color for &'a Color {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
(*self).write_fg(f)
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
(*self).write_bg(f)
}
}
/// An arbitrary ANSI color value.
#[derive(Clone, Copy, Debug)]
pub struct AnsiValue(pub u8);
impl AnsiValue {
/// 216-color (r, g, b ≤ 5) RGB.
pub fn rgb(r: u8, g: u8, b: u8) -> AnsiValue {
debug_assert!(r <= 5,
"Red color fragment (r = {}) is out of bound. Make sure r ≤ 5.",
r);
debug_assert!(g <= 5,
"Green color fragment (g = {}) is out of bound. Make sure g ≤ 5.",
g);
debug_assert!(b <= 5,
"Blue color fragment (b = {}) is out of bound. Make sure b ≤ 5.",
b);
AnsiValue(16 + 36 * r + 6 * g + b)
}
/// Grayscale color.
///
/// There are 24 shades of gray.
pub fn grayscale(shade: u8) -> AnsiValue {
// Unfortunately, there are a little less than fifty shades.
debug_assert!(shade < 24,
"Grayscale out of bound (shade = {}). There are only 24 shades of \
gray.",
shade);
AnsiValue(0xE8 + shade)
}
}
impl Color for AnsiValue {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("38;5;{}m"), self.0)
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("48;5;{}m"), self.0)
}
}
/// A truecolor RGB.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rgb(pub u8, pub u8, pub u8);
impl Color for Rgb {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("38;2;{};{};{}m"), self.0, self.1, self.2)
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("48;2;{};{};{}m"), self.0, self.1, self.2)
}
}
/// Reset colors to defaults.
#[derive(Debug, Clone, Copy)]
pub struct Reset;
impl Color for Reset {
#[inline]
fn write_fg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("39m"))
}
#[inline]
fn write_bg(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("49m"))
}
}
/// A foreground color.
#[derive(Debug, Clone, Copy)]
pub struct Fg<C: Color>(pub C);
impl<C: Color> fmt::Display for Fg<C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.write_fg(f)
}
}
/// A background color.
#[derive(Debug, Clone, Copy)]
pub struct Bg<C: Color>(pub C);
impl<C: Color> fmt::Display for Bg<C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.write_bg(f)
}
}
/// Types that allow detection of the colors they support.
pub trait DetectColors {
/// How many ANSI colors are supported (from 8 to 256)?
///
/// Beware: the information given isn't authoritative, it's infered through escape codes or the
/// value of `TERM`, more colors may be available.
fn available_colors(&mut self) -> io::Result<u16>;
}
impl<W: Write> DetectColors for W {
fn available_colors(&mut self) -> io::Result<u16> {
let mut stdin = async_stdin();
if detect_color(self, &mut stdin, 0)? {
// OSC 4 is supported, detect how many colors there are.
// Do a binary search of the last supported color.
let mut min = 8;
let mut max = 256;
let mut i;
while min + 1 < max {
i = (min + max) / 2;
if detect_color(self, &mut stdin, i)? {
min = i
} else {
max = i
}
}
Ok(max)
} else {
// OSC 4 is not supported, trust TERM contents.
Ok(match env::var_os("TERM") {
Some(val) => {
if val.to_str().unwrap_or("").contains("256color") {
256
} else {
8
}
}
None => 8,
})
}
}
}
/// Detect a color using OSC 4.
fn detect_color(stdout: &mut Write, stdin: &mut Read, color: u16) -> io::Result<bool> {
// Is the color available?
// Use `ESC ] 4 ; color ; ? BEL`.
write!(stdout, "\x1B]4;{};?\x07", color)?;
stdout.flush()?;
let mut buf: [u8; 1] = [0];
let mut total_read = 0;
let timeout = Duration::from_millis(CONTROL_SEQUENCE_TIMEOUT);
let now = SystemTime::now();
let bell = 7u8;
// Either consume all data up to bell or wait for a timeout.
while buf[0] != bell && now.elapsed().unwrap() < timeout {
total_read += stdin.read(&mut buf)?;
}
// If there was a response, the color is supported.
Ok(total_read > 0)
}

140
third_party/rust/termion/src/cursor.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,140 @@
//! Cursor movement.
use std::fmt;
use std::io::{self, Write, Error, ErrorKind, Read};
use async::async_stdin;
use std::time::{SystemTime, Duration};
use raw::CONTROL_SEQUENCE_TIMEOUT;
derive_csi_sequence!("Hide the cursor.", Hide, "?25l");
derive_csi_sequence!("Show the cursor.", Show, "?25h");
derive_csi_sequence!("Restore the cursor.", Restore, "u");
derive_csi_sequence!("Save the cursor.", Save, "s");
/// Goto some position ((1,1)-based).
///
/// # Why one-based?
///
/// ANSI escapes are very poorly designed, and one of the many odd aspects is being one-based. This
/// can be quite strange at first, but it is not that big of an obstruction once you get used to
/// it.
///
/// # Example
///
/// ```rust
/// extern crate termion;
///
/// fn main() {
/// print!("{}{}Stuff", termion::clear::All, termion::cursor::Goto(5, 3));
/// }
/// ```
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Goto(pub u16, pub u16);
impl Default for Goto {
fn default() -> Goto {
Goto(1, 1)
}
}
impl fmt::Display for Goto {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
debug_assert!(self != &Goto(0, 0), "Goto is one-based.");
write!(f, csi!("{};{}H"), self.1, self.0)
}
}
/// Move cursor left.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Left(pub u16);
impl fmt::Display for Left {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}D"), self.0)
}
}
/// Move cursor right.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Right(pub u16);
impl fmt::Display for Right {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}C"), self.0)
}
}
/// Move cursor up.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Up(pub u16);
impl fmt::Display for Up {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}A"), self.0)
}
}
/// Move cursor down.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Down(pub u16);
impl fmt::Display for Down {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}B"), self.0)
}
}
/// Types that allow detection of the cursor position.
pub trait DetectCursorPos {
/// Get the (1,1)-based cursor position from the terminal.
fn cursor_pos(&mut self) -> io::Result<(u16, u16)>;
}
impl<W: Write> DetectCursorPos for W {
fn cursor_pos(&mut self) -> io::Result<(u16, u16)> {
let mut stdin = async_stdin();
// Where is the cursor?
// Use `ESC [ 6 n`.
write!(self, "\x1B[6n")?;
self.flush()?;
let mut buf: [u8; 1] = [0];
let mut read_chars = Vec::new();
let timeout = Duration::from_millis(CONTROL_SEQUENCE_TIMEOUT);
let now = SystemTime::now();
// Either consume all data up to R or wait for a timeout.
while buf[0] != b'R' && now.elapsed().unwrap() < timeout {
if stdin.read(&mut buf)? > 0 {
read_chars.push(buf[0]);
}
}
if read_chars.len() == 0 {
return Err(Error::new(ErrorKind::Other, "Cursor position detection timed out."));
}
// The answer will look like `ESC [ Cy ; Cx R`.
read_chars.pop(); // remove trailing R.
let read_str = String::from_utf8(read_chars).unwrap();
let beg = read_str.rfind('[').unwrap();
let coords: String = read_str.chars().skip(beg + 1).collect();
let mut nums = coords.split(';');
let cy = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
let cx = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
Ok((cx, cy))
}
}

351
third_party/rust/termion/src/event.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,351 @@
//! Mouse and key events.
use std::io::{Error, ErrorKind};
use std::ascii::AsciiExt;
use std::str;
/// An event reported by the terminal.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Event {
/// A key press.
Key(Key),
/// A mouse button press, release or wheel use at specific coordinates.
Mouse(MouseEvent),
/// An event that cannot currently be evaluated.
Unsupported(Vec<u8>),
}
/// A mouse related event.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MouseEvent {
/// A mouse button was pressed.
///
/// The coordinates are one-based.
Press(MouseButton, u16, u16),
/// A mouse button was released.
///
/// The coordinates are one-based.
Release(u16, u16),
/// A mouse button is held over the given coordinates.
///
/// The coordinates are one-based.
Hold(u16, u16),
}
/// A mouse button.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum MouseButton {
/// The left mouse button.
Left,
/// The right mouse button.
Right,
/// The middle mouse button.
Middle,
/// Mouse wheel is going up.
///
/// This event is typically only used with Mouse::Press.
WheelUp,
/// Mouse wheel is going down.
///
/// This event is typically only used with Mouse::Press.
WheelDown,
}
/// A key.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Key {
/// Backspace.
Backspace,
/// Left arrow.
Left,
/// Right arrow.
Right,
/// Up arrow.
Up,
/// Down arrow.
Down,
/// Home key.
Home,
/// End key.
End,
/// Page Up key.
PageUp,
/// Page Down key.
PageDown,
/// Delete key.
Delete,
/// Insert key.
Insert,
/// Function keys.
///
/// Only function keys 1 through 12 are supported.
F(u8),
/// Normal character.
Char(char),
/// Alt modified character.
Alt(char),
/// Ctrl modified character.
///
/// Note that certain keys may not be modifiable with `ctrl`, due to limitations of terminals.
Ctrl(char),
/// Null byte.
Null,
/// Esc key.
Esc,
#[doc(hidden)]
__IsNotComplete,
}
/// Parse an Event from `item` and possibly subsequent bytes through `iter`.
pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
where I: Iterator<Item = Result<u8, Error>>
{
let error = Error::new(ErrorKind::Other, "Could not parse an event");
match item {
b'\x1B' => {
// This is an escape character, leading a control sequence.
Ok(match iter.next() {
Some(Ok(b'O')) => {
match iter.next() {
// F1-F4
Some(Ok(val @ b'P'...b'S')) => Event::Key(Key::F(1 + val - b'P')),
_ => return Err(error),
}
}
Some(Ok(b'[')) => {
// This is a CSI sequence.
parse_csi(iter).ok_or(error)?
}
Some(Ok(c)) => {
let ch = parse_utf8_char(c, iter);
Event::Key(Key::Alt(try!(ch)))
}
Some(Err(_)) | None => return Err(error),
})
}
b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))),
b'\t' => Ok(Event::Key(Key::Char('\t'))),
b'\x7F' => Ok(Event::Key(Key::Backspace)),
c @ b'\x01'...b'\x1A' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
c @ b'\x1C'...b'\x1F' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char))),
b'\0' => Ok(Event::Key(Key::Null)),
c => {
Ok({
let ch = parse_utf8_char(c, iter);
Event::Key(Key::Char(try!(ch)))
})
}
}
}
/// Parses a CSI sequence, just after reading ^[
///
/// Returns None if an unrecognized sequence is found.
fn parse_csi<I>(iter: &mut I) -> Option<Event>
where I: Iterator<Item = Result<u8, Error>>
{
Some(match iter.next() {
Some(Ok(b'[')) => match iter.next() {
Some(Ok(val @ b'A'...b'E')) => Event::Key(Key::F(1 + val - b'A')),
_ => return None,
},
Some(Ok(b'D')) => Event::Key(Key::Left),
Some(Ok(b'C')) => Event::Key(Key::Right),
Some(Ok(b'A')) => Event::Key(Key::Up),
Some(Ok(b'B')) => Event::Key(Key::Down),
Some(Ok(b'H')) => Event::Key(Key::Home),
Some(Ok(b'F')) => Event::Key(Key::End),
Some(Ok(b'M')) => {
// X10 emulation mouse encoding: ESC [ CB Cx Cy (6 characters only).
let mut next = || iter.next().unwrap().unwrap();
let cb = next() as i8 - 32;
// (1, 1) are the coords for upper left.
let cx = next().saturating_sub(32) as u16;
let cy = next().saturating_sub(32) as u16;
Event::Mouse(match cb & 0b11 {
0 => {
if cb & 0x40 != 0 {
MouseEvent::Press(MouseButton::WheelUp, cx, cy)
} else {
MouseEvent::Press(MouseButton::Left, cx, cy)
}
}
1 => {
if cb & 0x40 != 0 {
MouseEvent::Press(MouseButton::WheelDown, cx, cy)
} else {
MouseEvent::Press(MouseButton::Middle, cx, cy)
}
}
2 => MouseEvent::Press(MouseButton::Right, cx, cy),
3 => MouseEvent::Release(cx, cy),
_ => return None,
})
}
Some(Ok(b'<')) => {
// xterm mouse encoding:
// ESC [ < Cb ; Cx ; Cy (;) (M or m)
let mut buf = Vec::new();
let mut c = iter.next().unwrap().unwrap();
while match c {
b'm' | b'M' => false,
_ => true,
} {
buf.push(c);
c = iter.next().unwrap().unwrap();
}
let str_buf = String::from_utf8(buf).unwrap();
let nums = &mut str_buf.split(';');
let cb = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
let cx = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
let cy = nums.next()
.unwrap()
.parse::<u16>()
.unwrap();
let event = match cb {
0...2 | 64...65 => {
let button = match cb {
0 => MouseButton::Left,
1 => MouseButton::Middle,
2 => MouseButton::Right,
64 => MouseButton::WheelUp,
65 => MouseButton::WheelDown,
_ => unreachable!(),
};
match c {
b'M' => MouseEvent::Press(button, cx, cy),
b'm' => MouseEvent::Release(cx, cy),
_ => return None,
}
}
32 => MouseEvent::Hold(cx, cy),
3 => MouseEvent::Release(cx, cy),
_ => return None,
};
Event::Mouse(event)
}
Some(Ok(c @ b'0'...b'9')) => {
// Numbered escape code.
let mut buf = Vec::new();
buf.push(c);
let mut c = iter.next().unwrap().unwrap();
// The final byte of a CSI sequence can be in the range 64-126, so
// let's keep reading anything else.
while c < 64 || c > 126 {
buf.push(c);
c = iter.next().unwrap().unwrap();
}
match c {
// rxvt mouse encoding:
// ESC [ Cb ; Cx ; Cy ; M
b'M' => {
let str_buf = String::from_utf8(buf).unwrap();
let nums: Vec<u16> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
let cb = nums[0];
let cx = nums[1];
let cy = nums[2];
let event = match cb {
32 => MouseEvent::Press(MouseButton::Left, cx, cy),
33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
34 => MouseEvent::Press(MouseButton::Right, cx, cy),
35 => MouseEvent::Release(cx, cy),
64 => MouseEvent::Hold(cx, cy),
96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
_ => return None,
};
Event::Mouse(event)
}
// Special key code.
b'~' => {
let str_buf = String::from_utf8(buf).unwrap();
// This CSI sequence can be a list of semicolon-separated
// numbers.
let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
if nums.is_empty() {
return None;
}
// TODO: handle multiple values for key modififiers (ex: values
// [3, 2] means Shift+Delete)
if nums.len() > 1 {
return None;
}
match nums[0] {
1 | 7 => Event::Key(Key::Home),
2 => Event::Key(Key::Insert),
3 => Event::Key(Key::Delete),
4 | 8 => Event::Key(Key::End),
5 => Event::Key(Key::PageUp),
6 => Event::Key(Key::PageDown),
v @ 11...15 => Event::Key(Key::F(v - 10)),
v @ 17...21 => Event::Key(Key::F(v - 11)),
v @ 23...24 => Event::Key(Key::F(v - 12)),
_ => return None,
}
}
_ => return None,
}
}
_ => return None,
})
}
/// Parse `c` as either a single byte ASCII char or a variable size UTF-8 char.
fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
where I: Iterator<Item = Result<u8, Error>>
{
let error = Err(Error::new(ErrorKind::Other, "Input character is not valid UTF-8"));
if c.is_ascii() {
Ok(c as char)
} else {
let bytes = &mut Vec::new();
bytes.push(c);
loop {
match iter.next() {
Some(Ok(next)) => {
bytes.push(next);
if let Ok(st) = str::from_utf8(bytes) {
return Ok(st.chars().next().unwrap());
}
if bytes.len() >= 4 {
return error;
}
}
_ => return error,
}
}
}
}
#[cfg(test)]
#[test]
fn test_parse_utf8() {
let st = "abcéŷ¤£€ù%323";
let ref mut bytes = st.bytes().map(|x| Ok(x));
let chars = st.chars();
for c in chars {
let b = bytes.next().unwrap().unwrap();
assert!(c == parse_utf8_char(b, bytes).unwrap());
}
}

388
third_party/rust/termion/src/input.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,388 @@
//! User input.
use std::io::{self, Read, Write};
use std::ops;
use event::{self, Event, Key};
use raw::IntoRawMode;
/// An iterator over input keys.
pub struct Keys<R> {
iter: Events<R>,
}
impl<R: Read> Iterator for Keys<R> {
type Item = Result<Key, io::Error>;
fn next(&mut self) -> Option<Result<Key, io::Error>> {
loop {
match self.iter.next() {
Some(Ok(Event::Key(k))) => return Some(Ok(k)),
Some(Ok(_)) => continue,
e @ Some(Err(_)) => e,
None => return None,
};
}
}
}
/// An iterator over input events.
pub struct Events<R> {
inner: EventsAndRaw<R>
}
impl<R: Read> Iterator for Events<R> {
type Item = Result<Event, io::Error>;
fn next(&mut self) -> Option<Result<Event, io::Error>> {
self.inner.next().map(|tuple| tuple.map(|(event, _raw)| event))
}
}
/// An iterator over input events and the bytes that define them.
pub struct EventsAndRaw<R> {
source: R,
leftover: Option<u8>,
}
impl<R: Read> Iterator for EventsAndRaw<R> {
type Item = Result<(Event, Vec<u8>), io::Error>;
fn next(&mut self) -> Option<Result<(Event, Vec<u8>), io::Error>> {
let mut source = &mut self.source;
if let Some(c) = self.leftover {
// we have a leftover byte, use it
self.leftover = None;
return Some(parse_event(c, &mut source.bytes()));
}
// Here we read two bytes at a time. We need to distinguish between single ESC key presses,
// and escape sequences (which start with ESC or a x1B byte). The idea is that if this is
// an escape sequence, we will read multiple bytes (the first byte being ESC) but if this
// is a single ESC keypress, we will only read a single byte.
let mut buf = [0u8; 2];
let res = match source.read(&mut buf) {
Ok(0) => return None,
Ok(1) => {
match buf[0] {
b'\x1B' => Ok((Event::Key(Key::Esc), vec![b'\x1B'])),
c => parse_event(c, &mut source.bytes()),
}
}
Ok(2) => {
let mut option_iter = &mut Some(buf[1]).into_iter();
let result = {
let mut iter = option_iter.map(|c| Ok(c)).chain(source.bytes());
parse_event(buf[0], &mut iter)
};
// If the option_iter wasn't consumed, keep the byte for later.
self.leftover = option_iter.next();
result
}
Ok(_) => unreachable!(),
Err(e) => Err(e),
};
Some(res)
}
}
fn parse_event<I>(item: u8, iter: &mut I) -> Result<(Event, Vec<u8>), io::Error>
where I: Iterator<Item = Result<u8, io::Error>>
{
let mut buf = vec![item];
let result = {
let mut iter = iter.inspect(|byte| if let &Ok(byte) = byte {
buf.push(byte);
});
event::parse_event(item, &mut iter)
};
result.or(Ok(Event::Unsupported(buf.clone()))).map(|e| (e, buf))
}
/// Extension to `Read` trait.
pub trait TermRead {
/// An iterator over input events.
fn events(self) -> Events<Self> where Self: Sized;
/// An iterator over key inputs.
fn keys(self) -> Keys<Self> where Self: Sized;
/// Read a line.
///
/// EOT and ETX will abort the prompt, returning `None`. Newline or carriage return will
/// complete the input.
fn read_line(&mut self) -> io::Result<Option<String>>;
/// Read a password.
///
/// EOT and ETX will abort the prompt, returning `None`. Newline or carriage return will
/// complete the input.
fn read_passwd<W: Write>(&mut self, writer: &mut W) -> io::Result<Option<String>> {
let _raw = try!(writer.into_raw_mode());
self.read_line()
}
}
impl<R: Read + TermReadEventsAndRaw> TermRead for R {
fn events(self) -> Events<Self> {
Events {
inner: self.events_and_raw()
}
}
fn keys(self) -> Keys<Self> {
Keys { iter: self.events() }
}
fn read_line(&mut self) -> io::Result<Option<String>> {
let mut buf = Vec::with_capacity(30);
for c in self.bytes() {
match c {
Err(e) => return Err(e),
Ok(0) | Ok(3) | Ok(4) => return Ok(None),
Ok(0x7f) => {
buf.pop();
}
Ok(b'\n') | Ok(b'\r') => break,
Ok(c) => buf.push(c),
}
}
let string = try!(String::from_utf8(buf)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)));
Ok(Some(string))
}
}
/// Extension to `TermRead` trait. A separate trait in order to maintain backwards compatibility.
pub trait TermReadEventsAndRaw {
/// An iterator over input events and the bytes that define them.
fn events_and_raw(self) -> EventsAndRaw<Self> where Self: Sized;
}
impl<R: Read> TermReadEventsAndRaw for R {
fn events_and_raw(self) -> EventsAndRaw<Self> {
EventsAndRaw {
source: self,
leftover: None,
}
}
}
/// A sequence of escape codes to enable terminal mouse support.
const ENTER_MOUSE_SEQUENCE: &'static str = csi!("?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h");
/// A sequence of escape codes to disable terminal mouse support.
const EXIT_MOUSE_SEQUENCE: &'static str = csi!("?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l");
/// A terminal with added mouse support.
///
/// This can be obtained through the `From` implementations.
pub struct MouseTerminal<W: Write> {
term: W,
}
impl<W: Write> From<W> for MouseTerminal<W> {
fn from(mut from: W) -> MouseTerminal<W> {
from.write_all(ENTER_MOUSE_SEQUENCE.as_bytes()).unwrap();
MouseTerminal { term: from }
}
}
impl<W: Write> Drop for MouseTerminal<W> {
fn drop(&mut self) {
self.term.write_all(EXIT_MOUSE_SEQUENCE.as_bytes()).unwrap();
}
}
impl<W: Write> ops::Deref for MouseTerminal<W> {
type Target = W;
fn deref(&self) -> &W {
&self.term
}
}
impl<W: Write> ops::DerefMut for MouseTerminal<W> {
fn deref_mut(&mut self) -> &mut W {
&mut self.term
}
}
impl<W: Write> Write for MouseTerminal<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.term.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.term.flush()
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io;
use event::{Key, Event, MouseEvent, MouseButton};
#[test]
fn test_keys() {
let mut i = b"\x1Bayo\x7F\x1B[D".keys();
assert_eq!(i.next().unwrap().unwrap(), Key::Alt('a'));
assert_eq!(i.next().unwrap().unwrap(), Key::Char('y'));
assert_eq!(i.next().unwrap().unwrap(), Key::Char('o'));
assert_eq!(i.next().unwrap().unwrap(), Key::Backspace);
assert_eq!(i.next().unwrap().unwrap(), Key::Left);
assert!(i.next().is_none());
}
#[test]
fn test_events() {
let mut i =
b"\x1B[\x00bc\x7F\x1B[D\
\x1B[M\x00\x22\x24\x1B[<0;2;4;M\x1B[32;2;4M\x1B[<0;2;4;m\x1B[35;2;4Mb"
.events();
assert_eq!(i.next().unwrap().unwrap(),
Event::Unsupported(vec![0x1B, b'[', 0x00]));
assert_eq!(i.next().unwrap().unwrap(), Event::Key(Key::Char('b')));
assert_eq!(i.next().unwrap().unwrap(), Event::Key(Key::Char('c')));
assert_eq!(i.next().unwrap().unwrap(), Event::Key(Key::Backspace));
assert_eq!(i.next().unwrap().unwrap(), Event::Key(Key::Left));
assert_eq!(i.next().unwrap().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::WheelUp, 2, 4)));
assert_eq!(i.next().unwrap().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::Left, 2, 4)));
assert_eq!(i.next().unwrap().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::Left, 2, 4)));
assert_eq!(i.next().unwrap().unwrap(),
Event::Mouse(MouseEvent::Release(2, 4)));
assert_eq!(i.next().unwrap().unwrap(),
Event::Mouse(MouseEvent::Release(2, 4)));
assert_eq!(i.next().unwrap().unwrap(), Event::Key(Key::Char('b')));
assert!(i.next().is_none());
}
#[test]
fn test_events_and_raw() {
let input = b"\x1B[\x00bc\x7F\x1B[D\
\x1B[M\x00\x22\x24\x1B[<0;2;4;M\x1B[32;2;4M\x1B[<0;2;4;m\x1B[35;2;4Mb";
let mut output = Vec::<u8>::new();
{
let mut i = input.events_and_raw().map(|res| res.unwrap())
.inspect(|&(_, ref raw)| { output.extend(raw); }).map(|(event, _)| event);
assert_eq!(i.next().unwrap(),
Event::Unsupported(vec![0x1B, b'[', 0x00]));
assert_eq!(i.next().unwrap(), Event::Key(Key::Char('b')));
assert_eq!(i.next().unwrap(), Event::Key(Key::Char('c')));
assert_eq!(i.next().unwrap(), Event::Key(Key::Backspace));
assert_eq!(i.next().unwrap(), Event::Key(Key::Left));
assert_eq!(i.next().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::WheelUp, 2, 4)));
assert_eq!(i.next().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::Left, 2, 4)));
assert_eq!(i.next().unwrap(),
Event::Mouse(MouseEvent::Press(MouseButton::Left, 2, 4)));
assert_eq!(i.next().unwrap(),
Event::Mouse(MouseEvent::Release(2, 4)));
assert_eq!(i.next().unwrap(),
Event::Mouse(MouseEvent::Release(2, 4)));
assert_eq!(i.next().unwrap(), Event::Key(Key::Char('b')));
assert!(i.next().is_none());
}
assert_eq!(input.iter().map(|b| *b).collect::<Vec<u8>>(), output)
}
#[test]
fn test_function_keys() {
let mut st = b"\x1BOP\x1BOQ\x1BOR\x1BOS".keys();
for i in 1..5 {
assert_eq!(st.next().unwrap().unwrap(), Key::F(i));
}
let mut st = b"\x1B[11~\x1B[12~\x1B[13~\x1B[14~\x1B[15~\
\x1B[17~\x1B[18~\x1B[19~\x1B[20~\x1B[21~\x1B[23~\x1B[24~"
.keys();
for i in 1..13 {
assert_eq!(st.next().unwrap().unwrap(), Key::F(i));
}
}
#[test]
fn test_special_keys() {
let mut st = b"\x1B[2~\x1B[H\x1B[7~\x1B[5~\x1B[3~\x1B[F\x1B[8~\x1B[6~".keys();
assert_eq!(st.next().unwrap().unwrap(), Key::Insert);
assert_eq!(st.next().unwrap().unwrap(), Key::Home);
assert_eq!(st.next().unwrap().unwrap(), Key::Home);
assert_eq!(st.next().unwrap().unwrap(), Key::PageUp);
assert_eq!(st.next().unwrap().unwrap(), Key::Delete);
assert_eq!(st.next().unwrap().unwrap(), Key::End);
assert_eq!(st.next().unwrap().unwrap(), Key::End);
assert_eq!(st.next().unwrap().unwrap(), Key::PageDown);
assert!(st.next().is_none());
}
#[test]
fn test_esc_key() {
let mut st = b"\x1B".keys();
assert_eq!(st.next().unwrap().unwrap(), Key::Esc);
assert!(st.next().is_none());
}
fn line_match(a: &str, b: Option<&str>) {
let mut sink = io::sink();
let line = a.as_bytes().read_line().unwrap();
let pass = a.as_bytes().read_passwd(&mut sink).unwrap();
// godammit rustc
assert_eq!(line, pass);
if let Some(l) = line {
assert_eq!(Some(l.as_str()), b);
} else {
assert!(b.is_none());
}
}
#[test]
fn test_read() {
let test1 = "this is the first test";
let test2 = "this is the second test";
line_match(test1, Some(test1));
line_match(test2, Some(test2));
}
#[test]
fn test_backspace() {
line_match("this is the\x7f first\x7f\x7f test",
Some("this is th fir test"));
line_match("this is the seco\x7fnd test\x7f",
Some("this is the secnd tes"));
}
#[test]
fn test_end() {
line_match("abc\nhttps://www.youtube.com/watch?v=dQw4w9WgXcQ",
Some("abc"));
line_match("hello\rhttps://www.youtube.com/watch?v=yPYZpwSpKmA",
Some("hello"));
}
#[test]
fn test_abort() {
line_match("abc\x03https://www.youtube.com/watch?v=dQw4w9WgXcQ", None);
line_match("hello\x04https://www.youtube.com/watch?v=yPYZpwSpKmA", None);
}
}

61
third_party/rust/termion/src/lib.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,61 @@
//! Termion is a pure Rust, bindless library for low-level handling, manipulating
//! and reading information about terminals. This provides a full-featured
//! alternative to Termbox.
//!
//! Termion aims to be simple and yet expressive. It is bindless, meaning that it
//! is not a front-end to some other library (e.g., ncurses or termbox), but a
//! standalone library directly talking to the TTY.
//!
//! Supports Redox, Mac OS X, and Linux (or, in general, ANSI terminals).
//!
//! For more information refer to the [README](https://github.com/ticki/termion).
#![warn(missing_docs)]
#[cfg(target_os = "redox")]
#[path="sys/redox/mod.rs"]
mod sys;
#[cfg(unix)]
#[path="sys/unix/mod.rs"]
mod sys;
pub use sys::size::terminal_size;
pub use sys::tty::{is_tty, get_tty};
mod async;
pub use async::{AsyncReader, async_stdin};
#[macro_use]
mod macros;
pub mod clear;
pub mod color;
pub mod cursor;
pub mod event;
pub mod input;
pub mod raw;
pub mod screen;
pub mod scroll;
pub mod style;
#[cfg(test)]
mod test {
use super::sys;
#[test]
fn test_get_terminal_attr() {
sys::attr::get_terminal_attr().unwrap();
sys::attr::get_terminal_attr().unwrap();
sys::attr::get_terminal_attr().unwrap();
}
#[test]
fn test_set_terminal_attr() {
let ios = sys::attr::get_terminal_attr().unwrap();
sys::attr::set_terminal_attr(&ios).unwrap();
}
#[test]
fn test_size() {
sys::size::terminal_size().unwrap();
}
}

19
third_party/rust/termion/src/macros.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
/// Create a CSI-introduced sequence.
macro_rules! csi {
($( $l:expr ),*) => { concat!("\x1B[", $( $l ),*) };
}
/// Derive a CSI sequence struct.
macro_rules! derive_csi_sequence {
($doc:expr, $name:ident, $value:expr) => {
#[doc = $doc]
#[derive(Copy, Clone)]
pub struct $name;
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!($value))
}
}
};
}

117
third_party/rust/termion/src/raw.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,117 @@
//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//! break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//! let mut stdout = stdout().into_raw_mode().unwrap();
//!
//! write!(stdout, "Hey there.").unwrap();
//! }
//! ```
use std::io::{self, Write};
use std::ops;
use sys::Termios;
use sys::attr::{get_terminal_attr, raw_terminal_attr, set_terminal_attr};
/// The timeout of an escape code control sequence, in milliseconds.
pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;
/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
pub struct RawTerminal<W: Write> {
prev_ios: Termios,
output: W,
}
impl<W: Write> Drop for RawTerminal<W> {
fn drop(&mut self) {
set_terminal_attr(&self.prev_ios).unwrap();
}
}
impl<W: Write> ops::Deref for RawTerminal<W> {
type Target = W;
fn deref(&self) -> &W {
&self.output
}
}
impl<W: Write> ops::DerefMut for RawTerminal<W> {
fn deref_mut(&mut self) -> &mut W {
&mut self.output
}
}
impl<W: Write> Write for RawTerminal<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.output.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.output.flush()
}
}
/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
/// Switch to raw mode.
///
/// Raw mode means that stdin won't be printed (it will instead have to be written manually by
/// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
/// read from stdin one byte of a time). The output is neither modified in any way.
fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}
impl<W: Write> IntoRawMode for W {
fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
let mut ios = get_terminal_attr()?;
let prev_ios = ios;
raw_terminal_attr(&mut ios);
set_terminal_attr(&ios)?;
Ok(RawTerminal {
prev_ios: prev_ios,
output: self,
})
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::{Write, stdout};
#[test]
fn test_into_raw_mode() {
let mut out = stdout().into_raw_mode().unwrap();
out.write_all(b"this is a test, muahhahahah\r\n").unwrap();
drop(out);
}
}

91
third_party/rust/termion/src/screen.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,91 @@
//! Managing switching between main and alternate screen buffers.
//!
//! Note that this implementation uses xterm's new escape sequences for screen switching and thus
//! only works for xterm compatible terminals (which should be most terminals nowadays).
//!
//! # Example
//!
//! ```rust
//! use termion::screen::AlternateScreen;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//! {
//! let mut screen = AlternateScreen::from(stdout());
//! write!(screen, "Writing to alternate screen!").unwrap();
//! screen.flush().unwrap();
//! }
//! println!("Writing to main screen.");
//! }
//! ```
use std::io::{self, Write};
use std::ops;
use std::fmt;
/// Switch to the main screen buffer of the terminal.
pub struct ToMainScreen;
impl fmt::Display for ToMainScreen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("?1049l"))
}
}
/// Switch to the alternate screen buffer of the terminal.
pub struct ToAlternateScreen;
impl fmt::Display for ToAlternateScreen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("?1049h"))
}
}
/// A terminal restorer, which wraps a type implementing Write, and causes all writes to be written
/// to an alternate screen.
///
/// This is achieved by switching the terminal to the alternate screen on creation and
/// automatically switching it back to the original screen on drop.
pub struct AlternateScreen<W: Write> {
/// The output target.
output: W,
}
impl<W: Write> AlternateScreen<W> {
/// Create an alternate screen wrapper struct for the provided output and switch the terminal
/// to the alternate screen.
pub fn from(mut output: W) -> Self {
write!(output, "{}", ToAlternateScreen).expect("switch to alternate screen");
AlternateScreen { output: output }
}
}
impl<W: Write> Drop for AlternateScreen<W> {
fn drop(&mut self) {
write!(self, "{}", ToMainScreen).expect("switch to main screen");
}
}
impl<W: Write> ops::Deref for AlternateScreen<W> {
type Target = W;
fn deref(&self) -> &W {
&self.output
}
}
impl<W: Write> ops::DerefMut for AlternateScreen<W> {
fn deref_mut(&mut self) -> &mut W {
&mut self.output
}
}
impl<W: Write> Write for AlternateScreen<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.output.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.output.flush()
}
}

23
third_party/rust/termion/src/scroll.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
//! Scrolling.
use std::fmt;
/// Scroll up.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Up(pub u16);
impl fmt::Display for Up {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}S"), self.0)
}
}
/// Scroll down.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct Down(pub u16);
impl fmt::Display for Down {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, csi!("{}T"), self.0)
}
}

22
third_party/rust/termion/src/style.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,22 @@
//! Text styling management.
use std::fmt;
derive_csi_sequence!("Reset SGR parameters.", Reset, "m");
derive_csi_sequence!("Bold text.", Bold, "1m");
derive_csi_sequence!("Fainted text (not widely supported).", Faint, "2m");
derive_csi_sequence!("Italic text.", Italic, "3m");
derive_csi_sequence!("Underlined text.", Underline, "4m");
derive_csi_sequence!("Blinking text (not widely supported).", Blink, "5m");
derive_csi_sequence!("Inverted colors (negative mode).", Invert, "7m");
derive_csi_sequence!("Crossed out text (not widely supported).", CrossedOut, "9m");
derive_csi_sequence!("Undo bold text.", NoBold, "21m");
derive_csi_sequence!("Undo fainted text (not widely supported).", NoFaint, "22m");
derive_csi_sequence!("Undo italic text.", NoItalic, "23m");
derive_csi_sequence!("Undo underlined text.", NoUnderline, "24m");
derive_csi_sequence!("Undo blinking text (not widely supported).", NoBlink, "25m");
derive_csi_sequence!("Undo inverted colors (negative mode).", NoInvert, "27m");
derive_csi_sequence!("Undo crossed out text (not widely supported).",
NoCrossedOut,
"29m");
derive_csi_sequence!("Framed text (not widely supported).", Framed, "51m");

33
third_party/rust/termion/src/sys/redox/attr.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,33 @@
use std::io;
use super::{cvt, syscall, Termios};
pub fn get_terminal_attr() -> io::Result<Termios> {
let mut termios = Termios::default();
let fd = cvt(syscall::dup(0, b"termios"))?;
let res = cvt(syscall::read(fd, &mut termios));
let _ = syscall::close(fd);
if res? == termios.len() {
Ok(termios)
} else {
Err(io::Error::new(io::ErrorKind::Other, "Unable to get the terminal attributes."))
}
}
pub fn set_terminal_attr(termios: &Termios) -> io::Result<()> {
let fd = cvt(syscall::dup(0, b"termios"))?;
let res = cvt(syscall::write(fd, termios));
let _ = syscall::close(fd);
if res? == termios.len() {
Ok(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "Unable to set the terminal attributes."))
}
}
pub fn raw_terminal_attr(ios: &mut Termios) {
ios.make_raw()
}

15
third_party/rust/termion/src/sys/redox/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,15 @@
extern crate redox_termios;
extern crate syscall;
use std::io;
pub use self::redox_termios::Termios;
pub mod attr;
pub mod size;
pub mod tty;
// Support function for converting syscall error to io error
fn cvt(result: Result<usize, syscall::Error>) -> io::Result<usize> {
result.map_err(|err| io::Error::from_raw_os_error(err.errno))
}

18
third_party/rust/termion/src/sys/redox/size.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,18 @@
use std::io;
use super::{cvt, redox_termios, syscall};
/// Get the size of the terminal.
pub fn terminal_size() -> io::Result<(u16, u16)> {
let mut winsize = redox_termios::Winsize::default();
let fd = cvt(syscall::dup(1, b"winsize"))?;
let res = cvt(syscall::read(fd, &mut winsize));
let _ = syscall::close(fd);
if res? == winsize.len() {
Ok((winsize.ws_col, winsize.ws_row))
} else {
Err(io::Error::new(io::ErrorKind::Other, "Unable to get the terminal size."))
}
}

22
third_party/rust/termion/src/sys/redox/tty.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,22 @@
use std::{env, fs, io};
use std::os::unix::io::AsRawFd;
use super::syscall;
/// Is this stream a TTY?
pub fn is_tty<T: AsRawFd>(stream: &T) -> bool {
if let Ok(fd) = syscall::dup(stream.as_raw_fd(), b"termios") {
let _ = syscall::close(fd);
true
} else {
false
}
}
/// Get the TTY device.
///
/// This allows for getting stdio representing _only_ the TTY, and not other streams.
pub fn get_tty() -> io::Result<fs::File> {
let tty = try!(env::var("TTY").map_err(|x| io::Error::new(io::ErrorKind::NotFound, x)));
fs::OpenOptions::new().read(true).write(true).open(tty)
}

29
third_party/rust/termion/src/sys/unix/attr.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,29 @@
use std::{io, mem};
use super::{cvt, Termios};
use super::libc::c_int;
pub fn get_terminal_attr() -> io::Result<Termios> {
extern "C" {
pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
}
unsafe {
let mut termios = mem::zeroed();
cvt(tcgetattr(0, &mut termios))?;
Ok(termios)
}
}
pub fn set_terminal_attr(termios: &Termios) -> io::Result<()> {
extern "C" {
pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int;
}
cvt(unsafe { tcsetattr(0, 0, termios) }).and(Ok(()))
}
pub fn raw_terminal_attr(termios: &mut Termios) {
extern "C" {
pub fn cfmakeraw(termptr: *mut Termios);
}
unsafe { cfmakeraw(termios) }
}

33
third_party/rust/termion/src/sys/unix/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,33 @@
extern crate libc;
use std::io;
pub use self::libc::termios as Termios;
pub mod attr;
pub mod size;
pub mod tty;
// Support functions for converting libc return values to io errors {
trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}
macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}
impl_is_minus_one! { i8 i16 i32 i64 isize }
fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
if t.is_minus_one() {
Err(io::Error::last_os_error())
} else {
Ok(t)
}
}
// } End of support functions

48
third_party/rust/termion/src/sys/unix/size.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
use std::{io, mem};
use super::cvt;
use super::libc::{c_ushort, ioctl, STDOUT_FILENO};
#[repr(C)]
struct TermSize {
row: c_ushort,
col: c_ushort,
_x: c_ushort,
_y: c_ushort,
}
#[cfg(target_os = "linux")]
pub const TIOCGWINSZ: usize = 0x00005413;
#[cfg(not(target_os = "linux"))]
pub const TIOCGWINSZ: usize = 0x40087468;
// Since attributes on non-item statements is not stable yet, we use a function.
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "64")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u64 {
TIOCGWINSZ as u64
}
#[cfg(not(target_os = "android"))]
#[cfg(not(target_os = "redox"))]
#[cfg(target_pointer_width = "32")]
#[cfg(not(target_env = "musl"))]
fn tiocgwinsz() -> u32 {
TIOCGWINSZ as u32
}
#[cfg(any(target_env = "musl", target_os = "android"))]
fn tiocgwinsz() -> i32 {
TIOCGWINSZ as i32
}
/// Get the size of the terminal.
pub fn terminal_size() -> io::Result<(u16, u16)> {
unsafe {
let mut size: TermSize = mem::zeroed();
cvt(ioctl(STDOUT_FILENO, tiocgwinsz(), &mut size as *mut _))?;
Ok((size.col as u16, size.row as u16))
}
}

17
third_party/rust/termion/src/sys/unix/tty.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
use std::{fs, io};
use std::os::unix::io::AsRawFd;
use super::libc;
/// Is this stream a TTY?
pub fn is_tty<T: AsRawFd>(stream: &T) -> bool {
unsafe { libc::isatty(stream.as_raw_fd()) == 1 }
}
/// Get the TTY device.
///
/// This allows for getting stdio representing _only_ the TTY, and not other streams.
pub fn get_tty() -> io::Result<fs::File> {
fs::OpenOptions::new().read(true).write(true).open("/dev/tty")
}