Compare commits
524 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8e9f25b85 | ||
|
|
9305f89f39 | ||
|
|
9c216ad9a4 | ||
|
|
6862e07870 | ||
|
|
a6d09b2d42 | ||
|
|
ab1b877c20 | ||
|
|
2b5c488814 | ||
|
|
cb47be938e | ||
|
|
fe9be658f4 | ||
|
|
8c800adab7 | ||
|
|
d65966efbc | ||
|
|
597bf04a56 | ||
|
|
c78ab9e669 | ||
|
|
d57fc58081 | ||
|
|
d09538c974 | ||
|
|
94768881e1 | ||
|
|
f3a9ced82c | ||
|
|
18f549d289 | ||
|
|
c749b604dc | ||
|
|
d6748a3445 | ||
|
|
9b7f420faa | ||
|
|
361698b90a | ||
|
|
b71a110ccf | ||
|
|
5c1af3c25d | ||
|
|
ad3f55b0e5 | ||
|
|
b8e6d50bbe | ||
|
|
81afe8c5a0 | ||
|
|
c4e0d4bd7b | ||
|
|
23d1b91ead | ||
|
|
ac83ed4992 | ||
|
|
555fbd1201 | ||
|
|
f3146f8316 | ||
|
|
56341973ee | ||
|
|
a431160d4c | ||
|
|
5d15f49f0c | ||
|
|
7718ee362e | ||
|
|
739f8f596b | ||
|
|
e818d7529b | ||
|
|
a2a7f58aa6 | ||
|
|
c4a5bc06c5 | ||
|
|
96ee4482cd | ||
|
|
3effea0b7c | ||
|
|
2d68054b1d | ||
|
|
65a63788bc | ||
|
|
7e5589f07d | ||
|
|
09c5b2c4ea | ||
|
|
904c75bd30 | ||
|
|
ca3e0e8a49 | ||
|
|
ae2d036dd4 | ||
|
|
8e93fa0e7f | ||
|
|
7f5c07434b | ||
|
|
874f0b96a6 | ||
|
|
706323ad8f | ||
|
|
8460d7fe3d | ||
|
|
e1f1ede17d | ||
|
|
6553940328 | ||
|
|
b50ae9a99c | ||
|
|
224c112e05 | ||
|
|
8cb5833ef9 | ||
|
|
85cd3f0a6e | ||
|
|
c57d0fb4e8 | ||
|
|
d83bab4d3f | ||
|
|
ce84e1ef04 | ||
|
|
c8e755f11f | ||
|
|
68dac7c4b0 | ||
|
|
3535047094 | ||
|
|
fe00255494 | ||
|
|
07c837e740 | ||
|
|
cb0e693e31 | ||
|
|
e9d448e93b | ||
|
|
c7fc916e6b | ||
|
|
e36b65a11a | ||
|
|
11ad7ab204 | ||
|
|
93943793c3 | ||
|
|
0fedaa7d28 | ||
|
|
e05023b406 | ||
|
|
f007f940c5 | ||
|
|
a8543f798d | ||
|
|
ef9e17d28a | ||
|
|
3cb4d1337e | ||
|
|
8514d4fbb4 | ||
|
|
ed9150c9b4 | ||
|
|
51864c13fc | ||
|
|
35f802166d | ||
|
|
bba2d56292 | ||
|
|
012880914b | ||
|
|
832f5baf1a | ||
|
|
a6d3a959eb | ||
|
|
f00625c3f4 | ||
|
|
82d03b99cd | ||
|
|
ab2e8190e7 | ||
|
|
58bdc366ec | ||
|
|
34c0b1bc70 | ||
|
|
74e96b498c | ||
|
|
7e0fa1c6be | ||
|
|
50616935a9 | ||
|
|
01b7859399 | ||
|
|
5aed0522e8 | ||
|
|
d1fa295bb2 | ||
|
|
85d463c0cc | ||
|
|
75a4b7b361 | ||
|
|
c687d3a7c0 | ||
|
|
fbc1e7fa18 | ||
|
|
14779ed0ea | ||
|
|
b6177f0459 | ||
|
|
ba1023e1e4 | ||
|
|
5e73075ef5 | ||
|
|
1b42c02489 | ||
|
|
0d03145293 | ||
|
|
f8162d2707 | ||
|
|
e044cfb33f | ||
|
|
7dd1194a97 | ||
|
|
a5855a5d73 | ||
|
|
03b0d832ed | ||
|
|
636bbc7c8f | ||
|
|
162e085b98 | ||
|
|
86c890bcec | ||
|
|
d775259ed9 | ||
|
|
d73a75d6cd | ||
|
|
7ae1f373c2 | ||
|
|
4d34132365 | ||
|
|
5173bfb11b | ||
|
|
8141da9d39 | ||
|
|
373e0595e6 | ||
|
|
1374f15bdf | ||
|
|
263e8f92b9 | ||
|
|
231698f802 | ||
|
|
3e8b44619d | ||
|
|
679198e71a | ||
|
|
2c84825ccb | ||
|
|
948821753c | ||
|
|
d2a3b61220 | ||
|
|
acb57eb4ad | ||
|
|
256aeb5546 | ||
|
|
a9377da624 | ||
|
|
c794ef2f04 | ||
|
|
8b9eba2147 | ||
|
|
c4732ca012 | ||
|
|
1aec4b1123 | ||
|
|
c4e1945384 | ||
|
|
04d17040e7 | ||
|
|
8c8c83a1f8 | ||
|
|
5714dbde09 | ||
|
|
311ccb1f6b | ||
|
|
efa4de8126 | ||
|
|
ad5fa56490 | ||
|
|
1bf9d29259 | ||
|
|
2a14bf2249 | ||
|
|
f0028a66ec | ||
|
|
08060a2105 | ||
|
|
cd575d99f8 | ||
|
|
1267f01c24 | ||
|
|
322d5515e5 | ||
|
|
f4770c2094 | ||
|
|
f887bc1f86 | ||
|
|
363a4fa9b7 | ||
|
|
712311fdc6 | ||
|
|
0d2354aca6 | ||
|
|
8dc513b5d2 | ||
|
|
a98156e71c | ||
|
|
cf94072429 | ||
|
|
db14046de4 | ||
|
|
36091591f0 | ||
|
|
12ffcb4296 | ||
|
|
e7c06b92fb | ||
|
|
353806b87a | ||
|
|
aebb132a86 | ||
|
|
ab4b6ab9c3 | ||
|
|
413178bc2c | ||
|
|
58fb4f987e | ||
|
|
4f1d6af296 | ||
|
|
6b79349f83 | ||
|
|
f858828f61 | ||
|
|
67b835fe2a | ||
|
|
214f2bef66 | ||
|
|
1136f8adab | ||
|
|
beb010d004 | ||
|
|
f9cbf7d3d4 | ||
|
|
7eb1dd129e | ||
|
|
a5f82e8826 | ||
|
|
ca6bd648ab | ||
|
|
af77dd55a2 | ||
|
|
3065a8c9c8 | ||
|
|
208c11af56 | ||
|
|
12a78a992c | ||
|
|
d97c80be63 | ||
|
|
5213bd30ea | ||
|
|
82d101907a | ||
|
|
30608f2444 | ||
|
|
3d323928a0 | ||
|
|
8b6a3bc858 | ||
|
|
e10544f819 | ||
|
|
dc7e39a6ba | ||
|
|
36c16eb00c | ||
|
|
fffee61f80 | ||
|
|
4cfb2b515b | ||
|
|
398326bfe2 | ||
|
|
01358a155c | ||
|
|
30ca3ecca6 | ||
|
|
dbc91644fd | ||
|
|
73c9ac4da5 | ||
|
|
fe7fe74b0a | ||
|
|
3d9acdab18 | ||
|
|
40bacbcd7c | ||
|
|
b3a9c34515 | ||
|
|
972ec1adc6 | ||
|
|
a2d4c03c71 | ||
|
|
b7c3cf314d | ||
|
|
6dce04963d | ||
|
|
d4b790fd8d | ||
|
|
9283dd122e | ||
|
|
4c41e9225b | ||
|
|
9f2b054550 | ||
|
|
5613df3034 | ||
|
|
79ad81626f | ||
|
|
354a5cad97 | ||
|
|
92e5fad27d | ||
|
|
f86f987d71 | ||
|
|
bfbd53eb92 | ||
|
|
0668c74ed4 | ||
|
|
1c03298903 | ||
|
|
e0e8f26c56 | ||
|
|
f5337329f4 | ||
|
|
84f4b4ef68 | ||
|
|
aeac85389d | ||
|
|
9b3921098a | ||
|
|
ad262f1146 | ||
|
|
170c078440 | ||
|
|
db044a058a | ||
|
|
c1f8040b32 | ||
|
|
c8a5a7a3f4 | ||
|
|
dd3df0ded7 | ||
|
|
62a182af78 | ||
|
|
4047d9db71 | ||
|
|
4683a325fa | ||
|
|
b6f1e5db1a | ||
|
|
9e51b18ac7 | ||
|
|
9d7b6eb09a | ||
|
|
7763c98188 | ||
|
|
06393f888c | ||
|
|
e0989ef13b | ||
|
|
45e850aff7 | ||
|
|
f2d1c582a8 | ||
|
|
ab70815ea2 | ||
|
|
27f97db510 | ||
|
|
506ad1f3cf | ||
|
|
13235b596f | ||
|
|
2628c8f38e | ||
|
|
112b3c5e0a | ||
|
|
4c78ca8b70 | ||
|
|
ff898cd105 | ||
|
|
2c98e5ce1e | ||
|
|
1e3fc79949 | ||
|
|
d1bbc6956b | ||
|
|
cd6c54f5f4 | ||
|
|
44c03f58bc | ||
|
|
d1a6ab922e | ||
|
|
b860fa3acd | ||
|
|
229b8e3b33 | ||
|
|
a515c4d601 | ||
|
|
5a666b042d | ||
|
|
16109166fe | ||
|
|
0b685c8429 | ||
|
|
d2c7a76a3c | ||
|
|
20f7d9b3a2 | ||
|
|
362abed44a | ||
|
|
c50b8b4125 | ||
|
|
7ad23e5565 | ||
|
|
66efbad871 | ||
|
|
1f2a9b0306 | ||
|
|
a45fe94240 | ||
|
|
ac1c95a6d9 | ||
|
|
685b431d80 | ||
|
|
487713aa34 | ||
|
|
e300541701 | ||
|
|
e9df420d2f | ||
|
|
201b4fc757 | ||
|
|
90a11dec5e | ||
|
|
9456d95e8f | ||
|
|
0c298f60a6 | ||
|
|
79271fcb33 | ||
|
|
fc975af8e9 | ||
|
|
1425d6735e | ||
|
|
aed3ccb9c7 | ||
|
|
33c95d2919 | ||
|
|
01deac9427 | ||
|
|
b4bc3b6349 | ||
|
|
685cc6c562 | ||
|
|
08c017330f | ||
|
|
2f3a8c7f69 | ||
|
|
3ac1b68e54 | ||
|
|
0ebd5465b7 | ||
|
|
5cb4bb9ea0 | ||
|
|
c8a179b4da | ||
|
|
46f94826fd | ||
|
|
75f1855a91 | ||
|
|
fd9870d668 | ||
|
|
a3a2708067 | ||
|
|
78847b65c8 | ||
|
|
e962eea1cc | ||
|
|
95bc678403 | ||
|
|
68af3bbdc4 | ||
|
|
70b6bdb104 | ||
|
|
c648eadbaa | ||
|
|
d352b79294 | ||
|
|
23aec58669 | ||
|
|
ae863bc7aa | ||
|
|
f0d3cae569 | ||
|
|
4ef4818130 | ||
|
|
8db24e1353 | ||
|
|
8bbe58d623 | ||
|
|
b3fd0df94b | ||
|
|
c1b841e934 | ||
|
|
f5ede0e319 | ||
|
|
6ecffec537 | ||
|
|
80e91a1f1d | ||
|
|
d570f78144 | ||
|
|
7c37065911 | ||
|
|
50f7a60a8d | ||
|
|
33ec988d70 | ||
|
|
adff43fbb4 | ||
|
|
71585f6d47 | ||
|
|
714ae82241 | ||
|
|
49fd668712 | ||
|
|
066f97d855 | ||
|
|
df1bf4a042 | ||
|
|
4e8c0fc4ad | ||
|
|
da1764dfd1 | ||
|
|
48a8a3a691 | ||
|
|
796eaab0d7 | ||
|
|
bf49448e1e | ||
|
|
cffba53379 | ||
|
|
79d40d0e20 | ||
|
|
525b278049 | ||
|
|
16de47920c | ||
|
|
a114b86063 | ||
|
|
a5a16ebb27 | ||
|
|
8ac5bc0147 | ||
|
|
cf750a190f | ||
|
|
d825648b86 | ||
|
|
22cb644eb6 | ||
|
|
e424f87487 | ||
|
|
f5b2c96b77 | ||
|
|
6e209b6fdb | ||
|
|
72e3c54e0a | ||
|
|
b67886264f | ||
|
|
e67ab459d3 | ||
|
|
7a926d090d | ||
|
|
596f94aa7f | ||
|
|
de55d37bea | ||
|
|
fecef10c1c | ||
|
|
79e5e6671f | ||
|
|
b04a68a782 | ||
|
|
e573ab5c60 | ||
|
|
f5a2d022ec | ||
|
|
b1d1cd2366 | ||
|
|
f26e0f088f | ||
|
|
057ed6305a | ||
|
|
730beb9cb5 | ||
|
|
ed60ec736c | ||
|
|
a7ca2d6563 | ||
|
|
a7d0e40668 | ||
|
|
7a951f103a | ||
|
|
c3de1f58ea | ||
|
|
e940bc956d | ||
|
|
8751e55706 | ||
|
|
2143bcf9cb | ||
|
|
a6a24bafb3 | ||
|
|
db27a33827 | ||
|
|
083fb73790 | ||
|
|
461e0c4e33 | ||
|
|
82df3b7685 | ||
|
|
ece6011164 | ||
|
|
00033e1875 | ||
|
|
5aea517fb4 | ||
|
|
073ff35ebb | ||
|
|
c4633ff187 | ||
|
|
97e6873b38 | ||
|
|
ed01e80a79 | ||
|
|
8f7b9be356 | ||
|
|
851799f42b | ||
|
|
b65a8c353b | ||
|
|
95cea77625 | ||
|
|
b187c1a817 | ||
|
|
f7a2fe30d4 | ||
|
|
aed315e80a | ||
|
|
2f0d9d411a | ||
|
|
163e00677a | ||
|
|
d58236fbdc | ||
|
|
932875684e | ||
|
|
b65bb37b14 | ||
|
|
de5cb7d22e | ||
|
|
7a682f465e | ||
|
|
084d3f4911 | ||
|
|
9911cd0cd9 | ||
|
|
de91c26bb1 | ||
|
|
5b1796d64d | ||
|
|
d4527854de | ||
|
|
82ceb818f3 | ||
|
|
dd5ded2f78 | ||
|
|
cbacf4f19e | ||
|
|
900ef0abc7 | ||
|
|
8396d3ffaa | ||
|
|
652c70f207 | ||
|
|
bb70f96743 | ||
|
|
6d346a09de | ||
|
|
699c76f45c | ||
|
|
de33003527 | ||
|
|
3e943636f4 | ||
|
|
3f515afbb4 | ||
|
|
30db03bb62 | ||
|
|
d66812102b | ||
|
|
86f8c3c818 | ||
|
|
5eb2ca4338 | ||
|
|
20bcb8d883 | ||
|
|
7282706b42 | ||
|
|
160f04894f | ||
|
|
0473df1ef5 | ||
|
|
301a3fd71d | ||
|
|
d12bdf35a5 | ||
|
|
08514e8e6c | ||
|
|
687e846944 | ||
|
|
b286fdcb88 | ||
|
|
e3959d67a6 | ||
|
|
7d475b0c70 | ||
|
|
42223047a8 | ||
|
|
42afb6faa5 | ||
|
|
c4a6733f3b | ||
|
|
9e04a8283c | ||
|
|
05b26d5986 | ||
|
|
506f046b8b | ||
|
|
ae592b11e3 | ||
|
|
a5e7f176f1 | ||
|
|
0428bd1bec | ||
|
|
7f3e7d2faa | ||
|
|
8d5906d7fc | ||
|
|
feda38852e | ||
|
|
59187902d0 | ||
|
|
aef46beaf2 | ||
|
|
f0e192943f | ||
|
|
df72d8d1e0 | ||
|
|
d06f84ced3 | ||
|
|
9598331fa8 | ||
|
|
883d8fc72f | ||
|
|
e8a30cb893 | ||
|
|
03f7605322 | ||
|
|
61663e2307 | ||
|
|
bd3e7eedb1 | ||
|
|
1e6c2ac8e3 | ||
|
|
0302d58eb8 | ||
|
|
e37f783fc0 | ||
|
|
495e13cc61 | ||
|
|
92dc402f7f | ||
|
|
a3f5e0c3d5 | ||
|
|
39e1a0d694 | ||
|
|
e9cd0a1cc3 | ||
|
|
cc35ae0748 | ||
|
|
5ee175beaf | ||
|
|
4b18f82899 | ||
|
|
5462af4434 | ||
|
|
d2e70da040 | ||
|
|
64dc9b6709 | ||
|
|
9ffd4c421f | ||
|
|
d862b80afb | ||
|
|
5b73dcc8ab | ||
|
|
2dce0dc0df | ||
|
|
2e5c3c05e8 | ||
|
|
6884eea2f5 | ||
|
|
a3a2f0be6a | ||
|
|
f24873c70b | ||
|
|
58126ffe15 | ||
|
|
17644a76c0 | ||
|
|
9fc9f368f5 | ||
|
|
9cab076a72 | ||
|
|
7aa9652f3c | ||
|
|
7187f61ca8 | ||
|
|
f869c58a5a | ||
|
|
3538ba3577 | ||
|
|
a454fa75b9 | ||
|
|
18943b9317 | ||
|
|
68427b5b79 | ||
|
|
4ca15a8a51 | ||
|
|
2daef51fe5 | ||
|
|
43ed91dc5c | ||
|
|
dada75d2a7 | ||
|
|
76b9f01ad2 | ||
|
|
8baa0e56b7 | ||
|
|
301ee6d3f5 | ||
|
|
77ad7588ae | ||
|
|
58aca2efb2 | ||
|
|
351eddc17e | ||
|
|
277dda544c | ||
|
|
8c869cbd87 | ||
|
|
598b162fea | ||
|
|
0222e024fe | ||
|
|
5bd0edbbe1 | ||
|
|
4368913d8f | ||
|
|
02de97b8ce | ||
|
|
32db773d51 | ||
|
|
b272be25fa | ||
|
|
f63c168563 | ||
|
|
a05671c8d7 | ||
|
|
1aeae3e22d | ||
|
|
60d537c43d | ||
|
|
ef5c07476b | ||
|
|
4f6f34307c | ||
|
|
7cf560d27c | ||
|
|
15b263ff55 | ||
|
|
53121e0733 | ||
|
|
404785f950 | ||
|
|
103c4c953c | ||
|
|
82abf883c5 | ||
|
|
a2315d5ee5 | ||
|
|
201d0cb8c1 | ||
|
|
6f45478a7d | ||
|
|
9c2c569624 | ||
|
|
a1e4e0f85c | ||
|
|
caf31a769b | ||
|
|
920112e640 | ||
|
|
a84ffe603b | ||
|
|
e4f83f3161 | ||
|
|
fbca4a0332 | ||
|
|
65c7df1c25 | ||
|
|
18237da9b2 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -4,3 +4,14 @@ target
|
||||
/grep/Cargo.lock
|
||||
/globset/Cargo.lock
|
||||
/ignore/Cargo.lock
|
||||
/termcolor/Cargo.lock
|
||||
/wincolor/Cargo.lock
|
||||
/deployment
|
||||
|
||||
# Snapcraft files
|
||||
stage
|
||||
prime
|
||||
parts
|
||||
*.snap
|
||||
*.pyc
|
||||
ripgrep*_source.tar.bz2
|
||||
|
||||
116
.travis.yml
116
.travis.yml
@@ -1,14 +1,27 @@
|
||||
language: rust
|
||||
cache: cargo
|
||||
|
||||
env:
|
||||
global:
|
||||
- PROJECT_NAME=ripgrep
|
||||
- PROJECT_NAME: ripgrep
|
||||
- RUST_BACKTRACE: full
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# For generating man page.
|
||||
- libxslt1-dev
|
||||
- asciidoc
|
||||
- docbook-xsl
|
||||
- xsltproc
|
||||
- libxml2-utils
|
||||
# Needed for completion-function test.
|
||||
- zsh
|
||||
# Needed for testing decompression search.
|
||||
- xz-utils
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
# Nightly channel.
|
||||
# (All *nix releases are done on the nightly channel to take advantage
|
||||
# of the regex library's multiple pattern SIMD search.)
|
||||
# All *nix releases are done on the nightly channel to take advantage
|
||||
# of the regex library's multiple pattern SIMD search.
|
||||
- os: linux
|
||||
rust: nightly
|
||||
env: TARGET=i686-unknown-linux-musl
|
||||
@@ -17,64 +30,77 @@ matrix:
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: osx
|
||||
rust: nightly
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
# Beta channel.
|
||||
# XML_CATALOG_FILES is apparently necessary for asciidoc on macOS.
|
||||
env: TARGET=x86_64-apple-darwin XML_CATALOG_FILES=/usr/local/etc/xml/catalog
|
||||
- os: linux
|
||||
rust: nightly
|
||||
env: TARGET=arm-unknown-linux-gnueabihf GCC_VERSION=4.8
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-4.8-arm-linux-gnueabihf
|
||||
- binutils-arm-linux-gnueabihf
|
||||
- libc6-armhf-cross
|
||||
- libc6-dev-armhf-cross
|
||||
# For generating man page.
|
||||
- libxslt1-dev
|
||||
- asciidoc
|
||||
- docbook-xsl
|
||||
- xsltproc
|
||||
- libxml2-utils
|
||||
# Beta channel. We enable these to make sure there are no regressions in
|
||||
# Rust beta releases.
|
||||
- os: linux
|
||||
rust: beta
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: beta
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: beta
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
# Minimum Rust supported channel.
|
||||
# Minimum Rust supported channel. We enable these to make sure ripgrep
|
||||
# continues to work on the advertised minimum Rust version.
|
||||
- os: linux
|
||||
rust: 1.9.0
|
||||
rust: 1.20.0
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: linux
|
||||
rust: 1.20.0
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: 1.9.0
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: 1.9.0
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
|
||||
before_install:
|
||||
- export PATH="$PATH:$HOME/.cargo/bin"
|
||||
|
||||
install:
|
||||
- bash ci/install.sh
|
||||
|
||||
script:
|
||||
- bash ci/script.sh
|
||||
|
||||
before_deploy:
|
||||
- bash ci/before_deploy.sh
|
||||
|
||||
rust: 1.20.0
|
||||
env: TARGET=arm-unknown-linux-gnueabihf GCC_VERSION=4.8
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-4.8-arm-linux-gnueabihf
|
||||
- binutils-arm-linux-gnueabihf
|
||||
- libc6-armhf-cross
|
||||
- libc6-dev-armhf-cross
|
||||
# For generating man page.
|
||||
- libxslt1-dev
|
||||
- asciidoc
|
||||
- docbook-xsl
|
||||
- xsltproc
|
||||
- libxml2-utils
|
||||
install: ci/install.sh
|
||||
script: ci/script.sh
|
||||
before_deploy: ci/before_deploy.sh
|
||||
deploy:
|
||||
provider: releases
|
||||
file_glob: true
|
||||
file: deployment/${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}.tar.gz
|
||||
skip_cleanup: true
|
||||
on:
|
||||
condition: $TRAVIS_RUST_VERSION = nightly
|
||||
branch: master
|
||||
tags: true
|
||||
api_key:
|
||||
secure: "IbSnsbGkxSydR/sozOf1/SRvHplzwRUHzcTjM7BKnr7GccL86gRPUrsrvD103KjQUGWIc1TnK1YTq5M0Onswg/ORDjqa1JEJPkPdPnVh9ipbF7M2De/7IlB4X4qXLKoApn8+bx2x/mfYXu4G+G1/2QdbaKK2yfXZKyjz0YFx+6CNrVCT2Nk8q7aHvOOzAL58vsG8iPDpupuhxlMDDn/UhyOWVInmPPQ0iJR1ZUJN8xJwXvKvBbfp3AhaBiAzkhXHNLgBR8QC5noWWMXnuVDMY3k4f3ic0V+p/qGUCN/nhptuceLxKFicMCYObSZeUzE5RAI0/OBW7l3z2iCoc+TbAnn+JrX/ObJCfzgAOXAU3tLaBFMiqQPGFKjKg1ltSYXomOFP/F7zALjpvFp4lYTBajRR+O3dqaxA9UQuRjw27vOeUpMcga4ZzL4VXFHzrxZKBHN//XIGjYAVhJ1NSSeGpeJV5/+jYzzWKfwSagRxQyVCzMooYFFXzn8Yxdm3PJlmp3GaAogNkdB9qKcrEvRINCelalzALPi0hD/HUDi8DD2PNTCLLMo6VSYtvc685Zbe+KgNzDV1YyTrRCUW6JotrS0r2ULLwnsh40hSB//nNv3XmwNmC/CmW5QAnIGj8cBMF4S2t6ohADIndojdAfNiptmaZOIT6owK7bWMgPMyopo="
|
||||
file_glob: true
|
||||
file: ${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}.*
|
||||
# don't delete the artifacts from previous phases
|
||||
skip_cleanup: true
|
||||
# deploy when a new tag is pushed
|
||||
on:
|
||||
# channel to use to produce the release artifacts
|
||||
# NOTE make sure you only release *once* per target
|
||||
# TODO you may want to pick a different channel
|
||||
condition: $TRAVIS_RUST_VERSION = nightly
|
||||
tags: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
# Pushes and PR to the master branch
|
||||
- master
|
||||
# IMPORTANT Ruby regex to match tags. Required, or travis won't trigger deploys when a new tag
|
||||
# is pushed. This regex matches semantic versions like v1.2.3-rc4+2016.02.22
|
||||
# Ruby regex to match tags. Required, or travis won't trigger deploys when
|
||||
# a new tag is pushed.
|
||||
- /^\d+\.\d+\.\d+.*$/
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
|
||||
611
CHANGELOG.md
611
CHANGELOG.md
@@ -1,3 +1,614 @@
|
||||
0.8.1 (2018-02-20)
|
||||
==================
|
||||
This is a patch release of ripgrep that primarily fixes regressions introduced
|
||||
in 0.8.0 (#820 and #824) in directory traversal on Windows. These regressions
|
||||
do not impact non-Windows users.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for csv and VHDL.
|
||||
* [FEATURE #798](https://github.com/BurntSushi/ripgrep/issues/798):
|
||||
Add `underline` support to `termcolor` and ripgrep. See documentation on the
|
||||
`--colors` flag for details.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #684](https://github.com/BurntSushi/ripgrep/issues/684):
|
||||
Improve documentation for the `--ignore-file` flag.
|
||||
* [BUG #789](https://github.com/BurntSushi/ripgrep/issues/789):
|
||||
Don't show `(rev )` if the revision wasn't available during the build.
|
||||
* [BUG #791](https://github.com/BurntSushi/ripgrep/issues/791):
|
||||
Add man page to ARM release.
|
||||
* [BUG #797](https://github.com/BurntSushi/ripgrep/issues/797):
|
||||
Improve documentation for "intense" setting in `termcolor`.
|
||||
* [BUG #800](https://github.com/BurntSushi/ripgrep/issues/800):
|
||||
Fix a bug in the `ignore` crate for custom ignore files. This had no impact
|
||||
on ripgrep.
|
||||
* [BUG #807](https://github.com/BurntSushi/ripgrep/issues/807):
|
||||
Fix a bug where `rg --hidden .` behaved differently from `rg --hidden ./`.
|
||||
* [BUG #815](https://github.com/BurntSushi/ripgrep/issues/815):
|
||||
Clarify a common failure mode in user guide.
|
||||
* [BUG #820](https://github.com/BurntSushi/ripgrep/issues/820):
|
||||
Fixes a bug on Windows where symlinks were followed even if not requested.
|
||||
* [BUG #824](https://github.com/BurntSushi/ripgrep/issues/824):
|
||||
Fix a performance regression in directory traversal on Windows.
|
||||
|
||||
|
||||
0.8.0 (2018-02-11)
|
||||
==================
|
||||
This is a new minor version releae of ripgrep that satisfies several popular
|
||||
feature requests (config files, search compressed files, true colors), fixes
|
||||
many bugs and improves the quality of life for ripgrep maintainers. This
|
||||
release also includes greatly improved documentation in the form of a
|
||||
[User Guide](GUIDE.md) and a [FAQ](FAQ.md).
|
||||
|
||||
This release increases the **minimum supported Rust version** from 1.17 to
|
||||
1.20.
|
||||
|
||||
**BREAKING CHANGES**:
|
||||
|
||||
Note that these are all very minor and unlikely to impact most users.
|
||||
|
||||
* In order to support configuration files, flag overrides needed to be
|
||||
rethought. In some cases, this changed ripgrep's behavior. For example,
|
||||
in ripgrep 0.7.1, `rg foo -s -i` will perform a case sensitive search
|
||||
since the `-s/--case-sensitive` flag was defined to always take precedence
|
||||
over the `-i/--ignore-case` flag, regardless of position. In ripgrep 0.8.0
|
||||
however, the override rule for all flags has changed to "the most recent
|
||||
flag wins among competing flags." That is, `rg foo -s -i` now performs a
|
||||
case insensitive search.
|
||||
* The `-M/--max-columns` flag was tweaked so that specifying a value of `0`
|
||||
now makes ripgrep behave as if the flag was absent. This makes it possible
|
||||
to set a default value in a configuration file and then override it. The
|
||||
previous ripgrep behavior was to suppress all matching non-empty lines.
|
||||
* In all globs, `[^...]` is now equivalent to `[!...]` (indicating class
|
||||
negation). Previously, `^` had no special significance in a character class.
|
||||
* For **downstream packagers**, the directory hierarchy in ripgrep's archive
|
||||
releases has changed. The root directory now only contains the executable,
|
||||
README and license. There is now a new directory called `doc` which contains
|
||||
the man page (previously in the root), a user guide (new), a FAQ (new) and
|
||||
the CHANGELOG (previously not included in release). The `complete`
|
||||
directory remains the same.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for
|
||||
Apache Avro, C++, GN, Google Closure Templates, Jupyter notebooks, man pages,
|
||||
Protocol Buffers, Smarty and Web IDL.
|
||||
* [FEATURE #196](https://github.com/BurntSushi/ripgrep/issues/196):
|
||||
Support a configuration file. See
|
||||
[the new user guide](GUIDE.md#configuration-file)
|
||||
for details.
|
||||
* [FEATURE #261](https://github.com/BurntSushi/ripgrep/issues/261):
|
||||
Add extended or "true" color support. Works in Windows 10!
|
||||
[See the FAQ for details.](FAQ.md#colors)
|
||||
* [FEATURE #539](https://github.com/BurntSushi/ripgrep/issues/539):
|
||||
Search gzip, bzip2, lzma or xz files when given `-z/--search-zip` flag.
|
||||
* [FEATURE #544](https://github.com/BurntSushi/ripgrep/issues/544):
|
||||
Add support for line number alignment via a new `--line-number-width` flag.
|
||||
* [FEATURE #654](https://github.com/BurntSushi/ripgrep/pull/654):
|
||||
Support linuxbrew in ripgrep's Brew tap.
|
||||
* [FEATURE #673](https://github.com/BurntSushi/ripgrep/issues/673):
|
||||
Bring back `.rgignore` files. (A higher precedent, application specific
|
||||
version of `.ignore`.)
|
||||
* [FEATURE #676](https://github.com/BurntSushi/ripgrep/issues/676):
|
||||
Provide ARM binaries. **WARNING:** This will be provided on a best effort
|
||||
basis.
|
||||
* [FEATURE #709](https://github.com/BurntSushi/ripgrep/issues/709):
|
||||
Suggest `-F/--fixed-strings` flag on a regex syntax error.
|
||||
* [FEATURE #740](https://github.com/BurntSushi/ripgrep/issues/740):
|
||||
Add a `--passthru` flag that causes ripgrep to print every line it reads.
|
||||
* [FEATURE #785](https://github.com/BurntSushi/ripgrep/pull/785):
|
||||
Overhaul documentation. Cleaned up README, added user guide and FAQ.
|
||||
* [FEATURE 7f5c07](https://github.com/BurntSushi/ripgrep/commit/7f5c07434be92103b5bf7e216b9c7494aed2d8cb):
|
||||
Add hidden flags for convenient overrides (e.g., `--no-text`).
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #553](https://github.com/BurntSushi/ripgrep/issues/553):
|
||||
Permit flags to be repeated.
|
||||
* [BUG #633](https://github.com/BurntSushi/ripgrep/issues/633):
|
||||
Fix a bug where ripgrep would panic on Windows while following symlinks.
|
||||
* [BUG #649](https://github.com/BurntSushi/ripgrep/issues/649):
|
||||
Fix handling of `!**/` in `.gitignore`.
|
||||
* [BUG #663](https://github.com/BurntSushi/ripgrep/issues/663):
|
||||
**BREAKING CHANGE:** Support `[^...]` glob syntax (as identical to `[!...]`).
|
||||
* [BUG #693](https://github.com/BurntSushi/ripgrep/issues/693):
|
||||
Don't display context separators when not printing matches.
|
||||
* [BUG #705](https://github.com/BurntSushi/ripgrep/issues/705):
|
||||
Fix a bug that prevented ripgrep from searching OneDrive directories.
|
||||
* [BUG #717](https://github.com/BurntSushi/ripgrep/issues/717):
|
||||
Improve `--smart-case` uppercase character detection.
|
||||
* [BUG #725](https://github.com/BurntSushi/ripgrep/issues/725):
|
||||
Clarify that globs do not override explicitly given paths to search.
|
||||
* [BUG #742](https://github.com/BurntSushi/ripgrep/pull/742):
|
||||
Write ANSI reset code as `\x1B[0m` instead of `\x1B[m`.
|
||||
* [BUG #747](https://github.com/BurntSushi/ripgrep/issues/747):
|
||||
Remove `yarn.lock` from YAML file type.
|
||||
* [BUG #760](https://github.com/BurntSushi/ripgrep/issues/760):
|
||||
ripgrep can now search `/sys/devices/system/cpu/vulnerabilities/*` files.
|
||||
* [BUG #761](https://github.com/BurntSushi/ripgrep/issues/761):
|
||||
Fix handling of gitignore patterns that contain a `/`.
|
||||
* [BUG #776](https://github.com/BurntSushi/ripgrep/pull/776):
|
||||
**BREAKING CHANGE:** `--max-columns=0` now disables the limit.
|
||||
* [BUG #779](https://github.com/BurntSushi/ripgrep/issues/779):
|
||||
Clarify documentation for `--files-without-match`.
|
||||
* [BUG #780](https://github.com/BurntSushi/ripgrep/issues/780),
|
||||
[BUG #781](https://github.com/BurntSushi/ripgrep/issues/781):
|
||||
Fix bug where ripgrep missed some matching lines.
|
||||
|
||||
Maintenance fixes:
|
||||
|
||||
* [MAINT #772](https://github.com/BurntSushi/ripgrep/pull/772):
|
||||
Drop `env_logger` in favor of simpler logger to avoid many new dependencies.
|
||||
* [MAINT #772](https://github.com/BurntSushi/ripgrep/pull/772):
|
||||
Add git revision hash to ripgrep's version string.
|
||||
* [MAINT #772](https://github.com/BurntSushi/ripgrep/pull/772):
|
||||
(Seemingly) improve compile times.
|
||||
* [MAINT #776](https://github.com/BurntSushi/ripgrep/pull/776):
|
||||
Automatically generate man page during build.
|
||||
* [MAINT #786](https://github.com/BurntSushi/ripgrep/pull/786):
|
||||
Remove use of `unsafe` in `globset`. :tada:
|
||||
* [MAINT e9d448](https://github.com/BurntSushi/ripgrep/commit/e9d448e93bb4e1fb3b0c1afc29adb5af6ed5283d):
|
||||
Add an issue template (has already drastically improved bug reports).
|
||||
* [MAINT ae2d03](https://github.com/BurntSushi/ripgrep/commit/ae2d036dd4ba2a46acac9c2d77c32e7c667eb850):
|
||||
Remove the `compile` script.
|
||||
|
||||
Friends of ripgrep:
|
||||
|
||||
I'd like to extend my gratitude to
|
||||
[@balajisivaraman](https://github.com/balajisivaraman)
|
||||
for their recent hard work in a number of areas, and in particular, for
|
||||
implementing the "search compressed files" feature. Their work in sketching out
|
||||
a specification for that and other work has been exemplary.
|
||||
|
||||
Thanks
|
||||
[@balajisivaraman](https://github.com/balajisivaraman)!
|
||||
|
||||
|
||||
0.7.1 (2017-10-22)
|
||||
==================
|
||||
This is a patch release of ripgrep that includes a fix to very bad regression
|
||||
introduced in ripgrep 0.7.0.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #648](https://github.com/BurntSushi/ripgrep/issues/648):
|
||||
Fix a bug where it was very easy to exceed standard file descriptor limits.
|
||||
|
||||
|
||||
0.7.0 (2017-10-20)
|
||||
==================
|
||||
This is a new minor version release of ripgrep that includes mostly bug fixes.
|
||||
|
||||
ripgrep continues to require Rust 1.17, and there are no known breaking changes
|
||||
introduced in this release.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for config & license files, Elm,
|
||||
Purescript, Standard ML, sh, systemd, Terraform
|
||||
* [FEATURE #593](https://github.com/BurntSushi/ripgrep/pull/593):
|
||||
Using both `-o/--only-matching` and `-r/--replace` does the right thing.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #200](https://github.com/BurntSushi/ripgrep/issues/200):
|
||||
ripgrep will stop when its pipe is closed.
|
||||
* [BUG #402](https://github.com/BurntSushi/ripgrep/issues/402):
|
||||
Fix context printing bug when the `-m/--max-count` flag is used.
|
||||
* [BUG #521](https://github.com/BurntSushi/ripgrep/issues/521):
|
||||
Fix interaction between `-r/--replace` and terminal colors.
|
||||
* [BUG #559](https://github.com/BurntSushi/ripgrep/issues/559):
|
||||
Ignore test that tried reading a non-UTF-8 file path on macOS.
|
||||
* [BUG #599](https://github.com/BurntSushi/ripgrep/issues/599):
|
||||
Fix color escapes on empty matches.
|
||||
* [BUG #600](https://github.com/BurntSushi/ripgrep/issues/600):
|
||||
Avoid expensive (on Windows) file handle check when using --files.
|
||||
* [BUG #618](https://github.com/BurntSushi/ripgrep/issues/618):
|
||||
Clarify installation instructions for Ubuntu users.
|
||||
* [BUG #633](https://github.com/BurntSushi/ripgrep/issues/633):
|
||||
Faster symlink loop checking on Windows.
|
||||
|
||||
|
||||
0.6.0 (2017-08-23)
|
||||
==================
|
||||
This is a new minor version release of ripgrep that includes many bug fixes
|
||||
and a few new features such as `--iglob` and `-x/--line-regexp`.
|
||||
|
||||
Note that this release increases the minimum supported Rust version from 1.12
|
||||
to 1.17.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for BitBake, C++, Cabal, cshtml, Julia,
|
||||
Make, msbuild, QMake, Yocto
|
||||
* [FEATURE #163](https://github.com/BurntSushi/ripgrep/issues/163):
|
||||
Add an `--iglob` flag that is like `-g/--glob`, but matches globs
|
||||
case insensitively.
|
||||
* [FEATURE #520](https://github.com/BurntSushi/ripgrep/pull/518):
|
||||
Add `-x/--line-regexp` flag, which requires a match to span an entire line.
|
||||
* [FEATURE #551](https://github.com/BurntSushi/ripgrep/pull/551),
|
||||
[FEATURE #554](https://github.com/BurntSushi/ripgrep/pull/554):
|
||||
`ignore`: add new `matched_path_or_any_parents` method.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #342](https://github.com/BurntSushi/ripgrep/issues/342):
|
||||
Fix invisible text in some PowerShell environments by changing the
|
||||
default color scheme on Windows.
|
||||
* [BUG #413](https://github.com/BurntSushi/ripgrep/issues/413):
|
||||
Release binaries on Unix are now `strip`'d by default. This decreases
|
||||
binary size by an order of magnitude.
|
||||
* [BUG #483](https://github.com/BurntSushi/ripgrep/issues/483):
|
||||
When `--quiet` is passed, `--files` should be quiet.
|
||||
* [BUG #488](https://github.com/BurntSushi/ripgrep/pull/488):
|
||||
When `--vimgrep` is passed, `--with-filename` should be enabled
|
||||
automatically.
|
||||
* [BUG #493](https://github.com/BurntSushi/ripgrep/issues/493):
|
||||
Fix another bug in the implementation of the `-o/--only-matching`
|
||||
flag.
|
||||
* [BUG #499](https://github.com/BurntSushi/ripgrep/pull/499):
|
||||
Permit certain flags to override others.
|
||||
* [BUG #523](https://github.com/BurntSushi/ripgrep/pull/523):
|
||||
`wincolor`: Re-fetch Windows console on all calls.
|
||||
* [BUG #523](https://github.com/BurntSushi/ripgrep/issues/524):
|
||||
`--version` now shows enabled compile-time features.
|
||||
* [BUG #532](https://github.com/BurntSushi/ripgrep/issues/532),
|
||||
[BUG #536](https://github.com/BurntSushi/ripgrep/pull/536),
|
||||
[BUG #538](https://github.com/BurntSushi/ripgrep/pull/538),
|
||||
[BUG #540](https://github.com/BurntSushi/ripgrep/pull/540),
|
||||
[BUG #560](https://github.com/BurntSushi/ripgrep/pull/560),
|
||||
[BUG #565](https://github.com/BurntSushi/ripgrep/pull/565):
|
||||
Improve zsh completion.
|
||||
* [BUG #578](https://github.com/BurntSushi/ripgrep/pull/578):
|
||||
Enable SIMD for `encoding_rs` when appropriate.
|
||||
* [BUG #580](https://github.com/BurntSushi/ripgrep/issues/580):
|
||||
Fix `-w/--word-regexp` in the presence of capturing groups.
|
||||
* [BUG #581](https://github.com/BurntSushi/ripgrep/issues/581):
|
||||
Document that ripgrep may terminate unexpectedly when searching via
|
||||
memory maps (which can happen using default settings).
|
||||
|
||||
Friends of ripgrep:
|
||||
|
||||
I'd like to give a big Thank You to @okdana for their recent hard work on
|
||||
ripgrep. This includes new features like `--line-regexp`, heroic effort on
|
||||
zsh auto-completion and thinking through some thorny argv issues with me.
|
||||
|
||||
I'd also like to thank @ericbn for their work on improving ripgrep's argv
|
||||
parsing by allowing some flags to override others.
|
||||
|
||||
Thanks @okdana and @ericbn!
|
||||
|
||||
|
||||
0.5.2 (2017-05-11)
|
||||
==================
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Nix.
|
||||
* [FEATURE #362](https://github.com/BurntSushi/ripgrep/issues/362):
|
||||
Add `--regex-size-limit` and `--dfa-size-limit` flags.
|
||||
* [FEATURE #444](https://github.com/BurntSushi/ripgrep/issues/444):
|
||||
Improve error messages for invalid globs.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #442](https://github.com/BurntSushi/ripgrep/issues/442):
|
||||
Fix line wrapping in `--help` output.
|
||||
* [BUG #451](https://github.com/BurntSushi/ripgrep/issues/451):
|
||||
Fix bug with duplicate output when using `-o/--only-matching` flag.
|
||||
|
||||
|
||||
0.5.1 (2017-04-09)
|
||||
==================
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for vim.
|
||||
* [FEATURE #34](https://github.com/BurntSushi/ripgrep/issues/34):
|
||||
Add a `-o/--only-matching` flag.
|
||||
* [FEATURE #377](https://github.com/BurntSushi/ripgrep/issues/377):
|
||||
Column numbers can now be customized with a color. (The default is
|
||||
no color.)
|
||||
* [FEATURE #419](https://github.com/BurntSushi/ripgrep/issues/419):
|
||||
Added `-0` short flag option for `--null`.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #381](https://github.com/BurntSushi/ripgrep/issues/381):
|
||||
Include license text in all subcrates.
|
||||
* [BUG #418](https://github.com/BurntSushi/ripgrep/issues/418),
|
||||
[BUG #426](https://github.com/BurntSushi/ripgrep/issues/426),
|
||||
[BUG #439](https://github.com/BurntSushi/ripgrep/issues/439):
|
||||
Fix a few bugs with `-h/--help` output.
|
||||
|
||||
|
||||
0.5.0 (2017-03-12)
|
||||
==================
|
||||
This is a new minor version release of ripgrep that includes one minor breaking
|
||||
change, bug fixes and several new features including support for text encodings
|
||||
other than UTF-8.
|
||||
|
||||
A notable accomplishment with respect to Rust is that ripgrep proper now only
|
||||
contains a single `unsafe` use (for accessing the contents of a memory map).
|
||||
|
||||
The **breaking change** is:
|
||||
|
||||
* [FEATURE #380](https://github.com/BurntSushi/ripgrep/issues/380):
|
||||
Line numbers are now hidden by default when ripgrep is printing to a tty
|
||||
**and** the only thing searched is stdin.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Ceylon, CSS, Elixir, HTML, log,
|
||||
SASS, SVG, Twig
|
||||
* [FEATURE #1](https://github.com/BurntSushi/ripgrep/issues/1):
|
||||
Add support for additional text encodings, including automatic detection for
|
||||
UTF-16 via BOM sniffing. Explicit text encoding support with the
|
||||
`-E/--encoding` flag was also added for latin-1, GBK, EUC-JP
|
||||
and Shift_JIS, among others. The full list can be found here:
|
||||
https://encoding.spec.whatwg.org/#concept-encoding-get
|
||||
* [FEATURE #129](https://github.com/BurntSushi/ripgrep/issues/129):
|
||||
Add a new `-M/--max-columns` flag that omits lines longer than the given
|
||||
number of bytes. (Disabled by default!)
|
||||
* [FEATURE #369](https://github.com/BurntSushi/ripgrep/issues/369):
|
||||
A new flag, `--max-filesize`, was added for limiting searches to files with
|
||||
a maximum file size.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #52](https://github.com/BurntSushi/ripgrep/issues/52),
|
||||
[BUG #311](https://github.com/BurntSushi/ripgrep/issues/311):
|
||||
Tweak how binary files are detected and handled. (We are slightly less
|
||||
conservative and will no longer use memory without bound.)
|
||||
* [BUG #326](https://github.com/BurntSushi/ripgrep/issues/326):
|
||||
When --files flag is given, we should never attempt to parse positional
|
||||
arguments as regexes.
|
||||
* [BUG #327](https://github.com/BurntSushi/ripgrep/issues/327):
|
||||
Permit the --heading flag to override the --no-heading flag.
|
||||
* [BUG #340](https://github.com/BurntSushi/ripgrep/pull/340):
|
||||
Clarify that the `-u/--unrestricted` flags are aliases.
|
||||
* [BUG #343](https://github.com/BurntSushi/ripgrep/pull/343):
|
||||
Global git ignore config should use `$HOME/.config/git/ignore` and not
|
||||
`$HOME/git/ignore`.
|
||||
* [BUG #345](https://github.com/BurntSushi/ripgrep/pull/345):
|
||||
Clarify docs for `-g/--glob` flag.
|
||||
* [BUG #381](https://github.com/BurntSushi/ripgrep/issues/381):
|
||||
Add license files to each sub-crate.
|
||||
* [BUG #383](https://github.com/BurntSushi/ripgrep/issues/383):
|
||||
Use latest version of clap (for argv parsing).
|
||||
* [BUG #392](https://github.com/BurntSushi/ripgrep/issues/391):
|
||||
Fix translation of set globs (e.g., `{foo,bar,quux}`) to regexes.
|
||||
* [BUG #401](https://github.com/BurntSushi/ripgrep/pull/401):
|
||||
Add PowerShell completion file to Windows release.
|
||||
* [BUG #405](https://github.com/BurntSushi/ripgrep/issues/405):
|
||||
Fix bug when excluding absolute paths with the `-g/--glob` flag.
|
||||
|
||||
|
||||
0.4.0
|
||||
=====
|
||||
This is a new minor version release of ripgrep that includes a couple very
|
||||
minor breaking changes, a few new features and lots of bug fixes.
|
||||
|
||||
This version of ripgrep upgrades its `regex` dependency from `0.1` to `0.2`,
|
||||
which includes a few minor syntax changes:
|
||||
|
||||
* POSIX character classes now require double bracketing. Previously, the regex
|
||||
`[:upper:]` would parse as the `upper` POSIX character class. Now it parses
|
||||
as the character class containing the characters `:upper:`. The fix to this
|
||||
change is to use `[[:upper:]]` instead. Note that variants like
|
||||
`[[:upper:][:blank:]]` continue to work.
|
||||
* The character `[` must always be escaped inside a character class.
|
||||
* The characters `&`, `-` and `~` must be escaped if any one of them are
|
||||
repeated consecutively. For example, `[&]`, `[\&]`, `[\&\&]`, `[&-&]` are all
|
||||
equivalent while `[&&]` is illegal. (The motivation for this and the prior
|
||||
change is to provide a backwards compatible path for adding character class
|
||||
set notation.)
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Crystal, Kotlin, Perl, PowerShell,
|
||||
Ruby, Swig
|
||||
* [FEATURE #83](https://github.com/BurntSushi/ripgrep/issues/83):
|
||||
Type definitions can now include other type definitions.
|
||||
* [FEATURE #243](https://github.com/BurntSushi/ripgrep/issues/243):
|
||||
**BREAKING CHANGE**: The `--column` flag now implies `--line-number`.
|
||||
* [FEATURE #263](https://github.com/BurntSushi/ripgrep/issues/263):
|
||||
Add a new `--sort-files` flag.
|
||||
* [FEATURE #275](https://github.com/BurntSushi/ripgrep/issues/275):
|
||||
Add a new `--path-separator` flag. Useful in cygwin.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #182](https://github.com/BurntSushi/ripgrep/issues/182):
|
||||
Redux: use more portable ANSI color escape sequences when possible.
|
||||
* [BUG #258](https://github.com/BurntSushi/ripgrep/issues/258):
|
||||
Fix bug that caused ripgrep's parallel iterator to spin and burn CPU.
|
||||
* [BUG #262](https://github.com/BurntSushi/ripgrep/issues/262):
|
||||
Document how to install shell completion files.
|
||||
* [BUG #266](https://github.com/BurntSushi/ripgrep/issues/266),
|
||||
[BUG #293](https://github.com/BurntSushi/ripgrep/issues/293):
|
||||
Fix handling of bold styling and change the default colors.
|
||||
* [BUG #268](https://github.com/BurntSushi/ripgrep/issues/268):
|
||||
Make lack of backreference support more explicit.
|
||||
* [BUG #271](https://github.com/BurntSushi/ripgrep/issues/271):
|
||||
Remove `~` dependency on clap.
|
||||
* [BUG #277](https://github.com/BurntSushi/ripgrep/issues/277):
|
||||
Fix cosmetic issue in `globset` crate docs.
|
||||
* [BUG #279](https://github.com/BurntSushi/ripgrep/issues/279):
|
||||
ripgrep did not terminate when `-q/--quiet` was given.
|
||||
* [BUG #281](https://github.com/BurntSushi/ripgrep/issues/281):
|
||||
**BREAKING CHANGE**: Completely remove `^C` handling from ripgrep.
|
||||
* [BUG #284](https://github.com/BurntSushi/ripgrep/issues/284):
|
||||
Make docs for `-g/--glob` clearer.
|
||||
* [BUG #286](https://github.com/BurntSushi/ripgrep/pull/286):
|
||||
When stdout is redirected to a file, don't search that file.
|
||||
* [BUG #287](https://github.com/BurntSushi/ripgrep/pull/287):
|
||||
Fix ZSH completions.
|
||||
* [BUG #295](https://github.com/BurntSushi/ripgrep/pull/295):
|
||||
Remove superfluous `memmap` dependency in `grep` crate.
|
||||
* [BUG #308](https://github.com/BurntSushi/ripgrep/pull/308):
|
||||
Improve docs for `-r/--replace`.
|
||||
* [BUG #313](https://github.com/BurntSushi/ripgrep/pull/313):
|
||||
Update bytecount dep to latest version.
|
||||
* [BUG #318](https://github.com/BurntSushi/ripgrep/pull/318):
|
||||
Fix invalid UTF-8 output bug in Windows consoles.
|
||||
|
||||
|
||||
0.3.2
|
||||
=====
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Less, Sass, stylus, Zsh
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #229](https://github.com/BurntSushi/ripgrep/issues/229):
|
||||
Make smart case slightly less conservative.
|
||||
* [BUG #247](https://github.com/BurntSushi/ripgrep/issues/247):
|
||||
Clarify use of --heading/--no-heading.
|
||||
* [BUG #251](https://github.com/BurntSushi/ripgrep/issues/251),
|
||||
[BUG #264](https://github.com/BurntSushi/ripgrep/issues/264),
|
||||
[BUG #267](https://github.com/BurntSushi/ripgrep/issues/267):
|
||||
Fix matching bug caused by literal optimizations.
|
||||
* [BUG #256](https://github.com/BurntSushi/ripgrep/issues/256):
|
||||
Fix bug that caused `rg foo` and `rg foo/` to have different behavior
|
||||
when `foo` was a symlink.
|
||||
* [BUG #270](https://github.com/BurntSushi/ripgrep/issues/270):
|
||||
Fix bug where patterns starting with a `-` couldn't be used with the
|
||||
`-e/--regexp` flag. (This resolves a regression that was introduced in
|
||||
ripgrep 0.3.0.)
|
||||
|
||||
|
||||
0.3.1
|
||||
=====
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #242](https://github.com/BurntSushi/ripgrep/issues/242):
|
||||
ripgrep didn't respect `--colors foo:none` correctly. Now it does.
|
||||
|
||||
|
||||
0.3.0
|
||||
=====
|
||||
This is a new minor version release of ripgrep that includes two breaking
|
||||
changes with lots of bug fixes and some new features and performance
|
||||
improvements. Notably, if you had a problem with colors or piping on Windows
|
||||
before, then that should now be fixed in this release.
|
||||
|
||||
**BREAKING CHANGES**:
|
||||
|
||||
* ripgrep now requires Rust 1.11 to compile. Previously, it could build on
|
||||
Rust 1.9. The cause of this was the move from
|
||||
[Docopt to Clap](https://github.com/BurntSushi/ripgrep/pull/233)
|
||||
for argument parsing.
|
||||
* The `-e/--regexp` flag can no longer accept a pattern starting with a `-`.
|
||||
There are two work-arounds: `rg -- -foo` and `rg [-]foo` or `rg -e [-]foo`
|
||||
will all search for the same `-foo` pattern. The cause of this was the move
|
||||
from [Docopt to Clap](https://github.com/BurntSushi/ripgrep/pull/233)
|
||||
for argument parsing.
|
||||
[This may get fixed in the
|
||||
future.](https://github.com/kbknapp/clap-rs/issues/742).
|
||||
|
||||
Performance improvements:
|
||||
|
||||
* [PERF #33](https://github.com/BurntSushi/ripgrep/issues/33):
|
||||
ripgrep now performs similar to GNU grep on small corpora.
|
||||
* [PERF #136](https://github.com/BurntSushi/ripgrep/issues/136):
|
||||
ripgrep no longer slows down because of argument parsing when given a large
|
||||
argument list.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Elixir.
|
||||
* [FEATURE #7](https://github.com/BurntSushi/ripgrep/issues/7):
|
||||
Add a `-f/--file` flag that causes ripgrep to read patterns from a file.
|
||||
* [FEATURE #51](https://github.com/BurntSushi/ripgrep/issues/51):
|
||||
Add a `--colors` flag that enables one to customize the colors used in
|
||||
ripgrep's output.
|
||||
* [FEATURE #138](https://github.com/BurntSushi/ripgrep/issues/138):
|
||||
Add a `--files-without-match` flag that shows only file paths that contain
|
||||
zero matches.
|
||||
* [FEATURE #230](https://github.com/BurntSushi/ripgrep/issues/230):
|
||||
Add completion files to the release (Bash, Fish and PowerShell).
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #37](https://github.com/BurntSushi/ripgrep/issues/37):
|
||||
Use correct ANSI escape sequences when `TERM=screen.linux`.
|
||||
* [BUG #94](https://github.com/BurntSushi/ripgrep/issues/94):
|
||||
ripgrep now detects stdin on Windows automatically.
|
||||
* [BUG #117](https://github.com/BurntSushi/ripgrep/issues/117):
|
||||
Colors should now work correctly and automatically inside mintty.
|
||||
* [BUG #182](https://github.com/BurntSushi/ripgrep/issues/182):
|
||||
Colors should now work within Emacs. In particular, `--color=always` will
|
||||
emit colors regardless of the current environment.
|
||||
* [BUG #189](https://github.com/BurntSushi/ripgrep/issues/189):
|
||||
Show less content when running `rg -h`. The full help content can be
|
||||
accessed with `rg --help`.
|
||||
* [BUG #210](https://github.com/BurntSushi/ripgrep/issues/210):
|
||||
Support non-UTF-8 file names on Unix platforms.
|
||||
* [BUG #231](https://github.com/BurntSushi/ripgrep/issues/231):
|
||||
Switch from block buffering to line buffering.
|
||||
* [BUG #241](https://github.com/BurntSushi/ripgrep/issues/241):
|
||||
Some error messages weren't suppressed when `--no-messages` was used.
|
||||
|
||||
|
||||
0.2.9
|
||||
=====
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #226](https://github.com/BurntSushi/ripgrep/issues/226):
|
||||
File paths explicitly given on the command line weren't searched in parallel.
|
||||
(This was a regression in `0.2.7`.)
|
||||
* [BUG #228](https://github.com/BurntSushi/ripgrep/issues/228):
|
||||
If a directory was given to `--ignore-file`, ripgrep's memory usage would
|
||||
grow without bound.
|
||||
|
||||
|
||||
0.2.8
|
||||
=====
|
||||
Bug fixes:
|
||||
|
||||
* Fixed a bug with the SIMD/AVX features for using bytecount in commit
|
||||
`4ca15a`.
|
||||
|
||||
|
||||
0.2.7
|
||||
=====
|
||||
Performance improvements:
|
||||
|
||||
* [PERF #223](https://github.com/BurntSushi/ripgrep/pull/223):
|
||||
Added a parallel recursive directory iterator. This results in major
|
||||
performance improvements on large repositories.
|
||||
* [PERF #11](https://github.com/BurntSushi/ripgrep/pull/11):
|
||||
ripgrep now uses the `bytecount` library for counting new lines. In some
|
||||
cases, ripgrep runs twice as fast. Use
|
||||
`RUSTFLAGS="-C target-cpu=native" cargo build --release --features 'simd-accel avx-accel'`
|
||||
to get the fastest possible binary.
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Agda, Tex, Taskpaper, Markdown,
|
||||
asciidoc, textile, rdoc, org, creole, wiki, pod, C#, PDF, C, C++.
|
||||
* [FEATURE #149](https://github.com/BurntSushi/ripgrep/issues/149):
|
||||
Add a new `--no-messages` flag that suppresses error messages.
|
||||
Note that `rg foo 2> /dev/null` also works.
|
||||
* [FEATURE #159](https://github.com/BurntSushi/ripgrep/issues/159):
|
||||
Add a new `-m/--max-count` flag that limits the total number of matches
|
||||
printed for each file searched.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #199](https://github.com/BurntSushi/ripgrep/issues/199):
|
||||
Fixed a bug where `-S/--smart-case` wasn't being applied correctly to
|
||||
literal optimizations.
|
||||
* [BUG #203](https://github.com/BurntSushi/ripgrep/issues/203):
|
||||
Mention the full name, ripgrep, in more places. It now appears in
|
||||
the output of `--help` and `--version`. The repository URL is now also
|
||||
in the output of `--help` and the man page.
|
||||
* [BUG #215](https://github.com/BurntSushi/ripgrep/issues/215):
|
||||
Include small note about how to search for a pattern that starts with a `-`.
|
||||
|
||||
|
||||
0.2.6
|
||||
=====
|
||||
Feature enhancements:
|
||||
|
||||
408
Cargo.lock
generated
408
Cargo.lock
generated
@@ -1,262 +1,319 @@
|
||||
[root]
|
||||
name = "ripgrep"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"ctrlc 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"grep 0.1.3",
|
||||
"ignore 0.1.3",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "2.0.1"
|
||||
name = "ansi_term"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.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)",
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (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]]
|
||||
name = "deque"
|
||||
name = "bitflags"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.6.86"
|
||||
name = "cfg-if"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.6 (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)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.3.5"
|
||||
name = "crossbeam"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.3.0"
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.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.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.1.1"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grep"
|
||||
version = "0.1.3"
|
||||
version = "0.1.8"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.1.3"
|
||||
version = "0.4.1"
|
||||
dependencies = [
|
||||
"globset 0.1.1",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"globset 0.3.0",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.1"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.17"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.6"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap"
|
||||
version = "0.5.0"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fs2 0.3.0 (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.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.1.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.14"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.37"
|
||||
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.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.80"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aho-corasick 0.6.4 (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.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.3.9"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.19"
|
||||
name = "ripgrep"
|
||||
version = "0.8.1"
|
||||
dependencies = [
|
||||
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"globset 0.3.0",
|
||||
"grep 0.1.8",
|
||||
"ignore 0.4.1",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.5",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd"
|
||||
version = "0.1.1"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.5.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.4.4"
|
||||
name = "tempdir"
|
||||
version = "0.3.5"
|
||||
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)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "termcolor"
|
||||
version = "0.3.5"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wincolor 0.1.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "3.0.0"
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
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.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.37 (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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.2.7"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.0"
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "0.1.1"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -264,7 +321,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -274,52 +331,77 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "1.0.1"
|
||||
version = "2.1.4"
|
||||
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)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wincolor"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||
"checksum ctrlc 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77f98bb69e3fefadcc5ca80a1368a55251f70295168203e01165bcaecb270891"
|
||||
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
"checksum fs2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "640001e1bd865c7c32806292822445af576a6866175b5225aa2087ca5e3de551"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
|
||||
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
|
||||
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||
"checksum memmap 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "065ce59af31c18ea2c419100bda6247dd4ec3099423202b12f0bd32e529fabd2"
|
||||
"checksum num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8890e6084723d57d0df8d2720b0d60c6ee67d6c93e7169630e4371e88765dcad"
|
||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
||||
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||
"checksum simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5847c2d766ca7ce7227672850955802fabd779ba616aeabead4c2c3877023"
|
||||
"checksum strsim 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50c069df92e4b01425a8bf3576d5d417943a6a7272fbabaf5bd80b1aaa76442e"
|
||||
"checksum term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3deff8a2b3b6607d6d7cc32ac25c0b33709453ca9cceac006caac51e963cf94a"
|
||||
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
|
||||
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||
"checksum thread_local 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50057ca52c629a39aed52d8eb253800cb727875fa6fc7c4b1445f0ac3b50c27c"
|
||||
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
||||
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
|
||||
"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
|
||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
||||
"checksum clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c07b9257a00f3fc93b7f3c417fc15607ec7a56823bc2c37ec744e266387de5b"
|
||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
||||
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"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 glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
||||
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
|
||||
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
|
||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5be5347bde0c48cfd8c3fdc0766cdfe9d8a755ef84d620d6794c778c91de8b2b"
|
||||
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
"checksum simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd0805c7363ab51a829a1511ad24b6ed0349feaa756c4bc2f977f9f496e6673"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
|
||||
"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 thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98da26f00240118fbb7a06fa29579d1b39d34cd6e0505ea5c125b26d5260a967"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
|
||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
69
Cargo.toml
69
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ripgrep"
|
||||
version = "0.2.6" #:version
|
||||
version = "0.8.1" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Line oriented search tool using Rust's regex library. Combines the raw
|
||||
@@ -11,8 +11,14 @@ homepage = "https://github.com/BurntSushi/ripgrep"
|
||||
repository = "https://github.com/BurntSushi/ripgrep"
|
||||
readme = "README.md"
|
||||
keywords = ["regex", "grep", "egrep", "search", "pattern"]
|
||||
categories = ["command-line-utilities", "text-processing"]
|
||||
license = "Unlicense/MIT"
|
||||
exclude = ["HomebrewFormula"]
|
||||
build = "build.rs"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "BurntSushi/ripgrep" }
|
||||
appveyor = { repository = "BurntSushi/ripgrep" }
|
||||
|
||||
[[bin]]
|
||||
bench = false
|
||||
@@ -23,29 +29,50 @@ name = "rg"
|
||||
name = "integration"
|
||||
path = "tests/tests.rs"
|
||||
|
||||
[dependencies]
|
||||
ctrlc = "2.0"
|
||||
deque = "0.3"
|
||||
docopt = "0.6"
|
||||
env_logger = "0.3"
|
||||
grep = { version = "0.1.3", path = "grep" }
|
||||
ignore = { version = "0.1.3", path = "ignore" }
|
||||
lazy_static = "0.2"
|
||||
libc = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.5"
|
||||
num_cpus = "1"
|
||||
regex = "0.1.77"
|
||||
rustc-serialize = "0.3"
|
||||
term = "0.4"
|
||||
[workspace]
|
||||
members = ["grep", "globset", "ignore", "termcolor", "wincolor"]
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
kernel32-sys = "0.2"
|
||||
winapi = "0.2"
|
||||
[dependencies]
|
||||
atty = "0.2.2"
|
||||
bytecount = "0.3.1"
|
||||
encoding_rs = "0.7"
|
||||
globset = { version = "0.3.0", path = "globset" }
|
||||
grep = { version = "0.1.8", path = "grep" }
|
||||
ignore = { version = "0.4.0", path = "ignore" }
|
||||
lazy_static = "1"
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
memchr = "2"
|
||||
memmap = "0.6"
|
||||
num_cpus = "1"
|
||||
regex = "0.2.4"
|
||||
same-file = "1"
|
||||
termcolor = { version = "0.3.4", path = "termcolor" }
|
||||
|
||||
[dependencies.clap]
|
||||
version = "2.29.4"
|
||||
default-features = false
|
||||
features = ["suggestions", "color"]
|
||||
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["std", "winnt"]
|
||||
|
||||
[build-dependencies]
|
||||
lazy_static = "1"
|
||||
|
||||
[build-dependencies.clap]
|
||||
version = "2.29.4"
|
||||
default-features = false
|
||||
features = ["suggestions", "color"]
|
||||
|
||||
[features]
|
||||
simd-accel = ["regex/simd-accel"]
|
||||
avx-accel = ["bytecount/avx-accel"]
|
||||
simd-accel = [
|
||||
"bytecount/simd-accel",
|
||||
"regex/simd-accel",
|
||||
"encoding_rs/simd-accel",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
532
FAQ.md
Normal file
532
FAQ.md
Normal file
@@ -0,0 +1,532 @@
|
||||
## FAQ
|
||||
|
||||
* [Does ripgrep support configuration files?](#config)
|
||||
* [What's changed in ripgrep recently?](#changelog)
|
||||
* [When is the next release?](#release)
|
||||
* [Does ripgrep have a man page?](#manpage)
|
||||
* [Does ripgrep have support for shell auto-completion?](#complete)
|
||||
* [How do I use lookaround and/or backreferences?](#fancy)
|
||||
* [How do I configure ripgrep's colors?](#colors)
|
||||
* [How do I enable true colors on Windows?](#truecolors-windows)
|
||||
* [How do I stop ripgrep from messing up colors when I kill it?](#stop-ripgrep)
|
||||
* [How can I get results in a consistent order?](#order)
|
||||
* [How do I search files that aren't UTF-8?](#encoding)
|
||||
* [How do I search compressed files?](#compressed)
|
||||
* [How do I search over multiple lines?](#multiline)
|
||||
* [How do I get around the regex size limit?](#size-limit)
|
||||
* [How do I make the `-f/--file` flag faster?](#dfa-size)
|
||||
* [How do I make the output look like The Silver Searcher's output?](#silver-searcher-output)
|
||||
* [When I run `rg`, why does it execute some other command?](#rg-other-cmd)
|
||||
* [How do I create an alias for ripgrep on Windows?](#rg-alias-windows)
|
||||
* [How do I create a PowerShell profile?](#powershell-profile)
|
||||
* [How do I pipe non-ASCII content to ripgrep on Windows?](#pipe-non-ascii-windows)
|
||||
* [Can ripgrep replace grep?](#posix4ever)
|
||||
|
||||
|
||||
<h3 name="config">
|
||||
Does ripgrep support configuration files?
|
||||
</h3>
|
||||
|
||||
Yes. See the
|
||||
[guide's section on configuration files](GUIDE.md#configuration-file).
|
||||
|
||||
|
||||
<h3 name="changelog">
|
||||
What's changed in ripgrep recently?
|
||||
</h3>
|
||||
|
||||
Please consult ripgrep's [CHANGELOG](CHANGELOG.md).
|
||||
|
||||
|
||||
<h3 name="release">
|
||||
When is the next release?
|
||||
</h3>
|
||||
|
||||
ripgrep is a project whose contributors are volunteers. A release schedule
|
||||
adds undue stress to said volunteers. Therefore, releases are made on a best
|
||||
effort basis and no dates **will ever be given**.
|
||||
|
||||
One exception to this is high impact bugs. If a ripgrep release contains a
|
||||
significant regression, then there will generally be a strong push to get a
|
||||
patch release out with a fix.
|
||||
|
||||
|
||||
<h3 name="manpage">
|
||||
Does ripgrep have a man page?
|
||||
</h3>
|
||||
|
||||
Yes! Whenever ripgrep is compiled on a system with `asciidoc` present, then a
|
||||
man page is generated from ripgrep's argv parser. After compiling ripgrep, you
|
||||
can find the man page like so from the root of the repository:
|
||||
|
||||
```
|
||||
$ find ./target -name rg.1 -print0 | xargs -0 ls -t | head -n1
|
||||
./target/debug/build/ripgrep-79899d0edd4129ca/out/rg.1
|
||||
```
|
||||
|
||||
Running `man -l ./target/debug/build/ripgrep-79899d0edd4129ca/out/rg.1` will
|
||||
show the man page in your normal pager.
|
||||
|
||||
Note that the man page's documentation for options is equivalent to the output
|
||||
shown in `rg --help`. To see more condensed documentation (one line per flag),
|
||||
run `rg -h`.
|
||||
|
||||
The man page is also included in all
|
||||
[ripgrep binary releases](https://github.com/BurntSushi/ripgrep/releases).
|
||||
|
||||
|
||||
<h3 name="complete">
|
||||
Does ripgrep have support for shell auto-completion?
|
||||
</h3>
|
||||
|
||||
Yes! Shell completions can be found in the
|
||||
[same directory as the man page](#manpage)
|
||||
after building ripgrep. Zsh completions are maintained separately and committed
|
||||
to the repository in `complete/_rg`.
|
||||
|
||||
Shell completions are also included in all
|
||||
[ripgrep binary releases](https://github.com/BurntSushi/ripgrep/releases).
|
||||
|
||||
For **bash**, move `rg.bash` to
|
||||
`$XDG_CONFIG_HOME/bash_completion` or `/etc/bash_completion.d/`.
|
||||
|
||||
For **fish**, move `rg.fish` to `$HOME/.config/fish/completions/`.
|
||||
|
||||
For **zsh**, move `_rg` to one of your `$fpath` directories.
|
||||
|
||||
For **PowerShell**, add `. _rg.ps1` to your PowerShell
|
||||
[profile](https://technet.microsoft.com/en-us/library/bb613488(v=vs.85).aspx)
|
||||
(note the leading period). If the `_rg.ps1` file is not on your `PATH`, do
|
||||
`. /path/to/_rg.ps1` instead.
|
||||
|
||||
|
||||
<h3 name="order">
|
||||
How can I get results in a consistent order?
|
||||
</h3>
|
||||
|
||||
By default, ripgrep uses parallelism to execute its search because this makes
|
||||
the search much faster on most modern systems. This in turn means that ripgrep
|
||||
has a non-deterministic aspect to it, since the interleaving of threads during
|
||||
the execution of the program is itself non-deterministic. This has the effect
|
||||
of printing results in a somewhat arbitrary order, and this order can change
|
||||
from run to run of ripgrep.
|
||||
|
||||
The only way to make the order of results consistent is to ask ripgrep to
|
||||
sort the output. Currently, this will disable all parallelism. (On smaller
|
||||
repositories, you might not notice much of a performance difference!) You
|
||||
can achieve this with the `--sort-files` flag.
|
||||
|
||||
There is more discussion on this topic here:
|
||||
https://github.com/BurntSushi/ripgrep/issues/152
|
||||
|
||||
|
||||
<h3 name="encoding">
|
||||
How do I search files that aren't UTF-8?
|
||||
</h3>
|
||||
|
||||
See the [guide's section on file encoding](GUIDE.md#file-encoding).
|
||||
|
||||
|
||||
<h3 name="compressed">
|
||||
How do I search compressed files?
|
||||
</h3>
|
||||
|
||||
ripgrep's `-z/--search-zip` flag will cause it to search compressed files
|
||||
automatically. Currently, this supports gzip, bzip2, lzma and xz only and
|
||||
requires the corresponding `gzip`, `bzip2` and `xz` binaries to be installed on
|
||||
your system. (That is, ripgrep does decompression by shelling out to another
|
||||
process.)
|
||||
|
||||
ripgrep currently does not search archive formats, so `*.tar.gz` files, for
|
||||
example, are skipped.
|
||||
|
||||
|
||||
<h3 name="multiline">
|
||||
How do I search over multiple lines?
|
||||
</h3>
|
||||
|
||||
This isn't currently possible. ripgrep is fundamentally a line-oriented search
|
||||
tool. With that said,
|
||||
[multiline search is a planned opt-in feature](https://github.com/BurntSushi/ripgrep/issues/176).
|
||||
|
||||
|
||||
<h3 name="fancy">
|
||||
How do I use lookaround and/or backreferences?
|
||||
</h3>
|
||||
|
||||
This isn't currently possible. ripgrep uses finite automata to implement
|
||||
regular expression search, and in turn, guarantees linear time searching on all
|
||||
inputs. It is difficult to efficiently support lookaround and backreferences in
|
||||
finite automata engines, so ripgrep does not provide these features.
|
||||
|
||||
If a production quality regular expression engine with these features is ever
|
||||
written in Rust, then it is possible ripgrep will provide it as an opt-in
|
||||
feature.
|
||||
|
||||
|
||||
<h3 name="colors">
|
||||
How do I configure ripgrep's colors?
|
||||
</h3>
|
||||
|
||||
ripgrep has two flags related to colors:
|
||||
|
||||
* `--color` controls *when* to use colors.
|
||||
* `--colors` controls *which* colors to use.
|
||||
|
||||
The `--color` flag accepts one of the following possible values: `never`,
|
||||
`auto`, `always` or `ansi`. The `auto` value is the default and will cause
|
||||
ripgrep to only enable colors when it is printing to a terminal. But if you
|
||||
pipe ripgrep to a file or some other process, then it will suppress colors.
|
||||
|
||||
The --colors` flag is a bit more complicated. The general format is:
|
||||
|
||||
```
|
||||
--colors '{type}:{attribute}:{value}'
|
||||
```
|
||||
|
||||
* `{type}` should be one of `path`, `line`, `column` or `match`. Each of these
|
||||
correspond to the four different types of things that ripgrep will add color
|
||||
to in its output. Select the type whose color you want to change.
|
||||
* `{attribute}` should be one of `fg`, `bg` or `style`, corresponding to
|
||||
foreground color, background color, or miscellaneous styling (such as whether
|
||||
to bold the output or not).
|
||||
* `{value}` is determined by the value of `{attribute}`. If
|
||||
`{attribute}` is `style`, then `{value}` should be one of `nobold`,
|
||||
`bold`, `nointense`, `intense`, `nounderline` or `underline`. If
|
||||
`{attribute}` is `fg` or `bg`, then `{value}` should be a color.
|
||||
|
||||
A color is specified by either one of eight of English names, a single 256-bit
|
||||
number or an RGB triple (with over 16 million possible values, or "true
|
||||
color").
|
||||
|
||||
The color names are `red`, `blue`, `green`, `cyan`, `magenta`, `yellow`,
|
||||
`white` or `black`.
|
||||
|
||||
A single 256-bit number is a value in the range 0-255 (inclusive). It can
|
||||
either be in decimal format (e.g., `62`) or hexadecimal format (e.g., `0x3E`).
|
||||
|
||||
An RGB triple corresponds to three numbers (decimal or hexadecimal) separated
|
||||
by commas.
|
||||
|
||||
As a special case, `--colors '{type}:none'` will clear all colors and styles
|
||||
associated with `{type}`, which lets you start with a clean slate (instead of
|
||||
building on top of ripgrep's default color settings).
|
||||
|
||||
Here's an example that makes highlights the matches with a nice blue background
|
||||
with bolded white text:
|
||||
|
||||
```
|
||||
$ rg somepattern \
|
||||
--colors 'match:none' \
|
||||
--colors 'match:bg:0x33,0x66,0xFF' \
|
||||
--colors 'match:fg:white' \
|
||||
--colors 'match:style:bold'
|
||||
```
|
||||
|
||||
Colors are an ideal candidate to set in your
|
||||
[configuration file](GUIDE.md#configuration-file). See the
|
||||
[question on emulating The Silver Searcher's output style](#silver-searcher-output)
|
||||
for an example specific to colors.
|
||||
|
||||
|
||||
<h3 name="truecolors-windows">
|
||||
How do I enable true colors on Windows?
|
||||
</h3>
|
||||
|
||||
First, see the previous question's
|
||||
[answer on configuring colors](#colors).
|
||||
|
||||
Secondly, coloring on Windows is a bit complicated. If you're using a terminal
|
||||
like Cygwin, then it's likely true color support already works out of the box.
|
||||
However, if you are using a normal Windows console (`cmd` or `PowerShell`) and
|
||||
a version of Windows prior to 10, then there is no known way to get true
|
||||
color support. If you are on Windows 10 and using a Windows console, then
|
||||
true colors should work out of the box with one caveat: you might need to
|
||||
clear ripgrep's default color settings first. That is, instead of this:
|
||||
|
||||
```
|
||||
$ rg somepattern --colors 'match:fg:0x33,0x66,0xFF'
|
||||
```
|
||||
|
||||
you should do this
|
||||
|
||||
```
|
||||
$ rg somepattern --colors 'match:none' --colors 'match:fg:0x33,0x66,0xFF'
|
||||
```
|
||||
|
||||
This is because ripgrep might set the default style for `match` to `bold`, and
|
||||
it seems like Windows 10's VT100 support doesn't permit bold and true color
|
||||
ANSI escapes to be used simultaneously. The work-around above will clear
|
||||
ripgrep's default styling, allowing you to craft it exactly as desired.
|
||||
|
||||
|
||||
<h3 name="stop-ripgrep">
|
||||
How do I stop ripgrep from messing up colors when I kill it?
|
||||
</h3>
|
||||
|
||||
Type in `color` in cmd.exe (Command Prompt) and `echo -ne "\033[0m"` on
|
||||
Unix-like systems to restore your original foreground color.
|
||||
|
||||
In PowerShell, you can add the following code to your profile which will
|
||||
restore the original foreground color when `Reset-ForegroundColor` is called.
|
||||
Including the `Set-Alias` line will allow you to call it with simply `color`.
|
||||
|
||||
```powershell
|
||||
$OrigFgColor = $Host.UI.RawUI.ForegroundColor
|
||||
function Reset-ForegroundColor {
|
||||
$Host.UI.RawUI.ForegroundColor = $OrigFgColor
|
||||
}
|
||||
Set-Alias -Name color -Value Reset-ForegroundColor
|
||||
```
|
||||
|
||||
PR [#187](https://github.com/BurntSushi/ripgrep/pull/187) fixed this, and it
|
||||
was later deprecated in
|
||||
[#281](https://github.com/BurntSushi/ripgrep/issues/281). A full explanation is
|
||||
available
|
||||
[here](https://github.com/BurntSushi/ripgrep/issues/281#issuecomment-269093893).
|
||||
|
||||
|
||||
<h3 name="size-limit">
|
||||
How do I get around the regex size limit?
|
||||
</h3>
|
||||
|
||||
If you've given ripgrep a particularly large pattern (or a large number of
|
||||
smaller patterns), then it is possible that it will fail to compile because it
|
||||
hit a pre-set limit. For example:
|
||||
|
||||
```
|
||||
$ rg '\pL{1000}'
|
||||
Compiled regex exceeds size limit of 10485760 bytes.
|
||||
```
|
||||
|
||||
(Note: `\pL{1000}` may look small, but `\pL` is the character class containing
|
||||
all Unicode letters, which is quite large. *And* it's repeated 1000 times.)
|
||||
|
||||
In this case, you can work around by simply increasing the limit:
|
||||
|
||||
```
|
||||
$ rg '\pL{1000}' --regex-size-limit 1G
|
||||
```
|
||||
|
||||
Increasing the limit to 1GB does not necessarily mean that ripgrep will use
|
||||
that much memory. The limit just says that it's allowed to (approximately) use
|
||||
that much memory for constructing the regular expression.
|
||||
|
||||
|
||||
<h3 name="dfa-size">
|
||||
How do I make the <code>-f/--file</code> flag faster?
|
||||
</h3>
|
||||
|
||||
The `-f/--file` permits one to give a file to ripgrep which contains a pattern
|
||||
on each line. ripgrep will then report any line that matches any of the
|
||||
patterns.
|
||||
|
||||
If this pattern file gets too big, then it is possible ripgrep will slow down
|
||||
dramatically. *Typically* this is because an internal cache is too small, and
|
||||
will cause ripgrep to spill over to a slower but more robust regular expression
|
||||
engine. If this is indeed the problem, then it is possible to increase this
|
||||
cache and regain speed. The cache can be controlled via the `--dfa-size-limit`
|
||||
flag. For example, using `--dfa-size-limit 1G` will set the cache size to 1GB.
|
||||
(Note that this doesn't mean ripgrep will use 1GB of memory automatically, but
|
||||
it will allow the regex engine to if it needs to.)
|
||||
|
||||
|
||||
<h3 name="silver-searcher-output">
|
||||
How do I make the output look like The Silver Searcher's output?
|
||||
</h3>
|
||||
|
||||
Use the `--colors` flag, like so:
|
||||
|
||||
```
|
||||
rg --colors line:fg:yellow \
|
||||
--colors line:style:bold \
|
||||
--colors path:fg:green \
|
||||
--colors path:style:bold \
|
||||
--colors match:fg:black \
|
||||
--colors match:bg:yellow \
|
||||
--colors match:style:nobold \
|
||||
foo
|
||||
```
|
||||
|
||||
Alternatively, add your color configuration to your ripgrep config file (which
|
||||
is activated by setting the `RIPGREP_CONFIG_PATH` environment variable to point
|
||||
to your config file). For example:
|
||||
|
||||
```
|
||||
$ cat $HOME/.config/ripgrep/rc
|
||||
--colors=line:fg:yellow
|
||||
--colors=line:style:bold
|
||||
--colors=path:fg:green
|
||||
--colors=path:style:bold
|
||||
--colors=match:fg:black
|
||||
--colors=match:bg:yellow
|
||||
--colors=match:style:nobold
|
||||
$ RIPGREP_CONFIG_PATH=$HOME/.config/ripgrep/rc rg foo
|
||||
```
|
||||
|
||||
|
||||
<h3 name="rg-other-cmd">
|
||||
When I run <code>rg</code>, why does it execute some other command?
|
||||
</h3>
|
||||
|
||||
It's likely that you have a shell alias or even another tool called `rg` which
|
||||
is interfering with ripgrep. Run `which rg` to see what it is.
|
||||
|
||||
(Notably, the Rails plug-in for
|
||||
[Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#rails) sets
|
||||
up an `rg` alias for `rails generate`.)
|
||||
|
||||
Problems like this can be resolved in one of several ways:
|
||||
|
||||
* If you're using the OMZ Rails plug-in, disable it by editing the `plugins`
|
||||
array in your zsh configuration.
|
||||
* Temporarily bypass an existing `rg` alias by calling ripgrep as
|
||||
`command rg`, `\rg`, or `'rg'`.
|
||||
* Temporarily bypass an existing alias or another tool named `rg` by calling
|
||||
ripgrep by its full path (e.g., `/usr/bin/rg` or `/usr/local/bin/rg`).
|
||||
* Permanently disable an existing `rg` alias by adding `unalias rg` to the
|
||||
bottom of your shell configuration file (e.g., `.bash_profile` or `.zshrc`).
|
||||
* Give ripgrep its own alias that doesn't conflict with other tools/aliases by
|
||||
adding a line like the following to the bottom of your shell configuration
|
||||
file: `alias ripgrep='command rg'`.
|
||||
|
||||
|
||||
<h3 name="rg-alias-windows">
|
||||
How do I create an alias for ripgrep on Windows?
|
||||
</h3>
|
||||
|
||||
Often you can find a need to make alias for commands you use a lot that set
|
||||
certain flags. But PowerShell function aliases do not behave like your typical
|
||||
linux shell alias. You always need to propagate arguments and `stdin` input.
|
||||
But it cannot be done simply as
|
||||
`function grep() { $input | rg.exe --hidden $args }`
|
||||
|
||||
Use below example as reference to how setup alias in PowerShell.
|
||||
|
||||
```powershell
|
||||
function grep {
|
||||
$count = @($input).Count
|
||||
$input.Reset()
|
||||
|
||||
if ($count) {
|
||||
$input | rg.exe --hidden $args
|
||||
}
|
||||
else {
|
||||
rg.exe --hidden $args
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
PowerShell special variables:
|
||||
|
||||
* input - is powershell `stdin` object that allows you to access its content.
|
||||
* args - is array of arguments passed to this function.
|
||||
|
||||
This alias checks whether there is `stdin` input and propagates only if there
|
||||
is some lines. Otherwise empty `$input` will make powershell to trigger `rg` to
|
||||
search empty `stdin`.
|
||||
|
||||
|
||||
<h3 name="powershell-profile">
|
||||
How do I create a PowerShell profile?
|
||||
</h3>
|
||||
|
||||
To customize powershell on start-up, there is a special PowerShell script that
|
||||
has to be created. In order to find its location, type `$profile`.
|
||||
See
|
||||
[Microsoft's documentation](https://technet.microsoft.com/en-us/library/bb613488(v=vs.85).aspx)
|
||||
for more details.
|
||||
|
||||
Any PowerShell code in this file gets evaluated at the start of console. This
|
||||
way you can have own aliases to be created at start.
|
||||
|
||||
|
||||
<h3 name="pipe-non-ascii-windows">
|
||||
How do I pipe non-ASCII content to ripgrep on Windows?
|
||||
</h3>
|
||||
|
||||
When piping input into native executables in PowerShell, the encoding of the
|
||||
input is controlled by the `$OutputEncoding` variable. By default, this is set
|
||||
to US-ASCII, and any characters in the pipeline that don't have encodings in
|
||||
US-ASCII are converted to `?` (question mark) characters.
|
||||
|
||||
To change this setting, set `$OutputEncoding` to a different encoding, as
|
||||
represented by a .NET encoding object. Some common examples are below. The
|
||||
value of this variable is reset when PowerShell restarts, so to make this
|
||||
change take effect every time PowerShell is started add a line setting the
|
||||
variable into your PowerShell profile.
|
||||
|
||||
Example `$OutputEncoding` settings:
|
||||
|
||||
* UTF-8 without BOM: `$OutputEncoding = [System.Text.UTF8Encoding]::new()`
|
||||
* The console's output encoding:
|
||||
`$OutputEncoding = [System.Console]::OutputEncoding`
|
||||
|
||||
If you continue to have encoding problems, you can also force the encoding
|
||||
that the console will use for printing to UTF-8 with
|
||||
`[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8`. This
|
||||
will also reset when PowerShell is restarted, so you can add that line
|
||||
to your profile as well if you want to make the setting permanent.
|
||||
|
||||
|
||||
<h3 name="posix4ever">
|
||||
Can ripgrep replace grep?
|
||||
</h3>
|
||||
|
||||
Yes and no.
|
||||
|
||||
If, upon hearing that "ripgrep can replace grep," you *actually* hear, "ripgrep
|
||||
can be used in every instance grep can be used, in exactly the same way, for
|
||||
the same use cases, with exactly the same bug-for-bug behavior," then no,
|
||||
ripgrep trivially *cannot* replace grep. Moreover, ripgrep will *never* replace
|
||||
grep.
|
||||
|
||||
If, upon hearing that "ripgrep can replace grep," you *actually* hear, "ripgrep
|
||||
can replace grep in some cases and not in other use cases," then yes, that is
|
||||
indeed true!
|
||||
|
||||
Let's go over some of those use cases in favor of ripgrep. Some of these may
|
||||
not apply to you. That's OK. There may be other use cases not listed here that
|
||||
do apply to you. That's OK too.
|
||||
|
||||
(For all claims related to performance in the following words, see my
|
||||
[blog post](https://blog.burntsushi.net/ripgrep/)
|
||||
introducing ripgrep.)
|
||||
|
||||
* Are you frequently searching a repository of code? If so, ripgrep might be a
|
||||
good choice since there's likely a good chunk of your repository that you
|
||||
don't want to search. grep, can, of course, be made to filter files using
|
||||
recursive search, and if you don't mind writing out the requisite `--exclude`
|
||||
rules or writing wrapper scripts, then grep might be sufficient. (I'm not
|
||||
kidding, I myself did this with grep for almost a decade before writing
|
||||
ripgrep.) But if you instead enjoy having a search tool respect your
|
||||
`.gitignore`, then ripgrep might be perfect for you!
|
||||
* Are you frequently searching non-ASCII text that is UTF-8 encoded? One of
|
||||
ripgrep's key features is that it can handle Unicode features in your
|
||||
patterns in a way that tends to be faster than GNU grep. Unicode features
|
||||
in ripgrep are enabled by default; there is no need to configure your locale
|
||||
settings to use ripgrep properly because ripgrep doesn't respect your locale
|
||||
settings.
|
||||
* Do you need to search UTF-16 files and you don't want to bother explicitly
|
||||
transcoding them? Great. ripgrep does this for you automatically. No need
|
||||
to enable it.
|
||||
* Do you need to search a large directory of large files? ripgrep uses
|
||||
parallelism by default, which tends to make it faster than a standard
|
||||
`grep -r` search. However, if you're OK writing the occasional
|
||||
`find ./ -print0 | xargs -P8 -0 grep` command, then maybe grep is good
|
||||
enough.
|
||||
|
||||
Here are some cases where you might *not* want to use ripgrep. The same caveats
|
||||
for the previous section apply.
|
||||
|
||||
* Are you writing portable shell scripts intended to work in a variety of
|
||||
environments? Great, probably not a good idea to use ripgrep! ripgrep is has
|
||||
nowhere near the ubquity of grep, so if you do use ripgrep, you might need
|
||||
to futz with the installation process more than you would with grep.
|
||||
* Do you care about POSIX compatibility? If so, then you can't use ripgrep
|
||||
because it never was, isn't and never will be POSIX compatible.
|
||||
* Do you hate tools that try to do something smart? If so, ripgrep is all about
|
||||
being smart, so you might prefer to just stick with grep.
|
||||
* Is there a particular feature of grep you rely on that ripgrep either doesn't
|
||||
have or never will have? If the former, file a bug report, maybe ripgrep can
|
||||
do it! If the latter, well, then, just use grep.
|
||||
680
GUIDE.md
Normal file
680
GUIDE.md
Normal file
@@ -0,0 +1,680 @@
|
||||
## User Guide
|
||||
|
||||
This guide is intended to give an elementary description of ripgrep and an
|
||||
overview of its capabilities. This guide assumes that ripgrep is
|
||||
[installed](README.md#installation)
|
||||
and that readers have passing familiarity with using command line tools. This
|
||||
also assumes a Unix-like system, although most commands are probably easily
|
||||
translatable to any command line shell environment.
|
||||
|
||||
|
||||
### Table of Contents
|
||||
|
||||
* [Basics](#basics)
|
||||
* [Recursive search](#recursive-search)
|
||||
* [Automatic filtering](#automatic-filtering)
|
||||
* [Manual filtering: globs](#manual-filtering-globs)
|
||||
* [Manual filtering: file types](#manual-filtering-file-types)
|
||||
* [Replacements](#replacements)
|
||||
* [Configuration file](#configuration-file)
|
||||
* [File encoding](#file-encoding)
|
||||
* [Common options](#common-options)
|
||||
|
||||
|
||||
### Basics
|
||||
|
||||
ripgrep is a command line tool that searches your files for patterns that
|
||||
you give it. ripgrep behaves as if reading each file line by line. If a line
|
||||
matches the pattern provided to ripgrep, then that line will be printed. If a
|
||||
line does not match the pattern, then the line is not printed.
|
||||
|
||||
The best way to see how this works is with an example. To show an example, we
|
||||
need something to search. Let's try searching ripgrep's source code. First
|
||||
grab a ripgrep source archive from
|
||||
https://github.com/BurntSushi/ripgrep/archive/0.7.1.zip
|
||||
and extract it:
|
||||
|
||||
```
|
||||
$ curl -LO https://github.com/BurntSushi/ripgrep/archive/0.7.1.zip
|
||||
$ unzip 0.7.1.zip
|
||||
$ cd ripgrep-0.7.1
|
||||
$ ls
|
||||
benchsuite grep tests Cargo.toml LICENSE-MIT
|
||||
ci ignore wincolor CHANGELOG.md README.md
|
||||
complete pkg appveyor.yml compile snapcraft.yaml
|
||||
doc src build.rs COPYING UNLICENSE
|
||||
globset termcolor Cargo.lock HomebrewFormula
|
||||
```
|
||||
|
||||
Let's try our first search by looking for all occurrences of the word `fast`
|
||||
in `README.md`:
|
||||
|
||||
```
|
||||
$ rg fast README.md
|
||||
75: faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
|
||||
119:### Is it really faster than everything else?
|
||||
124:Summarizing, `ripgrep` is fast because:
|
||||
129: optimizations to make searching very fast.
|
||||
```
|
||||
|
||||
(**Note:** If you see an error message from ripgrep saying that it didn't
|
||||
search any files, then re-run ripgrep with the `--debug` flag. One likely cause
|
||||
of this is that you have a `*` rule in a `$HOME/.gitignore` file.)
|
||||
|
||||
So what happened here? ripgrep read the contents of `README.md`, and for each
|
||||
line that contained `fast`, ripgrep printed it to your terminal. ripgrep also
|
||||
included the line number for each line by default. If your terminal supports
|
||||
colors, then your output might actually look something like this screenshot:
|
||||
|
||||
[](https://burntsushi.net/stuff/ripgrep-guide-sample.png)
|
||||
|
||||
In this example, we searched for something called a "literal" string. This
|
||||
means that our pattern was just some normal text that we asked ripgrep to
|
||||
find. But ripgrep supports the ability to specify patterns via [regular
|
||||
expressions](https://en.wikipedia.org/wiki/Regular_expression). As an example,
|
||||
what if we wanted to find all lines have a word that contains `fast` followed
|
||||
by some number of other letters?
|
||||
|
||||
```
|
||||
$ rg 'fast\w+' README.md
|
||||
75: faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
||||
119:### Is it really faster than everything else?
|
||||
```
|
||||
|
||||
In this example, we used the pattern `fast\w+`. This pattern tells ripgrep to
|
||||
look for any lines containing the letters `fast` followed by *one or more*
|
||||
word-like characters. Namely, `\w` matches characters that compose words (like
|
||||
`a` and `L` but unlike `.` and ` `). The `+` after the `\w` means, "match the
|
||||
previous pattern one or more times." This means that the word `fast` won't
|
||||
match because there are no word characters following the final `t`. But a word
|
||||
like `faster` will. `faste` would also match!
|
||||
|
||||
Here's a different variation on this same theme:
|
||||
|
||||
```
|
||||
$ rg 'fast\w*' README.md
|
||||
75: faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
|
||||
119:### Is it really faster than everything else?
|
||||
124:Summarizing, `ripgrep` is fast because:
|
||||
129: optimizations to make searching very fast.
|
||||
```
|
||||
|
||||
In this case, we used `fast\w*` for our pattern instead of `fast\w+`. The `*`
|
||||
means that it should match *zero* or more times. In this case, ripgrep will
|
||||
print the same lines as the pattern `fast`, but if your terminal supports
|
||||
colors, you'll notice that `faster` will be highlighted instead of just the
|
||||
`fast` prefix.
|
||||
|
||||
It is beyond the scope of this guide to provide a full tutorial on regular
|
||||
expressions, but ripgrep's specific syntax is documented here:
|
||||
https://docs.rs/regex/0.2.5/regex/#syntax
|
||||
|
||||
|
||||
### Recursive search
|
||||
|
||||
In the previous section, we showed how to use ripgrep to search a single file.
|
||||
In this section, we'll show how to use ripgrep to search an entire directory
|
||||
of files. In fact, *recursively* searching your current working directory is
|
||||
the default mode of operation for ripgrep, which means doing this is very
|
||||
simple.
|
||||
|
||||
Using our unzipped archive of ripgrep source code, here's how to find all
|
||||
function definitions whose name is `write`:
|
||||
|
||||
```
|
||||
$ rg 'fn write\('
|
||||
src/printer.rs
|
||||
469: fn write(&mut self, buf: &[u8]) {
|
||||
|
||||
termcolor/src/lib.rs
|
||||
227: fn write(&mut self, b: &[u8]) -> io::Result<usize> {
|
||||
250: fn write(&mut self, b: &[u8]) -> io::Result<usize> {
|
||||
428: fn write(&mut self, b: &[u8]) -> io::Result<usize> { self.wtr.write(b) }
|
||||
441: fn write(&mut self, b: &[u8]) -> io::Result<usize> { self.wtr.write(b) }
|
||||
454: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
511: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
848: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
915: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
949: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
1114: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
1348: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
1353: fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
```
|
||||
|
||||
(**Note:** We escape the `(` here because `(` has special significance inside
|
||||
regular expressions. You could also use `rg -F 'fn write('` to achieve the
|
||||
same thing, where `-F` interprets your pattern as a literal string instead of
|
||||
a regular expression.)
|
||||
|
||||
In this example, we didn't specify a file at all. Instead, ripgrep defaulted
|
||||
to searching your current directory in the absence of a path. In general,
|
||||
`rg foo` is equivalent to `rg foo ./`.
|
||||
|
||||
This particular search showed us results in both the `src` and `termcolor`
|
||||
directories. The `src` directory is the core ripgrep code where as `termcolor`
|
||||
is a dependency of ripgrep (and is used by other tools). What if we only wanted
|
||||
to search core ripgrep code? Well, that's easy, just specify the directory you
|
||||
want:
|
||||
|
||||
```
|
||||
$ rg 'fn write\(' src
|
||||
src/printer.rs
|
||||
469: fn write(&mut self, buf: &[u8]) {
|
||||
```
|
||||
|
||||
Here, ripgrep limited its search to the `src` directory. Another way of doing
|
||||
this search would be to `cd` into the `src` directory and simply use `rg 'fn
|
||||
write\('` again.
|
||||
|
||||
|
||||
### Automatic filtering
|
||||
|
||||
After recursive search, ripgrep's most important feature is what it *doesn't*
|
||||
search. By default, when you search a directory, ripgrep will ignore all of
|
||||
the following:
|
||||
|
||||
1. Files and directories that match the rules in your `.gitignore` glob
|
||||
pattern.
|
||||
2. Hidden files and directories.
|
||||
3. Binary files. (ripgrep considers any file with a `NUL` byte to be binary.)
|
||||
4. Symbolic links aren't followed.
|
||||
|
||||
All of these things can be toggled using various flags provided by ripgrep:
|
||||
|
||||
1. You can disable `.gitignore` handling with the `--no-ignore` flag.
|
||||
2. Hidden files and directories can be searched with the `--hidden` flag.
|
||||
3. Binary files can be searched via the `--text` (`-a` for short) flag.
|
||||
Be careful with this flag! Binary files may emit control characters to your
|
||||
terminal, which might cause strange behavior.
|
||||
4. ripgrep can follow symlinks with the `--follow` (`-L` for short) flag.
|
||||
|
||||
As a special convenience, ripgrep also provides a flag called `--unrestricted`
|
||||
(`-u` for short). Repeated uses of this flag will cause ripgrep to disable
|
||||
more and more of its filtering. That is, `-u` will disable `.gitignore`
|
||||
handling, `-uu` will search hidden files and directories and `-uuu` will search
|
||||
binary files. This is useful when you're using ripgrep and you aren't sure
|
||||
whether its filtering is hiding results from you. Tacking on a couple `-u`
|
||||
flags is a quick way to find out. (Use the `--debug` flag if you're still
|
||||
perplexed, and if that doesn't help,
|
||||
[file an issue](https://github.com/BurntSushi/ripgrep/issues/new).)
|
||||
|
||||
ripgrep's `.gitignore` handling actually goes a bit beyond just `.gitignore`
|
||||
files. ripgrep will also respect repository specific rules found in
|
||||
`$GIT_DIR/info/exclude`, as well as any global ignore rules in your
|
||||
`core.excludesFile` (which is usually `$XDG_CONFIG_HOME/git/ignore` on
|
||||
Unix-like systems).
|
||||
|
||||
Sometimes you want to search files that are in your `.gitignore`, so it is
|
||||
possible to specify additional ignore rules or overrides in a `.ignore`
|
||||
(application agnostic) or `.rgignore` (ripgrep specific) file.
|
||||
|
||||
For example, let's say you have a `.gitignore` file that looks like this:
|
||||
|
||||
```
|
||||
log/
|
||||
```
|
||||
|
||||
This generally means that any `log` directory won't be tracked by `git`.
|
||||
However, perhaps it contains useful output that you'd like to include in your
|
||||
searches, but you still don't want to track it in `git`. You can achieve this
|
||||
by creating a `.ignore` file in the same directory as the `.gitignore` file
|
||||
with the following contents:
|
||||
|
||||
```
|
||||
!log/
|
||||
```
|
||||
|
||||
ripgrep treats `.ignore` files with higher precedence than `.gitignore` files
|
||||
(and treats `.rgignore` files with higher precdence than `.ignore` files).
|
||||
This means ripgrep will see the `!log/` whitelist rule first and search that
|
||||
directory.
|
||||
|
||||
Like `.gitignore`, a `.ignore` file can be placed in any directory. Its rules
|
||||
will be processed with respect to the directory it resides in, just like
|
||||
`.gitignore`.
|
||||
|
||||
For a more in depth description of how glob patterns in a `.gitignore` file
|
||||
are interpreted, please see `man gitignore`.
|
||||
|
||||
|
||||
### Manual filtering: globs
|
||||
|
||||
In the previous section, we talked about ripgrep's filtering that it does by
|
||||
default. It is "automatic" because it reacts to your environment. That is, it
|
||||
uses already existing `.gitignore` files to produce more relevant search
|
||||
results.
|
||||
|
||||
In addition to automatic filtering, ripgrep also provides more manual or ad hoc
|
||||
filtering. This comes in two varieties: additional glob patterns specified in
|
||||
your ripgrep commands and file type filtering. This section covers glob
|
||||
patterns while the next section covers file type filtering.
|
||||
|
||||
In our ripgrep source code (see [Basics](#basics) for instructions on how to
|
||||
get a source archive to search), let's say we wanted to see which things depend
|
||||
on `clap`, our argument parser.
|
||||
|
||||
We could do this:
|
||||
|
||||
```
|
||||
$ rg clap
|
||||
[lots of results]
|
||||
```
|
||||
|
||||
But this shows us many things, and we're only interested in where we wrote
|
||||
`clap` as a dependency. Instead, we could limit ourselves to TOML files, which
|
||||
is how dependencies are communicated to Rust's build tool, Cargo:
|
||||
|
||||
```
|
||||
$ rg clap -g '*.toml'
|
||||
Cargo.toml
|
||||
35:clap = "2.26"
|
||||
51:clap = "2.26"
|
||||
```
|
||||
|
||||
The `-g '*.toml'` syntax says, "make sure every file searched matches this
|
||||
glob pattern." Note that we put `'*.toml'` in single quotes to prevent our
|
||||
shell from expanding the `*`.
|
||||
|
||||
If we wanted, we could tell ripgrep to search anything *but* `*.toml` files:
|
||||
|
||||
```
|
||||
$ rg clap -g '!*.toml'
|
||||
[lots of results]
|
||||
```
|
||||
|
||||
This will give you a lot of results again as above, but they won't include
|
||||
files ending with `.toml`. Note that the use of a `!` here to mean "negation"
|
||||
is a bit non-standard, but it was chosen to be consistent with how globs in
|
||||
`.gitignore` files are written. (Although, the meaning is reversed. In
|
||||
`.gitignore` files, a `!` prefix means whitelist, and on the command line, a
|
||||
`!` means blacklist.)
|
||||
|
||||
Globs are interpreted in exactly the same way as `.gitignore` patterns. That
|
||||
is, later globs will override earlier globs. For example, the following command
|
||||
will search only `*.toml` files:
|
||||
|
||||
```
|
||||
$ rg clap -g '!*.toml' -g '*.toml'
|
||||
```
|
||||
|
||||
Interestingly, reversing the order of the globs in this case will match
|
||||
nothing, since the presence of at least one non-blacklist glob will institute a
|
||||
requirement that every file searched must match at least one glob. In this
|
||||
case, the blacklist glob takes precedence over the previous glob and prevents
|
||||
any file from being searched at all!
|
||||
|
||||
|
||||
### Manual filtering: file types
|
||||
|
||||
Over time, you might notice that you use the same glob patterns over and over.
|
||||
For example, you might find yourself doing a lot of searches where you only
|
||||
want to see results for Rust files:
|
||||
|
||||
```
|
||||
$ rg 'fn run' -g '*.rs'
|
||||
```
|
||||
|
||||
Instead of writing out the glob every time, you can use ripgrep's support for
|
||||
file types:
|
||||
|
||||
```
|
||||
$ rg 'fn run' --type rust
|
||||
```
|
||||
|
||||
or, more succinctly,
|
||||
|
||||
```
|
||||
$ rg 'fn run' -trust
|
||||
```
|
||||
|
||||
The way the `--type` flag functions is simple. It acts as a name that is
|
||||
assigned to one or more globs that match the relevant files. This lets you
|
||||
write a single type that might encompass a broad range of file extensions. For
|
||||
example, if you wanted to search C files, you'd have to check both C source
|
||||
files and C header files:
|
||||
|
||||
```
|
||||
$ rg 'int main' -g '*.{c,h}'
|
||||
```
|
||||
|
||||
or you could just use the C file type:
|
||||
|
||||
```
|
||||
$ rg 'int main' -tc
|
||||
```
|
||||
|
||||
Just as you can write blacklist globs, you can blacklist file types too:
|
||||
|
||||
```
|
||||
$ rg clap --type-not rust
|
||||
```
|
||||
|
||||
or, more succinctly,
|
||||
|
||||
```
|
||||
$ rg clap -Trust
|
||||
```
|
||||
|
||||
That is, `-t` means "include files of this type" where as `-T` means "exclude
|
||||
files of this type."
|
||||
|
||||
To see the globs that make up a type, run `rg --type-list`:
|
||||
|
||||
```
|
||||
$ rg --type-list | rg '^make:'
|
||||
make: *.mak, *.mk, GNUmakefile, Gnumakefile, Makefile, gnumakefile, makefile
|
||||
```
|
||||
|
||||
By default, ripgrep comes with a bunch of pre-defined types. Generally, these
|
||||
types correspond to well known public formats. But you can define your own
|
||||
types as well. For example, perhaps you frequently search "web" files, which
|
||||
consist of Javascript, HTML and CSS:
|
||||
|
||||
```
|
||||
$ rg --type-add 'web:*.html' --type-add 'web:*.css' --type-add 'web:*.js' -tweb title
|
||||
```
|
||||
|
||||
or, more succinctly,
|
||||
|
||||
```
|
||||
$ rg --type-add 'web:*.{html,css,js}' -tweb title
|
||||
```
|
||||
|
||||
The above command defines a new type, `web`, corresponding to the glob
|
||||
`*.{html,css,js}`. It then applies the new filter with `-tweb` and searches for
|
||||
the pattern `title`. If you ran
|
||||
|
||||
```
|
||||
$ rg --type-add 'web:*.{html,css,js}' --type-list
|
||||
```
|
||||
|
||||
Then you would see your `web` type show up in the list, even though it is not
|
||||
part of ripgrep's built-in types.
|
||||
|
||||
It is important to stress here that the `--type-add` flag only applies to the
|
||||
current command. It does not add a new file type and save it somewhere in a
|
||||
persistent form. If you want a type to be available in every ripgrep command,
|
||||
then you should either create a shell alias:
|
||||
|
||||
```
|
||||
alias rg="rg --type-add 'web:*.{html,css,js}'"
|
||||
```
|
||||
|
||||
or add `--type-add=web:*.{html,css,js}` to your ripgrep configuration file.
|
||||
([Configuration files](#configuration-file) are covered in more detail later.)
|
||||
|
||||
|
||||
### Replacements
|
||||
|
||||
ripgrep provides a limited ability to modify its output by replacing matched
|
||||
text with some other text. This is easiest to explain with an example. Remember
|
||||
when we searched for the word `fast` in ripgrep's README?
|
||||
|
||||
```
|
||||
$ rg fast README.md
|
||||
75: faster than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
|
||||
119:### Is it really faster than everything else?
|
||||
124:Summarizing, `ripgrep` is fast because:
|
||||
129: optimizations to make searching very fast.
|
||||
```
|
||||
|
||||
What if we wanted to *replace* all occurrences of `fast` with `FAST`? That's
|
||||
easy with ripgrep's `--replace` flag:
|
||||
|
||||
```
|
||||
$ rg fast README.md --replace FAST
|
||||
75: FASTer than both. (N.B. It is not, strictly speaking, a "drop-in" replacement
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays FAST while
|
||||
119:### Is it really FASTer than everything else?
|
||||
124:Summarizing, `ripgrep` is FAST because:
|
||||
129: optimizations to make searching very FAST.
|
||||
```
|
||||
|
||||
or, more succinctly,
|
||||
|
||||
```
|
||||
$ rg fast README.md -r FAST
|
||||
[snip]
|
||||
```
|
||||
|
||||
In essence, the `--replace` flag applies *only* to the matching portion of text
|
||||
in the output. If you instead wanted to replace an entire line of text, then
|
||||
you need to include the entire line in your match. For example:
|
||||
|
||||
```
|
||||
$ rg '^.*fast.*$' README.md -r FAST
|
||||
75:FAST
|
||||
88:FAST
|
||||
119:FAST
|
||||
124:FAST
|
||||
129:FAST
|
||||
```
|
||||
|
||||
Alternatively, you can combine the `--only-matching` (or `-o` for short) with
|
||||
the `--replace` flag to achieve the same result:
|
||||
|
||||
```
|
||||
$ rg fast README.md --only-matching --replace FAST
|
||||
75:FAST
|
||||
88:FAST
|
||||
119:FAST
|
||||
124:FAST
|
||||
129:FAST
|
||||
```
|
||||
|
||||
or, more succinctly,
|
||||
|
||||
```
|
||||
$ rg fast README.md -or FAST
|
||||
[snip]
|
||||
```
|
||||
|
||||
Finally, replacements can include capturing groups. For example, let's say
|
||||
we wanted to find all occurrences of `fast` followed by another word and
|
||||
join them together with a dash. The pattern we might use for that is
|
||||
`fast\s+(\w+)`, which matches `fast`, followed by any amount of whitespace,
|
||||
followed by any number of "word" characters. We put the `\w+` in a "capturing
|
||||
group" (indicated by parentheses) so that we can reference it later in our
|
||||
replacement string. For example:
|
||||
|
||||
```
|
||||
$ rg 'fast\s+(\w+)' README.md -r 'fast-$1'
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while
|
||||
124:Summarizing, `ripgrep` is fast-because:
|
||||
```
|
||||
|
||||
Our replacement string here, `fast-$1`, consists of `fast-` followed by the
|
||||
contents of the capturing group at index `1`. (Capturing groups actually start
|
||||
at index 0, but the `0`th capturing group always corresponds to the entire
|
||||
match. The capturing group at index `1` always corresponds to the first
|
||||
explicit capturing group found in the regex pattern.)
|
||||
|
||||
Capturing groups can also be named, which is sometimes more convenient than
|
||||
using the indices. For example, the following command is equivalent to the
|
||||
above command:
|
||||
|
||||
```
|
||||
$ rg 'fast\s+(?P<word>\w+)' README.md -r 'fast-$word'
|
||||
88: color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast-while
|
||||
124:Summarizing, `ripgrep` is fast-because:
|
||||
```
|
||||
|
||||
It is important to note that ripgrep **will never modify your files**. The
|
||||
`--replace` flag only controls ripgrep's output. (And there is no flag to let
|
||||
you do a replacement in a file.)
|
||||
|
||||
|
||||
### Configuration file
|
||||
|
||||
It is possible that ripgrep's default options aren't suitable in every case.
|
||||
For that reason, and because shell aliases aren't always convenient, ripgrep
|
||||
supports configuration files.
|
||||
|
||||
Setting up a configuration file is simple. ripgrep will not look in any
|
||||
predetermined directory for a config file automatically. Instead, you need to
|
||||
set the `RIPGREP_CONFIG_PATH` environment variable to the file path of your
|
||||
config file. Once the environment variable is set, open the file and just type
|
||||
in the flags you want set automatically. There are only two rules for
|
||||
describing the format of the config file:
|
||||
|
||||
1. Every line is a shell argument, after trimming ASCII whitespace.
|
||||
2. Lines starting with `#` (optionally preceded by any amount of
|
||||
ASCII whitespace) are ignored.
|
||||
|
||||
In particular, there is no escaping. Each line is given to ripgrep as a single
|
||||
command line argument verbatim.
|
||||
|
||||
Here's an example of a configuration file, which demonstrates some of the
|
||||
formatting peculiarities:
|
||||
|
||||
```
|
||||
$ cat $HOME/.ripgreprc
|
||||
# Don't let ripgrep vomit really long lines to my terminal.
|
||||
--max-columns=150
|
||||
|
||||
# Add my 'web' type.
|
||||
--type-add
|
||||
web:*.{html,css,js}*
|
||||
|
||||
# Set the colors.
|
||||
--colors=line:none
|
||||
--colors=line:style:bold
|
||||
|
||||
# Because who cares about case!?
|
||||
--smart-case
|
||||
```
|
||||
|
||||
When we use a flag that has a value, we either put the flag and the value on
|
||||
the same line but delimited by an `=` sign (e.g., `--max-columns=150`), or we
|
||||
put the flag and the value on two different lines. This is because ripgrep's
|
||||
argument parser knows to treat the single argument `--max-columns=150` as a
|
||||
flag with a value, but if we had written `--max-columns 150` in our
|
||||
configuration file, then ripgrep's argument parser wouldn't know what to do
|
||||
with it.
|
||||
|
||||
Putting the flag and value on different lines is exactly equivalent and is a
|
||||
matter of style.
|
||||
|
||||
Comments are encouraged so that you remember what the config is doing. Empty
|
||||
lines are OK too.
|
||||
|
||||
So let's say you're using the above configuration file, but while you're at a
|
||||
terminal, you really want to be able to see lines longer than 150 columns. What
|
||||
do you do? Thankfully, all you need to do is pass `--max-columns 0` (or `-M0`
|
||||
for short) on the command line, which will override your configuration file's
|
||||
setting. This works because ripgrep's configuration file is *prepended* to the
|
||||
explicit arguments you give it on the command line. Since flags given later
|
||||
override flags given earlier, everything works as expected. This works for most
|
||||
other flags as well, and each flag's documentation states which other flags
|
||||
override it.
|
||||
|
||||
If you're confused about what configuration file ripgrep is reading arguments
|
||||
from, then running ripgrep with the `--debug` flag should help clarify things.
|
||||
The debug output should note what config file is being loaded and the arugments
|
||||
that have been read from the configuration.
|
||||
|
||||
Finally, if you want to make absolutely sure that ripgrep *isn't* reading a
|
||||
configuration file, then you can pass the `--no-config` flag, which will always
|
||||
prevent ripgrep from reading extraneous configuration from the environment,
|
||||
regardless of what other methods of configuration are added to ripgrep in the
|
||||
future.
|
||||
|
||||
|
||||
### File encoding
|
||||
|
||||
[Text encoding](https://en.wikipedia.org/wiki/Character_encoding) is a complex
|
||||
topic, but we can try to summarize its relevancy to ripgrep:
|
||||
|
||||
* Files are generally just a bundle of bytes. There is no reliable way to know
|
||||
their encoding.
|
||||
* Either the encoding of the pattern must match the encoding of the files being
|
||||
searched, or a form of transcoding must be performed converts either the
|
||||
pattern or the file to the same encoding as the other.
|
||||
* ripgrep tends to work best on plain text files, and among plain text files,
|
||||
the most popular encodings likely consist of ASCII, latin1 or UTF-8. As
|
||||
a special exception, UTF-16 is prevalent in Windows environments
|
||||
|
||||
In light of the above, here is how ripgrep behaves:
|
||||
|
||||
* All input is assumed to be ASCII compatible (which means every byte that
|
||||
corresponds to an ASCII codepoint actually is an ASCII codepoint). This
|
||||
includes ASCII itself, latin1 and UTF-8.
|
||||
* ripgrep works best with UTF-8. For example, ripgrep's regular expression
|
||||
engine supports Unicode features. Namely, character classes like `\w` will
|
||||
match all word characters by Unicode's definition and `.` will match any
|
||||
Unicode codepoint instead of any byte. These constructions assume UTF-8,
|
||||
so they simply won't match when they come across bytes in a file that aren't
|
||||
UTF-8.
|
||||
* To handle the UTF-16 case, ripgrep will do something called "BOM sniffing"
|
||||
by default. That is, the first three bytes of a file will be read, and if
|
||||
they correspond to a UTF-16 BOM, then ripgrep will transcode the contents of
|
||||
the file from UTF-16 to UTF-8, and then execute the search on the transcoded
|
||||
version of the file. (This incurs a performance penalty since transcoding
|
||||
is slower than regex searching.)
|
||||
* To handle other cases, ripgrep provides a `-E/--encoding` flag, which permits
|
||||
you to specify an encoding from the
|
||||
[Encoding Standard](https://encoding.spec.whatwg.org/#concept-encoding-get).
|
||||
ripgrep will assume *all* files searched are the encoding specified and
|
||||
will perform a transcoding step just like in the UTF-16 case described above.
|
||||
|
||||
By default, ripgrep will not require its input be valid UTF-8. That is, ripgrep
|
||||
can and will search arbitrary bytes. The key here is that if you're searching
|
||||
content that isn't UTF-8, then the usefulness of your pattern will degrade. If
|
||||
you're searching bytes that aren't ASCII compatible, then it's likely the
|
||||
pattern won't find anything. With all that said, this mode of operation is
|
||||
important, because it lets you find ASCII or UTF-8 *within* files that are
|
||||
otherwise arbitrary bytes.
|
||||
|
||||
Finally, it is possible to disable ripgrep's Unicode support from within the
|
||||
pattern regular expression. For example, let's say you wanted `.` to match any
|
||||
byte rather than any Unicode codepoint. (You might want this while searching a
|
||||
binary file, since `.` by default will not match invalid UTF-8.) You could do
|
||||
this by disabling Unicode via a regular expression flag:
|
||||
|
||||
```
|
||||
$ rg '(?-u:.)'
|
||||
```
|
||||
|
||||
This works for any part of the pattern. For example, the following will find
|
||||
any Unicode word character followed by any ASCII word character followed by
|
||||
another Unicode word character:
|
||||
|
||||
```
|
||||
$ rg '\w(?-u:\w)\w'
|
||||
```
|
||||
|
||||
|
||||
### Common options
|
||||
|
||||
ripgrep has a lot of flags. Too many to keep in your head at once. This section
|
||||
is intended to give you a sampling of some of the most important and frequently
|
||||
used options that will likely impact how you use ripgrep on a regular basis.
|
||||
|
||||
* `-h`: Show ripgrep's condensed help output.
|
||||
* `--help`: Show ripgrep's longer form help output. (Nearly what you'd find in
|
||||
ripgrep's man page, so pipe it into a pager!)
|
||||
* `-i/--ignore-case`: When searching for a pattern, ignore case differences.
|
||||
That is `rg -i fast` matches `fast`, `fASt`, `FAST`, etc.
|
||||
* `-S/--smart-case`: This is similar to `--ignore-case`, but disables itself
|
||||
if the pattern contains any uppercase letters. Usually this flag is put into
|
||||
alias or a config file.
|
||||
* `-w/--word-regexp`: Require that all matches of the pattern be surrounded
|
||||
by word boundaries. That is, given `pattern`, the `--word-regexp` flag will
|
||||
cause ripgrep to behave as if `pattern` were actually `\b(?:pattern)\b`.
|
||||
* `-c/--count`: Report a count of total matched lines.
|
||||
* `--files`: Print the files that ripgrep *would* search, but don't actually
|
||||
search them.
|
||||
* `-a/--text`: Search binary files as if they were plain text.
|
||||
* `-z/--search-zip`: Search compressed files (gzip, bzip2, lzma, xz). This is
|
||||
disabled by default.
|
||||
* `-C/--context`: Show the lines surrounding a match.
|
||||
* `--sort-files`: Force ripgrep to sort its output by file name. (This disables
|
||||
parallelism, so it might be slower.)
|
||||
* `-L/--follow`: Follow symbolic links while recursively searching.
|
||||
* `-M/--max-columns`: Limit the length of lines printed by ripgrep.
|
||||
* `--debug`: Shows ripgrep's debug output. This is useful for understanding
|
||||
why a particular file might be ignored from search, or what kinds of
|
||||
configuration ripgrep is loading from the environment.
|
||||
47
ISSUE_TEMPLATE.md
Normal file
47
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,47 @@
|
||||
#### What version of ripgrep are you using?
|
||||
|
||||
Replace this text with the output of `rg --version`.
|
||||
|
||||
#### What operating system are you using ripgrep on?
|
||||
|
||||
Replace this text with your operating system and version.
|
||||
|
||||
#### Describe your question, feature request, or bug.
|
||||
|
||||
If a question, please describe the problem you're trying to solve and give
|
||||
as much context as possible.
|
||||
|
||||
If a feature request, please describe the behavior you want and the motivation.
|
||||
Please also provide an example of how ripgrep would be used if your feature
|
||||
request were added.
|
||||
|
||||
If a bug, please see below.
|
||||
|
||||
#### If this is a bug, what are the steps to reproduce the behavior?
|
||||
|
||||
If possible, please include both your search patterns and the corpus on which
|
||||
you are searching. Unless the bug is very obvious, then it is unlikely that it
|
||||
will be fixed if the ripgrep maintainers cannot reproduce it.
|
||||
|
||||
If the corpus is too big and you cannot decrease its size, file the bug anyway
|
||||
and the ripgrep maintainers will help figure out next steps.
|
||||
|
||||
#### If this is a bug, what is the actual behavior?
|
||||
|
||||
Show the command you ran and the actual output. Include the `--debug` flag in
|
||||
your invocation of ripgrep.
|
||||
|
||||
If the output is large, put it in a gist: https://gist.github.com/
|
||||
|
||||
If the output is small, put it in code fences:
|
||||
|
||||
```
|
||||
your
|
||||
output
|
||||
goes
|
||||
here
|
||||
```
|
||||
|
||||
#### If this is a bug, what is the expected behavior?
|
||||
|
||||
What do you think ripgrep should have done?
|
||||
355
README.md
355
README.md
@@ -1,9 +1,11 @@
|
||||
ripgrep (rg)
|
||||
------------
|
||||
`ripgrep` is a command line search tool that combines the usability of The
|
||||
Silver Searcher (an `ack` clone) with the raw speed of GNU grep. `ripgrep` has
|
||||
first class support on Windows, Mac and Linux, with binary downloads available
|
||||
for [every release](https://github.com/BurntSushi/ripgrep/releases).
|
||||
ripgrep is a line-oriented search tool that recursively searches your current
|
||||
directory for a regex pattern while respecting your gitignore rules. ripgrep
|
||||
has first class support on Windows, macOS and Linux, with binary downloads
|
||||
available for [every release](https://github.com/BurntSushi/ripgrep/releases).
|
||||
ripgrep is similar to other popular search tools like The Silver Searcher,
|
||||
ack and grep.
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
@@ -11,61 +13,131 @@ for [every release](https://github.com/BurntSushi/ripgrep/releases).
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
|
||||
### CHANGELOG
|
||||
|
||||
Please see the [CHANGELOG](CHANGELOG.md) for a release history.
|
||||
|
||||
### Documentation quick links
|
||||
|
||||
* [Installation](#installation)
|
||||
* [User Guide](GUIDE.md)
|
||||
* [Frequently Asked Questions](FAQ.md)
|
||||
* [Regex syntax](https://docs.rs/regex/0.2.5/regex/#syntax)
|
||||
* [Configuration files](GUIDE.md#configuration-file)
|
||||
* [Shell completions](FAQ.md#complete)
|
||||
* [Building](#building)
|
||||
|
||||
|
||||
### Screenshot of search results
|
||||
|
||||
[](http://burntsushi.net/stuff/ripgrep1.png)
|
||||
|
||||
### Quick example comparing tools
|
||||
|
||||
### Quick examples comparing tools
|
||||
|
||||
This example searches the entire Linux kernel source tree (after running
|
||||
`make defconfig && make -j8`) for `[A-Z]+_SUSPEND`, where all matches must be
|
||||
words. Timings were collected on a system with an Intel i7-6900K 3.2 GHz.
|
||||
words. Timings were collected on a system with an Intel i7-6900K 3.2 GHz, and
|
||||
ripgrep was compiled with SIMD enabled.
|
||||
|
||||
Please remember that a single benchmark is never enough! See my
|
||||
[blog post on `ripgrep`](http://blog.burntsushi.net/ripgrep/)
|
||||
[blog post on ripgrep](http://blog.burntsushi.net/ripgrep/)
|
||||
for a very detailed comparison with more benchmarks and analysis.
|
||||
|
||||
| Tool | Command | Line count | Time |
|
||||
| ---- | ------- | ---------- | ---- |
|
||||
| ripgrep | `rg -n -w '[A-Z]+_SUSPEND'` | 450 | **0.245s** |
|
||||
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 450 | 0.753s |
|
||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 0.823s |
|
||||
| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 2.880s |
|
||||
| [sift](https://github.com/svent/sift) | `sift --git -n -w '[A-Z]+_SUSPEND'` | 450 | 3.656s |
|
||||
| [The Platinum Searcher](https://github.com/monochromegane/the_platinum_searcher) | `pt -w -e '[A-Z]+_SUSPEND'` | 450 | 12.369s |
|
||||
| [ack](http://beyondgrep.com/) | `ack -w '[A-Z]+_SUSPEND'` | 1878 | 16.952s |
|
||||
| ripgrep (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 450 | **0.106s** |
|
||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 0.553s |
|
||||
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 450 | 0.589s |
|
||||
| [git grep (Unicode)](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 2.266s |
|
||||
| [sift](https://github.com/svent/sift) | `sift --git -n -w '[A-Z]+_SUSPEND'` | 450 | 3.505s |
|
||||
| [ack](https://github.com/petdance/ack2) | `ack -w '[A-Z]+_SUSPEND'` | 1878 | 6.823s |
|
||||
| [The Platinum Searcher](https://github.com/monochromegane/the_platinum_searcher) | `pt -w -e '[A-Z]+_SUSPEND'` | 450 | 14.208s |
|
||||
|
||||
(Yes, `ack` [has](https://github.com/petdance/ack2/issues/445) a
|
||||
[bug](https://github.com/petdance/ack2/issues/14).)
|
||||
|
||||
### Why should I use `ripgrep`?
|
||||
Here's another benchmark that disregards gitignore files and searches with a
|
||||
whitelist instead. The corpus is the same as in the previous benchmark, and the
|
||||
flags passed to each command ensure that they are doing equivalent work:
|
||||
|
||||
* It can replace both The Silver Searcher and GNU grep because it is faster
|
||||
than both. (N.B. It is not, strictly speaking, a "drop-in" replacement for
|
||||
both, but the feature sets are far more similar than different.)
|
||||
* Like The Silver Searcher, `ripgrep` defaults to recursive directory search
|
||||
| Tool | Command | Line count | Time |
|
||||
| ---- | ------- | ---------- | ---- |
|
||||
| ripgrep | `rg -L -u -tc -n -w '[A-Z]+_SUSPEND'` | 404 | **0.079s** |
|
||||
| [ucg](https://github.com/gvansickle/ucg) | `ucg --type=cc -w '[A-Z]+_SUSPEND'` | 390 | 0.163s |
|
||||
| [GNU grep](https://www.gnu.org/software/grep/) | `egrep -R -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 404 | 0.611s |
|
||||
|
||||
(`ucg` [has slightly different behavior in the presence of symbolic links](https://github.com/gvansickle/ucg/issues/106).)
|
||||
|
||||
And finally, a straight-up comparison between ripgrep and GNU grep on a single
|
||||
large file (~9.3GB,
|
||||
[`OpenSubtitles2016.raw.en.gz`](http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.en.gz)):
|
||||
|
||||
| Tool | Command | Line count | Time |
|
||||
| ---- | ------- | ---------- | ---- |
|
||||
| ripgrep | `rg -w 'Sherlock [A-Z]\w+'` | 5268 | **2.108s** |
|
||||
| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C egrep -w 'Sherlock [A-Z]\w+'` | 5268 | 7.014s |
|
||||
|
||||
In the above benchmark, passing the `-n` flag (for showing line numbers)
|
||||
increases the times to `2.640s` for ripgrep and `10.277s` for GNU grep.
|
||||
|
||||
|
||||
### Why should I use ripgrep?
|
||||
|
||||
* It can replace many use cases served by both The Silver Searcher and GNU grep
|
||||
because it is generally faster than both. (See [the FAQ](FAQ.md#posix4ever)
|
||||
for more details on whether ripgrep can truly replace grep.)
|
||||
* Like The Silver Searcher, ripgrep defaults to recursive directory search
|
||||
and won't search files ignored by your `.gitignore` files. It also ignores
|
||||
hidden and binary files by default. `ripgrep` also implements full support
|
||||
for `.gitignore`, where as there are many bugs related to that functionality
|
||||
hidden and binary files by default. ripgrep also implements full support
|
||||
for `.gitignore`, whereas there are many bugs related to that functionality
|
||||
in The Silver Searcher.
|
||||
* `ripgrep` can search specific types of files. For example, `rg -tpy foo`
|
||||
* ripgrep can search specific types of files. For example, `rg -tpy foo`
|
||||
limits your search to Python files and `rg -Tjs foo` excludes Javascript
|
||||
files from your search. `ripgrep` can be taught about new file types with
|
||||
files from your search. ripgrep can be taught about new file types with
|
||||
custom matching rules.
|
||||
* `ripgrep` supports many features found in `grep`, such as showing the context
|
||||
* ripgrep supports many features found in `grep`, such as showing the context
|
||||
of search results, searching multiple patterns, highlighting matches with
|
||||
color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
|
||||
color and full Unicode support. Unlike GNU grep, ripgrep stays fast while
|
||||
supporting Unicode (which is always on).
|
||||
* ripgrep supports searching files in text encodings other than UTF-8, such
|
||||
as UTF-16, latin-1, GBK, EUC-JP, Shift_JIS and more. (Some support for
|
||||
automatically detecting UTF-16 is provided. Other text encodings must be
|
||||
specifically specified with the `-E/--encoding` flag.)
|
||||
* ripgrep supports searching files compressed in a common format (gzip, xz,
|
||||
lzma or bzip2 current) with the `-z/--search-zip` flag.
|
||||
|
||||
In other words, use ripgrep if you like speed, filtering by default, fewer
|
||||
bugs, and Unicode support.
|
||||
|
||||
|
||||
### Why shouldn't I use ripgrep?
|
||||
|
||||
I'd like to try to convince you why you *shouldn't* use ripgrep. This should
|
||||
give you a glimpse at some important downsides or missing features of
|
||||
ripgrep.
|
||||
|
||||
* ripgrep uses a regex engine based on finite automata, so if you want fancy
|
||||
regex features such as backreferences or lookaround, ripgrep won't provide
|
||||
them to you. ripgrep does support lots of things though, including, but not
|
||||
limited to: lazy quantification (e.g., `a+?`), repetitions (e.g., `a{2,5}`),
|
||||
begin/end assertions (e.g., `^\w+$`), word boundaries (e.g., `\bfoo\b`), and
|
||||
support for Unicode categories (e.g., `\p{Sc}` to match currency symbols or
|
||||
`\p{Lu}` to match any uppercase letter). (Fancier regexes will never be
|
||||
supported.)
|
||||
* ripgrep doesn't have multiline search. (Will happen as an opt-in feature.)
|
||||
|
||||
In other words, if you like fancy regexes or multiline search, then ripgrep
|
||||
may not quite meet your needs (yet).
|
||||
|
||||
In other words, use `ripgrep` if you like speed, sane defaults, fewer bugs and
|
||||
Unicode.
|
||||
|
||||
### Is it really faster than everything else?
|
||||
|
||||
Yes. A large number of benchmarks with detailed analysis for each is
|
||||
Generally, yes. A large number of benchmarks with detailed analysis for each is
|
||||
[available on my blog](http://blog.burntsushi.net/ripgrep/).
|
||||
|
||||
Summarizing, `ripgrep` is fast because:
|
||||
Summarizing, ripgrep is fast because:
|
||||
|
||||
* It is built on top of
|
||||
[Rust's regex engine](https://github.com/rust-lang-nursery/regex).
|
||||
@@ -76,28 +148,41 @@ Summarizing, `ripgrep` is fast because:
|
||||
engine.
|
||||
* It supports searching with either memory maps or by searching incrementally
|
||||
with an intermediate buffer. The former is better for single files and the
|
||||
latter is better for large directories. `ripgrep` chooses the best searching
|
||||
latter is better for large directories. ripgrep chooses the best searching
|
||||
strategy for you automatically.
|
||||
* Applies your ignore patterns in `.gitignore` files using a
|
||||
[`RegexSet`](https://doc.rust-lang.org/regex/regex/struct.RegexSet.html).
|
||||
That means a single file path can be matched against multiple glob patterns
|
||||
simultaneously.
|
||||
* Uses a Chase-Lev work-stealing queue for quickly distributing work to
|
||||
multiple threads.
|
||||
* It uses a lock-free parallel recursive directory iterator, courtesy of
|
||||
[`crossbeam`](https://docs.rs/crossbeam) and
|
||||
[`ignore`](https://docs.rs/ignore).
|
||||
|
||||
|
||||
### Feature comparison
|
||||
|
||||
Andy Lester, author of [ack](https://beyondgrep.com/), has published an
|
||||
excellent table comparing the features of ack, ag, git-grep, GNU grep and
|
||||
ripgrep: https://beyondgrep.com/feature-comparison/
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
The binary name for `ripgrep` is `rg`.
|
||||
The binary name for ripgrep is `rg`.
|
||||
|
||||
[Binaries for `ripgrep` are available for Windows, Mac and
|
||||
Linux.](https://github.com/BurntSushi/ripgrep/releases) Linux binaries are
|
||||
static executables. Windows binaries are available either as built with MinGW
|
||||
(GNU) or with Microsoft Visual C++ (MSVC). When possible, prefer MSVC over GNU,
|
||||
but you'll need to have the
|
||||
[Microsoft VC++ 2015 redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
**[Archives of precompiled binaries for ripgrep are available for Windows,
|
||||
macOS and Linux.](https://github.com/BurntSushi/ripgrep/releases)** Users of
|
||||
platforms not explicitly mentioned below are advised to download one of these
|
||||
archives.
|
||||
|
||||
Linux binaries are static executables. Windows binaries are available either as
|
||||
built with MinGW (GNU) or with Microsoft Visual C++ (MSVC). When possible,
|
||||
prefer MSVC over GNU, but you'll need to have the [Microsoft VC++ 2015
|
||||
redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
installed.
|
||||
|
||||
If you're a **Mac OS X Homebrew** user, then you can install ripgrep either
|
||||
If you're a **macOS Homebrew** or a **Linuxbrew** user,
|
||||
then you can install ripgrep either
|
||||
from homebrew-core, (compiled with rust stable, no SIMD):
|
||||
|
||||
```
|
||||
@@ -112,157 +197,91 @@ $ brew tap burntsushi/ripgrep https://github.com/BurntSushi/ripgrep.git
|
||||
$ brew install burntsushi/ripgrep/ripgrep-bin
|
||||
```
|
||||
|
||||
If you're an **Arch Linux** user, then you can install `ripgrep` from the official repos:
|
||||
If you're a **Windows Chocolatey** user, then you can install ripgrep from the [official repo](https://chocolatey.org/packages/ripgrep):
|
||||
|
||||
```
|
||||
$ choco install ripgrep
|
||||
```
|
||||
|
||||
If you're an **Arch Linux** user, then you can install ripgrep from the official repos:
|
||||
|
||||
```
|
||||
$ pacman -S ripgrep
|
||||
```
|
||||
|
||||
If you're a **Fedora 24+** user, you can install `ripgrep` from [copr](https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/):
|
||||
If you're a **Gentoo** user, you can install ripgrep from the [official repo](https://packages.gentoo.org/packages/sys-apps/ripgrep):
|
||||
|
||||
```
|
||||
$ dnf copr enable carlgeorge/ripgrep
|
||||
$ dnf install ripgrep
|
||||
$ emerge sys-apps/ripgrep
|
||||
```
|
||||
|
||||
If you're a **RHEL/CentOS 7** user, you can install `ripgrep` from [copr](https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/):
|
||||
If you're a **Fedora 27+** user, you can install ripgrep from official repositories.
|
||||
|
||||
```
|
||||
$ yum-config-manager --add-repo=https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/repo/epel-7/carlgeorge-ripgrep-epel-7.repo
|
||||
$ yum install ripgrep
|
||||
$ sudo dnf install ripgrep
|
||||
```
|
||||
|
||||
If you're a **Nix** user, you can install `ripgrep` from
|
||||
If you're a **Fedora 24+** user, you can install ripgrep from [copr](https://copr.fedorainfracloud.org/coprs/carlwgeorge/ripgrep/):
|
||||
|
||||
```
|
||||
$ sudo dnf copr enable carlwgeorge/ripgrep
|
||||
$ sudo dnf install ripgrep
|
||||
```
|
||||
|
||||
If you're a **RHEL/CentOS 7** user, you can install ripgrep from [copr](https://copr.fedorainfracloud.org/coprs/carlwgeorge/ripgrep/):
|
||||
|
||||
```
|
||||
$ sudo yum-config-manager --add-repo=https://copr.fedorainfracloud.org/coprs/carlwgeorge/ripgrep/repo/epel-7/carlwgeorge-ripgrep-epel-7.repo
|
||||
$ sudo yum install ripgrep
|
||||
```
|
||||
|
||||
If you're a **Nix** user, you can install ripgrep from
|
||||
[nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/text/ripgrep/default.nix):
|
||||
|
||||
```
|
||||
$ nix-env --install ripgrep
|
||||
$ # (Or using the attribute name, which is also `ripgrep`.)
|
||||
$ # (Or using the attribute name, which is also ripgrep.)
|
||||
```
|
||||
|
||||
If you're a **Rust programmer**, `ripgrep` can be installed with `cargo`:
|
||||
If you're a **Debian** user (or a user of a Debian derivative like **Ubuntu**),
|
||||
then ripgrep can be installed using a binary `.deb` file provided in each
|
||||
[ripgrep release](https://github.com/BurntSushi/ripgrep/releases). Note that
|
||||
ripgrep is not in the official Debian or Ubuntu repositories.
|
||||
|
||||
```
|
||||
$ curl -LO https://github.com/BurntSushi/ripgrep/releases/download/0.8.1/ripgrep_0.8.1_amd64.deb
|
||||
$ sudo dpkg -i ripgrep_0.8.1_amd64.deb
|
||||
```
|
||||
|
||||
If you're an **Ubuntu** user, ripgrep can be installed from the `snap` store.
|
||||
* Note that if you are using `16.04 LTS` or later, snap is already installed.
|
||||
* For older versions you can install snap using
|
||||
[this guide](https://docs.snapcraft.io/core/install-ubuntu).
|
||||
|
||||
```
|
||||
$ sudo snap install rg
|
||||
```
|
||||
|
||||
If you're a **Rust programmer**, ripgrep can be installed with `cargo`.
|
||||
* Note that the minimum supported version of Rust for ripgrep is **1.20**,
|
||||
although ripgrep may work with older versions.
|
||||
* Note that the binary may be bigger than expected because it contains debug
|
||||
symbols. This is intentional. To remove debug symbols and therefore reduce
|
||||
the file size, run `strip` on the binary.
|
||||
|
||||
```
|
||||
$ cargo install ripgrep
|
||||
```
|
||||
|
||||
`ripgrep` isn't currently in any other package repositories.
|
||||
ripgrep isn't currently in any other package repositories.
|
||||
[I'd like to change that](https://github.com/BurntSushi/ripgrep/issues/10).
|
||||
|
||||
### Whirlwind tour
|
||||
|
||||
The command line usage of `ripgrep` doesn't differ much from other tools that
|
||||
perform a similar function, so you probably already know how to use `ripgrep`.
|
||||
The full details can be found in `rg --help`, but let's go on a whirlwind tour.
|
||||
|
||||
`ripgrep` detects when its printing to a terminal, and will automatically
|
||||
colorize your output and show line numbers, just like The Silver Searcher.
|
||||
Coloring works on Windows too! Colors can be controlled more granularly with
|
||||
the `--color` flag.
|
||||
|
||||
One last thing before we get started: `ripgrep` assumes UTF-8 *everywhere*. It
|
||||
can still search files that are invalid UTF-8 (like, say, latin-1), but it will
|
||||
simply not work on UTF-16 encoded files or other more exotic encodings.
|
||||
[Support for other encodings may
|
||||
happen.](https://github.com/BurntSushi/ripgrep/issues/1)
|
||||
|
||||
To recursively search the current directory, while respecting all `.gitignore`
|
||||
files, ignore hidden files and directories and skip binary files:
|
||||
|
||||
```
|
||||
$ rg foobar
|
||||
```
|
||||
|
||||
The above command also respects all `.ignore` files, including in parent
|
||||
directories. `.ignore` files can be used when `.gitignore` files are
|
||||
insufficient. In all cases, `.ignore` patterns take precedence over
|
||||
`.gitignore`.
|
||||
|
||||
To ignore all ignore files, use `-u`. To additionally search hidden files
|
||||
and directories, use `-uu`. To additionally search binary files, use `-uuu`.
|
||||
(In other words, "search everything, dammit!") In particular, `rg -uuu` is
|
||||
similar to `grep -a -r`.
|
||||
|
||||
```
|
||||
$ rg -uu foobar # similar to `grep -r`
|
||||
$ rg -uuu foobar # similar to `grep -a -r`
|
||||
```
|
||||
|
||||
(Tip: If your ignore files aren't being adhered to like you expect, run your
|
||||
search with the `--debug` flag.)
|
||||
|
||||
Make the search case insensitive with `-i`, invert the search with `-v` or
|
||||
show the 2 lines before and after every search result with `-C2`.
|
||||
|
||||
Force all matches to be surrounded by word boundaries with `-w`.
|
||||
|
||||
Search and replace (find first and last names and swap them):
|
||||
|
||||
```
|
||||
$ rg '([A-Z][a-z]+)\s+([A-Z][a-z]+)' --replace '$2, $1'
|
||||
```
|
||||
|
||||
Named groups are supported:
|
||||
|
||||
```
|
||||
$ rg '(?P<first>[A-Z][a-z]+)\s+(?P<last>[A-Z][a-z]+)' --replace '$last, $first'
|
||||
```
|
||||
|
||||
Up the ante with full Unicode support, by matching any uppercase Unicode letter
|
||||
followed by any sequence of lowercase Unicode letters (good luck doing this
|
||||
with other search tools!):
|
||||
|
||||
```
|
||||
$ rg '(\p{Lu}\p{Ll}+)\s+(\p{Lu}\p{Ll}+)' --replace '$2, $1'
|
||||
```
|
||||
|
||||
Search only files matching a particular glob:
|
||||
|
||||
```
|
||||
$ rg foo -g 'README.*'
|
||||
```
|
||||
|
||||
<!--*-->
|
||||
|
||||
Or exclude files matching a particular glob:
|
||||
|
||||
```
|
||||
$ rg foo -g '!*.min.js'
|
||||
```
|
||||
|
||||
Search only HTML and CSS files:
|
||||
|
||||
```
|
||||
$ rg -thtml -tcss foobar
|
||||
```
|
||||
|
||||
Search everything except for Javascript files:
|
||||
|
||||
```
|
||||
$ rg -Tjs foobar
|
||||
```
|
||||
|
||||
To see a list of types supported, run `rg --type-list`. To add a new type, use
|
||||
`--type-add`, which must be accompanied by a pattern for searching (`rg` won't
|
||||
persist your type settings):
|
||||
|
||||
```
|
||||
$ rg --type-add 'foo:*.{foo,foobar}' -tfoo bar
|
||||
```
|
||||
|
||||
The type `foo` will now match any file ending with the `.foo` or `.foobar`
|
||||
extensions.
|
||||
|
||||
### Regex syntax
|
||||
|
||||
The syntax supported is
|
||||
[documented as part of Rust's regex library](https://doc.rust-lang.org/regex/regex/index.html#syntax).
|
||||
|
||||
### Building
|
||||
|
||||
`ripgrep` is written in Rust, so you'll need to grab a
|
||||
ripgrep is written in Rust, so you'll need to grab a
|
||||
[Rust installation](https://www.rust-lang.org/) in order to compile it.
|
||||
`ripgrep` compiles with Rust 1.9 (stable) or newer. Building is easy:
|
||||
ripgrep compiles with Rust 1.20 (stable) or newer. Building is easy:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/BurntSushi/ripgrep
|
||||
@@ -272,20 +291,24 @@ $ ./target/release/rg --version
|
||||
0.1.3
|
||||
```
|
||||
|
||||
If you have a Rust nightly compiler, then you can enable optional SIMD
|
||||
acceleration like so:
|
||||
If you have a Rust nightly compiler and a recent Intel CPU, then you can enable
|
||||
optional SIMD acceleration like so:
|
||||
|
||||
```
|
||||
RUSTFLAGS="-C target-cpu=native" cargo build --release --features simd-accel
|
||||
RUSTFLAGS="-C target-cpu=native" cargo build --release --features 'simd-accel avx-accel'
|
||||
```
|
||||
|
||||
If your machine doesn't support AVX instructions, then simply remove
|
||||
`avx-accel` from the features list. Similarly for SIMD.
|
||||
|
||||
|
||||
### Running tests
|
||||
|
||||
`ripgrep` is relatively well tested, including both unit tests and integration
|
||||
ripgrep is relatively well-tested, including both unit tests and integration
|
||||
tests. To run the full test suite, use:
|
||||
|
||||
```
|
||||
$ cargo test
|
||||
$ cargo test --all
|
||||
```
|
||||
|
||||
from the repository root.
|
||||
|
||||
29
appveyor.yml
29
appveyor.yml
@@ -1,6 +1,23 @@
|
||||
# Inspired from https://github.com/habitat-sh/habitat/blob/master/appveyor.yml
|
||||
cache:
|
||||
- c:\cargo\registry
|
||||
- c:\cargo\git
|
||||
- c:\projects\ripgrep\target
|
||||
|
||||
init:
|
||||
- mkdir c:\cargo
|
||||
- mkdir c:\rustup
|
||||
- SET PATH=c:\cargo\bin;%PATH%
|
||||
|
||||
clone_folder: c:\projects\ripgrep
|
||||
|
||||
environment:
|
||||
CARGO_HOME: "c:\\cargo"
|
||||
RUSTUP_HOME: "c:\\rustup"
|
||||
CARGO_TARGET_DIR: "c:\\projects\\ripgrep\\target"
|
||||
global:
|
||||
PROJECT_NAME: ripgrep
|
||||
RUST_BACKTRACE: full
|
||||
matrix:
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: stable
|
||||
@@ -11,12 +28,14 @@ environment:
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: stable
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
# Install Rust and Cargo
|
||||
# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
|
||||
install:
|
||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||
- rustup-init.exe -y --default-host %TARGET%
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustup-init.exe -y --default-host %TARGET% --no-modify-path
|
||||
- if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
@@ -27,10 +46,7 @@ build: false
|
||||
# Equivalent to Travis' `script` phase
|
||||
# TODO modify this phase as you see fit
|
||||
test_script:
|
||||
- cargo test --verbose
|
||||
- cargo test --verbose --manifest-path grep/Cargo.toml
|
||||
- cargo test --verbose --manifest-path globset/Cargo.toml
|
||||
- cargo test --verbose --manifest-path ignore/Cargo.toml
|
||||
- cargo test --verbose --all
|
||||
|
||||
before_deploy:
|
||||
# Generate artifacts for release
|
||||
@@ -38,6 +54,7 @@ before_deploy:
|
||||
- cargo build --release
|
||||
- mkdir staging
|
||||
- copy target\release\rg.exe staging
|
||||
- ps: copy target\release\build\ripgrep-*\out\_rg.ps1 staging
|
||||
- cd staging
|
||||
# release zipfile will look like 'rust-everywhere-v1.2.3-x86_64-pc-windows-msvc'
|
||||
- 7z a ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip *
|
||||
|
||||
@@ -26,10 +26,10 @@ SUBTITLES_DIR = 'subtitles'
|
||||
SUBTITLES_EN_NAME = 'OpenSubtitles2016.raw.en'
|
||||
SUBTITLES_EN_NAME_SAMPLE = 'OpenSubtitles2016.raw.sample.en'
|
||||
SUBTITLES_EN_NAME_GZ = '%s.gz' % SUBTITLES_EN_NAME
|
||||
SUBTITLES_EN_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.en.gz'
|
||||
SUBTITLES_EN_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.en.gz' # noqa
|
||||
SUBTITLES_RU_NAME = 'OpenSubtitles2016.raw.ru'
|
||||
SUBTITLES_RU_NAME_GZ = '%s.gz' % SUBTITLES_RU_NAME
|
||||
SUBTITLES_RU_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.ru.gz'
|
||||
SUBTITLES_RU_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.ru.gz' # noqa
|
||||
|
||||
LINUX_DIR = 'linux'
|
||||
LINUX_CLONE = 'git://github.com/BurntSushi/linux'
|
||||
@@ -755,7 +755,8 @@ class Benchmark(object):
|
||||
|
||||
def __init__(self, name=None, pattern=None, commands=None,
|
||||
warmup_count=1, count=3, line_count=True,
|
||||
allow_missing_commands=False):
|
||||
allow_missing_commands=False,
|
||||
disabled_cmds=None):
|
||||
'''
|
||||
Create a single benchmark.
|
||||
|
||||
@@ -786,6 +787,11 @@ class Benchmark(object):
|
||||
:param bool line_count:
|
||||
When set, the lines of each search are counted and included
|
||||
in the samples produced.
|
||||
:param bool allow_missing_commands:
|
||||
When set, if a command is missing, then the benchmark
|
||||
will simply skip it.
|
||||
:param list(str) disabled_cmds:
|
||||
A list of commands to skip.
|
||||
'''
|
||||
self.name = name
|
||||
self.pattern = pattern
|
||||
@@ -794,6 +800,7 @@ class Benchmark(object):
|
||||
self.count = count
|
||||
self.line_count = line_count
|
||||
self.allow_missing_commands = allow_missing_commands
|
||||
self.disabled_cmds = set(disabled_cmds or [])
|
||||
|
||||
def raise_if_missing(self):
|
||||
'''
|
||||
@@ -804,8 +811,11 @@ class Benchmark(object):
|
||||
least one command in this benchmark could not be found on this
|
||||
system.
|
||||
'''
|
||||
missing_commands = \
|
||||
[c.binary_name for c in self.commands if not c.exists()]
|
||||
missing_commands = []
|
||||
for c in self.commands:
|
||||
if c.binary_name in self.disabled_cmds or c.exists():
|
||||
continue
|
||||
missing_commands.append(c.binary_name)
|
||||
if not self.allow_missing_commands and len(missing_commands) > 0:
|
||||
raise MissingCommands(missing_commands)
|
||||
|
||||
@@ -821,6 +831,8 @@ class Benchmark(object):
|
||||
self.raise_if_missing()
|
||||
result = Result(self)
|
||||
for cmd in self.commands:
|
||||
if cmd.binary_name in self.disabled_cmds:
|
||||
continue
|
||||
if self.allow_missing_commands and not cmd.exists():
|
||||
# Skip this command if we're OK with it.
|
||||
continue
|
||||
@@ -849,7 +861,7 @@ class Benchmark(object):
|
||||
:rtype: int
|
||||
'''
|
||||
if not cmd.exists():
|
||||
raise MissingCommand(cmd.cmd[0])
|
||||
raise MissingCommands([cmd.cmd[0]])
|
||||
cmd.kwargs['stderr'] = subprocess.DEVNULL
|
||||
if self.line_count:
|
||||
cmd.kwargs['stdout'] = subprocess.PIPE
|
||||
@@ -936,8 +948,9 @@ class Result(object):
|
||||
A dictionary from command name to a set of line
|
||||
counts recorded.
|
||||
'''
|
||||
return {s['line_count'] for s in self.samples_for(cmd)
|
||||
if s['line_count'] is not None}
|
||||
return {s['line_count']
|
||||
for s in self.samples_for(cmd)
|
||||
if s['line_count'] is not None}
|
||||
|
||||
def distribution_for(self, cmd):
|
||||
'''
|
||||
@@ -1069,7 +1082,7 @@ def download_subtitles_en(suite_dir):
|
||||
if not os.path.exists(en_path):
|
||||
if not os.path.exists(en_path_gz):
|
||||
run_cmd(['curl', '-LO', SUBTITLES_EN_URL], cwd=subtitle_dir)
|
||||
run_cmd(['gunzip', en_path_gz], cwd=subtitle_dir)
|
||||
run_cmd(['gunzip', en_path_gz])
|
||||
if not os.path.exists(en_path_sample):
|
||||
# Get a sample roughly the same size as the Russian corpus so that
|
||||
# benchmarks finish in a reasonable time.
|
||||
@@ -1096,7 +1109,7 @@ def download_subtitles_ru(suite_dir):
|
||||
if not os.path.exists(ru_path):
|
||||
if not os.path.exists(ru_path_gz):
|
||||
run_cmd(['curl', '-LO', SUBTITLES_RU_URL], cwd=subtitle_dir)
|
||||
run_cmd(['gunzip', ru_path_gz], cwd=subtitle_dir)
|
||||
run_cmd(['gunzip', ru_path_gz])
|
||||
|
||||
|
||||
def has_subtitles_ru(suite_dir):
|
||||
@@ -1135,6 +1148,7 @@ def download(suite_dir, choices):
|
||||
|
||||
def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
allow_missing_commands=False,
|
||||
disabled_cmds=None,
|
||||
warmup_iter=1, bench_iter=3):
|
||||
'''
|
||||
Return an iterable of all runnable benchmarks.
|
||||
@@ -1161,6 +1175,7 @@ def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
benchmark.warmup_count = warmup_iter
|
||||
benchmark.count = bench_iter
|
||||
benchmark.allow_missing_commands = allow_missing_commands
|
||||
benchmark.disabled_cmds = disabled_cmds
|
||||
benchmark.raise_if_missing()
|
||||
except MissingDependencies as e:
|
||||
eprint(
|
||||
@@ -1169,6 +1184,7 @@ def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
name,
|
||||
' '.join(['--download %s' % n for n in e.missing_names]),
|
||||
))
|
||||
continue
|
||||
except MissingCommands as e:
|
||||
fmt = 'missing commands: %s, skipping benchmark %s ' \
|
||||
'(run with --allow-missing to run incomplete benchmarks)'
|
||||
@@ -1195,6 +1211,8 @@ def main():
|
||||
p.add_argument(
|
||||
'--allow-missing', action='store_true',
|
||||
help='Permit benchmarks to run even if some commands are missing.')
|
||||
p.add_argument(
|
||||
'--disabled', help='A list of comma separated commands to skip.')
|
||||
p.add_argument(
|
||||
'-f', '--force', action='store_true',
|
||||
help='Overwrite existing files if there is a conflict.')
|
||||
@@ -1222,6 +1240,7 @@ def main():
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing,
|
||||
disabled_cmds=(args.disabled or '').split(','),
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for b in benchmarks:
|
||||
print(b.name)
|
||||
@@ -1248,6 +1267,7 @@ def main():
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing,
|
||||
disabled_cmds=(args.disabled or '').split(','),
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for i, b in enumerate(benchmarks):
|
||||
result = b.run()
|
||||
@@ -1265,8 +1285,6 @@ def main():
|
||||
if mean is None:
|
||||
# If we couldn't get a distribution for this command then
|
||||
# it was skipped.
|
||||
print('{name:{pad}} SKIPPED'.format(
|
||||
name=name, pad=max_name_len + 2))
|
||||
continue
|
||||
line_counts = result.line_counts_for(cmd)
|
||||
show_fast_cmd, show_line_counts = '', ''
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09452986717224121,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08666801452636719,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08859610557556152,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07011771202087402,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06441712379455566,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06532430648803711,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10056233406066895,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09930968284606934,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09773039817810059,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07829093933105469,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0827643871307373,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08210110664367676,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06728911399841309,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06839728355407715,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.0736091136932373,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3859975337982178,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.38575077056884766,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.4032607078552246,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.0657193660736084,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.058367013931274414,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.05761837959289551,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07888174057006836,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08236145973205566,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07680559158325195,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3796377182006836,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3852665424346924,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.387775182723999,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06758904457092285,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06706357002258301,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07329010963439941,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06952190399169922,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06766009330749512,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06621623039245605,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.29076576232910156,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3039717674255371,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3147861957550049,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16966867446899414,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16578006744384766,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16440153121948242,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2742593288421631,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.27411365509033203,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2799038887023926,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15713810920715332,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15285205841064453,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.14862322807312012,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.06728196144104004,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.06869316101074219,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07347917556762695,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.05894923210144043,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.0584101676940918,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.05851030349731445,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16553878784179688,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16529393196105957,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16843223571777344,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16363120079040527,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16463160514831543,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16590571403503418,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07585549354553223,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07546257972717285,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07645726203918457,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.0733344554901123,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07160758972167969,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07302546501159668,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06922054290771484,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06507658958435059,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06478118896484375,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06373715400695801,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06354117393493652,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06615662574768066,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07121825218200684,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07050347328186035,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07254600524902344,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06099557876586914,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.061118364334106445,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.062296390533447266,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2724471092224121,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.26970720291137695,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2697625160217285,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21796512603759766,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.32093358039855957,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.35228729248046875,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2418622970581055,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2306008338928223,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.1873059272766113,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22467422485351562,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23565077781677246,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21903586387634277,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19292092323303223,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19452929496765137,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1927196979522705,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28882503509521484,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29108643531799316,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29820847511291504,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.32578349113464355,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2801830768585205,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.41840386390686035,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.42424988746643066,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3513953685760498,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.35476160049438477,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2841978073120117,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18991756439208984,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.296999454498291,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2810351848602295,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27904558181762695,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28331899642944336,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.065884590148926,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9066839218139648,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8898587226867676,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8937196731567383,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8904955387115479,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8846819400787354,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2928280830383301,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2243812084197998,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2868325710296631,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2832787036895752,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2892146110534668,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22050261497497559,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1501314640045166,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3660097122192383,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3461437225341797,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.281209945678711,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.287156343460083,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2730507850646973,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.712820529937744,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7904467582702637,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.657541036605835,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.28091931343078613,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2749307155609131,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.27948546409606934,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3499312400817871,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3630790710449219,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.35364317893981934,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36719226837158203,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3705906867980957,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3758120536804199,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1964221000671387,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1625583171844482,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1898295879364014,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.168842077255249,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2533905506134033,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2375917434692383,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.27202439308166504,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.26978445053100586,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.21065115928649902,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36217236518859863,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36077117919921875,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2883784770965576,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.496169090270996,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.315001964569092,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.3024141788482666,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.0939135551452637,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.8922672271728516,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1002702713012695,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3976116180419922,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.4013686180114746,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3070716857910156,278,
|
||||
|
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.090 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.067 +/- 0.003 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.099 +/- 0.001 (lines: 160)
|
||||
rg (whitelist)* 0.081 +/- 0.002 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.070 +/- 0.003 (lines: 16)
|
||||
rg (ignore) (mmap) 0.392 +/- 0.010 (lines: 16)
|
||||
rg (whitelist)* 0.061 +/- 0.004 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.079 +/- 0.003 (lines: 370)
|
||||
rg (ignore) (mmap) 0.384 +/- 0.004 (lines: 370)
|
||||
rg (whitelist)* 0.069 +/- 0.003 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.068 +/- 0.002 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.303 +/- 0.012 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.167 +/- 0.003 (lines: 490)
|
||||
rg (whitelist) 0.276 +/- 0.003 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.153 +/- 0.004 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.070 +/- 0.003 (lines: 1652)
|
||||
rg (whitelist)* 0.059 +/- 0.000 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.166 +/- 0.002 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.165 +/- 0.001 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.076 +/- 0.001 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.073 +/- 0.001 (lines: 174)
|
||||
rg (whitelist) 0.066 +/- 0.002 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.064 +/- 0.001 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.071 +/- 0.001 (lines: 6)
|
||||
rg (whitelist)* 0.061 +/- 0.001 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.271 +/- 0.002 (lines: 848)*
|
||||
rg* 0.297 +/- 0.070 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 2.220 +/- 0.029 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg 0.226 +/- 0.008 (lines: 629)
|
||||
rg (no mmap)* 0.193 +/- 0.001 (lines: 629)*
|
||||
rg (lines) 0.293 +/- 0.005 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.341 +/- 0.070 (lines: 642)*
|
||||
rg (lines) 0.377 +/- 0.041 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.257 +/- 0.058 (lines: 629)*
|
||||
rg 0.281 +/- 0.002 (lines: 629)
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 1.954 +/- 0.097 (lines: 13)
|
||||
rg (ASCII)* 1.890 +/- 0.005 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.268 +/- 0.038 (lines: 317)
|
||||
rg (ASCII)* 0.264 +/- 0.038 (lines: 317)*
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines)* 1.287 +/- 0.119 (lines: 691)
|
||||
rg 1.280 +/- 0.007 (lines: 691)*
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.720 +/- 0.067 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.278 +/- 0.003 (lines: 583)*
|
||||
rg (no mmap) 0.356 +/- 0.007 (lines: 583)
|
||||
rg (lines) 0.371 +/- 0.004 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg* 1.183 +/- 0.018 (lines: 604)*
|
||||
rg (lines) 1.220 +/- 0.045 (lines: 604)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.251 +/- 0.035 (lines: 0)*
|
||||
rg 0.337 +/- 0.042 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.371 +/- 0.108 (lines: 41)
|
||||
rg (ASCII)* 3.029 +/- 0.118 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.369 +/- 0.053 (lines: 278)*
|
||||
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09608030319213867,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08815908432006836,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08974266052246094,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06675052642822266,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06632375717163086,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06531620025634766,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09764790534973145,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10003781318664551,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10493707656860352,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07940077781677246,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07863998413085938,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07791614532470703,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06878829002380371,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06836318969726562,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.07277226448059082,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.379986047744751,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.40039825439453125,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.39777183532714844,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.059081315994262695,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.05873990058898926,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.0586698055267334,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07791399955749512,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.0774388313293457,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07851481437683105,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3788566589355469,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.385251522064209,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38781046867370605,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06934094429016113,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07142090797424316,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07115054130554199,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06683826446533203,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.0690450668334961,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06625819206237793,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2812047004699707,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2557988166809082,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2892444133758545,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16913127899169922,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16315627098083496,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16622567176818848,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2771792411804199,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2861213684082031,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2742443084716797,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15151619911193848,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15233445167541504,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1620476245880127,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07045555114746094,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07046008110046387,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07087540626525879,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06178712844848633,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.0631401538848877,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.0627889633178711,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16510963439941406,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16919803619384766,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16366028785705566,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.17235875129699707,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16506695747375488,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16702055931091309,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07636308670043945,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.0767667293548584,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07441020011901855,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07776570320129395,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07788562774658203,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07390785217285156,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06318306922912598,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06787896156311035,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06569766998291016,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06557774543762207,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06389331817626953,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06407284736633301,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06868839263916016,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07014894485473633,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06822323799133301,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.05816149711608887,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.0577540397644043,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06107187271118164,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.38473939895629883,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2760040760040283,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.366499662399292,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.32836484909057617,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3063969612121582,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3368823528289795,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2332417964935303,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0444729328155518,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0396711826324463,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.13685226440429688,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1380929946899414,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.13843274116516113,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.192030668258667,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1971268653869629,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2931783199310303,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2777669429779053,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28525233268737793,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22691082954406738,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.31324243545532227,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4144246578216553,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.41251444816589355,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.492443323135376,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4691810607910156,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4890565872192383,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2987544536590576,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28134918212890625,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29971933364868164,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22062921524047852,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2716941833496094,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2172706127166748,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0828537940979004,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8791723251342773,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.079643964767456,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8388440608978271,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8970744609832764,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6844482421875,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28177690505981445,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29820775985717773,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2861142158508301,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22010159492492676,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22217011451721191,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2219986915588379,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.146566390991211,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3609087467193604,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1496453285217285,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.281858205795288,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.365553855895996,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2781758308410645,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.622640609741211,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7452948093414307,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.762295961380005,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.27922916412353516,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2578129768371582,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.21048188209533691,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.34738945960998535,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.368546724319458,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.35752224922180176,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2654876708984375,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2697427272796631,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3652024269104004,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.178579330444336,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1693329811096191,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.144824504852295,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0454356670379639,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0725409984588623,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2725732326507568,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.20514369010925293,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.18602967262268066,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2725963592529297,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.35959553718566895,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36090755462646484,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.35926032066345215,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.509491205215454,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.292212963104248,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4941117763519287,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.0987064838409424,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1049976348876953,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.098233222961426,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3214902877807617,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.38519954681396484,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3827836513519287,278,
|
||||
|
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.091 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.066 +/- 0.001 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.101 +/- 0.004 (lines: 160)
|
||||
rg (whitelist)* 0.079 +/- 0.001 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.070 +/- 0.002 (lines: 16)
|
||||
rg (ignore) (mmap) 0.393 +/- 0.011 (lines: 16)
|
||||
rg (whitelist)* 0.059 +/- 0.000 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.078 +/- 0.001 (lines: 370)
|
||||
rg (ignore) (mmap) 0.384 +/- 0.005 (lines: 370)
|
||||
rg (whitelist)* 0.071 +/- 0.001 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.067 +/- 0.001 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.275 +/- 0.017 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.166 +/- 0.003 (lines: 490)
|
||||
rg (whitelist) 0.279 +/- 0.006 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.155 +/- 0.006 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.071 +/- 0.000 (lines: 1652)
|
||||
rg (whitelist)* 0.063 +/- 0.001 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.166 +/- 0.003 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.168 +/- 0.004 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.076 +/- 0.001 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.077 +/- 0.002 (lines: 174)
|
||||
rg (whitelist)* 0.066 +/- 0.002 (lines: 180)
|
||||
rg (whitelist) (ASCII) 0.065 +/- 0.001 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.069 +/- 0.001 (lines: 6)
|
||||
rg (whitelist)* 0.059 +/- 0.002 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines)* 0.342 +/- 0.058 (lines: 848)
|
||||
rg 0.324 +/- 0.016 (lines: 848)*
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 2.106 +/- 0.110 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.138 +/- 0.001 (lines: 629)*
|
||||
rg (no mmap) 0.227 +/- 0.057 (lines: 629)
|
||||
rg (lines) 0.263 +/- 0.032 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.380 +/- 0.058 (lines: 642)*
|
||||
rg (lines) 0.484 +/- 0.013 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII) 0.293 +/- 0.010 (lines: 629)
|
||||
rg* 0.237 +/- 0.030 (lines: 629)*
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.014 +/- 0.117 (lines: 13)
|
||||
rg (ASCII)* 1.807 +/- 0.110 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.289 +/- 0.009 (lines: 317)
|
||||
rg (ASCII)* 0.221 +/- 0.001 (lines: 317)*
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines)* 1.219 +/- 0.123 (lines: 691)*
|
||||
rg 1.309 +/- 0.049 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.710 +/- 0.076 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.249 +/- 0.035 (lines: 583)*
|
||||
rg (no mmap) 0.358 +/- 0.011 (lines: 583)
|
||||
rg (lines) 0.300 +/- 0.056 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.164 +/- 0.017 (lines: 604)
|
||||
rg (lines)* 1.130 +/- 0.124 (lines: 604)*
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.221 +/- 0.045 (lines: 0)*
|
||||
rg 0.360 +/- 0.001 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.432 +/- 0.121 (lines: 41)
|
||||
rg (ASCII)* 3.101 +/- 0.004 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.363 +/- 0.036 (lines: 278)*
|
||||
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10048675537109375,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09462523460388184,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0931856632232666,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06952047348022461,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07045698165893555,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06589603424072266,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09840559959411621,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0973203182220459,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09747123718261719,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07976746559143066,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07973408699035645,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0842599868774414,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06900453567504883,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06771540641784668,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.07333683967590332,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.38510584831237793,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.38396191596984863,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.37463903427124023,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.05757570266723633,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.058022260665893555,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.06006050109863281,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07654142379760742,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07764244079589844,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07787275314331055,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38339757919311523,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38019704818725586,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3887295722961426,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06747794151306152,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06868124008178711,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06679105758666992,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.07849764823913574,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.08336472511291504,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06723690032958984,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.25814294815063477,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.29274845123291016,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2985391616821289,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16458344459533691,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16898059844970703,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1756742000579834,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3002643585205078,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2709066867828369,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2683436870574951,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1489565372467041,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.14751625061035156,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1487743854522705,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.06930160522460938,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07447147369384766,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07432723045349121,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06141376495361328,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06345224380493164,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.05813455581665039,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16566061973571777,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.17109084129333496,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16268444061279297,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16269755363464355,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16636371612548828,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16133809089660645,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07663178443908691,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07986211776733398,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07756590843200684,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07402157783508301,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07861495018005371,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07465910911560059,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06782341003417969,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06639862060546875,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06768679618835449,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06638240814208984,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06481051445007324,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06659054756164551,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06744074821472168,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06904149055480957,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07302141189575195,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.05972766876220703,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.0587460994720459,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.05879020690917969,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3649451732635498,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.37390756607055664,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3691575527191162,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3192598819732666,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3968648910522461,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.347275972366333,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.11361026763916,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9423036575317383,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9265573024749756,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21686100959777832,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23349666595458984,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2394559383392334,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2971608638763428,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2950170040130615,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2873063087463379,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2898998260498047,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21834325790405273,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2833542823791504,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3961493968963623,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.30686163902282715,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.44585490226745605,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.46064209938049316,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4497091770172119,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.34823131561279297,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2819490432739258,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18886327743530273,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28542351722717285,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18991541862487793,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27848052978515625,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21271944046020508,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0810630321502686,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0093939304351807,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8533532619476318,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8952853679656982,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7897896766662598,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.893296480178833,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19786620140075684,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1896834373474121,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29248762130737305,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2933495044708252,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29410600662231445,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23128199577331543,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.343696117401123,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3544535636901855,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3534214496612549,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2638463973999023,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2450191974639893,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2779006958007812,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7900640964508057,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.812807321548462,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7412266731262207,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2562215328216553,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2781085968017578,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.21145415306091309,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36469101905822754,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.37107086181640625,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.29900336265563965,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3739583492279053,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3521237373352051,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3766622543334961,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1903154850006104,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.196908950805664,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1714701652526855,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0471339225769043,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2229478359222412,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1774308681488037,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.20592975616455078,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2680799961090088,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.29538846015930176,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36015796661376953,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3006131649017334,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36701369285583496,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4495208263397217,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4749486446380615,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.29917049407959,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.0949668884277344,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1213910579681396,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.905003070831299,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.39461803436279297,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3211812973022461,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3848116397857666,278,
|
||||
|
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.096 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.069 +/- 0.002 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.098 +/- 0.001 (lines: 160)
|
||||
rg (whitelist)* 0.081 +/- 0.003 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.070 +/- 0.003 (lines: 16)
|
||||
rg (ignore) (mmap) 0.381 +/- 0.006 (lines: 16)
|
||||
rg (whitelist)* 0.059 +/- 0.001 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.077 +/- 0.001 (lines: 370)
|
||||
rg (ignore) (mmap) 0.384 +/- 0.004 (lines: 370)
|
||||
rg (whitelist)* 0.068 +/- 0.001 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.076 +/- 0.008 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.283 +/- 0.022 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.170 +/- 0.006 (lines: 490)
|
||||
rg (whitelist) 0.280 +/- 0.018 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.148 +/- 0.001 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.073 +/- 0.003 (lines: 1652)
|
||||
rg (whitelist)* 0.061 +/- 0.003 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.166 +/- 0.004 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.163 +/- 0.003 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.078 +/- 0.002 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.076 +/- 0.002 (lines: 174)
|
||||
rg (whitelist) 0.067 +/- 0.001 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.066 +/- 0.001 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.070 +/- 0.003 (lines: 6)
|
||||
rg (whitelist)* 0.059 +/- 0.001 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.369 +/- 0.004 (lines: 848)
|
||||
rg* 0.354 +/- 0.039 (lines: 848)*
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 1.994 +/- 0.104 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.230 +/- 0.012 (lines: 629)*
|
||||
rg (no mmap) 0.293 +/- 0.005 (lines: 629)
|
||||
rg (lines) 0.264 +/- 0.040 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.383 +/- 0.070 (lines: 642)*
|
||||
rg (lines) 0.420 +/- 0.062 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.252 +/- 0.055 (lines: 629)
|
||||
rg 0.227 +/- 0.046 (lines: 629)*
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 1.981 +/- 0.116 (lines: 13)
|
||||
rg (ASCII)* 1.859 +/- 0.060 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg* 0.227 +/- 0.057 (lines: 317)*
|
||||
rg (ASCII) 0.273 +/- 0.036 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.351 +/- 0.006 (lines: 691)
|
||||
rg* 1.262 +/- 0.016 (lines: 691)*
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.781 +/- 0.037 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.249 +/- 0.034 (lines: 583)*
|
||||
rg (no mmap) 0.345 +/- 0.040 (lines: 583)
|
||||
rg (lines) 0.368 +/- 0.013 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.186 +/- 0.013 (lines: 604)
|
||||
rg (lines)* 1.149 +/- 0.091 (lines: 604)*
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.256 +/- 0.046 (lines: 0)*
|
||||
rg 0.343 +/- 0.037 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.408 +/- 0.095 (lines: 41)
|
||||
rg (ASCII)* 3.040 +/- 0.118 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.367 +/- 0.040 (lines: 278)*
|
||||
157
benchsuite/runs/2016-12-24-archlinux-cheetah-musl-system/raw.csv
Normal file
157
benchsuite/runs/2016-12-24-archlinux-cheetah-musl-system/raw.csv
Normal file
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09466052055358887,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09342074394226074,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0869603157043457,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06717634201049805,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06487321853637695,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06573486328125,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10077238082885742,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10428118705749512,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09920215606689453,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07973098754882812,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07897496223449707,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07888197898864746,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06830811500549316,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.0715939998626709,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06830549240112305,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3897213935852051,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.39376020431518555,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3769495487213135,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.060272932052612305,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.058103322982788086,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.06174445152282715,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07664990425109863,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07809257507324219,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08361077308654785,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38071417808532715,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.37515711784362793,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38091325759887695,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06704211235046387,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06667947769165039,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06667375564575195,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06779932975769043,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06725239753723145,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06754946708679199,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2662222385406494,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.30044007301330566,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.30494165420532227,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.17267060279846191,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16266226768493652,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16399097442626953,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.25603818893432617,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.26952672004699707,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2737579345703125,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.14797663688659668,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15069222450256348,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15210580825805664,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.06923699378967285,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07373404502868652,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07130026817321777,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.05809664726257324,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06291556358337402,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.062150001525878906,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16234064102172852,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16682648658752441,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.1634657382965088,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16612553596496582,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.1632983684539795,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16044902801513672,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07571697235107422,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07967901229858398,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07469820976257324,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07374238967895508,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07341313362121582,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07449674606323242,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06552338600158691,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06324410438537598,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.0665595531463623,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06373834609985352,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06749844551086426,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06431031227111816,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.0686798095703125,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06870913505554199,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06892633438110352,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.05895066261291504,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06163740158081055,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.058525800704956055,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.34538722038269043,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.265763521194458,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.26305389404296875,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20859956741333008,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20516705513000488,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20496821403503418,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2090365886688232,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.226768732070923,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.226130962371826,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.24144577980041504,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21985626220703125,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21775150299072266,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2918863296508789,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1962728500366211,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19310998916625977,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.26285672187805176,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18955564498901367,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1910560131072998,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.40812134742736816,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.31265878677368164,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.31433773040771484,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3256862163543701,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.32616353034973145,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.32959580421447754,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27936625480651855,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28154826164245605,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20779705047607422,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.26377248764038086,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2896091938018799,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21306395530700684,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0740439891815186,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.875295639038086,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0514187812805176,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6831274032592773,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6856412887573242,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6853716373443604,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2878584861755371,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22226691246032715,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.294330358505249,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3013031482696533,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2214052677154541,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19563746452331543,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1506719589233398,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.345916509628296,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3316686153411865,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2255687713623047,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0810630321502686,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2861762046813965,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.666182279586792,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.730118751525879,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7910759449005127,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.265308141708374,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2775256633758545,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.29873085021972656,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3600039482116699,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3705918788909912,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.37277793884277344,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3728773593902588,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2903330326080322,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3601820468902588,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1635336875915527,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9739360809326172,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.155383825302124,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2030081748962402,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0454139709472656,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2500181198120117,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2797272205352783,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2795555591583252,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2683413028717041,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2863891124725342,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.35770344734191895,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3524661064147949,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.514166831970215,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4967641830444336,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.2882306575775146,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.8897318840026855,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1153793334960938,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.100428581237793,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.4093492031097412,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.4054989814758301,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3883328437805176,278,
|
||||
|
126
benchsuite/runs/2016-12-24-archlinux-cheetah-musl-system/summary
Normal file
126
benchsuite/runs/2016-12-24-archlinux-cheetah-musl-system/summary
Normal file
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.092 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.066 +/- 0.001 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.101 +/- 0.003 (lines: 160)
|
||||
rg (whitelist)* 0.079 +/- 0.000 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.069 +/- 0.002 (lines: 16)
|
||||
rg (ignore) (mmap) 0.387 +/- 0.009 (lines: 16)
|
||||
rg (whitelist)* 0.060 +/- 0.002 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.079 +/- 0.004 (lines: 370)
|
||||
rg (ignore) (mmap) 0.379 +/- 0.003 (lines: 370)
|
||||
rg (whitelist)* 0.067 +/- 0.000 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.068 +/- 0.000 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.291 +/- 0.021 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.166 +/- 0.005 (lines: 490)
|
||||
rg (whitelist) 0.266 +/- 0.009 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.150 +/- 0.002 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.071 +/- 0.002 (lines: 1652)
|
||||
rg (whitelist)* 0.061 +/- 0.003 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.164 +/- 0.002 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.163 +/- 0.003 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.077 +/- 0.003 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.074 +/- 0.001 (lines: 174)
|
||||
rg (whitelist)* 0.065 +/- 0.002 (lines: 180)*
|
||||
rg (whitelist) (ASCII) 0.065 +/- 0.002 (lines: 168)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.069 +/- 0.000 (lines: 6)
|
||||
rg (whitelist)* 0.060 +/- 0.002 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.291 +/- 0.047 (lines: 848)
|
||||
rg* 0.206 +/- 0.002 (lines: 848)*
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 2.221 +/- 0.010 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg 0.226 +/- 0.013 (lines: 629)
|
||||
rg (no mmap) 0.227 +/- 0.056 (lines: 629)
|
||||
rg (lines)* 0.214 +/- 0.042 (lines: 629)*
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.345 +/- 0.055 (lines: 642)
|
||||
rg (lines) 0.327 +/- 0.002 (lines: 642)*
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.256 +/- 0.042 (lines: 629)
|
||||
rg 0.255 +/- 0.039 (lines: 629)*
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.000 +/- 0.109 (lines: 13)
|
||||
rg (ASCII)* 1.685 +/- 0.001 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.268 +/- 0.040 (lines: 317)
|
||||
rg (ASCII)* 0.239 +/- 0.055 (lines: 317)*
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.276 +/- 0.109 (lines: 691)
|
||||
rg* 1.198 +/- 0.105 (lines: 691)*
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.729 +/- 0.062 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.281 +/- 0.017 (lines: 583)*
|
||||
rg (no mmap) 0.368 +/- 0.007 (lines: 583)
|
||||
rg (lines) 0.341 +/- 0.044 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg* 1.098 +/- 0.107 (lines: 604)*
|
||||
rg (lines) 1.166 +/- 0.107 (lines: 604)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.276 +/- 0.007 (lines: 0)*
|
||||
rg 0.332 +/- 0.040 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.433 +/- 0.126 (lines: 41)
|
||||
rg (ASCII)* 3.035 +/- 0.126 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.401 +/- 0.011 (lines: 278)*
|
||||
157
benchsuite/runs/2016-12-24-archlinux-cheetah/raw.csv
Normal file
157
benchsuite/runs/2016-12-24-archlinux-cheetah/raw.csv
Normal file
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09865546226501465,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08865809440612793,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0934293270111084,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07241153717041016,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06905841827392578,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.06687068939208984,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1011350154876709,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1053009033203125,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10577726364135742,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0832066535949707,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0812225341796875,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08363056182861328,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.07260608673095703,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06956887245178223,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.07262110710144043,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3854484558105469,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3801109790802002,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.38498902320861816,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.06220889091491699,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.059615373611450195,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.06207394599914551,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08192729949951172,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08037471771240234,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08067464828491211,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3890647888183594,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3882875442504883,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3826119899749756,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07255673408508301,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07240700721740723,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06744766235351562,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06866455078125,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06612515449523926,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06630897521972656,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.30286335945129395,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2710304260253906,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.30267834663391113,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16382431983947754,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1649789810180664,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16989731788635254,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3308746814727783,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.27356576919555664,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2729830741882324,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16254186630249023,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15763211250305176,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15112638473510742,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07556724548339844,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07514452934265137,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.06890320777893066,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.061008453369140625,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06007099151611328,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.058913469314575195,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.1675281524658203,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.1719217300415039,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.1675257682800293,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16816997528076172,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16349577903747559,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.1649951934814453,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07944488525390625,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.08015990257263184,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07640767097473145,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.0741121768951416,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07456159591674805,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07508492469787598,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06891131401062012,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.0655059814453125,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06730937957763672,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.0630197525024414,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06429147720336914,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06670451164245605,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07088422775268555,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06971001625061035,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.06918931007385254,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.05994749069213867,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06264781951904297,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.061440467834472656,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4529764652252197,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28824853897094727,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.287844181060791,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.34439826011657715,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.34816765785217285,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23656105995178223,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.026144027709961,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2452991008758545,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2087535858154297,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2194046974182129,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22587895393371582,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22500324249267578,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3005552291870117,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2805304527282715,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.30254316329956055,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2822296619415283,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2205369472503662,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23558998107910156,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4217369556427002,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4352266788482666,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3286154270172119,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4068911075592041,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4721720218658447,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.49277544021606445,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2922394275665283,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2809920310974121,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2835381031036377,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28315305709838867,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29279136657714844,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29344797134399414,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0767383575439453,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0589702129364014,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8731834888458252,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6820619106292725,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8845677375793457,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6996817588806152,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2987375259399414,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2955625057220459,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2865116596221924,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27387547492980957,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2899343967437744,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19668984413146973,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4088802337646484,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3826014995574951,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4164769649505615,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2548110485076904,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.080472707748413,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3337528705596924,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.449100971221924,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.747535467147827,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7990715503692627,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.21280717849731445,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.18636178970336914,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2740190029144287,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36304640769958496,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3737907409667969,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.37337779998779297,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2974729537963867,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2715010643005371,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36052799224853516,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.206491231918335,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.202974557876587,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.195291519165039,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2875757217407227,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2895469665527344,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.277585506439209,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2928614616394043,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2610359191894531,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2692301273345947,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36007237434387207,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.37184953689575195,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3902134895324707,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.2949090003967285,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.48958683013916,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.389604091644287,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.894768714904785,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.873474359512329,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.088130474090576,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3918273448944092,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.38251543045043945,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2919657230377197,278,
|
||||
|
126
benchsuite/runs/2016-12-24-archlinux-cheetah/summary
Normal file
126
benchsuite/runs/2016-12-24-archlinux-cheetah/summary
Normal file
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.094 +/- 0.005 (lines: 68)
|
||||
rg (whitelist)* 0.069 +/- 0.003 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.104 +/- 0.003 (lines: 160)
|
||||
rg (whitelist)* 0.083 +/- 0.001 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.072 +/- 0.002 (lines: 16)
|
||||
rg (ignore) (mmap) 0.384 +/- 0.003 (lines: 16)
|
||||
rg (whitelist)* 0.061 +/- 0.001 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.081 +/- 0.001 (lines: 370)
|
||||
rg (ignore) (mmap) 0.387 +/- 0.004 (lines: 370)
|
||||
rg (whitelist)* 0.071 +/- 0.003 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.067 +/- 0.001 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.292 +/- 0.018 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.166 +/- 0.003 (lines: 490)
|
||||
rg (whitelist) 0.292 +/- 0.033 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.157 +/- 0.006 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.073 +/- 0.004 (lines: 1652)
|
||||
rg (whitelist)* 0.060 +/- 0.001 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.169 +/- 0.003 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.166 +/- 0.002 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.079 +/- 0.002 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.075 +/- 0.000 (lines: 174)
|
||||
rg (whitelist) 0.067 +/- 0.002 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.065 +/- 0.002 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.070 +/- 0.001 (lines: 6)
|
||||
rg (whitelist)* 0.061 +/- 0.001 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.343 +/- 0.095 (lines: 848)
|
||||
rg* 0.310 +/- 0.063 (lines: 848)*
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 2.160 +/- 0.117 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.223 +/- 0.004 (lines: 629)*
|
||||
rg (no mmap) 0.295 +/- 0.012 (lines: 629)
|
||||
rg (lines) 0.246 +/- 0.032 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.395 +/- 0.058 (lines: 642)*
|
||||
rg (lines) 0.457 +/- 0.045 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.286 +/- 0.006 (lines: 629)*
|
||||
rg 0.290 +/- 0.006 (lines: 629)
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.003 +/- 0.113 (lines: 13)
|
||||
rg (ASCII)* 1.755 +/- 0.112 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.294 +/- 0.006 (lines: 317)
|
||||
rg (ASCII)* 0.253 +/- 0.050 (lines: 317)*
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.403 +/- 0.018 (lines: 691)
|
||||
rg* 1.223 +/- 0.130 (lines: 691)*
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.665 +/- 0.189 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.224 +/- 0.045 (lines: 583)*
|
||||
rg (no mmap) 0.370 +/- 0.006 (lines: 583)
|
||||
rg (lines) 0.310 +/- 0.046 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg* 1.202 +/- 0.006 (lines: 604)*
|
||||
rg (lines) 1.285 +/- 0.006 (lines: 604)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.274 +/- 0.017 (lines: 0)*
|
||||
rg 0.374 +/- 0.015 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.391 +/- 0.097 (lines: 41)
|
||||
rg (ASCII)* 2.952 +/- 0.118 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.355 +/- 0.055 (lines: 278)*
|
||||
157
benchsuite/runs/2016-12-30-archlinux-cheetah/raw.csv
Normal file
157
benchsuite/runs/2016-12-30-archlinux-cheetah/raw.csv
Normal file
@@ -0,0 +1,157 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09816598892211914,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08965039253234863,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09101128578186035,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07472872734069824,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07628297805786133,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07189559936523438,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10288548469543457,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10204243659973145,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1031193733215332,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08190178871154785,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08523178100585938,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.07952761650085449,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06972551345825195,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.0691523551940918,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.06865429878234863,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.39247632026672363,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.4009978771209717,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.40122294425964355,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.062048912048339844,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.05932760238647461,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.058171749114990234,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.08261799812316895,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.0780181884765625,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.07934045791625977,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.4008915424346924,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3899986743927002,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.39725732803344727,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.07104611396789551,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.0707247257232666,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.06864142417907715,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06764745712280273,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.06994485855102539,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.0682222843170166,16,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.27941250801086426,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.31389880180358887,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.30502963066101074,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16565680503845215,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16579079627990723,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.169691801071167,490,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2969038486480713,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2995884418487549,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.27426910400390625,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15207958221435547,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15367984771728516,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15249848365783691,419,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07145977020263672,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.07139325141906738,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.0708932876586914,1652,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.05987191200256348,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06223797798156738,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.06115579605102539,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16427040100097656,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.16524410247802734,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.1664714813232422,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16639113426208496,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16803503036499023,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.16656923294067383,103,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07580804824829102,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07589507102966309,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.07574295997619629,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07641291618347168,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07523059844970703,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.07748007774353027,174,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06804847717285156,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06720519065856934,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.06687021255493164,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06528687477111816,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.07101035118103027,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.06446981430053711,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07159972190856934,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.0695488452911377,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.07082796096801758,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06297016143798828,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06128263473510742,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.06177973747253418,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.36841607093811035,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.30306172370910645,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3288271427154541,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3186373710632324,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23814082145690918,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23152780532836914,848,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2480580806732178,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2288904190063477,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.287020206451416,862,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21738362312316895,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.16032648086547852,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.15392351150512695,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21230578422546387,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27013158798217773,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19994258880615234,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2728753089904785,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23652935028076172,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2579770088195801,629,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3031468391418457,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.40822505950927734,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.38727545738220215,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4260599613189697,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4490511417388916,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.49449872970581055,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2707977294921875,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2691836357116699,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.24464011192321777,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22373199462890625,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.25702810287475586,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23047828674316406,629,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.139404773712158,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0484464168548584,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0293972492218018,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.840238094329834,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7812306880950928,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7657690048217773,13,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.26054978370666504,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2869753837585449,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22949600219726562,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21858429908752441,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2064223289489746,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20789289474487305,317,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.313758373260498,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2925219535827637,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3444299697875977,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.264918565750122,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.30733060836792,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1466560363769531,691,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.783818244934082,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.76894474029541,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.788987398147583,735,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2822730541229248,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.25232434272766113,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2563645839691162,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.34694504737854004,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3202054500579834,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3236703872680664,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.36035776138305664,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3270585536956787,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3121967315673828,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0397696495056152,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.158402442932129,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1158676147460938,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2041549682617188,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1511006355285645,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1794021129608154,604,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.19694828987121582,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.1980271339416504,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2128591537475586,,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3568108081817627,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3353869915008545,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3075387477874756,579,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.5629587173461914,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.5984435081481934,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4725229740142822,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.170077323913574,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.064476490020752,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.159156084060669,,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3924906253814697,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3874075412750244,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.39940643310546875,278,
|
||||
|
126
benchsuite/runs/2016-12-30-archlinux-cheetah/summary
Normal file
126
benchsuite/runs/2016-12-30-archlinux-cheetah/summary
Normal file
@@ -0,0 +1,126 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.093 +/- 0.005 (lines: 68)
|
||||
rg (whitelist)* 0.074 +/- 0.002 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.103 +/- 0.001 (lines: 160)
|
||||
rg (whitelist)* 0.082 +/- 0.003 (lines: 160)*
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.069 +/- 0.001 (lines: 16)
|
||||
rg (ignore) (mmap) 0.398 +/- 0.005 (lines: 16)
|
||||
rg (whitelist)* 0.060 +/- 0.002 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.080 +/- 0.002 (lines: 370)
|
||||
rg (ignore) (mmap) 0.396 +/- 0.006 (lines: 370)
|
||||
rg (whitelist)* 0.070 +/- 0.001 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.069 +/- 0.001 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.299 +/- 0.018 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.167 +/- 0.002 (lines: 490)
|
||||
rg (whitelist) 0.290 +/- 0.014 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.153 +/- 0.001 (lines: 419)*
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.071 +/- 0.000 (lines: 1652)
|
||||
rg (whitelist)* 0.061 +/- 0.001 (lines: 1630)*
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.165 +/- 0.001 (lines: 23)*
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.167 +/- 0.001 (lines: 103)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.076 +/- 0.000 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.076 +/- 0.001 (lines: 174)
|
||||
rg (whitelist) 0.067 +/- 0.001 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.067 +/- 0.004 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.071 +/- 0.001 (lines: 6)
|
||||
rg (whitelist)* 0.062 +/- 0.001 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.333 +/- 0.033 (lines: 848)
|
||||
rg* 0.263 +/- 0.048 (lines: 848)*
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
rg* 2.255 +/- 0.030 (lines: 862)*
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.177 +/- 0.035 (lines: 629)*
|
||||
rg (no mmap) 0.227 +/- 0.037 (lines: 629)
|
||||
rg (lines) 0.256 +/- 0.018 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.366 +/- 0.056 (lines: 642)*
|
||||
rg (lines) 0.457 +/- 0.035 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII) 0.262 +/- 0.015 (lines: 629)
|
||||
rg* 0.237 +/- 0.018 (lines: 629)*
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.072 +/- 0.059 (lines: 13)
|
||||
rg (ASCII)* 1.796 +/- 0.039 (lines: 13)*
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.259 +/- 0.029 (lines: 317)
|
||||
rg (ASCII)* 0.211 +/- 0.007 (lines: 317)*
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.317 +/- 0.026 (lines: 691)
|
||||
rg* 1.240 +/- 0.083 (lines: 691)*
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg* 3.781 +/- 0.010 (lines: 735)*
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.264 +/- 0.016 (lines: 583)*
|
||||
rg (no mmap) 0.330 +/- 0.015 (lines: 583)
|
||||
rg (lines) 0.333 +/- 0.025 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg* 1.105 +/- 0.060 (lines: 604)*
|
||||
rg (lines) 1.178 +/- 0.027 (lines: 604)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.203 +/- 0.009 (lines: 0)*
|
||||
rg 0.333 +/- 0.025 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.545 +/- 0.065 (lines: 41)
|
||||
rg (ASCII)* 3.131 +/- 0.058 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.393 +/- 0.006 (lines: 278)*
|
||||
59
benchsuite/runs/2018-01-08-archlinux-cheetah/README
Normal file
59
benchsuite/runs/2018-01-08-archlinux-cheetah/README
Normal file
@@ -0,0 +1,59 @@
|
||||
This directory contains updated benchmarks as of 2018-01-08. They were captured
|
||||
via the benchsuite script at `benchsuite/benchsuite` from the root of this
|
||||
repository. The command that was run:
|
||||
|
||||
$ ./benchsuite \
|
||||
--dir /tmp/benchsuite \
|
||||
--raw runs/2018-01-08-archlinux-cheetah/raw.csv \
|
||||
--warmup-iter 1 \
|
||||
--bench-iter 5
|
||||
|
||||
These results are most directly comparable to the
|
||||
`2016-09-22-archlinux-cheetah` run in the parent directory.
|
||||
|
||||
The versions of each tool are as follows:
|
||||
|
||||
$ grep -V
|
||||
grep (GNU grep) 3.1
|
||||
|
||||
$ ag -V
|
||||
ag version 2.1.0
|
||||
Features:
|
||||
+jit +lzma +zlib
|
||||
|
||||
$ sift -V
|
||||
sift 0.8.0 (linux/amd64)
|
||||
built from commit 2ca94717 (which seems to be 0.9.0)
|
||||
|
||||
$ pt --version
|
||||
pt version 2.1.4
|
||||
|
||||
$ ucg -V
|
||||
UniversalCodeGrep 0.3.3
|
||||
[...]
|
||||
Build info
|
||||
|
||||
Repo version: 0.3.3-251-g9b5a3e3
|
||||
|
||||
Compiler info:
|
||||
Name ($(CXX)): "g++ -std=gnu++1z"
|
||||
Version string: "g++ (GCC) 7.2.1 20171224"
|
||||
|
||||
ISA extensions in use:
|
||||
sse4.2: yes
|
||||
popcnt: yes
|
||||
|
||||
libpcre info:
|
||||
Not linked against libpcre.
|
||||
|
||||
libpcre2-8 info:
|
||||
Version: 10.30 2017-08-14
|
||||
JIT support built in?: yes
|
||||
JIT target architecture: x86 64bit (little endian + unaligned)
|
||||
Newline style: LF
|
||||
|
||||
The version of ripgrep was compiled from source on commit 85d463c0, with the
|
||||
simd-accel and avx-accel features enabled:
|
||||
|
||||
$ export RUSTFLAGS="-C target-cpu=native"
|
||||
$ cargo build --release --features 'simd-accel avx-accel'
|
||||
806
benchsuite/runs/2018-01-08-archlinux-cheetah/raw.csv
Normal file
806
benchsuite/runs/2018-01-08-archlinux-cheetah/raw.csv
Normal file
@@ -0,0 +1,806 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,5,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10186767578125,68,
|
||||
linux_alternates,1,5,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10199356079101562,68,
|
||||
linux_alternates,1,5,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09750819206237793,68,
|
||||
linux_alternates,1,5,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09634733200073242,68,
|
||||
linux_alternates,1,5,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10117292404174805,68,
|
||||
linux_alternates,1,5,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.49642109870910645,68,
|
||||
linux_alternates,1,5,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.48993706703186035,68,
|
||||
linux_alternates,1,5,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4837028980255127,68,
|
||||
linux_alternates,1,5,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4773833751678467,68,
|
||||
linux_alternates,1,5,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.558436393737793,68,
|
||||
linux_alternates,1,5,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2605454921722412,68,LC_ALL=C
|
||||
linux_alternates,1,5,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.26748204231262207,68,LC_ALL=C
|
||||
linux_alternates,1,5,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.26719212532043457,68,LC_ALL=C
|
||||
linux_alternates,1,5,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2719383239746094,68,LC_ALL=C
|
||||
linux_alternates,1,5,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.26963257789611816,68,LC_ALL=C
|
||||
linux_alternates,1,5,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.08797001838684082,68,
|
||||
linux_alternates,1,5,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09073781967163086,68,
|
||||
linux_alternates,1,5,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0914468765258789,68,
|
||||
linux_alternates,1,5,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09071612358093262,68,
|
||||
linux_alternates,1,5,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.0914316177368164,68,
|
||||
linux_alternates,1,5,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1372535228729248,68,
|
||||
linux_alternates,1,5,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.13880419731140137,68,
|
||||
linux_alternates,1,5,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.13315439224243164,68,
|
||||
linux_alternates,1,5,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1367807388305664,68,
|
||||
linux_alternates,1,5,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.13135552406311035,68,
|
||||
linux_alternates_casei,1,5,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12781810760498047,160,
|
||||
linux_alternates_casei,1,5,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11988544464111328,160,
|
||||
linux_alternates_casei,1,5,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1205439567565918,160,
|
||||
linux_alternates_casei,1,5,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12867259979248047,160,
|
||||
linux_alternates_casei,1,5,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1215970516204834,160,
|
||||
linux_alternates_casei,1,5,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5444357395172119,160,
|
||||
linux_alternates_casei,1,5,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5511739253997803,160,
|
||||
linux_alternates_casei,1,5,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5382294654846191,160,
|
||||
linux_alternates_casei,1,5,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5499558448791504,160,
|
||||
linux_alternates_casei,1,5,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6376545429229736,160,
|
||||
linux_alternates_casei,1,5,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9767155647277832,160,LC_ALL=C
|
||||
linux_alternates_casei,1,5,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.920574426651001,160,LC_ALL=C
|
||||
linux_alternates_casei,1,5,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9352290630340576,160,LC_ALL=C
|
||||
linux_alternates_casei,1,5,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.8866012096405029,160,LC_ALL=C
|
||||
linux_alternates_casei,1,5,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9189445972442627,160,LC_ALL=C
|
||||
linux_alternates_casei,1,5,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09351730346679688,160,
|
||||
linux_alternates_casei,1,5,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09393739700317383,160,
|
||||
linux_alternates_casei,1,5,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09986448287963867,160,
|
||||
linux_alternates_casei,1,5,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09596824645996094,160,
|
||||
linux_alternates_casei,1,5,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.09604883193969727,160,
|
||||
linux_alternates_casei,1,5,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23943114280700684,160,
|
||||
linux_alternates_casei,1,5,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2587015628814697,160,
|
||||
linux_alternates_casei,1,5,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2543606758117676,160,
|
||||
linux_alternates_casei,1,5,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2490406036376953,160,
|
||||
linux_alternates_casei,1,5,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24046540260314941,160,
|
||||
linux_literal,1,5,rg (ignore),rg -n PM_RESUME,0.08253765106201172,16,
|
||||
linux_literal,1,5,rg (ignore),rg -n PM_RESUME,0.08176755905151367,16,
|
||||
linux_literal,1,5,rg (ignore),rg -n PM_RESUME,0.08141684532165527,16,
|
||||
linux_literal,1,5,rg (ignore),rg -n PM_RESUME,0.08108830451965332,16,
|
||||
linux_literal,1,5,rg (ignore),rg -n PM_RESUME,0.08082938194274902,16,
|
||||
linux_literal,1,5,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.6870582103729248,16,
|
||||
linux_literal,1,5,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.807842493057251,16,
|
||||
linux_literal,1,5,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.8129942417144775,16,
|
||||
linux_literal,1,5,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.7582321166992188,16,
|
||||
linux_literal,1,5,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.6869800090789795,16,
|
||||
linux_literal,1,5,ag (ignore) (mmap),ag -s PM_RESUME,0.6534101963043213,16,
|
||||
linux_literal,1,5,ag (ignore) (mmap),ag -s PM_RESUME,0.6020612716674805,16,
|
||||
linux_literal,1,5,ag (ignore) (mmap),ag -s PM_RESUME,0.6712157726287842,16,
|
||||
linux_literal,1,5,ag (ignore) (mmap),ag -s PM_RESUME,0.6267571449279785,16,
|
||||
linux_literal,1,5,ag (ignore) (mmap),ag -s PM_RESUME,0.505136251449585,16,
|
||||
linux_literal,1,5,pt (ignore),pt PM_RESUME,0.21415948867797852,16,
|
||||
linux_literal,1,5,pt (ignore),pt PM_RESUME,0.19318318367004395,16,
|
||||
linux_literal,1,5,pt (ignore),pt PM_RESUME,0.21352124214172363,16,
|
||||
linux_literal,1,5,pt (ignore),pt PM_RESUME,0.18979454040527344,16,
|
||||
linux_literal,1,5,pt (ignore),pt PM_RESUME,0.16629600524902344,16,
|
||||
linux_literal,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.46967077255249023,16,
|
||||
linux_literal,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.46343088150024414,16,
|
||||
linux_literal,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.4723978042602539,16,
|
||||
linux_literal,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.4741063117980957,16,
|
||||
linux_literal,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.4613051414489746,16,
|
||||
linux_literal,1,5,git grep (ignore),git grep -I -n PM_RESUME,0.20196986198425293,16,LC_ALL=C
|
||||
linux_literal,1,5,git grep (ignore),git grep -I -n PM_RESUME,0.18932533264160156,16,LC_ALL=C
|
||||
linux_literal,1,5,git grep (ignore),git grep -I -n PM_RESUME,0.19396305084228516,16,LC_ALL=C
|
||||
linux_literal,1,5,git grep (ignore),git grep -I -n PM_RESUME,0.1952073574066162,16,LC_ALL=C
|
||||
linux_literal,1,5,git grep (ignore),git grep -I -n PM_RESUME,0.20149731636047363,16,LC_ALL=C
|
||||
linux_literal,1,5,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.08270478248596191,16,
|
||||
linux_literal,1,5,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.08414745330810547,16,
|
||||
linux_literal,1,5,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.08627724647521973,16,
|
||||
linux_literal,1,5,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.08978700637817383,16,
|
||||
linux_literal,1,5,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.0836489200592041,16,
|
||||
linux_literal,1,5,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.15774202346801758,16,
|
||||
linux_literal,1,5,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.16005396842956543,16,
|
||||
linux_literal,1,5,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.15743708610534668,16,
|
||||
linux_literal,1,5,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.16156601905822754,16,
|
||||
linux_literal,1,5,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.1557624340057373,16,
|
||||
linux_literal_casei,1,5,rg (ignore),rg -n -i PM_RESUME,0.1028127670288086,374,
|
||||
linux_literal_casei,1,5,rg (ignore),rg -n -i PM_RESUME,0.10258054733276367,374,
|
||||
linux_literal_casei,1,5,rg (ignore),rg -n -i PM_RESUME,0.10902261734008789,374,
|
||||
linux_literal_casei,1,5,rg (ignore),rg -n -i PM_RESUME,0.10802555084228516,374,
|
||||
linux_literal_casei,1,5,rg (ignore),rg -n -i PM_RESUME,0.10153412818908691,374,
|
||||
linux_literal_casei,1,5,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.7902817726135254,374,
|
||||
linux_literal_casei,1,5,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.7985179424285889,374,
|
||||
linux_literal_casei,1,5,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.8208649158477783,374,
|
||||
linux_literal_casei,1,5,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.7937076091766357,374,
|
||||
linux_literal_casei,1,5,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.7936429977416992,374,
|
||||
linux_literal_casei,1,5,ag (ignore) (mmap),ag -i PM_RESUME,0.5215470790863037,374,
|
||||
linux_literal_casei,1,5,ag (ignore) (mmap),ag -i PM_RESUME,0.46518707275390625,374,
|
||||
linux_literal_casei,1,5,ag (ignore) (mmap),ag -i PM_RESUME,0.4467353820800781,374,
|
||||
linux_literal_casei,1,5,ag (ignore) (mmap),ag -i PM_RESUME,0.4595184326171875,374,
|
||||
linux_literal_casei,1,5,ag (ignore) (mmap),ag -i PM_RESUME,0.4531285762786865,374,
|
||||
linux_literal_casei,1,5,pt (ignore),pt -i PM_RESUME,14.187762022018433,374,
|
||||
linux_literal_casei,1,5,pt (ignore),pt -i PM_RESUME,14.178058385848999,374,
|
||||
linux_literal_casei,1,5,pt (ignore),pt -i PM_RESUME,14.096448421478271,374,
|
||||
linux_literal_casei,1,5,pt (ignore),pt -i PM_RESUME,14.190524339675903,374,
|
||||
linux_literal_casei,1,5,pt (ignore),pt -i PM_RESUME,14.231573343276978,374,
|
||||
linux_literal_casei,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.4668574333190918,374,
|
||||
linux_literal_casei,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.46050214767456055,374,
|
||||
linux_literal_casei,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.46228861808776855,374,
|
||||
linux_literal_casei,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.44957947731018066,374,
|
||||
linux_literal_casei,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.4612581729888916,374,
|
||||
linux_literal_casei,1,5,git grep (ignore),git grep -I -n -i PM_RESUME,0.1932981014251709,370,LC_ALL=C
|
||||
linux_literal_casei,1,5,git grep (ignore),git grep -I -n -i PM_RESUME,0.20561552047729492,370,LC_ALL=C
|
||||
linux_literal_casei,1,5,git grep (ignore),git grep -I -n -i PM_RESUME,0.19516706466674805,370,LC_ALL=C
|
||||
linux_literal_casei,1,5,git grep (ignore),git grep -I -n -i PM_RESUME,0.20196247100830078,370,LC_ALL=C
|
||||
linux_literal_casei,1,5,git grep (ignore),git grep -I -n -i PM_RESUME,0.19236421585083008,370,LC_ALL=C
|
||||
linux_literal_casei,1,5,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.09555959701538086,370,
|
||||
linux_literal_casei,1,5,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.09589338302612305,370,
|
||||
linux_literal_casei,1,5,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.09479856491088867,370,
|
||||
linux_literal_casei,1,5,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.09741568565368652,370,
|
||||
linux_literal_casei,1,5,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.10127615928649902,370,
|
||||
linux_literal_casei,1,5,ucg (whitelist),ucg -i PM_RESUME,0.15514039993286133,370,
|
||||
linux_literal_casei,1,5,ucg (whitelist),ucg -i PM_RESUME,0.15668940544128418,370,
|
||||
linux_literal_casei,1,5,ucg (whitelist),ucg -i PM_RESUME,0.15429425239562988,370,
|
||||
linux_literal_casei,1,5,ucg (whitelist),ucg -i PM_RESUME,0.15332818031311035,370,
|
||||
linux_literal_casei,1,5,ucg (whitelist),ucg -i PM_RESUME,0.14861536026000977,370,
|
||||
linux_literal_default,1,5,rg,rg PM_RESUME,0.08931398391723633,16,
|
||||
linux_literal_default,1,5,rg,rg PM_RESUME,0.08717465400695801,16,
|
||||
linux_literal_default,1,5,rg,rg PM_RESUME,0.0879361629486084,16,
|
||||
linux_literal_default,1,5,rg,rg PM_RESUME,0.08688950538635254,16,
|
||||
linux_literal_default,1,5,rg,rg PM_RESUME,0.09138607978820801,16,
|
||||
linux_literal_default,1,5,ag,ag PM_RESUME,0.5342838764190674,16,
|
||||
linux_literal_default,1,5,ag,ag PM_RESUME,0.47187042236328125,16,
|
||||
linux_literal_default,1,5,ag,ag PM_RESUME,0.4456596374511719,16,
|
||||
linux_literal_default,1,5,ag,ag PM_RESUME,0.4507424831390381,16,
|
||||
linux_literal_default,1,5,ag,ag PM_RESUME,0.44472575187683105,16,
|
||||
linux_literal_default,1,5,ucg,ucg PM_RESUME,0.15556907653808594,16,
|
||||
linux_literal_default,1,5,ucg,ucg PM_RESUME,0.1533644199371338,16,
|
||||
linux_literal_default,1,5,ucg,ucg PM_RESUME,0.15392351150512695,16,
|
||||
linux_literal_default,1,5,ucg,ucg PM_RESUME,0.1535196304321289,16,
|
||||
linux_literal_default,1,5,ucg,ucg PM_RESUME,0.15589547157287598,16,
|
||||
linux_literal_default,1,5,pt,pt PM_RESUME,0.2261514663696289,16,
|
||||
linux_literal_default,1,5,pt,pt PM_RESUME,0.2731902599334717,16,
|
||||
linux_literal_default,1,5,pt,pt PM_RESUME,0.2563004493713379,16,
|
||||
linux_literal_default,1,5,pt,pt PM_RESUME,0.2575085163116455,16,
|
||||
linux_literal_default,1,5,pt,pt PM_RESUME,0.1724245548248291,16,
|
||||
linux_literal_default,1,5,sift,sift PM_RESUME,0.13233542442321777,16,
|
||||
linux_literal_default,1,5,sift,sift PM_RESUME,0.1256580352783203,16,
|
||||
linux_literal_default,1,5,sift,sift PM_RESUME,0.12435102462768555,16,
|
||||
linux_literal_default,1,5,sift,sift PM_RESUME,0.1259307861328125,16,
|
||||
linux_literal_default,1,5,sift,sift PM_RESUME,0.12412142753601074,16,
|
||||
linux_literal_default,1,5,git grep,git grep PM_RESUME,0.1742086410522461,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,5,git grep,git grep PM_RESUME,0.16890597343444824,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,5,git grep,git grep PM_RESUME,0.16680669784545898,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,5,git grep,git grep PM_RESUME,0.16899871826171875,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,5,git grep,git grep PM_RESUME,0.19794917106628418,16,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.33940672874450684,490,
|
||||
linux_no_literal,1,5,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3274960517883301,490,
|
||||
linux_no_literal,1,5,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32681775093078613,490,
|
||||
linux_no_literal,1,5,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32865071296691895,490,
|
||||
linux_no_literal,1,5,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3240926265716553,490,
|
||||
linux_no_literal,1,5,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.17426586151123047,490,
|
||||
linux_no_literal,1,5,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.17265701293945312,490,
|
||||
linux_no_literal,1,5,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1703634262084961,490,
|
||||
linux_no_literal,1,5,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.17192435264587402,490,
|
||||
linux_no_literal,1,5,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.1704559326171875,490,
|
||||
linux_no_literal,1,5,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.8443403244018555,766,
|
||||
linux_no_literal,1,5,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.6956703662872314,766,
|
||||
linux_no_literal,1,5,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.6938261985778809,766,
|
||||
linux_no_literal,1,5,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.695967435836792,766,
|
||||
linux_no_literal,1,5,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.6945271492004395,766,
|
||||
linux_no_literal,1,5,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.645716428756714,490,
|
||||
linux_no_literal,1,5,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.441533088684082,490,
|
||||
linux_no_literal,1,5,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.472522735595703,490,
|
||||
linux_no_literal,1,5,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.42497444152832,490,
|
||||
linux_no_literal,1,5,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.407486200332642,490,
|
||||
linux_no_literal,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.091489553451538,490,
|
||||
linux_no_literal,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.049214124679565,490,
|
||||
linux_no_literal,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.879419803619385,490,
|
||||
linux_no_literal,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.07261848449707,490,
|
||||
linux_no_literal,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.918747901916504,490,
|
||||
linux_no_literal,1,5,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.334321975708008,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.993232727050781,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.622304916381836,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.35973048210144,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.39980435371399,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,5,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.0318400859832764,490,LC_ALL=C
|
||||
linux_no_literal,1,5,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.8587837219238281,490,LC_ALL=C
|
||||
linux_no_literal,1,5,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.873384714126587,490,LC_ALL=C
|
||||
linux_no_literal,1,5,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.8111364841461182,490,LC_ALL=C
|
||||
linux_no_literal,1,5,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.8385357856750488,490,LC_ALL=C
|
||||
linux_no_literal,1,5,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28792643547058105,458,
|
||||
linux_no_literal,1,5,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28545212745666504,458,
|
||||
linux_no_literal,1,5,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28576135635375977,458,
|
||||
linux_no_literal,1,5,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.29883813858032227,458,
|
||||
linux_no_literal,1,5,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28493285179138184,458,
|
||||
linux_no_literal,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15974783897399902,458,
|
||||
linux_no_literal,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.15943312644958496,458,
|
||||
linux_no_literal,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.160233736038208,458,
|
||||
linux_no_literal,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16201996803283691,458,
|
||||
linux_no_literal,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.16033530235290527,458,
|
||||
linux_no_literal,1,5,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4639148712158203,416,
|
||||
linux_no_literal,1,5,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.46042823791503906,416,
|
||||
linux_no_literal,1,5,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.45925426483154297,416,
|
||||
linux_no_literal,1,5,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.477064847946167,416,
|
||||
linux_no_literal,1,5,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.507554292678833,416,
|
||||
linux_re_literal_suffix,1,5,rg (ignore),rg -n [A-Z]+_RESUME,0.08520364761352539,1652,
|
||||
linux_re_literal_suffix,1,5,rg (ignore),rg -n [A-Z]+_RESUME,0.08203816413879395,1652,
|
||||
linux_re_literal_suffix,1,5,rg (ignore),rg -n [A-Z]+_RESUME,0.08355021476745605,1652,
|
||||
linux_re_literal_suffix,1,5,rg (ignore),rg -n [A-Z]+_RESUME,0.0865166187286377,1652,
|
||||
linux_re_literal_suffix,1,5,rg (ignore),rg -n [A-Z]+_RESUME,0.08125448226928711,1652,
|
||||
linux_re_literal_suffix,1,5,ag (ignore),ag -s [A-Z]+_RESUME,0.4846627712249756,1652,
|
||||
linux_re_literal_suffix,1,5,ag (ignore),ag -s [A-Z]+_RESUME,0.48070311546325684,1652,
|
||||
linux_re_literal_suffix,1,5,ag (ignore),ag -s [A-Z]+_RESUME,0.4813041687011719,1652,
|
||||
linux_re_literal_suffix,1,5,ag (ignore),ag -s [A-Z]+_RESUME,0.4755582809448242,1652,
|
||||
linux_re_literal_suffix,1,5,ag (ignore),ag -s [A-Z]+_RESUME,0.4926290512084961,1652,
|
||||
linux_re_literal_suffix,1,5,pt (ignore),pt -e [A-Z]+_RESUME,14.124520540237427,1652,
|
||||
linux_re_literal_suffix,1,5,pt (ignore),pt -e [A-Z]+_RESUME,14.151537656784058,1652,
|
||||
linux_re_literal_suffix,1,5,pt (ignore),pt -e [A-Z]+_RESUME,14.157994270324707,1652,
|
||||
linux_re_literal_suffix,1,5,pt (ignore),pt -e [A-Z]+_RESUME,14.102291822433472,1652,
|
||||
linux_re_literal_suffix,1,5,pt (ignore),pt -e [A-Z]+_RESUME,14.103861093521118,1652,
|
||||
linux_re_literal_suffix,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,4.182392835617065,1652,
|
||||
linux_re_literal_suffix,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,4.190829277038574,1652,
|
||||
linux_re_literal_suffix,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,3.9770240783691406,1652,
|
||||
linux_re_literal_suffix,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,3.9978606700897217,1652,
|
||||
linux_re_literal_suffix,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,4.146454572677612,1652,
|
||||
linux_re_literal_suffix,1,5,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5080702304840088,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,5,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5281260013580322,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,5,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5350546836853027,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,5,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5474245548248291,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,5,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5256762504577637,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,5,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.07924222946166992,1630,
|
||||
linux_re_literal_suffix,1,5,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.0767812728881836,1630,
|
||||
linux_re_literal_suffix,1,5,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.07874488830566406,1630,
|
||||
linux_re_literal_suffix,1,5,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.0804905891418457,1630,
|
||||
linux_re_literal_suffix,1,5,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.07479119300842285,1630,
|
||||
linux_re_literal_suffix,1,5,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13643193244934082,1630,
|
||||
linux_re_literal_suffix,1,5,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13543128967285156,1630,
|
||||
linux_re_literal_suffix,1,5,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13312768936157227,1630,
|
||||
linux_re_literal_suffix,1,5,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13562273979187012,1630,
|
||||
linux_re_literal_suffix,1,5,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13236212730407715,1630,
|
||||
linux_unicode_greek,1,5,rg,rg -n \p{Greek},0.17355775833129883,23,
|
||||
linux_unicode_greek,1,5,rg,rg -n \p{Greek},0.1676032543182373,23,
|
||||
linux_unicode_greek,1,5,rg,rg -n \p{Greek},0.1727275848388672,23,
|
||||
linux_unicode_greek,1,5,rg,rg -n \p{Greek},0.17095375061035156,23,
|
||||
linux_unicode_greek,1,5,rg,rg -n \p{Greek},0.17271947860717773,23,
|
||||
linux_unicode_greek,1,5,pt,pt -e \p{Greek},14.14364218711853,23,
|
||||
linux_unicode_greek,1,5,pt,pt -e \p{Greek},14.137334108352661,23,
|
||||
linux_unicode_greek,1,5,pt,pt -e \p{Greek},14.083475351333618,23,
|
||||
linux_unicode_greek,1,5,pt,pt -e \p{Greek},14.095231056213379,23,
|
||||
linux_unicode_greek,1,5,pt,pt -e \p{Greek},14.151906490325928,23,
|
||||
linux_unicode_greek,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.8376963138580322,23,
|
||||
linux_unicode_greek,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.8271427154541016,23,
|
||||
linux_unicode_greek,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.8310961723327637,23,
|
||||
linux_unicode_greek,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.826141595840454,23,
|
||||
linux_unicode_greek,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.805818796157837,23,
|
||||
linux_unicode_greek_casei,1,5,rg,rg -n -i \p{Greek},0.16843819618225098,103,
|
||||
linux_unicode_greek_casei,1,5,rg,rg -n -i \p{Greek},0.1704998016357422,103,
|
||||
linux_unicode_greek_casei,1,5,rg,rg -n -i \p{Greek},0.17055058479309082,103,
|
||||
linux_unicode_greek_casei,1,5,rg,rg -n -i \p{Greek},0.17064881324768066,103,
|
||||
linux_unicode_greek_casei,1,5,rg,rg -n -i \p{Greek},0.1699228286743164,103,
|
||||
linux_unicode_greek_casei,1,5,pt,pt -i -e \p{Greek},14.164355993270874,23,
|
||||
linux_unicode_greek_casei,1,5,pt,pt -i -e \p{Greek},14.099931478500366,23,
|
||||
linux_unicode_greek_casei,1,5,pt,pt -i -e \p{Greek},14.155095338821411,23,
|
||||
linux_unicode_greek_casei,1,5,pt,pt -i -e \p{Greek},14.109308004379272,23,
|
||||
linux_unicode_greek_casei,1,5,pt,pt -i -e \p{Greek},14.072362422943115,23,
|
||||
linux_unicode_greek_casei,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.003945589065551758,,
|
||||
linux_unicode_greek_casei,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.004189729690551758,,
|
||||
linux_unicode_greek_casei,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.0034589767456054688,,
|
||||
linux_unicode_greek_casei,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.003614187240600586,,
|
||||
linux_unicode_greek_casei,1,5,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.003975629806518555,,
|
||||
linux_unicode_word,1,5,rg (ignore),rg -n \wAh,0.09798526763916016,186,
|
||||
linux_unicode_word,1,5,rg (ignore),rg -n \wAh,0.09575009346008301,186,
|
||||
linux_unicode_word,1,5,rg (ignore),rg -n \wAh,0.10181760787963867,186,
|
||||
linux_unicode_word,1,5,rg (ignore),rg -n \wAh,0.09650158882141113,186,
|
||||
linux_unicode_word,1,5,rg (ignore),rg -n \wAh,0.09717488288879395,186,
|
||||
linux_unicode_word,1,5,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.09417867660522461,174,
|
||||
linux_unicode_word,1,5,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.09903812408447266,174,
|
||||
linux_unicode_word,1,5,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.09407877922058105,174,
|
||||
linux_unicode_word,1,5,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.09681963920593262,174,
|
||||
linux_unicode_word,1,5,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.09762454032897949,174,
|
||||
linux_unicode_word,1,5,ag (ignore) (ASCII),ag -s \wAh,0.5779609680175781,174,
|
||||
linux_unicode_word,1,5,ag (ignore) (ASCII),ag -s \wAh,0.635645866394043,174,
|
||||
linux_unicode_word,1,5,ag (ignore) (ASCII),ag -s \wAh,0.6109263896942139,174,
|
||||
linux_unicode_word,1,5,ag (ignore) (ASCII),ag -s \wAh,0.6260912418365479,174,
|
||||
linux_unicode_word,1,5,ag (ignore) (ASCII),ag -s \wAh,0.6823546886444092,174,
|
||||
linux_unicode_word,1,5,pt (ignore) (ASCII),pt -e \wAh,14.178487062454224,174,
|
||||
linux_unicode_word,1,5,pt (ignore) (ASCII),pt -e \wAh,14.190000057220459,174,
|
||||
linux_unicode_word,1,5,pt (ignore) (ASCII),pt -e \wAh,14.16363000869751,174,
|
||||
linux_unicode_word,1,5,pt (ignore) (ASCII),pt -e \wAh,14.160430431365967,174,
|
||||
linux_unicode_word,1,5,pt (ignore) (ASCII),pt -e \wAh,14.2189621925354,174,
|
||||
linux_unicode_word,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.17629337310791,174,
|
||||
linux_unicode_word,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.051238059997559,174,
|
||||
linux_unicode_word,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.323853015899658,174,
|
||||
linux_unicode_word,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.085661172866821,174,
|
||||
linux_unicode_word,1,5,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.036486625671387,174,
|
||||
linux_unicode_word,1,5,git grep (ignore),git grep -E -I -n \wAh,4.620476961135864,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,5,git grep (ignore),git grep -E -I -n \wAh,4.536192417144775,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,5,git grep (ignore),git grep -E -I -n \wAh,4.510494232177734,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,5,git grep (ignore),git grep -E -I -n \wAh,6.001620769500732,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,5,git grep (ignore),git grep -E -I -n \wAh,4.602652311325073,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,5,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.3785994052886963,174,LC_ALL=C
|
||||
linux_unicode_word,1,5,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.4163663387298584,174,LC_ALL=C
|
||||
linux_unicode_word,1,5,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.402677297592163,174,LC_ALL=C
|
||||
linux_unicode_word,1,5,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.3327512741088867,174,LC_ALL=C
|
||||
linux_unicode_word,1,5,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.3501760959625244,174,LC_ALL=C
|
||||
linux_unicode_word,1,5,rg (whitelist),rg -n --no-ignore -tall \wAh,0.07958698272705078,180,
|
||||
linux_unicode_word,1,5,rg (whitelist),rg -n --no-ignore -tall \wAh,0.0798649787902832,180,
|
||||
linux_unicode_word,1,5,rg (whitelist),rg -n --no-ignore -tall \wAh,0.08086204528808594,180,
|
||||
linux_unicode_word,1,5,rg (whitelist),rg -n --no-ignore -tall \wAh,0.0814356803894043,180,
|
||||
linux_unicode_word,1,5,rg (whitelist),rg -n --no-ignore -tall \wAh,0.08273720741271973,180,
|
||||
linux_unicode_word,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.08280825614929199,168,
|
||||
linux_unicode_word,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.08074021339416504,168,
|
||||
linux_unicode_word,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.0821676254272461,168,
|
||||
linux_unicode_word,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.07926368713378906,168,
|
||||
linux_unicode_word,1,5,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.08405280113220215,168,
|
||||
linux_unicode_word,1,5,ucg (ASCII),ucg --nosmart-case \wAh,0.1545090675354004,168,
|
||||
linux_unicode_word,1,5,ucg (ASCII),ucg --nosmart-case \wAh,0.1517190933227539,168,
|
||||
linux_unicode_word,1,5,ucg (ASCII),ucg --nosmart-case \wAh,0.15704965591430664,168,
|
||||
linux_unicode_word,1,5,ucg (ASCII),ucg --nosmart-case \wAh,0.15523767471313477,168,
|
||||
linux_unicode_word,1,5,ucg (ASCII),ucg --nosmart-case \wAh,0.1582942008972168,168,
|
||||
linux_word,1,5,rg (ignore),rg -n -w PM_RESUME,0.09102368354797363,6,
|
||||
linux_word,1,5,rg (ignore),rg -n -w PM_RESUME,0.08986210823059082,6,
|
||||
linux_word,1,5,rg (ignore),rg -n -w PM_RESUME,0.08989477157592773,6,
|
||||
linux_word,1,5,rg (ignore),rg -n -w PM_RESUME,0.0895695686340332,6,
|
||||
linux_word,1,5,rg (ignore),rg -n -w PM_RESUME,0.09547114372253418,6,
|
||||
linux_word,1,5,ag (ignore),ag -s -w PM_RESUME,0.4948008060455322,6,
|
||||
linux_word,1,5,ag (ignore),ag -s -w PM_RESUME,0.45710110664367676,6,
|
||||
linux_word,1,5,ag (ignore),ag -s -w PM_RESUME,0.44803452491760254,6,
|
||||
linux_word,1,5,ag (ignore),ag -s -w PM_RESUME,0.44779396057128906,6,
|
||||
linux_word,1,5,ag (ignore),ag -s -w PM_RESUME,0.4563112258911133,6,
|
||||
linux_word,1,5,pt (ignore),pt -w PM_RESUME,14.233235597610474,6,
|
||||
linux_word,1,5,pt (ignore),pt -w PM_RESUME,14.277648687362671,6,
|
||||
linux_word,1,5,pt (ignore),pt -w PM_RESUME,14.218127727508545,6,
|
||||
linux_word,1,5,pt (ignore),pt -w PM_RESUME,14.171622037887573,6,
|
||||
linux_word,1,5,pt (ignore),pt -w PM_RESUME,14.214240312576294,6,
|
||||
linux_word,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.1536731719970703,6,
|
||||
linux_word,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.2415099143981934,6,
|
||||
linux_word,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.2526626586914062,6,
|
||||
linux_word,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.2590816020965576,6,
|
||||
linux_word,1,5,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.222473621368408,6,
|
||||
linux_word,1,5,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.16982412338256836,6,LC_ALL=C
|
||||
linux_word,1,5,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.16739583015441895,6,LC_ALL=C
|
||||
linux_word,1,5,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.16866540908813477,6,LC_ALL=C
|
||||
linux_word,1,5,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.18207120895385742,6,LC_ALL=C
|
||||
linux_word,1,5,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.17716264724731445,6,LC_ALL=C
|
||||
linux_word,1,5,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.07490420341491699,6,
|
||||
linux_word,1,5,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.07714152336120605,6,
|
||||
linux_word,1,5,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.07552146911621094,6,
|
||||
linux_word,1,5,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.07651710510253906,6,
|
||||
linux_word,1,5,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.0757131576538086,6,
|
||||
linux_word,1,5,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.1530015468597412,6,
|
||||
linux_word,1,5,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.15152239799499512,6,
|
||||
linux_word,1,5,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.1571195125579834,6,
|
||||
linux_word,1,5,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.15993595123291016,6,
|
||||
linux_word,1,5,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.15633797645568848,6,
|
||||
subtitles_en_alternate,1,5,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.33371877670288086,848,
|
||||
subtitles_en_alternate,1,5,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3207988739013672,848,
|
||||
subtitles_en_alternate,1,5,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3301675319671631,848,
|
||||
subtitles_en_alternate,1,5,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.29731154441833496,848,
|
||||
subtitles_en_alternate,1,5,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2711911201477051,848,
|
||||
subtitles_en_alternate,1,5,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.186570405960083,848,
|
||||
subtitles_en_alternate,1,5,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.1659939289093018,848,
|
||||
subtitles_en_alternate,1,5,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.187847137451172,848,
|
||||
subtitles_en_alternate,1,5,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.3522064685821533,848,
|
||||
subtitles_en_alternate,1,5,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.316105842590332,848,
|
||||
subtitles_en_alternate,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1400718688964844,848,
|
||||
subtitles_en_alternate,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1492774486541748,848,
|
||||
subtitles_en_alternate,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1337254047393799,848,
|
||||
subtitles_en_alternate,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1037378311157227,848,
|
||||
subtitles_en_alternate,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1312851905822754,848,
|
||||
subtitles_en_alternate,1,5,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8294000625610352,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.808884620666504,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8134734630584717,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8405649662017822,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8500289916992188,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21175312995910645,848,
|
||||
subtitles_en_alternate,1,5,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2118232250213623,848,
|
||||
subtitles_en_alternate,1,5,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21287035942077637,848,
|
||||
subtitles_en_alternate,1,5,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21167230606079102,848,
|
||||
subtitles_en_alternate,1,5,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.28102636337280273,848,
|
||||
subtitles_en_alternate,1,5,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5029187202453613,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.49977445602417,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.508340835571289,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5002548694610596,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,5,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.629526138305664,848,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.730497360229492,862,
|
||||
subtitles_en_alternate_casei,1,5,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.781018018722534,862,
|
||||
subtitles_en_alternate_casei,1,5,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.7858059406280518,862,
|
||||
subtitles_en_alternate_casei,1,5,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.7127914428710938,862,
|
||||
subtitles_en_alternate_casei,1,5,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.717308759689331,862,
|
||||
subtitles_en_alternate_casei,1,5,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.428208351135254,862,
|
||||
subtitles_en_alternate_casei,1,5,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.389420509338379,862,
|
||||
subtitles_en_alternate_casei,1,5,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.403301954269409,862,
|
||||
subtitles_en_alternate_casei,1,5,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.4691550731658936,862,
|
||||
subtitles_en_alternate_casei,1,5,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.4245004653930664,862,
|
||||
subtitles_en_alternate_casei,1,5,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.978189706802368,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.974303722381592,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.982886552810669,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.90018630027771,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.0078439712524414,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,5,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9129142761230469,862,
|
||||
subtitles_en_alternate_casei,1,5,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9066660404205322,862,
|
||||
subtitles_en_alternate_casei,1,5,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.946380615234375,862,
|
||||
subtitles_en_alternate_casei,1,5,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9672930240631104,862,
|
||||
subtitles_en_alternate_casei,1,5,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.028451919555664,862,
|
||||
subtitles_en_alternate_casei,1,5,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.9427030086517334,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,5,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.938739061355591,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,5,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.921248435974121,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,5,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.9194068908691406,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,5,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.917184829711914,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal,1,5,rg,rg Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.12293672561645508,629,
|
||||
subtitles_en_literal,1,5,rg,rg Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1259000301361084,629,
|
||||
subtitles_en_literal,1,5,rg,rg Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.12285709381103516,629,
|
||||
subtitles_en_literal,1,5,rg,rg Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.12280964851379395,629,
|
||||
subtitles_en_literal,1,5,rg,rg Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1547396183013916,629,
|
||||
subtitles_en_literal,1,5,rg (no mmap),rg --no-mmap Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.22011375427246094,629,
|
||||
subtitles_en_literal,1,5,rg (no mmap),rg --no-mmap Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23095202445983887,629,
|
||||
subtitles_en_literal,1,5,rg (no mmap),rg --no-mmap Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2577846050262451,629,
|
||||
subtitles_en_literal,1,5,rg (no mmap),rg --no-mmap Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2563819885253906,629,
|
||||
subtitles_en_literal,1,5,rg (no mmap),rg --no-mmap Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.24869346618652344,629,
|
||||
subtitles_en_literal,1,5,pt,pt -N Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.415337324142456,629,
|
||||
subtitles_en_literal,1,5,pt,pt -N Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4208543300628662,629,
|
||||
subtitles_en_literal,1,5,pt,pt -N Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.416351079940796,629,
|
||||
subtitles_en_literal,1,5,pt,pt -N Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4270708560943604,629,
|
||||
subtitles_en_literal,1,5,pt,pt -N Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4243996143341064,629,
|
||||
subtitles_en_literal,1,5,sift,sift Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2245020866394043,629,
|
||||
subtitles_en_literal,1,5,sift,sift Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2382345199584961,629,
|
||||
subtitles_en_literal,1,5,sift,sift Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.23533034324645996,629,
|
||||
subtitles_en_literal,1,5,sift,sift Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2577829360961914,629,
|
||||
subtitles_en_literal,1,5,sift,sift Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2599349021911621,629,
|
||||
subtitles_en_literal,1,5,grep,grep -a Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4733700752258301,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep,grep -a Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4598572254180908,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep,grep -a Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5303301811218262,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep,grep -a Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4775106906890869,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep,grep -a Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4881136417388916,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,rg (lines),rg -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20051789283752441,629,
|
||||
subtitles_en_literal,1,5,rg (lines),rg -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17326998710632324,629,
|
||||
subtitles_en_literal,1,5,rg (lines),rg -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20733428001403809,629,
|
||||
subtitles_en_literal,1,5,rg (lines),rg -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.189713716506958,629,
|
||||
subtitles_en_literal,1,5,rg (lines),rg -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17817258834838867,629,
|
||||
subtitles_en_literal,1,5,ag (lines),ag -s Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5327835083007812,629,
|
||||
subtitles_en_literal,1,5,ag (lines),ag -s Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5411181449890137,629,
|
||||
subtitles_en_literal,1,5,ag (lines),ag -s Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.600783109664917,629,
|
||||
subtitles_en_literal,1,5,ag (lines),ag -s Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5838911533355713,629,
|
||||
subtitles_en_literal,1,5,ag (lines),ag -s Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6051928997039795,629,
|
||||
subtitles_en_literal,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4090385437011719,629,
|
||||
subtitles_en_literal,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3816399574279785,629,
|
||||
subtitles_en_literal,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.38033008575439453,629,
|
||||
subtitles_en_literal,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3731727600097656,629,
|
||||
subtitles_en_literal,1,5,ucg (lines),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.38796329498291016,629,
|
||||
subtitles_en_literal,1,5,pt (lines),pt Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4102630615234375,629,
|
||||
subtitles_en_literal,1,5,pt (lines),pt Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4137451648712158,629,
|
||||
subtitles_en_literal,1,5,pt (lines),pt Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4649333953857422,629,
|
||||
subtitles_en_literal,1,5,pt (lines),pt Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.430387258529663,629,
|
||||
subtitles_en_literal,1,5,pt (lines),pt Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.541991949081421,629,
|
||||
subtitles_en_literal,1,5,sift (lines),sift -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6231405735015869,629,
|
||||
subtitles_en_literal,1,5,sift (lines),sift -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5986526012420654,629,
|
||||
subtitles_en_literal,1,5,sift (lines),sift -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5821917057037354,629,
|
||||
subtitles_en_literal,1,5,sift (lines),sift -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6045489311218262,629,
|
||||
subtitles_en_literal,1,5,sift (lines),sift -n Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5986905097961426,629,
|
||||
subtitles_en_literal,1,5,grep (lines),grep -an Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8278565406799316,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep (lines),grep -an Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.777052640914917,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep (lines),grep -an Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7619414329528809,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep (lines),grep -an Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8248744010925293,629,LC_ALL=C
|
||||
subtitles_en_literal,1,5,grep (lines),grep -an Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.824932336807251,629,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,rg,rg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2718961238861084,642,
|
||||
subtitles_en_literal_casei,1,5,rg,rg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27082157135009766,642,
|
||||
subtitles_en_literal_casei,1,5,rg,rg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27086758613586426,642,
|
||||
subtitles_en_literal_casei,1,5,rg,rg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.274705171585083,642,
|
||||
subtitles_en_literal_casei,1,5,rg,rg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3337059020996094,642,
|
||||
subtitles_en_literal_casei,1,5,grep,grep -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9112112522125244,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,5,grep,grep -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.907888650894165,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,5,grep,grep -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.912668228149414,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,5,grep,grep -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9082865715026855,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,5,grep,grep -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9177796840667725,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,5,grep (ASCII),grep -E -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6020669937133789,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,grep (ASCII),grep -E -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.568228006362915,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,grep (ASCII),grep -E -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5648214817047119,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,grep (ASCII),grep -E -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5568234920501709,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,grep (ASCII),grep -E -ai Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5588953495025635,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,5,rg (lines),rg -n -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3486766815185547,642,
|
||||
subtitles_en_literal_casei,1,5,rg (lines),rg -n -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.34010815620422363,642,
|
||||
subtitles_en_literal_casei,1,5,rg (lines),rg -n -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.33849263191223145,642,
|
||||
subtitles_en_literal_casei,1,5,rg (lines),rg -n -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3917088508605957,642,
|
||||
subtitles_en_literal_casei,1,5,rg (lines),rg -n -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.39266490936279297,642,
|
||||
subtitles_en_literal_casei,1,5,ag (lines) (ASCII),ag -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5564041137695312,642,
|
||||
subtitles_en_literal_casei,1,5,ag (lines) (ASCII),ag -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5533506870269775,642,
|
||||
subtitles_en_literal_casei,1,5,ag (lines) (ASCII),ag -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6205368041992188,642,
|
||||
subtitles_en_literal_casei,1,5,ag (lines) (ASCII),ag -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5530028343200684,642,
|
||||
subtitles_en_literal_casei,1,5,ag (lines) (ASCII),ag -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6189889907836914,642,
|
||||
subtitles_en_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3834850788116455,642,
|
||||
subtitles_en_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.41916346549987793,642,
|
||||
subtitles_en_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3895289897918701,642,
|
||||
subtitles_en_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4278140068054199,642,
|
||||
subtitles_en_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.4013493061065674,642,
|
||||
subtitles_en_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17953085899353027,629,
|
||||
subtitles_en_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17679834365844727,629,
|
||||
subtitles_en_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17448186874389648,629,
|
||||
subtitles_en_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21117281913757324,629,
|
||||
subtitles_en_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1848156452178955,629,
|
||||
subtitles_en_literal_word,1,5,ag (ASCII),ag -sw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5236153602600098,629,
|
||||
subtitles_en_literal_word,1,5,ag (ASCII),ag -sw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.52512526512146,629,
|
||||
subtitles_en_literal_word,1,5,ag (ASCII),ag -sw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5218794345855713,629,
|
||||
subtitles_en_literal_word,1,5,ag (ASCII),ag -sw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5384306907653809,629,
|
||||
subtitles_en_literal_word,1,5,ag (ASCII),ag -sw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5150353908538818,629,
|
||||
subtitles_en_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3757903575897217,629,
|
||||
subtitles_en_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3744041919708252,629,
|
||||
subtitles_en_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.37261366844177246,629,
|
||||
subtitles_en_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.40795230865478516,629,
|
||||
subtitles_en_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3868849277496338,629,
|
||||
subtitles_en_literal_word,1,5,grep (ASCII),grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8265349864959717,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,5,grep (ASCII),grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8123743534088135,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,5,grep (ASCII),grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7669925689697266,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,5,grep (ASCII),grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.766636848449707,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,5,grep (ASCII),grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7665839195251465,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,5,rg,rg -nw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1879115104675293,629,
|
||||
subtitles_en_literal_word,1,5,rg,rg -nw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18082356452941895,629,
|
||||
subtitles_en_literal_word,1,5,rg,rg -nw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18497347831726074,629,
|
||||
subtitles_en_literal_word,1,5,rg,rg -nw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1769394874572754,629,
|
||||
subtitles_en_literal_word,1,5,rg,rg -nw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1917715072631836,629,
|
||||
subtitles_en_literal_word,1,5,grep,grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8192996978759766,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,5,grep,grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8193323612213135,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,5,grep,grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7837738990783691,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,5,grep,grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7639024257659912,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,5,grep,grep -anw Sherlock Holmes /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7634689807891846,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7922985553741455,13,
|
||||
subtitles_en_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7885758876800537,13,
|
||||
subtitles_en_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.802325963973999,13,
|
||||
subtitles_en_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.792595386505127,13,
|
||||
subtitles_en_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7909605503082275,13,
|
||||
subtitles_en_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5903098583221436,13,
|
||||
subtitles_en_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5982813835144043,13,
|
||||
subtitles_en_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5926671028137207,13,
|
||||
subtitles_en_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5976767539978027,13,
|
||||
subtitles_en_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.593153953552246,13,
|
||||
subtitles_en_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.614634275436401,48,
|
||||
subtitles_en_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.574857473373413,48,
|
||||
subtitles_en_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.54079270362854,48,
|
||||
subtitles_en_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.600660800933838,48,
|
||||
subtitles_en_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.531627178192139,48,
|
||||
subtitles_en_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.361133337020874,13,
|
||||
subtitles_en_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.456786870956421,13,
|
||||
subtitles_en_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.403071403503418,13,
|
||||
subtitles_en_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.398236274719238,13,
|
||||
subtitles_en_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.348573923110962,13,
|
||||
subtitles_en_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.5057969093322754,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.4157862663269043,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.471182346343994,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.4590909481048584,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.3759689331054688,13,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,5,rg,rg -n \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18518710136413574,317,
|
||||
subtitles_en_surrounding_words,1,5,rg,rg -n \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18791556358337402,317,
|
||||
subtitles_en_surrounding_words,1,5,rg,rg -n \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18598675727844238,317,
|
||||
subtitles_en_surrounding_words,1,5,rg,rg -n \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18552684783935547,317,
|
||||
subtitles_en_surrounding_words,1,5,rg,rg -n \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.19262075424194336,317,
|
||||
subtitles_en_surrounding_words,1,5,grep,grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1321008205413818,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,5,grep,grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0709969997406006,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,5,grep,grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1117346286773682,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,5,grep,grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0880234241485596,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,5,grep,grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0745558738708496,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,5,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.1827528476715088,317,
|
||||
subtitles_en_surrounding_words,1,5,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18874144554138184,317,
|
||||
subtitles_en_surrounding_words,1,5,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17983436584472656,317,
|
||||
subtitles_en_surrounding_words,1,5,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18831133842468262,317,
|
||||
subtitles_en_surrounding_words,1,5,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.17810606956481934,317,
|
||||
subtitles_en_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.5957207679748535,323,
|
||||
subtitles_en_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.627211570739746,323,
|
||||
subtitles_en_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.554431200027466,323,
|
||||
subtitles_en_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.492656469345093,323,
|
||||
subtitles_en_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.443558216094971,323,
|
||||
subtitles_en_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.522758722305298,317,
|
||||
subtitles_en_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.502918004989624,317,
|
||||
subtitles_en_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.6503307819366455,317,
|
||||
subtitles_en_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.58940052986145,317,
|
||||
subtitles_en_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.569624423980713,317,
|
||||
subtitles_en_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0672054290771484,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0729331970214844,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.052501916885376,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0711696147918701,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0863316059112549,317,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0312588214874268,691,
|
||||
subtitles_ru_alternate,1,5,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.063939094543457,691,
|
||||
subtitles_ru_alternate,1,5,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0000121593475342,691,
|
||||
subtitles_ru_alternate,1,5,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9842438697814941,691,
|
||||
subtitles_ru_alternate,1,5,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.95733642578125,691,
|
||||
subtitles_ru_alternate,1,5,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7781903743743896,691,
|
||||
subtitles_ru_alternate,1,5,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.861164093017578,691,
|
||||
subtitles_ru_alternate,1,5,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8268885612487793,691,
|
||||
subtitles_ru_alternate,1,5,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8621268272399902,691,
|
||||
subtitles_ru_alternate,1,5,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8216166496276855,691,
|
||||
subtitles_ru_alternate,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0069098472595215,691,
|
||||
subtitles_ru_alternate,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.025178909301758,691,
|
||||
subtitles_ru_alternate,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0631070137023926,691,
|
||||
subtitles_ru_alternate,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0902633666992188,691,
|
||||
subtitles_ru_alternate,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0272655487060547,691,
|
||||
subtitles_ru_alternate,1,5,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.510146617889404,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.541701793670654,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.506088733673096,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.51838755607605,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.486810684204102,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9679937362670898,691,
|
||||
subtitles_ru_alternate,1,5,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9942011833190918,691,
|
||||
subtitles_ru_alternate,1,5,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9233448505401611,691,
|
||||
subtitles_ru_alternate,1,5,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9294781684875488,691,
|
||||
subtitles_ru_alternate,1,5,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8729774951934814,691,
|
||||
subtitles_ru_alternate,1,5,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.100147485733032,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.075790166854858,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.069685220718384,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.0526063442230225,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,5,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.129194498062134,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7894201278686523,691,
|
||||
subtitles_ru_alternate_casei,1,5,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7878782749176025,691,
|
||||
subtitles_ru_alternate_casei,1,5,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.796328544616699,691,
|
||||
subtitles_ru_alternate_casei,1,5,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8249149322509766,691,
|
||||
subtitles_ru_alternate_casei,1,5,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7949724197387695,691,
|
||||
subtitles_ru_alternate_casei,1,5,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.075739622116089,691,
|
||||
subtitles_ru_alternate_casei,1,5,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.013590097427368,691,
|
||||
subtitles_ru_alternate_casei,1,5,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.012375593185425,691,
|
||||
subtitles_ru_alternate_casei,1,5,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.023118495941162,691,
|
||||
subtitles_ru_alternate_casei,1,5,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0641982555389404,691,
|
||||
subtitles_ru_alternate_casei,1,5,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.467320442199707,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.486851692199707,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.479818344116211,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.516186475753784,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.471773862838745,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,5,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,11.026185274124146,735,
|
||||
subtitles_ru_alternate_casei,1,5,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,11.168465614318848,735,
|
||||
subtitles_ru_alternate_casei,1,5,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,11.039950370788574,735,
|
||||
subtitles_ru_alternate_casei,1,5,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,11.089850425720215,735,
|
||||
subtitles_ru_alternate_casei,1,5,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,11.112446546554565,735,
|
||||
subtitles_ru_alternate_casei,1,5,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.822641849517822,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,5,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.808355331420898,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,5,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.80171275138855,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,5,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.794351577758789,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,5,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.844403266906738,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal,1,5,rg,rg Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.20681476593017578,583,
|
||||
subtitles_ru_literal,1,5,rg,rg Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.190568208694458,583,
|
||||
subtitles_ru_literal,1,5,rg,rg Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.18462657928466797,583,
|
||||
subtitles_ru_literal,1,5,rg,rg Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.1873643398284912,583,
|
||||
subtitles_ru_literal,1,5,rg,rg Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.20382428169250488,583,
|
||||
subtitles_ru_literal,1,5,rg (no mmap),rg --no-mmap Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3085510730743408,583,
|
||||
subtitles_ru_literal,1,5,rg (no mmap),rg --no-mmap Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.318758487701416,583,
|
||||
subtitles_ru_literal,1,5,rg (no mmap),rg --no-mmap Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3177149295806885,583,
|
||||
subtitles_ru_literal,1,5,rg (no mmap),rg --no-mmap Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.31236958503723145,583,
|
||||
subtitles_ru_literal,1,5,rg (no mmap),rg --no-mmap Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.31880998611450195,583,
|
||||
subtitles_ru_literal,1,5,pt,pt -N Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.152938365936279,583,
|
||||
subtitles_ru_literal,1,5,pt,pt -N Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.124867677688599,583,
|
||||
subtitles_ru_literal,1,5,pt,pt -N Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.132290363311768,583,
|
||||
subtitles_ru_literal,1,5,pt,pt -N Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.158328056335449,583,
|
||||
subtitles_ru_literal,1,5,pt,pt -N Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.1022467613220215,583,
|
||||
subtitles_ru_literal,1,5,sift,sift Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.807113409042358,583,
|
||||
subtitles_ru_literal,1,5,sift,sift Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.8178558349609375,583,
|
||||
subtitles_ru_literal,1,5,sift,sift Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.925220012664795,583,
|
||||
subtitles_ru_literal,1,5,sift,sift Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.861236333847046,583,
|
||||
subtitles_ru_literal,1,5,sift,sift Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.763278484344482,583,
|
||||
subtitles_ru_literal,1,5,grep,grep -a Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.704503059387207,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep,grep -a Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6887199878692627,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep,grep -a Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7092702388763428,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep,grep -a Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6964359283447266,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep,grep -a Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6928379535675049,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,rg (lines),rg -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2646975517272949,583,
|
||||
subtitles_ru_literal,1,5,rg (lines),rg -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.26806163787841797,583,
|
||||
subtitles_ru_literal,1,5,rg (lines),rg -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2700214385986328,583,
|
||||
subtitles_ru_literal,1,5,rg (lines),rg -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2669072151184082,583,
|
||||
subtitles_ru_literal,1,5,rg (lines),rg -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2656106948852539,583,
|
||||
subtitles_ru_literal,1,5,ag (lines),ag -s Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.9972407817840576,583,
|
||||
subtitles_ru_literal,1,5,ag (lines),ag -s Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.906053066253662,583,
|
||||
subtitles_ru_literal,1,5,ag (lines),ag -s Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.864766836166382,583,
|
||||
subtitles_ru_literal,1,5,ag (lines),ag -s Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.7820546627044678,583,
|
||||
subtitles_ru_literal,1,5,ag (lines),ag -s Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.7599871158599854,583,
|
||||
subtitles_ru_literal,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.411653995513916,583,
|
||||
subtitles_ru_literal,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.394604206085205,583,
|
||||
subtitles_ru_literal,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.362853765487671,583,
|
||||
subtitles_ru_literal,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.4795477390289307,583,
|
||||
subtitles_ru_literal,1,5,ucg (lines),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.4428844451904297,583,
|
||||
subtitles_ru_literal,1,5,pt (lines),pt Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.122563123703003,583,
|
||||
subtitles_ru_literal,1,5,pt (lines),pt Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.17008900642395,583,
|
||||
subtitles_ru_literal,1,5,pt (lines),pt Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.1965367794036865,583,
|
||||
subtitles_ru_literal,1,5,pt (lines),pt Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.152370929718018,583,
|
||||
subtitles_ru_literal,1,5,pt (lines),pt Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.106513738632202,583,
|
||||
subtitles_ru_literal,1,5,sift (lines),sift -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.408761978149414,583,
|
||||
subtitles_ru_literal,1,5,sift (lines),sift -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.423579454421997,583,
|
||||
subtitles_ru_literal,1,5,sift (lines),sift -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.2807464599609375,583,
|
||||
subtitles_ru_literal,1,5,sift (lines),sift -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.3771467208862305,583,
|
||||
subtitles_ru_literal,1,5,sift (lines),sift -n Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.378506422042847,583,
|
||||
subtitles_ru_literal,1,5,grep (lines),grep -an Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.121800422668457,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep (lines),grep -an Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1189923286437988,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep (lines),grep -an Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0678138732910156,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep (lines),grep -an Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0668041706085205,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,5,grep (lines),grep -an Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0713574886322021,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,rg,rg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9427816867828369,604,
|
||||
subtitles_ru_literal_casei,1,5,rg,rg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0397350788116455,604,
|
||||
subtitles_ru_literal_casei,1,5,rg,rg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9732518196105957,604,
|
||||
subtitles_ru_literal_casei,1,5,rg,rg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9387776851654053,604,
|
||||
subtitles_ru_literal_casei,1,5,rg,rg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.9536802768707275,604,
|
||||
subtitles_ru_literal_casei,1,5,grep,grep -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.338641405105591,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,5,grep,grep -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.280565023422241,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,5,grep,grep -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.241750240325928,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,5,grep,grep -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.316105604171753,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,5,grep,grep -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.307560205459595,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,5,grep (ASCII),grep -E -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7379302978515625,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,grep (ASCII),grep -E -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7226619720458984,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,grep (ASCII),grep -E -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.683293342590332,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,grep (ASCII),grep -E -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.714146614074707,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,grep (ASCII),grep -E -ai Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7654330730438232,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,5,rg (lines),rg -n -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0237820148468018,604,
|
||||
subtitles_ru_literal_casei,1,5,rg (lines),rg -n -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0194151401519775,604,
|
||||
subtitles_ru_literal_casei,1,5,rg (lines),rg -n -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0364336967468262,604,
|
||||
subtitles_ru_literal_casei,1,5,rg (lines),rg -n -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.035005807876587,604,
|
||||
subtitles_ru_literal_casei,1,5,rg (lines),rg -n -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0438766479492188,604,
|
||||
subtitles_ru_literal_casei,1,5,ag (lines) (ASCII),ag -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.619025468826294,,
|
||||
subtitles_ru_literal_casei,1,5,ag (lines) (ASCII),ag -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.647244930267334,,
|
||||
subtitles_ru_literal_casei,1,5,ag (lines) (ASCII),ag -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6785612106323242,,
|
||||
subtitles_ru_literal_casei,1,5,ag (lines) (ASCII),ag -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6503715515136719,,
|
||||
subtitles_ru_literal_casei,1,5,ag (lines) (ASCII),ag -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6314499378204346,,
|
||||
subtitles_ru_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8302316665649414,583,
|
||||
subtitles_ru_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7719593048095703,583,
|
||||
subtitles_ru_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7697594165802002,583,
|
||||
subtitles_ru_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7312629222869873,583,
|
||||
subtitles_ru_literal_casei,1,5,ucg (lines) (ASCII),ucg -i Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.767866849899292,583,
|
||||
subtitles_ru_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.19411826133728027,,
|
||||
subtitles_ru_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.18651676177978516,,
|
||||
subtitles_ru_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.19614577293395996,,
|
||||
subtitles_ru_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.18459081649780273,,
|
||||
subtitles_ru_literal_word,1,5,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.1797487735748291,,
|
||||
subtitles_ru_literal_word,1,5,ag (ASCII),ag -sw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6507105827331543,,
|
||||
subtitles_ru_literal_word,1,5,ag (ASCII),ag -sw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6480035781860352,,
|
||||
subtitles_ru_literal_word,1,5,ag (ASCII),ag -sw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7138750553131104,,
|
||||
subtitles_ru_literal_word,1,5,ag (ASCII),ag -sw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6521759033203125,,
|
||||
subtitles_ru_literal_word,1,5,ag (ASCII),ag -sw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6728894710540771,,
|
||||
subtitles_ru_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.3646819591522217,583,
|
||||
subtitles_ru_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.3836848735809326,583,
|
||||
subtitles_ru_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.419490337371826,583,
|
||||
subtitles_ru_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.363335609436035,583,
|
||||
subtitles_ru_literal_word,1,5,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.488351345062256,583,
|
||||
subtitles_ru_literal_word,1,5,grep (ASCII),grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.171506643295288,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,5,grep (ASCII),grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1602776050567627,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,5,grep (ASCII),grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.084787368774414,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,5,grep (ASCII),grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0714166164398193,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,5,grep (ASCII),grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.083632469177246,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,5,rg,rg -nw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2769143581390381,579,
|
||||
subtitles_ru_literal_word,1,5,rg,rg -nw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2694058418273926,579,
|
||||
subtitles_ru_literal_word,1,5,rg,rg -nw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.26763367652893066,579,
|
||||
subtitles_ru_literal_word,1,5,rg,rg -nw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2671318054199219,579,
|
||||
subtitles_ru_literal_word,1,5,rg,rg -nw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2922348976135254,579,
|
||||
subtitles_ru_literal_word,1,5,grep,grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.083528757095337,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,5,grep,grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0857081413269043,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,5,grep,grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.07025146484375,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,5,grep,grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.071930170059204,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,5,grep,grep -anw Шерлок Холмс /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.0709245204925537,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1552906036376953,41,
|
||||
subtitles_ru_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.164951801300049,41,
|
||||
subtitles_ru_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.175389289855957,41,
|
||||
subtitles_ru_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1861774921417236,41,
|
||||
subtitles_ru_no_literal,1,5,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.153625011444092,41,
|
||||
subtitles_ru_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.7353317737579346,,
|
||||
subtitles_ru_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.7592883110046387,,
|
||||
subtitles_ru_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.7242491245269775,,
|
||||
subtitles_ru_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.747089385986328,,
|
||||
subtitles_ru_no_literal,1,5,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.732586145401001,,
|
||||
subtitles_ru_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0796375274658203,,
|
||||
subtitles_ru_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9670393466949463,,
|
||||
subtitles_ru_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9413447380065918,,
|
||||
subtitles_ru_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.916764497756958,,
|
||||
subtitles_ru_no_literal,1,5,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9110031127929688,,
|
||||
subtitles_ru_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0622072219848633,,
|
||||
subtitles_ru_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0975682735443115,,
|
||||
subtitles_ru_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0741493701934814,,
|
||||
subtitles_ru_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0423810482025146,,
|
||||
subtitles_ru_no_literal,1,5,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.000764846801758,,
|
||||
subtitles_ru_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6251120567321777,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.644089698791504,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6416165828704834,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6321892738342285,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,5,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6264762878417969,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,5,rg,rg -n \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.29879307746887207,278,
|
||||
subtitles_ru_surrounding_words,1,5,rg,rg -n \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3226010799407959,278,
|
||||
subtitles_ru_surrounding_words,1,5,rg,rg -n \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.32187771797180176,278,
|
||||
subtitles_ru_surrounding_words,1,5,rg,rg -n \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2825047969818115,278,
|
||||
subtitles_ru_surrounding_words,1,5,rg,rg -n \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.283217191696167,278,
|
||||
subtitles_ru_surrounding_words,1,5,grep,grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3977878093719482,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,5,grep,grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4288139343261719,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,5,grep,grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4054889678955078,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,5,grep,grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4003441333770752,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,5,grep,grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5269148349761963,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8912529945373535,,
|
||||
subtitles_ru_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9221522808074951,,
|
||||
subtitles_ru_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9416618347167969,,
|
||||
subtitles_ru_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.893650770187378,,
|
||||
subtitles_ru_surrounding_words,1,5,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8895554542541504,,
|
||||
subtitles_ru_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0110745429992676,,
|
||||
subtitles_ru_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9790067672729492,,
|
||||
subtitles_ru_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0426392555236816,,
|
||||
subtitles_ru_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.121723175048828,,
|
||||
subtitles_ru_surrounding_words,1,5,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.1247596740722656,,
|
||||
subtitles_ru_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3579976558685303,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.382859468460083,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.393401861190796,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.474374532699585,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,5,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3835601806640625,,LC_ALL=C
|
||||
|
235
benchsuite/runs/2018-01-08-archlinux-cheetah/summary
Normal file
235
benchsuite/runs/2018-01-08-archlinux-cheetah/summary
Normal file
@@ -0,0 +1,235 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.100 +/- 0.003 (lines: 68)
|
||||
ag (ignore) 0.501 +/- 0.033 (lines: 68)
|
||||
git grep (ignore) 0.267 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.090 +/- 0.001 (lines: 68)*
|
||||
ucg (whitelist) 0.135 +/- 0.003 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.124 +/- 0.004 (lines: 160)
|
||||
ag (ignore) 0.564 +/- 0.041 (lines: 160)
|
||||
git grep (ignore) 0.928 +/- 0.033 (lines: 160)
|
||||
rg (whitelist)* 0.096 +/- 0.003 (lines: 160)*
|
||||
ucg (whitelist) 0.248 +/- 0.008 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore)* 0.082 +/- 0.001 (lines: 16)*
|
||||
rg (ignore) (mmap) 0.751 +/- 0.062 (lines: 16)
|
||||
ag (ignore) (mmap) 0.612 +/- 0.065 (lines: 16)
|
||||
pt (ignore) 0.195 +/- 0.020 (lines: 16)
|
||||
sift (ignore) 0.468 +/- 0.006 (lines: 16)
|
||||
git grep (ignore) 0.196 +/- 0.005 (lines: 16)
|
||||
rg (whitelist) 0.085 +/- 0.003 (lines: 16)
|
||||
ucg (whitelist) 0.159 +/- 0.002 (lines: 16)
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.105 +/- 0.003 (lines: 374)
|
||||
rg (ignore) (mmap) 0.799 +/- 0.012 (lines: 374)
|
||||
ag (ignore) (mmap) 0.469 +/- 0.030 (lines: 374)
|
||||
pt (ignore) 14.177 +/- 0.049 (lines: 374)
|
||||
sift (ignore) 0.460 +/- 0.006 (lines: 374)
|
||||
git grep (ignore) 0.198 +/- 0.006 (lines: 370)
|
||||
rg (whitelist)* 0.097 +/- 0.003 (lines: 370)*
|
||||
ucg (whitelist) 0.154 +/- 0.003 (lines: 370)
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg* 0.089 +/- 0.002 (lines: 16)*
|
||||
ag 0.469 +/- 0.038 (lines: 16)
|
||||
ucg 0.154 +/- 0.001 (lines: 16)
|
||||
pt 0.237 +/- 0.040 (lines: 16)
|
||||
sift 0.126 +/- 0.003 (lines: 16)
|
||||
git grep 0.175 +/- 0.013 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.329 +/- 0.006 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.172 +/- 0.002 (lines: 490)
|
||||
ag (ignore) (ASCII) 0.725 +/- 0.067 (lines: 766)
|
||||
pt (ignore) (ASCII) 12.478 +/- 0.097 (lines: 490)
|
||||
sift (ignore) (ASCII) 9.002 +/- 0.096 (lines: 490)
|
||||
git grep (ignore) 8.542 +/- 0.277 (lines: 490)
|
||||
git grep (ignore) (ASCII) 1.883 +/- 0.087 (lines: 490)
|
||||
rg (whitelist) 0.289 +/- 0.006 (lines: 458)
|
||||
rg (whitelist) (ASCII)* 0.160 +/- 0.001 (lines: 458)*
|
||||
ucg (whitelist) (ASCII) 0.474 +/- 0.020 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.084 +/- 0.002 (lines: 1652)
|
||||
ag (ignore) 0.483 +/- 0.006 (lines: 1652)
|
||||
pt (ignore) 14.128 +/- 0.026 (lines: 1652)
|
||||
sift (ignore) 4.099 +/- 0.103 (lines: 1652)
|
||||
git grep (ignore) 0.529 +/- 0.014 (lines: 1652)
|
||||
rg (whitelist)* 0.078 +/- 0.002 (lines: 1630)*
|
||||
ucg (whitelist) 0.135 +/- 0.002 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.172 +/- 0.002 (lines: 23)*
|
||||
pt 14.122 +/- 0.031 (lines: 23)
|
||||
sift 2.826 +/- 0.012 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.170 +/- 0.001 (lines: 103)
|
||||
pt 14.120 +/- 0.039 (lines: 23)
|
||||
sift* 0.004 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.098 +/- 0.002 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.096 +/- 0.002 (lines: 174)
|
||||
ag (ignore) (ASCII) 0.627 +/- 0.038 (lines: 174)
|
||||
pt (ignore) (ASCII) 14.182 +/- 0.024 (lines: 174)
|
||||
sift (ignore) (ASCII) 4.135 +/- 0.119 (lines: 174)
|
||||
git grep (ignore) 4.854 +/- 0.643 (lines: 186)
|
||||
git grep (ignore) (ASCII) 1.376 +/- 0.035 (lines: 174)
|
||||
rg (whitelist) 0.081 +/- 0.001 (lines: 180)*
|
||||
rg (whitelist) (ASCII)* 0.082 +/- 0.002 (lines: 168)
|
||||
ucg (ASCII) 0.155 +/- 0.003 (lines: 168)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.091 +/- 0.002 (lines: 6)
|
||||
ag (ignore) 0.461 +/- 0.020 (lines: 6)
|
||||
pt (ignore) 14.223 +/- 0.038 (lines: 6)
|
||||
sift (ignore) 3.226 +/- 0.043 (lines: 6)
|
||||
git grep (ignore) 0.173 +/- 0.006 (lines: 6)
|
||||
rg (whitelist)* 0.076 +/- 0.001 (lines: 6)*
|
||||
ucg (whitelist) 0.156 +/- 0.003 (lines: 6)
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.311 +/- 0.026 (lines: 848)
|
||||
ag (lines) 2.242 +/- 0.086 (lines: 848)
|
||||
ucg (lines) 1.132 +/- 0.017 (lines: 848)
|
||||
grep (lines) 1.828 +/- 0.017 (lines: 848)
|
||||
rg* 0.226 +/- 0.031 (lines: 848)*
|
||||
grep 1.528 +/- 0.057 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 3.745 +/- 0.035 (lines: 862)
|
||||
ucg (ASCII) 2.423 +/- 0.030 (lines: 862)
|
||||
grep (ASCII) 2.969 +/- 0.040 (lines: 862)
|
||||
rg* 1.952 +/- 0.049 (lines: 862)*
|
||||
grep 2.928 +/- 0.012 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.130 +/- 0.014 (lines: 629)*
|
||||
rg (no mmap) 0.243 +/- 0.017 (lines: 629)
|
||||
pt 1.421 +/- 0.005 (lines: 629)
|
||||
sift 0.243 +/- 0.015 (lines: 629)
|
||||
grep 0.486 +/- 0.027 (lines: 629)
|
||||
rg (lines) 0.190 +/- 0.014 (lines: 629)
|
||||
ag (lines) 1.573 +/- 0.034 (lines: 629)
|
||||
ucg (lines) 0.386 +/- 0.014 (lines: 629)
|
||||
pt (lines) 1.452 +/- 0.055 (lines: 629)
|
||||
sift (lines) 0.601 +/- 0.015 (lines: 629)
|
||||
grep (lines) 0.803 +/- 0.031 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.284 +/- 0.028 (lines: 642)*
|
||||
grep 1.912 +/- 0.004 (lines: 642)
|
||||
grep (ASCII) 0.570 +/- 0.018 (lines: 642)
|
||||
rg (lines) 0.362 +/- 0.028 (lines: 642)
|
||||
ag (lines) (ASCII) 1.580 +/- 0.036 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.404 +/- 0.019 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.185 +/- 0.015 (lines: 629)
|
||||
ag (ASCII) 1.525 +/- 0.009 (lines: 629)
|
||||
ucg (ASCII) 0.384 +/- 0.015 (lines: 629)
|
||||
grep (ASCII) 0.788 +/- 0.029 (lines: 629)
|
||||
rg 0.184 +/- 0.006 (lines: 629)*
|
||||
grep 0.790 +/- 0.028 (lines: 629)
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 1.793 +/- 0.005 (lines: 13)
|
||||
rg (ASCII)* 1.594 +/- 0.003 (lines: 13)*
|
||||
ag (ASCII) 6.573 +/- 0.036 (lines: 48)
|
||||
ucg (ASCII) 5.394 +/- 0.042 (lines: 13)
|
||||
grep (ASCII) 3.446 +/- 0.050 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.187 +/- 0.003 (lines: 317)
|
||||
grep 1.095 +/- 0.026 (lines: 317)
|
||||
rg (ASCII)* 0.184 +/- 0.005 (lines: 317)*
|
||||
ag (ASCII) 4.543 +/- 0.075 (lines: 323)
|
||||
ucg (ASCII) 3.567 +/- 0.058 (lines: 317)
|
||||
grep (ASCII) 1.070 +/- 0.012 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.007 +/- 0.041 (lines: 691)
|
||||
ag (lines) 3.830 +/- 0.035 (lines: 691)
|
||||
ucg (lines) 2.043 +/- 0.034 (lines: 691)
|
||||
grep (lines) 7.513 +/- 0.020 (lines: 691)
|
||||
rg* 0.938 +/- 0.046 (lines: 691)*
|
||||
grep 7.085 +/- 0.030 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 3.799 +/- 0.015 (lines: 691)
|
||||
ucg (ASCII)* 2.038 +/- 0.030 (lines: 691)*
|
||||
grep (ASCII) 7.484 +/- 0.019 (lines: 691)
|
||||
rg 11.087 +/- 0.057 (lines: 735)
|
||||
grep 6.814 +/- 0.020 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.195 +/- 0.010 (lines: 583)*
|
||||
rg (no mmap) 0.315 +/- 0.005 (lines: 583)
|
||||
pt 5.134 +/- 0.023 (lines: 583)
|
||||
sift 5.835 +/- 0.061 (lines: 583)
|
||||
grep 0.698 +/- 0.008 (lines: 583)
|
||||
rg (lines) 0.267 +/- 0.002 (lines: 583)
|
||||
ag (lines) 2.862 +/- 0.096 (lines: 583)
|
||||
ucg (lines) 2.418 +/- 0.045 (lines: 583)
|
||||
pt (lines) 5.150 +/- 0.036 (lines: 583)
|
||||
sift (lines) 6.374 +/- 0.056 (lines: 583)
|
||||
grep (lines) 1.089 +/- 0.028 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 0.970 +/- 0.041 (lines: 604)
|
||||
grep 6.297 +/- 0.037 (lines: 604)
|
||||
grep (ASCII) 0.725 +/- 0.030 (lines: 583)
|
||||
rg (lines) 1.032 +/- 0.010 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.645 +/- 0.022 (lines: 0)*
|
||||
ucg (lines) (ASCII) 0.774 +/- 0.036 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.188 +/- 0.007 (lines: 0)*
|
||||
ag (ASCII) 0.668 +/- 0.028 (lines: 0)
|
||||
ucg (ASCII) 2.404 +/- 0.052 (lines: 583)
|
||||
grep (ASCII) 1.114 +/- 0.048 (lines: 583)
|
||||
rg 0.275 +/- 0.011 (lines: 579)
|
||||
grep 1.076 +/- 0.008 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.167 +/- 0.014 (lines: 41)
|
||||
rg (ASCII) 2.740 +/- 0.014 (lines: 0)
|
||||
ag (ASCII) 1.963 +/- 0.069 (lines: 0)
|
||||
ucg (ASCII) 2.055 +/- 0.037 (lines: 0)
|
||||
grep (ASCII)* 1.634 +/- 0.009 (lines: 0)*
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.302 +/- 0.020 (lines: 278)*
|
||||
grep 1.432 +/- 0.055 (lines: 278)
|
||||
ag (ASCII) 1.908 +/- 0.023 (lines: 0)
|
||||
ucg (ASCII) 2.056 +/- 0.066 (lines: 0)
|
||||
grep (ASCII) 1.398 +/- 0.044 (lines: 0)
|
||||
184
build.rs
Normal file
184
build.rs
Normal file
@@ -0,0 +1,184 @@
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
|
||||
use clap::Shell;
|
||||
|
||||
use app::{RGArg, RGArgKind};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[path = "src/app.rs"]
|
||||
mod app;
|
||||
|
||||
fn main() {
|
||||
// OUT_DIR is set by Cargo and it's where any additional build artifacts
|
||||
// are written.
|
||||
let outdir = match env::var_os("OUT_DIR") {
|
||||
Some(outdir) => outdir,
|
||||
None => {
|
||||
eprintln!(
|
||||
"OUT_DIR environment variable not defined. \
|
||||
Please file a bug: \
|
||||
https://github.com/BurntSushi/ripgrep/issues/new");
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
fs::create_dir_all(&outdir).unwrap();
|
||||
|
||||
let stamp_path = Path::new(&outdir).join("ripgrep-stamp");
|
||||
if let Err(err) = File::create(&stamp_path) {
|
||||
panic!("failed to write {}: {}", stamp_path.display(), err);
|
||||
}
|
||||
if let Err(err) = generate_man_page(&outdir) {
|
||||
eprintln!("failed to generate man page: {}", err);
|
||||
}
|
||||
|
||||
// Use clap to build completion files.
|
||||
let mut app = app::app();
|
||||
app.gen_completions("rg", Shell::Bash, &outdir);
|
||||
app.gen_completions("rg", Shell::Fish, &outdir);
|
||||
app.gen_completions("rg", Shell::PowerShell, &outdir);
|
||||
// Note that we do not use clap's support for zsh. Instead, zsh completions
|
||||
// are manually maintained in `complete/_rg`.
|
||||
|
||||
// Make the current git hash available to the build.
|
||||
if let Some(rev) = git_revision_hash() {
|
||||
println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev);
|
||||
}
|
||||
}
|
||||
|
||||
fn git_revision_hash() -> Option<String> {
|
||||
let result = process::Command::new("git")
|
||||
.args(&["rev-parse", "--short=10", "HEAD"])
|
||||
.output();
|
||||
result.ok().and_then(|output| {
|
||||
let v = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
if v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn generate_man_page<P: AsRef<Path>>(outdir: P) -> io::Result<()> {
|
||||
// If asciidoc isn't installed, then don't do anything.
|
||||
if let Err(err) = process::Command::new("a2x").output() {
|
||||
eprintln!("Could not run 'a2x' binary, skipping man page generation.");
|
||||
eprintln!("Error from running 'a2x': {}", err);
|
||||
return Ok(());
|
||||
}
|
||||
// 1. Read asciidoc template.
|
||||
// 2. Interpolate template with auto-generated docs.
|
||||
// 3. Save interpolation to disk.
|
||||
// 4. Use a2x (part of asciidoc) to convert to man page.
|
||||
let outdir = outdir.as_ref();
|
||||
let cwd = env::current_dir()?;
|
||||
let tpl_path = cwd.join("doc").join("rg.1.txt.tpl");
|
||||
let txt_path = outdir.join("rg.1.txt");
|
||||
|
||||
let mut tpl = String::new();
|
||||
File::open(&tpl_path)?.read_to_string(&mut tpl)?;
|
||||
tpl = tpl.replace("{OPTIONS}", &formatted_options()?);
|
||||
|
||||
let githash = git_revision_hash();
|
||||
let githash = githash.as_ref().map(|x| &**x);
|
||||
tpl = tpl.replace("{VERSION}", &app::long_version(githash));
|
||||
|
||||
File::create(&txt_path)?.write_all(tpl.as_bytes())?;
|
||||
let result = process::Command::new("a2x")
|
||||
.arg("--no-xmllint")
|
||||
.arg("--doctype").arg("manpage")
|
||||
.arg("--format").arg("manpage")
|
||||
.arg(&txt_path)
|
||||
.spawn()?
|
||||
.wait()?;
|
||||
if !result.success() {
|
||||
let msg = format!("'a2x' failed with exit code {:?}", result.code());
|
||||
return Err(ioerr(msg));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn formatted_options() -> io::Result<String> {
|
||||
let mut args = app::all_args_and_flags();
|
||||
args.sort_by(|x1, x2| x1.name.cmp(&x2.name));
|
||||
|
||||
let mut formatted = vec![];
|
||||
for arg in args {
|
||||
if arg.hidden {
|
||||
continue;
|
||||
}
|
||||
// ripgrep only has two positional arguments, and probably will only
|
||||
// ever have two positional arguments, so we just hardcode them into
|
||||
// the template.
|
||||
if let app::RGArgKind::Positional{..} = arg.kind {
|
||||
continue;
|
||||
}
|
||||
formatted.push(formatted_arg(&arg)?);
|
||||
}
|
||||
Ok(formatted.join("\n\n"))
|
||||
}
|
||||
|
||||
fn formatted_arg(arg: &RGArg) -> io::Result<String> {
|
||||
match arg.kind {
|
||||
RGArgKind::Positional{..} => panic!("unexpected positional argument"),
|
||||
RGArgKind::Switch { long, short, multiple } => {
|
||||
let mut out = vec![];
|
||||
|
||||
let mut header = format!("--{}", long);
|
||||
if let Some(short) = short {
|
||||
header = format!("-{}, {}", short, header);
|
||||
}
|
||||
if multiple {
|
||||
header = format!("*{}* ...::", header);
|
||||
} else {
|
||||
header = format!("*{}*::", header);
|
||||
}
|
||||
writeln!(out, "{}", header)?;
|
||||
writeln!(out, "{}", formatted_doc_txt(arg)?)?;
|
||||
|
||||
Ok(String::from_utf8(out).unwrap())
|
||||
}
|
||||
RGArgKind::Flag { long, short, value_name, multiple, .. } => {
|
||||
let mut out = vec![];
|
||||
|
||||
let mut header = format!("--{}", long);
|
||||
if let Some(short) = short {
|
||||
header = format!("-{}, {}", short, header);
|
||||
}
|
||||
if multiple {
|
||||
header = format!("*{}* _{}_ ...::", header, value_name);
|
||||
} else {
|
||||
header = format!("*{}* _{}_::", header, value_name);
|
||||
}
|
||||
writeln!(out, "{}", header)?;
|
||||
writeln!(out, "{}", formatted_doc_txt(arg)?)?;
|
||||
|
||||
Ok(String::from_utf8(out).unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn formatted_doc_txt(arg: &RGArg) -> io::Result<String> {
|
||||
let paragraphs: Vec<&str> = arg.doc_long.split("\n\n").collect();
|
||||
if paragraphs.is_empty() {
|
||||
return Err(ioerr(format!("missing docs for --{}", arg.name)));
|
||||
}
|
||||
let first = format!(" {}", paragraphs[0].replace("\n", "\n "));
|
||||
if paragraphs.len() == 1 {
|
||||
return Ok(first);
|
||||
}
|
||||
Ok(format!("{}\n+\n{}", first, paragraphs[1..].join("\n+\n")))
|
||||
}
|
||||
|
||||
fn ioerr(msg: String) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, msg)
|
||||
}
|
||||
54
ci/before_deploy.sh
Normal file → Executable file
54
ci/before_deploy.sh
Normal file → Executable file
@@ -1,29 +1,55 @@
|
||||
# `before_deploy` phase: here we package the build artifacts
|
||||
#!/bin/bash
|
||||
|
||||
# package the build artifacts
|
||||
|
||||
set -ex
|
||||
|
||||
. $(dirname $0)/utils.sh
|
||||
. "$(dirname $0)/utils.sh"
|
||||
|
||||
# Generate artifacts for release
|
||||
mk_artifacts() {
|
||||
RUSTFLAGS="-C target-feature=+ssse3" \
|
||||
cargo build --target $TARGET --release --features simd-accel
|
||||
if is_ssse3_target; then
|
||||
RUSTFLAGS="-C target-feature=+ssse3" \
|
||||
cargo build --target "$TARGET" --release --features simd-accel
|
||||
else
|
||||
cargo build --target "$TARGET" --release
|
||||
fi
|
||||
}
|
||||
|
||||
mk_tarball() {
|
||||
# create a "staging" directory
|
||||
local td=$(mktempd)
|
||||
local out_dir=$(pwd)
|
||||
# When cross-compiling, use the right `strip` tool on the binary.
|
||||
local gcc_prefix="$(gcc_prefix)"
|
||||
# Create a temporary dir that contains our staging area.
|
||||
# $tmpdir/$name is what eventually ends up as the deployed archive.
|
||||
local tmpdir="$(mktemp -d)"
|
||||
local name="${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}"
|
||||
mkdir "$td/$name"
|
||||
local staging="$tmpdir/$name"
|
||||
mkdir -p "$staging"/{complete,doc}
|
||||
# The deployment directory is where the final archive will reside.
|
||||
# This path is known by the .travis.yml configuration.
|
||||
local out_dir="$(pwd)/deployment"
|
||||
mkdir -p "$out_dir"
|
||||
# Find the correct (most recent) Cargo "out" directory. The out directory
|
||||
# contains shell completion files and the man page.
|
||||
local cargo_out_dir="$(cargo_out_dir "target/$TARGET")"
|
||||
|
||||
cp target/$TARGET/release/rg "$td/$name/"
|
||||
cp {doc/rg.1,README.md,UNLICENSE,COPYING,LICENSE-MIT} "$td/$name/"
|
||||
# Copy the ripgrep binary and strip it.
|
||||
cp "target/$TARGET/release/rg" "$staging/rg"
|
||||
"${gcc_prefix}strip" "$staging/rg"
|
||||
# Copy the licenses and README.
|
||||
cp {README.md,UNLICENSE,COPYING,LICENSE-MIT} "$staging/"
|
||||
# Copy documentation and man page.
|
||||
cp {CHANGELOG.md,FAQ.md,GUIDE.md} "$staging/doc/"
|
||||
if command -V a2x 2>&1 > /dev/null; then
|
||||
# The man page should only exist if we have asciidoc installed.
|
||||
cp "$cargo_out_dir/rg.1" "$staging/doc/"
|
||||
fi
|
||||
# Copy shell completion files.
|
||||
cp "$cargo_out_dir"/{rg.bash,rg.fish,_rg.ps1} "$staging/complete/"
|
||||
cp complete/_rg "$staging/complete/"
|
||||
|
||||
pushd $td
|
||||
tar czf "$out_dir/$name.tar.gz" *
|
||||
popd
|
||||
rm -r $td
|
||||
(cd "$tmpdir" && tar czf "$out_dir/$name.tar.gz" "$name")
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
55
ci/install.sh
Normal file → Executable file
55
ci/install.sh
Normal file → Executable file
@@ -1,60 +1,61 @@
|
||||
# `install` phase: install stuff needed for the `script` phase
|
||||
#!/bin/bash
|
||||
|
||||
# install stuff needed for the `script` phase
|
||||
|
||||
# Where rustup gets installed.
|
||||
export PATH="$PATH:$HOME/.cargo/bin"
|
||||
|
||||
set -ex
|
||||
|
||||
. $(dirname $0)/utils.sh
|
||||
|
||||
install_c_toolchain() {
|
||||
case $TARGET in
|
||||
aarch64-unknown-linux-gnu)
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
gcc-aarch64-linux-gnu libc6-arm64-cross libc6-dev-arm64-cross
|
||||
;;
|
||||
*)
|
||||
# For other targets, this is handled by addons.apt.packages in .travis.yml
|
||||
;;
|
||||
esac
|
||||
}
|
||||
. "$(dirname $0)/utils.sh"
|
||||
|
||||
install_rustup() {
|
||||
# uninstall the rust toolchain installed by travis, we are going to use rustup
|
||||
sh ~/rust/lib/rustlib/uninstall.sh
|
||||
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION
|
||||
|
||||
curl https://sh.rustup.rs -sSf \
|
||||
| sh -s -- -y --default-toolchain="$TRAVIS_RUST_VERSION"
|
||||
rustc -V
|
||||
cargo -V
|
||||
}
|
||||
|
||||
install_standard_crates() {
|
||||
install_targets() {
|
||||
if [ $(host) != "$TARGET" ]; then
|
||||
rustup target add $TARGET
|
||||
fi
|
||||
}
|
||||
|
||||
install_osx_dependencies() {
|
||||
if ! is_osx; then
|
||||
return
|
||||
fi
|
||||
|
||||
brew install asciidoc docbook-xsl
|
||||
}
|
||||
|
||||
configure_cargo() {
|
||||
local prefix=$(gcc_prefix)
|
||||
if [ -n "${prefix}" ]; then
|
||||
local gcc_suffix=
|
||||
if [ -n "$GCC_VERSION" ]; then
|
||||
gcc_suffix="-$GCC_VERSION"
|
||||
fi
|
||||
local gcc="${prefix}gcc${gcc_suffix}"
|
||||
|
||||
if [ ! -z $prefix ]; then
|
||||
# information about the cross compiler
|
||||
${prefix}gcc -v
|
||||
"${gcc}" -v
|
||||
|
||||
# tell cargo which linker to use for cross compilation
|
||||
mkdir -p .cargo
|
||||
cat >>.cargo/config <<EOF
|
||||
[target.$TARGET]
|
||||
linker = "${prefix}gcc"
|
||||
linker = "${gcc}"
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
install_c_toolchain
|
||||
install_osx_dependencies
|
||||
install_rustup
|
||||
install_standard_crates
|
||||
install_targets
|
||||
configure_cargo
|
||||
|
||||
# TODO if you need to install extra stuff add it here
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
68
ci/script.sh
Normal file → Executable file
68
ci/script.sh
Normal file → Executable file
@@ -1,38 +1,46 @@
|
||||
# `script` phase: you usually build, test and generate docs in this phase
|
||||
#!/bin/bash
|
||||
|
||||
# build, test and generate docs in this phase
|
||||
|
||||
set -ex
|
||||
|
||||
. $(dirname $0)/utils.sh
|
||||
|
||||
# NOTE Workaround for rust-lang/rust#31907 - disable doc tests when cross compiling
|
||||
# This has been fixed in the nightly channel but it would take a while to reach the other channels
|
||||
disable_cross_doctests() {
|
||||
if [ $(host) != "$TARGET" ] && [ "$TRAVIS_RUST_VERSION" = "stable" ]; then
|
||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew install gnu-sed --default-names
|
||||
fi
|
||||
find src -name '*.rs' -type f | xargs sed -i -e 's:\(//.\s*```\):\1 ignore,:g'
|
||||
fi
|
||||
}
|
||||
|
||||
run_test_suite() {
|
||||
cargo clean --target $TARGET --verbose
|
||||
cargo build --target $TARGET --verbose
|
||||
cargo test --target $TARGET --verbose
|
||||
cargo build --target $TARGET --verbose --manifest-path grep/Cargo.toml
|
||||
cargo test --target $TARGET --verbose --manifest-path grep/Cargo.toml
|
||||
cargo build --target $TARGET --verbose --manifest-path globset/Cargo.toml
|
||||
cargo test --target $TARGET --verbose --manifest-path globset/Cargo.toml
|
||||
cargo build --target $TARGET --verbose --manifest-path ignore/Cargo.toml
|
||||
cargo test --target $TARGET --verbose --manifest-path ignore/Cargo.toml
|
||||
|
||||
# sanity check the file type
|
||||
file target/$TARGET/debug/rg
|
||||
}
|
||||
. "$(dirname $0)/utils.sh"
|
||||
|
||||
main() {
|
||||
# disable_cross_doctests
|
||||
run_test_suite
|
||||
# Test a normal debug build.
|
||||
cargo build --target "$TARGET" --verbose --all
|
||||
|
||||
# Show the output of the most recent build.rs stderr.
|
||||
set +x
|
||||
stderr="$(find "target/$TARGET/debug" -name stderr -print0 | xargs -0 ls -t | head -n1)"
|
||||
if [ -s "$stderr" ]; then
|
||||
echo "===== $stderr ====="
|
||||
cat "$stderr"
|
||||
echo "====="
|
||||
fi
|
||||
set -x
|
||||
|
||||
# sanity check the file type
|
||||
file target/"$TARGET"/debug/rg
|
||||
|
||||
# Check that we've generated man page and other shell completions.
|
||||
outdir="$(cargo_out_dir "target/$TARGET/debug")"
|
||||
file "$outdir/rg.bash"
|
||||
file "$outdir/rg.fish"
|
||||
file "$outdir/_rg.ps1"
|
||||
file "$outdir/rg.1"
|
||||
|
||||
# Apparently tests don't work on arm, so just bail now. I guess we provide
|
||||
# ARM releases on a best effort basis?
|
||||
if is_arm; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Test that zsh completions are in sync with ripgrep's actual args.
|
||||
"$(dirname "${0}")/test_complete.sh"
|
||||
|
||||
# Run tests for ripgrep and all sub-crates.
|
||||
cargo test --target "$TARGET" --verbose --all
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
0
ci/sha256.sh
Normal file → Executable file
0
ci/sha256.sh
Normal file → Executable file
94
ci/test_complete.sh
Executable file
94
ci/test_complete.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
##
|
||||
# Compares options in `rg --help` output to options in zsh completion function
|
||||
|
||||
emulate -R zsh
|
||||
setopt extended_glob
|
||||
setopt no_function_argzero
|
||||
setopt no_unset
|
||||
|
||||
get_comp_args() {
|
||||
setopt local_options unset
|
||||
|
||||
# Our completion function recognises a special variable which tells it to
|
||||
# dump the _arguments specs and then just return. But do this in a sub-shell
|
||||
# anyway to avoid any weirdness
|
||||
( _RG_COMPLETE_LIST_ARGS=1 source $1 )
|
||||
return $?
|
||||
}
|
||||
|
||||
main() {
|
||||
local diff
|
||||
local rg="${${0:a}:h}/../target/${TARGET:-}/release/rg"
|
||||
local _rg="${${0:a}:h}/../complete/_rg"
|
||||
local -a help_args comp_args
|
||||
|
||||
[[ -e $rg ]] || rg=${rg/%\/release\/rg/\/debug\/rg}
|
||||
|
||||
[[ -e $rg ]] || {
|
||||
printf >&2 'File not found: %s\n' $rg
|
||||
return 1
|
||||
}
|
||||
[[ -e $_rg ]] || {
|
||||
printf >&2 'File not found: %s\n' $_rg
|
||||
return 1
|
||||
}
|
||||
|
||||
printf 'Comparing options:\n-%s\n+%s\n' $rg $_rg
|
||||
|
||||
# 'Parse' options out of the `--help` output. To prevent false positives we
|
||||
# only look at lines where the first non-white-space character is `-`
|
||||
help_args=( ${(f)"$(
|
||||
$rg --help |
|
||||
$rg -- '^\s*-' |
|
||||
$rg -io -- '[\t ,](-[a-z0-9]|--[a-z0-9-]+)\b' |
|
||||
tr -d '\t ,' |
|
||||
sort -u
|
||||
)"} )
|
||||
|
||||
# 'Parse' options out of the completion function
|
||||
comp_args=( ${(f)"$( get_comp_args $_rg )"} )
|
||||
|
||||
comp_args=( ${comp_args#\(*\)} ) # Strip excluded options
|
||||
comp_args=( ${comp_args#\*} ) # Strip repetition indicator
|
||||
comp_args=( ${comp_args%%-[:[]*} ) # Strip everything after -optname-
|
||||
comp_args=( ${comp_args%%[:+=[]*} ) # Strip everything after other optspecs
|
||||
comp_args=( ${comp_args##[^-]*} ) # Remove non-options
|
||||
|
||||
# This probably isn't necessary, but we should ensure the same order
|
||||
comp_args=( ${(f)"$( printf '%s\n' $comp_args | sort -u )"} )
|
||||
|
||||
(( $#help_args )) || {
|
||||
printf >&2 'Failed to get help_args\n'
|
||||
return 1
|
||||
}
|
||||
(( $#comp_args )) || {
|
||||
printf >&2 'Failed to get comp_args\n'
|
||||
return 1
|
||||
}
|
||||
|
||||
diff="$(
|
||||
if diff --help 2>&1 | grep -qF -- '--label'; then
|
||||
diff -U2 \
|
||||
--label '`rg --help`' \
|
||||
--label '`_rg`' \
|
||||
=( printf '%s\n' $help_args ) =( printf '%s\n' $comp_args )
|
||||
else
|
||||
diff -U2 \
|
||||
-L '`rg --help`' \
|
||||
-L '`_rg`' \
|
||||
=( printf '%s\n' $help_args ) =( printf '%s\n' $comp_args )
|
||||
fi
|
||||
)"
|
||||
|
||||
(( $#diff )) && {
|
||||
printf >&2 '%s\n' 'zsh completion options differ from `--help` options:'
|
||||
printf >&2 '%s\n' $diff
|
||||
return 1
|
||||
}
|
||||
printf 'OK\n'
|
||||
return 0
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
95
ci/utils.sh
95
ci/utils.sh
@@ -1,5 +1,19 @@
|
||||
mktempd() {
|
||||
echo $(mktemp -d 2>/dev/null || mktemp -d -t tmp)
|
||||
#!/bin/bash
|
||||
|
||||
# Various utility functions used through CI.
|
||||
|
||||
# Finds Cargo's `OUT_DIR` directory from the most recent build.
|
||||
#
|
||||
# This requires one parameter corresponding to the target directory
|
||||
# to search for the build output.
|
||||
cargo_out_dir() {
|
||||
# This works by finding the most recent stamp file, which is produced by
|
||||
# every ripgrep build.
|
||||
target_dir="$1"
|
||||
find "$target_dir" -name ripgrep-stamp -print0 \
|
||||
| xargs -0 ls -t \
|
||||
| head -n1 \
|
||||
| xargs dirname
|
||||
}
|
||||
|
||||
host() {
|
||||
@@ -13,37 +27,12 @@ host() {
|
||||
esac
|
||||
}
|
||||
|
||||
gcc_prefix() {
|
||||
case "$TARGET" in
|
||||
aarch64-unknown-linux-gnu)
|
||||
echo aarch64-linux-gnu-
|
||||
;;
|
||||
arm*-gnueabihf)
|
||||
echo arm-linux-gnueabihf-
|
||||
;;
|
||||
*)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
dobin() {
|
||||
[ -z $MAKE_DEB ] && die 'dobin: $MAKE_DEB not set'
|
||||
[ $# -lt 1 ] && die "dobin: at least one argument needed"
|
||||
|
||||
local f prefix=$(gcc_prefix)
|
||||
for f in "$@"; do
|
||||
install -m0755 $f $dtd/debian/usr/bin/
|
||||
${prefix}strip -s $dtd/debian/usr/bin/$(basename $f)
|
||||
done
|
||||
}
|
||||
|
||||
architecture() {
|
||||
case $1 in
|
||||
x86_64-unknown-linux-gnu|x86_64-unknown-linux-musl)
|
||||
case "$TARGET" in
|
||||
x86_64-*)
|
||||
echo amd64
|
||||
;;
|
||||
i686-unknown-linux-gnu|i686-unknown-linux-musl)
|
||||
i686-*|i586-*|i386-*)
|
||||
echo i386
|
||||
;;
|
||||
arm*-unknown-linux-gnueabihf)
|
||||
@@ -54,3 +43,49 @@ architecture() {
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
gcc_prefix() {
|
||||
case "$(architecture)" in
|
||||
armhf)
|
||||
echo arm-linux-gnueabihf-
|
||||
;;
|
||||
*)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_ssse3_target() {
|
||||
case "$(architecture)" in
|
||||
amd64) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_x86() {
|
||||
case "$(architecture)" in
|
||||
amd64|i386) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_arm() {
|
||||
case "$(architecture)" in
|
||||
armhf) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_linux() {
|
||||
case "$TRAVIS_OS_NAME" in
|
||||
linux) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_osx() {
|
||||
case "$TRAVIS_OS_NAME" in
|
||||
osx) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
5
compile
5
compile
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
export RUSTFLAGS="-C target-feature=+ssse3"
|
||||
# export RUSTFLAGS="-C target-cpu=native"
|
||||
cargo build --release --features simd-accel
|
||||
260
complete/_rg
Normal file
260
complete/_rg
Normal file
@@ -0,0 +1,260 @@
|
||||
#compdef rg
|
||||
|
||||
##
|
||||
# zsh completion function for ripgrep
|
||||
#
|
||||
# Run ci/test_complete.sh after building to ensure that the options supported by
|
||||
# this function stay in synch with the `rg` binary.
|
||||
#
|
||||
# @see https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide
|
||||
#
|
||||
# Based on code from the zsh-users project — see copyright notice below.
|
||||
|
||||
_rg() {
|
||||
local state_descr ret curcontext="${curcontext:-}"
|
||||
local -a context line state
|
||||
local -A opt_args val_args
|
||||
local -a rg_args
|
||||
|
||||
# Sort by long option name to match `rg --help`
|
||||
rg_args=(
|
||||
'(-A -C --after-context --context)'{-A+,--after-context=}'[specify lines to show after each match]:number of lines'
|
||||
'(-B -C --before-context --context)'{-B+,--before-context=}'[specify lines to show before each match]:number of lines'
|
||||
'(-i -s -S --ignore-case --case-sensitive --smart-case)'{-s,--case-sensitive}'[search case-sensitively]'
|
||||
'--color=[specify when to use colors in output]:when:( never auto always ansi )'
|
||||
'*--colors=[specify color settings and styles]: :->colorspec'
|
||||
'--column[show column numbers]'
|
||||
'(-A -B -C --after-context --before-context --context)'{-C+,--context=}'[specify lines to show before and after each match]:number of lines'
|
||||
'--context-separator=[specify string used to separate non-continuous context lines in output]:separator'
|
||||
'(-c --count --passthrough --passthru)'{-c,--count}'[only show count of matches for each file]'
|
||||
'--debug[show debug messages]'
|
||||
'--dfa-size-limit=[specify upper size limit of generated DFA]:DFA size'
|
||||
'(-E --encoding)'{-E+,--encoding=}'[specify text encoding of files to search]: :_rg_encodings'
|
||||
'*'{-f+,--file=}'[specify file containing patterns to search for]:file:_files'
|
||||
"(1)--files[show each file that would be searched (but don't search)]"
|
||||
'(-l --files-with-matches --files-without-match)'{-l,--files-with-matches}'[only show names of files with matches]'
|
||||
'(-l --files-with-matches --files-without-match)--files-without-match[only show names of files without matches]'
|
||||
'(-F --fixed-strings)'{-F,--fixed-strings}'[treat pattern as literal string instead of regular expression]'
|
||||
'(-L --follow)'{-L,--follow}'[follow symlinks]'
|
||||
'*'{-g+,--glob=}'[include or exclude files for searching that match the specified glob]:glob'
|
||||
'(: -)'{-h,--help}'[display help information]'
|
||||
'(-p --no-heading --pretty --vimgrep)--heading[show matches grouped by file name]'
|
||||
'--hidden[search hidden files and directories]'
|
||||
'*--iglob=[include or exclude files for searching that match the specified case-insensitive glob]:glob'
|
||||
'(-i -s -S --case-sensitive --ignore-case --smart-case)'{-i,--ignore-case}'[search case-insensitively]'
|
||||
'--ignore-file=[specify additional ignore file]:file:_files'
|
||||
'(-v --invert-match)'{-v,--invert-match}'[invert matching]'
|
||||
'(-n -N --line-number --no-line-number)'{-n,--line-number}'[show line numbers]'
|
||||
'(-N --no-line-number)--line-number-width=[specify width of displayed line number]:number of columns'
|
||||
'(-w -x --line-regexp --word-regexp)'{-x,--line-regexp}'[only show matches surrounded by line boundaries]'
|
||||
'(-M --max-columns)'{-M+,--max-columns=}'[specify max length of lines to print]:number of bytes'
|
||||
'(-m --max-count)'{-m+,--max-count=}'[specify max number of matches per file]:number of matches'
|
||||
'--max-filesize=[specify size above which files should be ignored]:file size'
|
||||
'--maxdepth=[specify max number of directories to descend]:number of directories'
|
||||
'(--mmap --no-mmap)--mmap[search using memory maps when possible]'
|
||||
'(-H --with-filename --no-filename)--no-filename[suppress all file names]'
|
||||
"(-p --heading --pretty --vimgrep)--no-heading[don't group matches by file name]"
|
||||
"--no-config[don't load configuration files]"
|
||||
"(--no-ignore-parent)--no-ignore[don't respect ignore files]"
|
||||
"--no-ignore-parent[don't respect ignore files in parent directories]"
|
||||
"--no-ignore-vcs[don't respect version control ignore files]"
|
||||
'(-n -N --line-number --no-line-number)'{-N,--no-line-number}'[suppress line numbers]'
|
||||
'--no-messages[suppress all error messages]'
|
||||
"(--mmap --no-mmap)--no-mmap[don't search using memory maps]"
|
||||
'(-0 --null)'{-0,--null}'[print NUL byte after file names]'
|
||||
'(-o -r --only-matching --passthrough --passthru --replace)'{-o,--only-matching}'[show only matching part of each line]'
|
||||
'(-c -o -r --count --only-matching --passthrough --replace)--passthru[show both matching and non-matching lines]'
|
||||
'!(-c -o -r --count --only-matching --passthru --replace)--passthrough'
|
||||
'--path-separator=[specify path separator to use when printing file names]:separator'
|
||||
'(-p --heading --no-heading --pretty --vimgrep)'{-p,--pretty}'[alias for --color=always --heading -n]'
|
||||
'(-q --quiet)'{-q,--quiet}'[suppress normal output]'
|
||||
'--regex-size-limit=[specify upper size limit of compiled regex]:regex size'
|
||||
'(1 -f --file)*'{-e+,--regexp=}'[specify pattern]:pattern'
|
||||
'(-c -o -r --count --only-matching --passthrough --passthru --replace)'{-r+,--replace=}'[specify string used to replace matches]:replace string'
|
||||
'(-i -s -S --ignore-case --case-sensitive --smart-case)'{-S,--smart-case}'[search case-insensitively if the pattern is all lowercase]'
|
||||
'(-j --threads)--sort-files[sort results by file path (disables parallelism)]'
|
||||
'(-a --text)'{-a,--text}'[search binary files as if they were text]'
|
||||
'(-j --sort-files --threads)'{-j+,--threads=}'[specify approximate number of threads to use]:number of threads'
|
||||
'*'{-t+,--type=}'[only search files matching specified type]: :_rg_types'
|
||||
'*--type-add=[add new glob for file type]: :->typespec'
|
||||
'*--type-clear=[clear globs previously defined for specified file type]: :_rg_types'
|
||||
# This should actually be exclusive with everything but other type options
|
||||
'(:)--type-list[show all supported file types and their associated globs]'
|
||||
'*'{-T+,--type-not=}"[don't search files matching specified type]: :_rg_types"
|
||||
'*'{-u,--unrestricted}'[reduce level of "smart" searching]'
|
||||
'(: -)'{-V,--version}'[display version information]'
|
||||
'(-p --heading --no-heading --pretty)--vimgrep[show results in vim-compatible format]'
|
||||
'(-H --no-filename --with-filename)'{-H,--with-filename}'[display the file name for matches]'
|
||||
'(-w -x --line-regexp --word-regexp)'{-w,--word-regexp}'[only show matches surrounded by word boundaries]'
|
||||
'(-e -f --file --files --regexp --type-list)1: :_rg_pattern'
|
||||
'(--type-list)*:file:_files'
|
||||
'(-z --search-zip)'{-z,--search-zip}'[search in compressed files]'
|
||||
)
|
||||
|
||||
[[ ${_RG_COMPLETE_LIST_ARGS:-} == (1|t*|y*) ]] && {
|
||||
printf '%s\n' "${rg_args[@]}"
|
||||
return 0
|
||||
}
|
||||
|
||||
_arguments -s -S : "${rg_args[@]}" && return 0
|
||||
|
||||
while (( $#state )); do
|
||||
case "${state[1]}" in
|
||||
colorspec)
|
||||
# @todo I don't like this because it allows you to do weird things like
|
||||
# `line:line:bg:`. Also, i would like the `compadd -q` behaviour
|
||||
[[ -prefix *:none: ]] && return 1
|
||||
[[ -prefix *:*:*:* ]] && return 1
|
||||
|
||||
_values -S ':' 'color/style type' \
|
||||
'column[specify coloring for column numbers]: :->attribute' \
|
||||
'line[specify coloring for line numbers]: :->attribute' \
|
||||
'match[specify coloring for match text]: :->attribute' \
|
||||
'path[specify color for file names]: :->attribute' && return 0
|
||||
|
||||
[[ "${state}" == 'attribute' ]] &&
|
||||
_values -S ':' 'color/style attribute' \
|
||||
'none[clear color/style for type]' \
|
||||
'bg[specify background color]: :->color' \
|
||||
'fg[specify foreground color]: :->color' \
|
||||
'style[specify text style]: :->style' && return 0
|
||||
|
||||
[[ "${state}" == 'color' ]] &&
|
||||
_values -S ':' 'color value' \
|
||||
black blue green red cyan magenta yellow white && return 0
|
||||
|
||||
[[ "${state}" == 'style' ]] &&
|
||||
_values -S ':' 'style value' \
|
||||
bold nobold intense nointense underline nounderline && return 0
|
||||
;;
|
||||
|
||||
typespec)
|
||||
if compset -P '[^:]##:include:'; then
|
||||
_sequence -s ',' _rg_types && return 0
|
||||
# @todo This bit in particular could be better, but it's a little
|
||||
# complex, and attempting to solve it seems to run us up against a crash
|
||||
# bug — zsh # 40362
|
||||
elif compset -P '[^:]##:'; then
|
||||
_message 'glob or include directive' && return 1
|
||||
elif [[ ! -prefix *:* ]]; then
|
||||
_rg_types -qS ':' && return 0
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift state
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# zsh 5.1 refuses to complete options if a 'match-less' operand like our pattern
|
||||
# could be 'completed' instead. We can use _guard() to avoid this problem, but
|
||||
# it introduces another one: zsh won't print the message if we try to complete
|
||||
# the pattern after having passed `--`. To work around *that* problem, we can
|
||||
# use this function to bypass the _guard() when `--` is on the command line.
|
||||
# This is inaccurate (it'd get confused by e.g. `rg -e --`), but zsh's handling
|
||||
# of `--` isn't accurate anyway
|
||||
_rg_pattern() {
|
||||
if (( ${words[(I)--]} )); then
|
||||
_message 'pattern'
|
||||
else
|
||||
_guard '^-*' 'pattern'
|
||||
fi
|
||||
}
|
||||
|
||||
# Complete encodings
|
||||
_rg_encodings() {
|
||||
local -a expl
|
||||
local -aU _encodings
|
||||
|
||||
# This is impossible to read, but these encodings rarely if ever change, so it
|
||||
# probably doesn't matter. They are derived from the list given here:
|
||||
# https://encoding.spec.whatwg.org/#concept-encoding-get
|
||||
_encodings=(
|
||||
{{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
|
||||
logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
|
||||
866 ibm{819,866} csibm866
|
||||
big5{,-hkscs} {cn-,cs}big5 x-x-big5
|
||||
cp{819,866,125{0..8}} x-cp125{0..8}
|
||||
csiso2022{jp,kr} csiso8859{6,8}{e,i}
|
||||
csisolatin{{1..6},9} csisolatin{arabic,cyrillic,greek,hebrew}
|
||||
ecma-{114,118} asmo-708 elot_928 sun_eu_greek
|
||||
euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
|
||||
{,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
|
||||
iso-2022-{cn,cn-ext,jp,kr}
|
||||
iso8859{,-}{{1..11},13,14,15}
|
||||
iso-8859-{{1..11},{6,8}-{e,i},13,14,15,16} iso_8859-{{1..9},15}
|
||||
iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
|
||||
iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
|
||||
koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
|
||||
ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
|
||||
latin{1..6} l{{1..6},9}
|
||||
shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
|
||||
utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
|
||||
windows-{31j,874,949,125{0..8}} dos-874 tis-620 ansi_x3.4-1968
|
||||
x-user-defined auto
|
||||
)
|
||||
|
||||
_wanted rg-encodings expl 'encoding' compadd -a "${@}" - _encodings
|
||||
}
|
||||
|
||||
# Complete file types
|
||||
_rg_types() {
|
||||
local -a expl
|
||||
local -aU _types
|
||||
|
||||
_types=( ${${(f)"$( _call_program rg-types rg --type-list )"}%%:*} )
|
||||
|
||||
_wanted rg-types expl 'file type' compadd -a "${@}" - _types
|
||||
}
|
||||
|
||||
_rg "${@}"
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the zsh-users nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# ------------------------------------------------------------------------------
|
||||
# Description
|
||||
# -----------
|
||||
#
|
||||
# Completion script for ripgrep
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
# Authors
|
||||
# -------
|
||||
#
|
||||
# * arcizan <ghostrevery@gmail.com>
|
||||
# * MaskRay <i@maskray.me>
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# coding: utf-8-unix
|
||||
# indent-tabs-mode: nil
|
||||
# sh-indentation: 2
|
||||
# sh-basic-offset: 2
|
||||
# End:
|
||||
# vim: ft=zsh sw=2 ts=2 et
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
pandoc -s -t man rg.1.md -o rg.1
|
||||
sed -i 's/\.TH.*/.TH "rg" "1"/g' rg.1
|
||||
324
doc/rg.1
324
doc/rg.1
@@ -1,324 +0,0 @@
|
||||
.\" Automatically generated by Pandoc 1.17.2
|
||||
.\"
|
||||
.TH "rg" "1"
|
||||
.hy
|
||||
.SH NAME
|
||||
.PP
|
||||
rg \- recursively search current directory for lines matching a pattern
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
rg [\f[I]options\f[]] \-e PATTERN ...
|
||||
[\f[I]<\f[]path\f[I]> ...\f[]]
|
||||
.PP
|
||||
rg [\f[I]options\f[]] <\f[I]pattern\f[]> [\f[I]<\f[]path\f[I]> ...\f[]]
|
||||
.PP
|
||||
rg [\f[I]options\f[]] \-\-files [\f[I]<\f[]path\f[I]> ...\f[]]
|
||||
.PP
|
||||
rg [\f[I]options\f[]] \-\-type\-list
|
||||
.PP
|
||||
rg [\f[I]options\f[]] \-\-help
|
||||
.PP
|
||||
rg [\f[I]options\f[]] \-\-version
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
rg (ripgrep) combines the usability of The Silver Searcher (an ack
|
||||
clone) with the raw speed of grep.
|
||||
.SH COMMON OPTIONS
|
||||
.TP
|
||||
.B \-a, \-\-text
|
||||
Search binary files as if they were text.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-c, \-\-count
|
||||
Only show count of line matches for each file.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-color \f[I]WHEN\f[]
|
||||
Whether to use coloring in match.
|
||||
Valid values are never, always or auto.
|
||||
[default: auto]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-e, \-\-regexp \f[I]PATTERN\f[] ...
|
||||
Use PATTERN to search.
|
||||
This option can be provided multiple times, where all patterns given are
|
||||
searched.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-F, \-\-fixed\-strings
|
||||
Treat the pattern as a literal string instead of a regular expression.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-g, \-\-glob \f[I]GLOB\f[] ...
|
||||
Include or exclude files for searching that match the given glob.
|
||||
This always overrides any other ignore logic.
|
||||
Multiple glob flags may be used.
|
||||
Globbing rules match .gitignore globs.
|
||||
Precede a glob with a \[aq]!\[aq] to exclude it.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Show this usage message.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-i, \-\-ignore\-case
|
||||
Case insensitive search.
|
||||
Overridden by \-\-case\-sensitive.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-n, \-\-line\-number
|
||||
Show line numbers (1\-based).
|
||||
This is enabled by default at a tty.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-N, \-\-no\-line\-number
|
||||
Suppress line numbers.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-q, \-\-quiet
|
||||
Do not print anything to stdout.
|
||||
If a match is found in a file, stop searching that file.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-t, \-\-type \f[I]TYPE\f[] ...
|
||||
Only search files matching TYPE.
|
||||
Multiple type flags may be provided.
|
||||
Use the \-\-type\-list flag to list all available types.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-T, \-\-type\-not \f[I]TYPE\f[] ...
|
||||
Do not search files matching TYPE.
|
||||
Multiple not\-type flags may be provided.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-u, \-\-unrestricted ...
|
||||
Reduce the level of \[aq]smart\[aq] searching.
|
||||
A single \-u doesn\[aq]t respect .gitignore (etc.) files.
|
||||
Two \-u flags will search hidden files and directories.
|
||||
Three \-u flags will search binary files.
|
||||
\-uu is equivalent to grep \-r, and \-uuu is equivalent to grep \-a \-r.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-v, \-\-invert\-match
|
||||
Invert matching.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-w, \-\-word\-regexp
|
||||
Only show matches surrounded by word boundaries.
|
||||
This is equivalent to putting \\b before and after the search pattern.
|
||||
.RS
|
||||
.RE
|
||||
.SH LESS COMMON OPTIONS
|
||||
.TP
|
||||
.B \-A, \-\-after\-context \f[I]NUM\f[]
|
||||
Show NUM lines after each match.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-B, \-\-before\-context \f[I]NUM\f[]
|
||||
Show NUM lines before each match.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-C, \-\-context \f[I]NUM\f[]
|
||||
Show NUM lines before and after each match.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-column
|
||||
Show column numbers (1 based) in output.
|
||||
This only shows the column numbers for the first match on each line.
|
||||
Note that this doesn\[aq]t try to account for Unicode.
|
||||
One byte is equal to one column.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-context\-separator \f[I]ARG\f[]
|
||||
The string to use when separating non\-continuous context lines.
|
||||
Escape sequences may be used.
|
||||
[default: \-\-]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-debug
|
||||
Show debug messages.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-files
|
||||
Print each file that would be searched (but don\[aq]t search).
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-l, \-\-files\-with\-matches
|
||||
Only show path of each file with matches.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-H, \-\-with\-filename
|
||||
Prefix each match with the file name that contains it.
|
||||
This is the default when more than one file is searched.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-filename
|
||||
Never show the filename for a match.
|
||||
This is the default when one file is searched.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-heading
|
||||
Show the file name above clusters of matches from each file.
|
||||
This is the default mode at a tty.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-heading
|
||||
Don\[aq]t show any file name heading.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-hidden
|
||||
Search hidden directories and files.
|
||||
(Hidden directories and files are skipped by default.)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-L, \-\-follow
|
||||
Follow symlinks.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-maxdepth \f[I]NUM\f[]
|
||||
Descend at most NUM directories below the command line arguments.
|
||||
A value of zero searches only the starting\-points themselves.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-mmap
|
||||
Search using memory maps when possible.
|
||||
This is enabled by default when ripgrep thinks it will be faster.
|
||||
(Note that mmap searching doesn\[aq]t currently support the various
|
||||
context related options.)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-mmap
|
||||
Never use memory maps, even when they might be faster.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-ignore
|
||||
Don\[aq]t respect ignore files (.gitignore, .ignore, etc.) This implies
|
||||
\-\-no\-ignore\-parent.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-ignore\-parent
|
||||
Don\[aq]t respect ignore files in parent directories.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-ignore\-vcs
|
||||
Don\[aq]t respect version control ignore files (e.g., .gitignore).
|
||||
Note that .ignore files will continue to be respected.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-null
|
||||
Whenever a file name is printed, follow it with a NUL byte.
|
||||
This includes printing filenames before matches, and when printing a
|
||||
list of matching files such as with \-\-count, \-\-files\-with\-matches
|
||||
and \-\-files.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-p, \-\-pretty
|
||||
Alias for \-\-color=always \-\-heading \-n.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-r, \-\-replace \f[I]ARG\f[]
|
||||
Replace every match with the string given when printing search results.
|
||||
Neither this flag nor any other flag will modify your files.
|
||||
.RS
|
||||
.PP
|
||||
Capture group indices (e.g., $5) and names (e.g., $foo) are supported in
|
||||
the replacement string.
|
||||
.RE
|
||||
.TP
|
||||
.B \-s, \-\-case\-sensitive
|
||||
Search case sensitively.
|
||||
This overrides \-\-ignore\-case and \-\-smart\-case.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-S, \-\-smart\-case
|
||||
Search case insensitively if the pattern is all lowercase.
|
||||
Search case sensitively otherwise.
|
||||
This is overridden by either \-\-case\-sensitive or \-\-ignore\-case.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-j, \-\-threads \f[I]ARG\f[]
|
||||
The number of threads to use.
|
||||
0 means use the number of logical CPUs (capped at 6).
|
||||
[default: 0]
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-version
|
||||
Show the version number of ripgrep and exit.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-vimgrep
|
||||
Show results with every match on its own line, including line numbers
|
||||
and column numbers.
|
||||
(With this option, a line with more than one match of the regex will be
|
||||
printed more than once.)
|
||||
.RS
|
||||
.RE
|
||||
.SH FILE TYPE MANAGEMENT OPTIONS
|
||||
.TP
|
||||
.B \-\-type\-list
|
||||
Show all supported file types and their associated globs.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-type\-add \f[I]ARG\f[] ...
|
||||
Add a new glob for a particular file type.
|
||||
Only one glob can be added at a time.
|
||||
Multiple \-\-type\-add flags can be provided.
|
||||
Unless \-\-type\-clear is used, globs are added to any existing globs
|
||||
inside of ripgrep.
|
||||
Note that this must be passed to every invocation of rg.
|
||||
Type settings are NOT persisted.
|
||||
.RS
|
||||
.PP
|
||||
Example:
|
||||
\f[C]rg\ \-\-type\-add\ \[aq]foo:*.foo\[aq]\ \-tfoo\ PATTERN\f[]
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-type\-clear \f[I]TYPE\f[] ...
|
||||
Clear the file type globs previously defined for TYPE.
|
||||
This only clears the default type definitions that are found inside of
|
||||
ripgrep.
|
||||
Note that this must be passed to every invocation of rg.
|
||||
.RS
|
||||
.RE
|
||||
211
doc/rg.1.md
211
doc/rg.1.md
@@ -1,211 +0,0 @@
|
||||
# NAME
|
||||
|
||||
rg - recursively search current directory for lines matching a pattern
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
rg [*options*] -e PATTERN ... [*<*path*> ...*]
|
||||
|
||||
rg [*options*] <*pattern*> [*<*path*> ...*]
|
||||
|
||||
rg [*options*] --files [*<*path*> ...*]
|
||||
|
||||
rg [*options*] --type-list
|
||||
|
||||
rg [*options*] --help
|
||||
|
||||
rg [*options*] --version
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
rg (ripgrep) combines the usability of The Silver Searcher (an ack clone) with
|
||||
the raw speed of grep.
|
||||
|
||||
# COMMON OPTIONS
|
||||
|
||||
-a, --text
|
||||
: Search binary files as if they were text.
|
||||
|
||||
-c, --count
|
||||
: Only show count of line matches for each file.
|
||||
|
||||
--color *WHEN*
|
||||
: Whether to use coloring in match. Valid values are never, always or auto.
|
||||
[default: auto]
|
||||
|
||||
-e, --regexp *PATTERN* ...
|
||||
: Use PATTERN to search. This option can be provided multiple times, where all
|
||||
patterns given are searched.
|
||||
|
||||
-F, --fixed-strings
|
||||
: Treat the pattern as a literal string instead of a regular expression.
|
||||
|
||||
-g, --glob *GLOB* ...
|
||||
: Include or exclude files for searching that match the given glob. This always
|
||||
overrides any other ignore logic. Multiple glob flags may be used. Globbing
|
||||
rules match .gitignore globs. Precede a glob with a '!' to exclude it.
|
||||
|
||||
-h, --help
|
||||
: Show this usage message.
|
||||
|
||||
-i, --ignore-case
|
||||
: Case insensitive search. Overridden by --case-sensitive.
|
||||
|
||||
-n, --line-number
|
||||
: Show line numbers (1-based). This is enabled by default at a tty.
|
||||
|
||||
-N, --no-line-number
|
||||
: Suppress line numbers.
|
||||
|
||||
-q, --quiet
|
||||
: Do not print anything to stdout. If a match is found in a file, stop
|
||||
searching that file.
|
||||
|
||||
-t, --type *TYPE* ...
|
||||
: Only search files matching TYPE. Multiple type flags may be provided. Use the
|
||||
--type-list flag to list all available types.
|
||||
|
||||
-T, --type-not *TYPE* ...
|
||||
: Do not search files matching TYPE. Multiple not-type flags may be provided.
|
||||
|
||||
-u, --unrestricted ...
|
||||
: Reduce the level of 'smart' searching. A single -u doesn't respect .gitignore
|
||||
(etc.) files. Two -u flags will search hidden files and directories. Three
|
||||
-u flags will search binary files. -uu is equivalent to grep -r, and -uuu is
|
||||
equivalent to grep -a -r.
|
||||
|
||||
-v, --invert-match
|
||||
: Invert matching.
|
||||
|
||||
-w, --word-regexp
|
||||
: Only show matches surrounded by word boundaries. This is equivalent to
|
||||
putting \\b before and after the search pattern.
|
||||
|
||||
# LESS COMMON OPTIONS
|
||||
|
||||
-A, --after-context *NUM*
|
||||
: Show NUM lines after each match.
|
||||
|
||||
-B, --before-context *NUM*
|
||||
: Show NUM lines before each match.
|
||||
|
||||
-C, --context *NUM*
|
||||
: Show NUM lines before and after each match.
|
||||
|
||||
--column
|
||||
: Show column numbers (1 based) in output. This only shows the column
|
||||
numbers for the first match on each line. Note that this doesn't try
|
||||
to account for Unicode. One byte is equal to one column.
|
||||
|
||||
--context-separator *ARG*
|
||||
: The string to use when separating non-continuous context lines. Escape
|
||||
sequences may be used. [default: --]
|
||||
|
||||
--debug
|
||||
: Show debug messages.
|
||||
|
||||
--files
|
||||
: Print each file that would be searched (but don't search).
|
||||
|
||||
-l, --files-with-matches
|
||||
: Only show path of each file with matches.
|
||||
|
||||
-H, --with-filename
|
||||
: Prefix each match with the file name that contains it. This is the
|
||||
default when more than one file is searched.
|
||||
|
||||
--no-filename
|
||||
: Never show the filename for a match. This is the default when
|
||||
one file is searched.
|
||||
|
||||
--heading
|
||||
: Show the file name above clusters of matches from each file.
|
||||
This is the default mode at a tty.
|
||||
|
||||
--no-heading
|
||||
: Don't show any file name heading.
|
||||
|
||||
--hidden
|
||||
: Search hidden directories and files. (Hidden directories and files are
|
||||
skipped by default.)
|
||||
|
||||
-L, --follow
|
||||
: Follow symlinks.
|
||||
|
||||
--maxdepth *NUM*
|
||||
: Descend at most NUM directories below the command line arguments.
|
||||
A value of zero searches only the starting-points themselves.
|
||||
|
||||
--mmap
|
||||
: Search using memory maps when possible. This is enabled by default
|
||||
when ripgrep thinks it will be faster. (Note that mmap searching
|
||||
doesn't currently support the various context related options.)
|
||||
|
||||
--no-mmap
|
||||
: Never use memory maps, even when they might be faster.
|
||||
|
||||
--no-ignore
|
||||
: Don't respect ignore files (.gitignore, .ignore, etc.)
|
||||
This implies --no-ignore-parent.
|
||||
|
||||
--no-ignore-parent
|
||||
: Don't respect ignore files in parent directories.
|
||||
|
||||
--no-ignore-vcs
|
||||
: Don't respect version control ignore files (e.g., .gitignore).
|
||||
Note that .ignore files will continue to be respected.
|
||||
|
||||
--null
|
||||
: Whenever a file name is printed, follow it with a NUL byte.
|
||||
This includes printing filenames before matches, and when printing
|
||||
a list of matching files such as with --count, --files-with-matches
|
||||
and --files.
|
||||
|
||||
-p, --pretty
|
||||
: Alias for --color=always --heading -n.
|
||||
|
||||
-r, --replace *ARG*
|
||||
: Replace every match with the string given when printing search results.
|
||||
Neither this flag nor any other flag will modify your files.
|
||||
|
||||
Capture group indices (e.g., $5) and names (e.g., $foo) are supported
|
||||
in the replacement string.
|
||||
|
||||
-s, --case-sensitive
|
||||
: Search case sensitively. This overrides --ignore-case and --smart-case.
|
||||
|
||||
-S, --smart-case
|
||||
: Search case insensitively if the pattern is all lowercase.
|
||||
Search case sensitively otherwise. This is overridden by either
|
||||
--case-sensitive or --ignore-case.
|
||||
|
||||
-j, --threads *ARG*
|
||||
: The number of threads to use. 0 means use the number of logical CPUs
|
||||
(capped at 6). [default: 0]
|
||||
|
||||
--version
|
||||
: Show the version number of ripgrep and exit.
|
||||
|
||||
--vimgrep
|
||||
: Show results with every match on its own line, including line
|
||||
numbers and column numbers. (With this option, a line with more
|
||||
than one match of the regex will be printed more than once.)
|
||||
|
||||
# FILE TYPE MANAGEMENT OPTIONS
|
||||
|
||||
--type-list
|
||||
: Show all supported file types and their associated globs.
|
||||
|
||||
--type-add *ARG* ...
|
||||
: Add a new glob for a particular file type. Only one glob can be added
|
||||
at a time. Multiple --type-add flags can be provided. Unless --type-clear
|
||||
is used, globs are added to any existing globs inside of ripgrep. Note that
|
||||
this must be passed to every invocation of rg. Type settings are NOT
|
||||
persisted.
|
||||
|
||||
Example: `rg --type-add 'foo:*.foo' -tfoo PATTERN`
|
||||
|
||||
--type-clear *TYPE* ...
|
||||
: Clear the file type globs previously defined for TYPE. This only clears
|
||||
the default type definitions that are found inside of ripgrep. Note
|
||||
that this must be passed to every invocation of rg.
|
||||
154
doc/rg.1.txt.tpl
Normal file
154
doc/rg.1.txt.tpl
Normal file
@@ -0,0 +1,154 @@
|
||||
rg(1)
|
||||
=====
|
||||
|
||||
Name
|
||||
----
|
||||
rg - recursively search current directory for lines matching a pattern
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
*rg* [_OPTIONS_] _PATTERN_ [_PATH_...]
|
||||
|
||||
*rg* [_OPTIONS_] *-e* _PATTERN_... [_PATH_...]
|
||||
|
||||
*rg* [_OPTIONS_] *-f* _PATH_... [_PATH_...]
|
||||
|
||||
*rg* [_OPTIONS_] *--files* [_PATH_...]
|
||||
|
||||
*rg* [_OPTIONS_] *--type-list*
|
||||
|
||||
*rg* [_OPTIONS_] *--help*
|
||||
|
||||
*rg* [_OPTIONS_] *--version*
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
ripgrep (rg) recursively searches your current directory for a regex pattern.
|
||||
By default, ripgrep will respect your `.gitignore` and automatically skip
|
||||
hidden files/directories and binary files.
|
||||
|
||||
ripgrep's regex engine uses finite automata and guarantees linear time
|
||||
searching. Because of this, features like backreferences and arbitrary
|
||||
lookaround are not supported.
|
||||
|
||||
|
||||
REGEX SYNTAX
|
||||
------------
|
||||
ripgrep uses Rust's regex engine, which documents its syntax:
|
||||
https://docs.rs/regex/0.2.5/regex/#syntax
|
||||
|
||||
ripgrep uses byte-oriented regexes, which has some additional documentation:
|
||||
https://docs.rs/regex/0.2.5/regex/bytes/index.html#syntax
|
||||
|
||||
To a first approximation, ripgrep uses Perl-like regexes without look-around or
|
||||
backreferences. This makes them very similar to the "extended" (ERE) regular
|
||||
expressions supported by `egrep`, but with a few additional features like
|
||||
Unicode character classes.
|
||||
|
||||
|
||||
POSITIONAL ARGUMENTS
|
||||
--------------------
|
||||
_PATTERN_::
|
||||
A regular expression used for searching. To match a pattern beginning with a
|
||||
dash, use the -e/--regexp option.
|
||||
|
||||
_PATH_::
|
||||
A file or directory to search. Directories are searched recursively. Paths
|
||||
specified expicitly on the command line override glob and ignore rules.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
{OPTIONS}
|
||||
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
If ripgrep finds a match, then the exit status of the program is 0. If no match
|
||||
could be found, then the exit status is non-zero.
|
||||
|
||||
|
||||
CONFIGURATION FILES
|
||||
-------------------
|
||||
ripgrep supports reading configuration files that change ripgrep's default
|
||||
behavior. The format of the configuration file is an "rc" style and is very
|
||||
simple. It is defined by two rules:
|
||||
|
||||
1. Every line is a shell argument, after trimming ASCII whitespace.
|
||||
2. Lines starting with _#_ (optionally preceded by any amount of
|
||||
ASCII whitespace) are ignored.
|
||||
|
||||
ripgrep will look for a single configuration file if and only if the
|
||||
_RIPGREP_CONFIG_PATH_ environment variable is set and is non-empty.
|
||||
ripgrep will parse shell arguments from this file on startup and will
|
||||
behave as if the arguments in this file were prepended to any explicit
|
||||
arguments given to ripgrep on the command line.
|
||||
|
||||
For example, if your ripgreprc file contained a single line:
|
||||
|
||||
--smart-case
|
||||
|
||||
then the following command
|
||||
|
||||
RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo
|
||||
|
||||
would behave identically to the following command
|
||||
|
||||
rg --smart-case foo
|
||||
|
||||
ripgrep also provides a flag, *--no-config*, that when present will suppress
|
||||
any and all support for configuration. This includes any future support
|
||||
for auto-loading configuration files from pre-determined paths.
|
||||
|
||||
Conflicts between configuration files and explicit arguments are handled
|
||||
exactly like conflicts in the same command line invocation. That is,
|
||||
this command:
|
||||
|
||||
RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo --case-sensitive
|
||||
|
||||
is exactly equivalent to
|
||||
|
||||
rg --smart-case foo --case-sensitive
|
||||
|
||||
in which case, the *--case-sensitive* flag would override the *--smart-case*
|
||||
flag.
|
||||
|
||||
|
||||
SHELL COMPLETION
|
||||
----------------
|
||||
Shell completion files are included in the release tarball for Bash, Fish, Zsh
|
||||
and PowerShell.
|
||||
|
||||
For *bash*, move `rg.bash` to `$XDG_CONFIG_HOME/bash_completion`
|
||||
or `/etc/bash_completion.d/`.
|
||||
|
||||
For *fish*, move `rg.fish` to `$HOME/.config/fish/completions`.
|
||||
|
||||
For *zsh*, move `_rg` to one of your `$fpath` directories.
|
||||
|
||||
|
||||
CAVEATS
|
||||
-------
|
||||
ripgrep may abort unexpectedly when using default settings if it searches a
|
||||
file that is simultaneously truncated. This behavior can be avoided by passing
|
||||
the --no-mmap flag which will forcefully disable the use of memory maps in all
|
||||
cases.
|
||||
|
||||
|
||||
VERSION
|
||||
-------
|
||||
{VERSION}
|
||||
|
||||
|
||||
HOMEPAGE
|
||||
--------
|
||||
https://github.com/BurntSushi/ripgrep
|
||||
|
||||
Please report bugs and feature requests in the issue tracker.
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Andrew Gallant <jamslam@gmail.com>
|
||||
3
globset/COPYING
Normal file
3
globset/COPYING
Normal file
@@ -0,0 +1,3 @@
|
||||
This project is dual-licensed under the Unlicense and MIT licenses.
|
||||
|
||||
You may use this code under the terms of either license.
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "globset"
|
||||
version = "0.1.1" #:version
|
||||
version = "0.3.0" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Cross platform single glob and glob set matching. Glob set matching is the
|
||||
@@ -19,12 +19,11 @@ name = "globset"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
aho-corasick = "0.5.3"
|
||||
aho-corasick = "0.6.0"
|
||||
fnv = "1.0"
|
||||
lazy_static = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
regex = "0.1.77"
|
||||
log = "0.4"
|
||||
memchr = "2"
|
||||
regex = "0.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2"
|
||||
|
||||
21
globset/LICENSE-MIT
Normal file
21
globset/LICENSE-MIT
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -20,7 +20,7 @@ Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
globset = "0.1"
|
||||
globset = "0.2"
|
||||
```
|
||||
|
||||
and this to your crate root:
|
||||
@@ -36,7 +36,7 @@ This example shows how to match a single glob against a single file path.
|
||||
```rust
|
||||
use globset::Glob;
|
||||
|
||||
let glob = try!(Glob::new("*.rs")).compile_matcher();
|
||||
let glob = Glob::new("*.rs")?.compile_matcher();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(glob.is_match("foo/bar.rs"));
|
||||
@@ -51,8 +51,8 @@ semantics. In this example, we prevent wildcards from matching path separators.
|
||||
```rust
|
||||
use globset::GlobBuilder;
|
||||
|
||||
let glob = try!(GlobBuilder::new("*.rs")
|
||||
.literal_separator(true).build()).compile_matcher();
|
||||
let glob = GlobBuilder::new("*.rs")
|
||||
.literal_separator(true).build()?.compile_matcher();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(!glob.is_match("foo/bar.rs")); // no longer matches
|
||||
@@ -69,10 +69,10 @@ use globset::{Glob, GlobSetBuilder};
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
// A GlobBuilder can be used to configure each glob's match semantics
|
||||
// independently.
|
||||
builder.add(try!(Glob::new("*.rs")));
|
||||
builder.add(try!(Glob::new("src/lib.rs")));
|
||||
builder.add(try!(Glob::new("src/**/foo.rs")));
|
||||
let set = try!(builder.build());
|
||||
builder.add(Glob::new("*.rs")?);
|
||||
builder.add(Glob::new("src/lib.rs")?);
|
||||
builder.add(Glob::new("src/**/foo.rs")?);
|
||||
let set = builder.build()?;
|
||||
|
||||
assert_eq!(set.matches("src/bar/baz/foo.rs"), vec![0, 2]);
|
||||
```
|
||||
|
||||
24
globset/UNLICENSE
Normal file
24
globset/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::iter;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::path::{Path, is_separator};
|
||||
@@ -8,7 +8,7 @@ use std::str;
|
||||
use regex;
|
||||
use regex::bytes::Regex;
|
||||
|
||||
use {Candidate, Error, new_regex};
|
||||
use {Candidate, Error, ErrorKind, new_regex};
|
||||
|
||||
/// Describes a matching strategy for a particular pattern.
|
||||
///
|
||||
@@ -27,7 +27,7 @@ pub enum MatchStrategy {
|
||||
BasenameLiteral(String),
|
||||
/// A pattern matches if and only if the file path's extension matches this
|
||||
/// literal string.
|
||||
Extension(OsString),
|
||||
Extension(String),
|
||||
/// A pattern matches if and only if this prefix literal is a prefix of the
|
||||
/// candidate file path.
|
||||
Prefix(String),
|
||||
@@ -46,7 +46,7 @@ pub enum MatchStrategy {
|
||||
/// extension. Note that this is a necessary but NOT sufficient criterion.
|
||||
/// Namely, if the extension matches, then a full regex search is still
|
||||
/// required.
|
||||
RequiredExtension(OsString),
|
||||
RequiredExtension(String),
|
||||
/// A regex needs to be used for matching.
|
||||
Regex,
|
||||
}
|
||||
@@ -76,7 +76,7 @@ impl MatchStrategy {
|
||||
///
|
||||
/// It cannot be used directly to match file paths, but it can be converted
|
||||
/// to a regular expression string or a matcher.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
pub struct Glob {
|
||||
glob: String,
|
||||
re: String,
|
||||
@@ -84,6 +84,19 @@ pub struct Glob {
|
||||
tokens: Tokens,
|
||||
}
|
||||
|
||||
impl PartialEq for Glob {
|
||||
fn eq(&self, other: &Glob) -> bool {
|
||||
self.glob == other.glob && self.opts == other.opts
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for Glob {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.glob.hash(state);
|
||||
self.opts.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Glob {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.glob.fmt(f)
|
||||
@@ -140,7 +153,7 @@ impl GlobStrategic {
|
||||
lit.as_bytes() == &*candidate.basename
|
||||
}
|
||||
MatchStrategy::Extension(ref ext) => {
|
||||
candidate.ext == ext
|
||||
ext.as_bytes() == &*candidate.ext
|
||||
}
|
||||
MatchStrategy::Prefix(ref pre) => {
|
||||
starts_with(pre.as_bytes(), byte_path)
|
||||
@@ -152,7 +165,8 @@ impl GlobStrategic {
|
||||
ends_with(suffix.as_bytes(), byte_path)
|
||||
}
|
||||
MatchStrategy::RequiredExtension(ref ext) => {
|
||||
candidate.ext == ext && self.re.is_match(byte_path)
|
||||
let ext = ext.as_bytes();
|
||||
&*candidate.ext == ext && self.re.is_match(byte_path)
|
||||
}
|
||||
MatchStrategy::Regex => self.re.is_match(byte_path),
|
||||
}
|
||||
@@ -173,7 +187,7 @@ pub struct GlobBuilder<'a> {
|
||||
opts: GlobOptions,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
|
||||
struct GlobOptions {
|
||||
/// Whether to match case insensitively.
|
||||
case_insensitive: bool,
|
||||
@@ -281,7 +295,7 @@ impl Glob {
|
||||
/// std::path::Path::extension returns. Namely, this extension includes
|
||||
/// the '.'. Also, paths like `.rs` are considered to have an extension
|
||||
/// of `.rs`.
|
||||
fn ext(&self) -> Option<OsString> {
|
||||
fn ext(&self) -> Option<String> {
|
||||
if self.opts.case_insensitive {
|
||||
return None;
|
||||
}
|
||||
@@ -305,11 +319,11 @@ impl Glob {
|
||||
Some(&Token::Literal('.')) => {}
|
||||
_ => return None,
|
||||
}
|
||||
let mut lit = OsStr::new(".").to_os_string();
|
||||
let mut lit = ".".to_string();
|
||||
for t in self.tokens[start + 2..].iter() {
|
||||
match *t {
|
||||
Token::Literal('.') | Token::Literal('/') => return None,
|
||||
Token::Literal(c) => lit.push(c.to_string()),
|
||||
Token::Literal(c) => lit.push(c),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
@@ -323,7 +337,7 @@ impl Glob {
|
||||
/// This is like `ext`, but returns an extension even if it isn't sufficent
|
||||
/// to imply a match. Namely, if an extension is returned, then it is
|
||||
/// necessary but not sufficient for a match.
|
||||
fn required_ext(&self) -> Option<OsString> {
|
||||
fn required_ext(&self) -> Option<String> {
|
||||
if self.opts.case_insensitive {
|
||||
return None;
|
||||
}
|
||||
@@ -346,7 +360,7 @@ impl Glob {
|
||||
None
|
||||
} else {
|
||||
ext.reverse();
|
||||
Some(OsString::from(ext.into_iter().collect::<String>()))
|
||||
Some(ext.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +509,7 @@ impl Glob {
|
||||
Some(&self.tokens[start..])
|
||||
}
|
||||
|
||||
/// Returns the pattern as a literal if and only if the pattern exclusiely
|
||||
/// Returns the pattern as a literal if and only if the pattern exclusively
|
||||
/// matches the basename of a file path *and* is a literal.
|
||||
///
|
||||
/// The basic format of these patterns is `**/{literal}`, where `{literal}`
|
||||
@@ -530,16 +544,23 @@ impl<'a> GlobBuilder<'a> {
|
||||
/// Parses and builds the pattern.
|
||||
pub fn build(&self) -> Result<Glob, Error> {
|
||||
let mut p = Parser {
|
||||
glob: &self.glob,
|
||||
stack: vec![Tokens::default()],
|
||||
chars: self.glob.chars().peekable(),
|
||||
prev: None,
|
||||
cur: None,
|
||||
};
|
||||
try!(p.parse());
|
||||
p.parse()?;
|
||||
if p.stack.is_empty() {
|
||||
Err(Error::UnopenedAlternates)
|
||||
Err(Error {
|
||||
glob: Some(self.glob.to_string()),
|
||||
kind: ErrorKind::UnopenedAlternates,
|
||||
})
|
||||
} else if p.stack.len() > 1 {
|
||||
Err(Error::UnclosedAlternates)
|
||||
Err(Error {
|
||||
glob: Some(self.glob.to_string()),
|
||||
kind: ErrorKind::UnclosedAlternates,
|
||||
})
|
||||
} else {
|
||||
let tokens = p.stack.pop().unwrap();
|
||||
Ok(Glob {
|
||||
@@ -645,9 +666,18 @@ impl Tokens {
|
||||
for pat in patterns {
|
||||
let mut altre = String::new();
|
||||
self.tokens_to_regex(options, &pat, &mut altre);
|
||||
parts.push(altre);
|
||||
if !altre.is_empty() {
|
||||
parts.push(altre);
|
||||
}
|
||||
}
|
||||
|
||||
// It is possible to have an empty set in which case the
|
||||
// resulting alternation '()' would be an error.
|
||||
if !parts.is_empty() {
|
||||
re.push('(');
|
||||
re.push_str(&parts.join("|"));
|
||||
re.push(')');
|
||||
}
|
||||
re.push_str(&parts.join("|"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,7 +696,7 @@ fn bytes_to_escaped_literal(bs: &[u8]) -> String {
|
||||
let mut s = String::with_capacity(bs.len());
|
||||
for &b in bs {
|
||||
if b <= 0x7F {
|
||||
s.push_str(®ex::quote(&(b as char).to_string()));
|
||||
s.push_str(®ex::escape(&(b as char).to_string()));
|
||||
} else {
|
||||
s.push_str(&format!("\\x{:02x}", b));
|
||||
}
|
||||
@@ -675,6 +705,7 @@ fn bytes_to_escaped_literal(bs: &[u8]) -> String {
|
||||
}
|
||||
|
||||
struct Parser<'a> {
|
||||
glob: &'a str,
|
||||
stack: Vec<Tokens>,
|
||||
chars: iter::Peekable<str::Chars<'a>>,
|
||||
prev: Option<char>,
|
||||
@@ -682,21 +713,25 @@ struct Parser<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
fn error(&self, kind: ErrorKind) -> Error {
|
||||
Error { glob: Some(self.glob.to_string()), kind: kind }
|
||||
}
|
||||
|
||||
fn parse(&mut self) -> Result<(), Error> {
|
||||
while let Some(c) = self.bump() {
|
||||
match c {
|
||||
'?' => try!(self.push_token(Token::Any)),
|
||||
'*' => try!(self.parse_star()),
|
||||
'[' => try!(self.parse_class()),
|
||||
'{' => try!(self.push_alternate()),
|
||||
'}' => try!(self.pop_alternate()),
|
||||
',' => try!(self.parse_comma()),
|
||||
'?' => self.push_token(Token::Any)?,
|
||||
'*' => self.parse_star()?,
|
||||
'[' => self.parse_class()?,
|
||||
'{' => self.push_alternate()?,
|
||||
'}' => self.pop_alternate()?,
|
||||
',' => self.parse_comma()?,
|
||||
c => {
|
||||
if is_separator(c) {
|
||||
// Normalize all patterns to use / as a separator.
|
||||
try!(self.push_token(Token::Literal('/')))
|
||||
self.push_token(Token::Literal('/'))?
|
||||
} else {
|
||||
try!(self.push_token(Token::Literal(c)))
|
||||
self.push_token(Token::Literal(c))?
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,7 +741,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
fn push_alternate(&mut self) -> Result<(), Error> {
|
||||
if self.stack.len() > 1 {
|
||||
return Err(Error::NestedAlternates);
|
||||
return Err(self.error(ErrorKind::NestedAlternates));
|
||||
}
|
||||
Ok(self.stack.push(Tokens::default()))
|
||||
}
|
||||
@@ -720,22 +755,22 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
fn push_token(&mut self, tok: Token) -> Result<(), Error> {
|
||||
match self.stack.last_mut() {
|
||||
None => Err(Error::UnopenedAlternates),
|
||||
Some(ref mut pat) => Ok(pat.push(tok)),
|
||||
if let Some(ref mut pat) = self.stack.last_mut() {
|
||||
return Ok(pat.push(tok));
|
||||
}
|
||||
Err(self.error(ErrorKind::UnopenedAlternates))
|
||||
}
|
||||
|
||||
fn pop_token(&mut self) -> Result<Token, Error> {
|
||||
match self.stack.last_mut() {
|
||||
None => Err(Error::UnopenedAlternates),
|
||||
Some(ref mut pat) => Ok(pat.pop().unwrap()),
|
||||
if let Some(ref mut pat) = self.stack.last_mut() {
|
||||
return Ok(pat.pop().unwrap());
|
||||
}
|
||||
Err(self.error(ErrorKind::UnopenedAlternates))
|
||||
}
|
||||
|
||||
fn have_tokens(&self) -> Result<bool, Error> {
|
||||
match self.stack.last() {
|
||||
None => Err(Error::UnopenedAlternates),
|
||||
None => Err(self.error(ErrorKind::UnopenedAlternates)),
|
||||
Some(ref pat) => Ok(!pat.is_empty()),
|
||||
}
|
||||
}
|
||||
@@ -754,23 +789,23 @@ impl<'a> Parser<'a> {
|
||||
fn parse_star(&mut self) -> Result<(), Error> {
|
||||
let prev = self.prev;
|
||||
if self.chars.peek() != Some(&'*') {
|
||||
try!(self.push_token(Token::ZeroOrMore));
|
||||
self.push_token(Token::ZeroOrMore)?;
|
||||
return Ok(());
|
||||
}
|
||||
assert!(self.bump() == Some('*'));
|
||||
if !try!(self.have_tokens()) {
|
||||
try!(self.push_token(Token::RecursivePrefix));
|
||||
if !self.have_tokens()? {
|
||||
self.push_token(Token::RecursivePrefix)?;
|
||||
let next = self.bump();
|
||||
if !next.map(is_separator).unwrap_or(true) {
|
||||
return Err(Error::InvalidRecursive);
|
||||
return Err(self.error(ErrorKind::InvalidRecursive));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
try!(self.pop_token());
|
||||
self.pop_token()?;
|
||||
if !prev.map(is_separator).unwrap_or(false) {
|
||||
if self.stack.len() <= 1
|
||||
|| (prev != Some(',') && prev != Some('{')) {
|
||||
return Err(Error::InvalidRecursive);
|
||||
return Err(self.error(ErrorKind::InvalidRecursive));
|
||||
}
|
||||
}
|
||||
match self.chars.peek() {
|
||||
@@ -785,28 +820,35 @@ impl<'a> Parser<'a> {
|
||||
assert!(self.bump().map(is_separator).unwrap_or(false));
|
||||
self.push_token(Token::RecursiveZeroOrMore)
|
||||
}
|
||||
_ => Err(Error::InvalidRecursive),
|
||||
_ => Err(self.error(ErrorKind::InvalidRecursive)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_class(&mut self) -> Result<(), Error> {
|
||||
fn add_to_last_range(
|
||||
glob: &str,
|
||||
r: &mut (char, char),
|
||||
add: char,
|
||||
) -> Result<(), Error> {
|
||||
r.1 = add;
|
||||
if r.1 < r.0 {
|
||||
Err(Error::InvalidRange(r.0, r.1))
|
||||
Err(Error {
|
||||
glob: Some(glob.to_string()),
|
||||
kind: ErrorKind::InvalidRange(r.0, r.1),
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
let mut negated = false;
|
||||
let mut ranges = vec![];
|
||||
if self.chars.peek() == Some(&'!') {
|
||||
assert!(self.bump() == Some('!'));
|
||||
negated = true;
|
||||
}
|
||||
let negated = match self.chars.peek() {
|
||||
Some(&'!') | Some(&'^') => {
|
||||
let bump = self.bump();
|
||||
assert!(bump == Some('!') || bump == Some('^'));
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let mut first = true;
|
||||
let mut in_range = false;
|
||||
loop {
|
||||
@@ -814,7 +856,7 @@ impl<'a> Parser<'a> {
|
||||
Some(c) => c,
|
||||
// The only way to successfully break this loop is to observe
|
||||
// a ']'.
|
||||
None => return Err(Error::UnclosedClass),
|
||||
None => return Err(self.error(ErrorKind::UnclosedClass)),
|
||||
};
|
||||
match c {
|
||||
']' => {
|
||||
@@ -831,7 +873,7 @@ impl<'a> Parser<'a> {
|
||||
// invariant: in_range is only set when there is
|
||||
// already at least one character seen.
|
||||
let r = ranges.last_mut().unwrap();
|
||||
try!(add_to_last_range(r, '-'));
|
||||
add_to_last_range(&self.glob, r, '-')?;
|
||||
in_range = false;
|
||||
} else {
|
||||
assert!(!ranges.is_empty());
|
||||
@@ -842,7 +884,8 @@ impl<'a> Parser<'a> {
|
||||
if in_range {
|
||||
// invariant: in_range is only set when there is
|
||||
// already at least one character seen.
|
||||
try!(add_to_last_range(ranges.last_mut().unwrap(), c));
|
||||
add_to_last_range(
|
||||
&self.glob, ranges.last_mut().unwrap(), c)?;
|
||||
} else {
|
||||
ranges.push((c, c));
|
||||
}
|
||||
@@ -884,9 +927,7 @@ fn ends_with(needle: &[u8], haystack: &[u8]) -> bool {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::ffi::{OsStr, OsString};
|
||||
|
||||
use {GlobSetBuilder, Error};
|
||||
use {GlobSetBuilder, ErrorKind};
|
||||
use super::{Glob, GlobBuilder, Token};
|
||||
use super::Token::*;
|
||||
|
||||
@@ -911,7 +952,7 @@ mod tests {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let err = Glob::new($pat).unwrap_err();
|
||||
assert_eq!($err, err);
|
||||
assert_eq!(&$err, err.kind());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,7 +1019,6 @@ mod tests {
|
||||
}
|
||||
|
||||
fn s(string: &str) -> String { string.to_string() }
|
||||
fn os(string: &str) -> OsString { OsStr::new(string).to_os_string() }
|
||||
|
||||
fn class(s: char, e: char) -> Token {
|
||||
Class { negated: false, ranges: vec![(s, e)] }
|
||||
@@ -1033,20 +1073,22 @@ mod tests {
|
||||
syntax!(cls17, "[a-z0-9]", vec![rclass(&[('a', 'z'), ('0', '9')])]);
|
||||
syntax!(cls18, "[!0-9a-z]", vec![rclassn(&[('0', '9'), ('a', 'z')])]);
|
||||
syntax!(cls19, "[!a-z0-9]", vec![rclassn(&[('a', 'z'), ('0', '9')])]);
|
||||
syntax!(cls20, "[^a]", vec![classn('a', 'a')]);
|
||||
syntax!(cls21, "[^a-z]", vec![classn('a', 'z')]);
|
||||
|
||||
syntaxerr!(err_rseq1, "a**", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq2, "**a", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq3, "a**b", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq4, "***", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq5, "/a**", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq6, "/**a", Error::InvalidRecursive);
|
||||
syntaxerr!(err_rseq7, "/a**b", Error::InvalidRecursive);
|
||||
syntaxerr!(err_unclosed1, "[", Error::UnclosedClass);
|
||||
syntaxerr!(err_unclosed2, "[]", Error::UnclosedClass);
|
||||
syntaxerr!(err_unclosed3, "[!", Error::UnclosedClass);
|
||||
syntaxerr!(err_unclosed4, "[!]", Error::UnclosedClass);
|
||||
syntaxerr!(err_range1, "[z-a]", Error::InvalidRange('z', 'a'));
|
||||
syntaxerr!(err_range2, "[z--]", Error::InvalidRange('z', '-'));
|
||||
syntaxerr!(err_rseq1, "a**", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq2, "**a", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq3, "a**b", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq4, "***", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq5, "/a**", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq6, "/**a", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_rseq7, "/a**b", ErrorKind::InvalidRecursive);
|
||||
syntaxerr!(err_unclosed1, "[", ErrorKind::UnclosedClass);
|
||||
syntaxerr!(err_unclosed2, "[]", ErrorKind::UnclosedClass);
|
||||
syntaxerr!(err_unclosed3, "[!", ErrorKind::UnclosedClass);
|
||||
syntaxerr!(err_unclosed4, "[!]", ErrorKind::UnclosedClass);
|
||||
syntaxerr!(err_range1, "[z-a]", ErrorKind::InvalidRange('z', 'a'));
|
||||
syntaxerr!(err_range2, "[z--]", ErrorKind::InvalidRange('z', '-'));
|
||||
|
||||
const CASEI: Options = Options {
|
||||
casei: true,
|
||||
@@ -1110,6 +1152,7 @@ mod tests {
|
||||
matches!(matchrec22, ".*/**", ".abc/abc");
|
||||
matches!(matchrec23, "foo/**", "foo");
|
||||
matches!(matchrec24, "**/foo/bar", "foo/bar");
|
||||
matches!(matchrec25, "some/*/needle.txt", "some/one/needle.txt");
|
||||
|
||||
matches!(matchrange1, "a[0-9]b", "a0b");
|
||||
matches!(matchrange2, "a[0-9]b", "a9b");
|
||||
@@ -1122,6 +1165,7 @@ mod tests {
|
||||
matches!(matchrange9, "[-a-c]", "b");
|
||||
matches!(matchrange10, "[a-c-]", "b");
|
||||
matches!(matchrange11, "[-]", "-");
|
||||
matches!(matchrange12, "a[^0-9]b", "a_b");
|
||||
|
||||
matches!(matchpat1, "*hello.txt", "hello.txt");
|
||||
matches!(matchpat2, "*hello.txt", "gareth_says_hello.txt");
|
||||
@@ -1194,6 +1238,16 @@ mod tests {
|
||||
nmatches!(matchnot25, "*.c", "mozilla-sha1/sha1.c", SLASHLIT);
|
||||
nmatches!(matchnot26, "**/m4/ltoptions.m4",
|
||||
"csharp/src/packages/repositories.config", SLASHLIT);
|
||||
nmatches!(matchnot27, "a[^0-9]b", "a0b");
|
||||
nmatches!(matchnot28, "a[^0-9]b", "a9b");
|
||||
nmatches!(matchnot29, "[^-]", "-");
|
||||
nmatches!(matchnot30, "some/*/needle.txt", "some/needle.txt");
|
||||
nmatches!(
|
||||
matchrec31,
|
||||
"some/*/needle.txt", "some/one/two/needle.txt", SLASHLIT);
|
||||
nmatches!(
|
||||
matchrec32,
|
||||
"some/*/needle.txt", "some/one/two/three/needle.txt", SLASHLIT);
|
||||
|
||||
macro_rules! extract {
|
||||
($which:ident, $name:ident, $pat:expr, $expect:expr) => {
|
||||
@@ -1262,19 +1316,19 @@ mod tests {
|
||||
Literal('f'), Literal('o'), ZeroOrMore, Literal('o'),
|
||||
]), SLASHLIT);
|
||||
|
||||
ext!(extract_ext1, "**/*.rs", Some(os(".rs")));
|
||||
ext!(extract_ext1, "**/*.rs", Some(s(".rs")));
|
||||
ext!(extract_ext2, "**/*.rs.bak", None);
|
||||
ext!(extract_ext3, "*.rs", Some(os(".rs")));
|
||||
ext!(extract_ext3, "*.rs", Some(s(".rs")));
|
||||
ext!(extract_ext4, "a*.rs", None);
|
||||
ext!(extract_ext5, "/*.c", None);
|
||||
ext!(extract_ext6, "*.c", None, SLASHLIT);
|
||||
ext!(extract_ext7, "*.c", Some(os(".c")));
|
||||
ext!(extract_ext7, "*.c", Some(s(".c")));
|
||||
|
||||
required_ext!(extract_req_ext1, "*.rs", Some(os(".rs")));
|
||||
required_ext!(extract_req_ext2, "/foo/bar/*.rs", Some(os(".rs")));
|
||||
required_ext!(extract_req_ext3, "/foo/bar/*.rs", Some(os(".rs")));
|
||||
required_ext!(extract_req_ext4, "/foo/bar/.rs", Some(os(".rs")));
|
||||
required_ext!(extract_req_ext5, ".rs", Some(os(".rs")));
|
||||
required_ext!(extract_req_ext1, "*.rs", Some(s(".rs")));
|
||||
required_ext!(extract_req_ext2, "/foo/bar/*.rs", Some(s(".rs")));
|
||||
required_ext!(extract_req_ext3, "/foo/bar/*.rs", Some(s(".rs")));
|
||||
required_ext!(extract_req_ext4, "/foo/bar/.rs", Some(s(".rs")));
|
||||
required_ext!(extract_req_ext5, ".rs", Some(s(".rs")));
|
||||
required_ext!(extract_req_ext6, "./rs", None);
|
||||
required_ext!(extract_req_ext7, "foo", None);
|
||||
required_ext!(extract_req_ext8, ".foo/", None);
|
||||
|
||||
@@ -14,8 +14,6 @@ src/**/foo.rs
|
||||
and a path `src/bar/baz/foo.rs`, then the set would report the first and third
|
||||
globs as matching.
|
||||
|
||||
Single glob matching is also provided and is done by converting globs to
|
||||
|
||||
# Example: one glob
|
||||
|
||||
This example shows how to match a single glob against a single file path.
|
||||
@@ -24,7 +22,7 @@ This example shows how to match a single glob against a single file path.
|
||||
# fn example() -> Result<(), globset::Error> {
|
||||
use globset::Glob;
|
||||
|
||||
let glob = try!(Glob::new("*.rs")).compile_matcher();
|
||||
let glob = Glob::new("*.rs")?.compile_matcher();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(glob.is_match("foo/bar.rs"));
|
||||
@@ -41,8 +39,8 @@ semantics. In this example, we prevent wildcards from matching path separators.
|
||||
# fn example() -> Result<(), globset::Error> {
|
||||
use globset::GlobBuilder;
|
||||
|
||||
let glob = try!(GlobBuilder::new("*.rs")
|
||||
.literal_separator(true).build()).compile_matcher();
|
||||
let glob = GlobBuilder::new("*.rs")
|
||||
.literal_separator(true).build()?.compile_matcher();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(!glob.is_match("foo/bar.rs")); // no longer matches
|
||||
@@ -61,10 +59,10 @@ use globset::{Glob, GlobSetBuilder};
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
// A GlobBuilder can be used to configure each glob's match semantics
|
||||
// independently.
|
||||
builder.add(try!(Glob::new("*.rs")));
|
||||
builder.add(try!(Glob::new("src/lib.rs")));
|
||||
builder.add(try!(Glob::new("src/**/foo.rs")));
|
||||
let set = try!(builder.build());
|
||||
builder.add(Glob::new("*.rs")?);
|
||||
builder.add(Glob::new("src/lib.rs")?);
|
||||
builder.add(Glob::new("src/**/foo.rs")?);
|
||||
let set = builder.build()?;
|
||||
|
||||
assert_eq!(set.matches("src/bar/baz/foo.rs"), vec![0, 2]);
|
||||
# Ok(()) } example().unwrap();
|
||||
@@ -103,8 +101,6 @@ or to enable case insensitive matching.
|
||||
extern crate aho_corasick;
|
||||
extern crate fnv;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate memchr;
|
||||
extern crate regex;
|
||||
@@ -112,7 +108,7 @@ extern crate regex;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::error::Error as StdError;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::path::Path;
|
||||
@@ -130,16 +126,18 @@ pub use glob::{Glob, GlobBuilder, GlobMatcher};
|
||||
mod glob;
|
||||
mod pathutil;
|
||||
|
||||
macro_rules! eprintln {
|
||||
($($tt:tt)*) => {{
|
||||
use std::io::Write;
|
||||
let _ = writeln!(&mut ::std::io::stderr(), $($tt)*);
|
||||
}}
|
||||
}
|
||||
|
||||
/// Represents an error that can occur when parsing a glob pattern.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
pub struct Error {
|
||||
/// The original glob provided by the caller.
|
||||
glob: Option<String>,
|
||||
/// The kind of error.
|
||||
kind: ErrorKind,
|
||||
}
|
||||
|
||||
/// The kind of error that can occur when parsing a glob pattern.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ErrorKind {
|
||||
/// Occurs when a use of `**` is invalid. Namely, `**` can only appear
|
||||
/// adjacent to a path separator, or the beginning/end of a glob.
|
||||
InvalidRecursive,
|
||||
@@ -161,45 +159,74 @@ pub enum Error {
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
self.kind.description()
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
/// Return the glob that caused this error, if one exists.
|
||||
pub fn glob(&self) -> Option<&str> {
|
||||
self.glob.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// Return the kind of this error.
|
||||
pub fn kind(&self) -> &ErrorKind {
|
||||
&self.kind
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::InvalidRecursive => {
|
||||
ErrorKind::InvalidRecursive => {
|
||||
"invalid use of **; must be one path component"
|
||||
}
|
||||
Error::UnclosedClass => {
|
||||
ErrorKind::UnclosedClass => {
|
||||
"unclosed character class; missing ']'"
|
||||
}
|
||||
Error::InvalidRange(_, _) => {
|
||||
ErrorKind::InvalidRange(_, _) => {
|
||||
"invalid character range"
|
||||
}
|
||||
Error::UnopenedAlternates => {
|
||||
ErrorKind::UnopenedAlternates => {
|
||||
"unopened alternate group; missing '{' \
|
||||
(maybe escape '}' with '[}]'?)"
|
||||
}
|
||||
Error::UnclosedAlternates => {
|
||||
ErrorKind::UnclosedAlternates => {
|
||||
"unclosed alternate group; missing '}' \
|
||||
(maybe escape '{' with '[{]'?)"
|
||||
}
|
||||
Error::NestedAlternates => {
|
||||
ErrorKind::NestedAlternates => {
|
||||
"nested alternate groups are not allowed"
|
||||
}
|
||||
Error::Regex(ref err) => err,
|
||||
ErrorKind::Regex(ref err) => err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.glob {
|
||||
None => self.kind.fmt(f),
|
||||
Some(ref glob) => {
|
||||
write!(f, "error parsing glob '{}': {}", glob, self.kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ErrorKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::InvalidRecursive
|
||||
| Error::UnclosedClass
|
||||
| Error::UnopenedAlternates
|
||||
| Error::UnclosedAlternates
|
||||
| Error::NestedAlternates
|
||||
| Error::Regex(_) => {
|
||||
ErrorKind::InvalidRecursive
|
||||
| ErrorKind::UnclosedClass
|
||||
| ErrorKind::UnopenedAlternates
|
||||
| ErrorKind::UnclosedAlternates
|
||||
| ErrorKind::NestedAlternates
|
||||
| ErrorKind::Regex(_) => {
|
||||
write!(f, "{}", self.description())
|
||||
}
|
||||
Error::InvalidRange(s, e) => {
|
||||
ErrorKind::InvalidRange(s, e) => {
|
||||
write!(f, "invalid range; '{}' > '{}'", s, e)
|
||||
}
|
||||
}
|
||||
@@ -211,13 +238,23 @@ fn new_regex(pat: &str) -> Result<Regex, Error> {
|
||||
.dot_matches_new_line(true)
|
||||
.size_limit(10 * (1 << 20))
|
||||
.dfa_size_limit(10 * (1 << 20))
|
||||
.compile()
|
||||
.map_err(|err| Error::Regex(err.to_string()))
|
||||
.build()
|
||||
.map_err(|err| {
|
||||
Error {
|
||||
glob: Some(pat.to_string()),
|
||||
kind: ErrorKind::Regex(err.to_string()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn new_regex_set<I, S>(pats: I) -> Result<RegexSet, Error>
|
||||
where S: AsRef<str>, I: IntoIterator<Item=S> {
|
||||
RegexSet::new(pats).map_err(|err| Error::Regex(err.to_string()))
|
||||
RegexSet::new(pats).map_err(|err| {
|
||||
Error {
|
||||
glob: None,
|
||||
kind: ErrorKind::Regex(err.to_string()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type Fnv = hash::BuildHasherDefault<fnv::FnvHasher>;
|
||||
@@ -375,8 +412,8 @@ impl GlobSet {
|
||||
GlobSetMatchStrategy::Suffix(suffixes.suffix()),
|
||||
GlobSetMatchStrategy::Prefix(prefixes.prefix()),
|
||||
GlobSetMatchStrategy::RequiredExtension(
|
||||
try!(required_exts.build())),
|
||||
GlobSetMatchStrategy::Regex(try!(regexes.regex_set())),
|
||||
required_exts.build()?),
|
||||
GlobSetMatchStrategy::Regex(regexes.regex_set()?),
|
||||
],
|
||||
})
|
||||
}
|
||||
@@ -421,7 +458,7 @@ impl GlobSetBuilder {
|
||||
pub struct Candidate<'a> {
|
||||
path: Cow<'a, [u8]>,
|
||||
basename: Cow<'a, [u8]>,
|
||||
ext: &'a OsStr,
|
||||
ext: Cow<'a, [u8]>,
|
||||
}
|
||||
|
||||
impl<'a> Candidate<'a> {
|
||||
@@ -432,7 +469,7 @@ impl<'a> Candidate<'a> {
|
||||
Candidate {
|
||||
path: normalize_path(path_bytes(path)),
|
||||
basename: os_str_bytes(basename),
|
||||
ext: file_name_ext(basename).unwrap_or(OsStr::new("")),
|
||||
ext: file_name_ext(basename).unwrap_or(Cow::Borrowed(b"")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,22 +584,22 @@ impl BasenameLiteralStrategy {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ExtensionStrategy(HashMap<OsString, Vec<usize>, Fnv>);
|
||||
struct ExtensionStrategy(HashMap<Vec<u8>, Vec<usize>, Fnv>);
|
||||
|
||||
impl ExtensionStrategy {
|
||||
fn new() -> ExtensionStrategy {
|
||||
ExtensionStrategy(HashMap::with_hasher(Fnv::default()))
|
||||
}
|
||||
|
||||
fn add(&mut self, global_index: usize, ext: OsString) {
|
||||
self.0.entry(ext).or_insert(vec![]).push(global_index);
|
||||
fn add(&mut self, global_index: usize, ext: String) {
|
||||
self.0.entry(ext.into_bytes()).or_insert(vec![]).push(global_index);
|
||||
}
|
||||
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
if candidate.ext.is_empty() {
|
||||
return false;
|
||||
}
|
||||
self.0.contains_key(candidate.ext)
|
||||
self.0.contains_key(&*candidate.ext)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
@@ -570,7 +607,7 @@ impl ExtensionStrategy {
|
||||
if candidate.ext.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(hits) = self.0.get(candidate.ext) {
|
||||
if let Some(hits) = self.0.get(&*candidate.ext) {
|
||||
matches.extend(hits);
|
||||
}
|
||||
}
|
||||
@@ -633,14 +670,14 @@ impl SuffixStrategy {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct RequiredExtensionStrategy(HashMap<OsString, Vec<(usize, Regex)>, Fnv>);
|
||||
struct RequiredExtensionStrategy(HashMap<Vec<u8>, Vec<(usize, Regex)>, Fnv>);
|
||||
|
||||
impl RequiredExtensionStrategy {
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
if candidate.ext.is_empty() {
|
||||
return false;
|
||||
}
|
||||
match self.0.get(candidate.ext) {
|
||||
match self.0.get(&*candidate.ext) {
|
||||
None => false,
|
||||
Some(regexes) => {
|
||||
for &(_, ref re) in regexes {
|
||||
@@ -658,7 +695,7 @@ impl RequiredExtensionStrategy {
|
||||
if candidate.ext.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(regexes) = self.0.get(candidate.ext) {
|
||||
if let Some(regexes) = self.0.get(&*candidate.ext) {
|
||||
for &(global_index, ref re) in regexes {
|
||||
if re.is_match(&*candidate.path) {
|
||||
matches.push(global_index);
|
||||
@@ -730,7 +767,7 @@ impl MultiStrategyBuilder {
|
||||
|
||||
fn regex_set(self) -> Result<RegexSetStrategy, Error> {
|
||||
Ok(RegexSetStrategy {
|
||||
matcher: try!(new_regex_set(self.literals)),
|
||||
matcher: new_regex_set(self.literals)?,
|
||||
map: self.map,
|
||||
})
|
||||
}
|
||||
@@ -738,7 +775,7 @@ impl MultiStrategyBuilder {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct RequiredExtensionStrategyBuilder(
|
||||
HashMap<OsString, Vec<(usize, String)>>,
|
||||
HashMap<Vec<u8>, Vec<(usize, String)>>,
|
||||
);
|
||||
|
||||
impl RequiredExtensionStrategyBuilder {
|
||||
@@ -746,8 +783,11 @@ impl RequiredExtensionStrategyBuilder {
|
||||
RequiredExtensionStrategyBuilder(HashMap::new())
|
||||
}
|
||||
|
||||
fn add(&mut self, global_index: usize, ext: OsString, regex: String) {
|
||||
self.0.entry(ext).or_insert(vec![]).push((global_index, regex));
|
||||
fn add(&mut self, global_index: usize, ext: String, regex: String) {
|
||||
self.0
|
||||
.entry(ext.into_bytes())
|
||||
.or_insert(vec![])
|
||||
.push((global_index, regex));
|
||||
}
|
||||
|
||||
fn build(self) -> Result<RequiredExtensionStrategy, Error> {
|
||||
@@ -755,7 +795,7 @@ impl RequiredExtensionStrategyBuilder {
|
||||
for (ext, regexes) in self.0.into_iter() {
|
||||
exts.insert(ext.clone(), vec![]);
|
||||
for (global_index, regex) in regexes {
|
||||
let compiled = try!(new_regex(®ex));
|
||||
let compiled = new_regex(®ex)?;
|
||||
exts.get_mut(&ext).unwrap().push((global_index, compiled));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,34 +54,28 @@ pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
/// a pattern like `*.rs` is obviously trying to match files with a `rs`
|
||||
/// extension, but it also matches files like `.rs`, which doesn't have an
|
||||
/// extension according to std::path::Path::extension.
|
||||
pub fn file_name_ext(name: &OsStr) -> Option<&OsStr> {
|
||||
// Yes, these functions are awful, and yes, we are completely violating
|
||||
// the abstraction barrier of std::ffi. The barrier we're violating is
|
||||
// that an OsStr's encoding is *ASCII compatible*. While this is obviously
|
||||
// true on Unix systems, it's also true on Windows because an OsStr uses
|
||||
// WTF-8 internally: https://simonsapin.github.io/wtf-8/
|
||||
//
|
||||
// We should consider doing the same for the other path utility functions.
|
||||
// Right now, we don't break any barriers, but Windows users are paying
|
||||
// for it.
|
||||
//
|
||||
// Got any better ideas that don't cost anything? Hit me up. ---AG
|
||||
unsafe fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
|
||||
::std::mem::transmute(s)
|
||||
}
|
||||
unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
|
||||
::std::mem::transmute(s)
|
||||
}
|
||||
pub fn file_name_ext(name: &OsStr) -> Option<Cow<[u8]>> {
|
||||
if name.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let name = unsafe { os_str_as_u8_slice(name) };
|
||||
for (i, &b) in name.iter().enumerate().rev() {
|
||||
if b == b'.' {
|
||||
return Some(unsafe { u8_slice_as_os_str(&name[i..]) });
|
||||
let name = os_str_bytes(name);
|
||||
let last_dot_at = {
|
||||
let result = name
|
||||
.iter().enumerate().rev()
|
||||
.find(|&(_, &b)| b == b'.')
|
||||
.map(|(i, _)| i);
|
||||
match result {
|
||||
None => return None,
|
||||
Some(i) => i,
|
||||
}
|
||||
}
|
||||
None
|
||||
};
|
||||
Some(match name {
|
||||
Cow::Borrowed(name) => Cow::Borrowed(&name[last_dot_at..]),
|
||||
Cow::Owned(mut name) => {
|
||||
name.drain(..last_dot_at);
|
||||
Cow::Owned(name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Return raw bytes of a path, transcoded to UTF-8 if necessary.
|
||||
@@ -144,7 +138,7 @@ mod tests {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let got = file_name_ext(OsStr::new($file_name));
|
||||
assert_eq!($ext.map(OsStr::new), got);
|
||||
assert_eq!($ext.map(|s| Cow::Borrowed(s.as_bytes())), got);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
3
grep/COPYING
Normal file
3
grep/COPYING
Normal file
@@ -0,0 +1,3 @@
|
||||
This project is dual-licensed under the Unlicense and MIT licenses.
|
||||
|
||||
You may use this code under the terms of either license.
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "grep"
|
||||
version = "0.1.3" #:version
|
||||
version = "0.1.8" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Fast line oriented regex searching as a library.
|
||||
@@ -13,8 +13,7 @@ keywords = ["regex", "grep", "egrep", "search", "pattern"]
|
||||
license = "Unlicense/MIT"
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.5"
|
||||
regex = "0.1.77"
|
||||
regex-syntax = "0.3.5"
|
||||
log = "0.4"
|
||||
memchr = "2"
|
||||
regex = "0.2.1"
|
||||
regex-syntax = "0.4.0"
|
||||
|
||||
21
grep/LICENSE-MIT
Normal file
21
grep/LICENSE-MIT
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
24
grep/UNLICENSE
Normal file
24
grep/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@@ -78,6 +78,6 @@ impl From<regex::Error> for Error {
|
||||
|
||||
impl From<syntax::Error> for Error {
|
||||
fn from(err: syntax::Error) -> Error {
|
||||
Error::Regex(regex::Error::Syntax(err))
|
||||
Error::Regex(regex::Error::Syntax(err.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ principled.
|
||||
*/
|
||||
use std::cmp;
|
||||
|
||||
use regex::bytes::Regex;
|
||||
use regex::bytes::RegexBuilder;
|
||||
use syntax::{
|
||||
Expr, Literals, Lit,
|
||||
ByteClass, ByteRange, CharClass, ClassRange, Repeater,
|
||||
@@ -33,7 +33,7 @@ impl LiteralSets {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_regex(&self) -> Option<Regex> {
|
||||
pub fn to_regex_builder(&self) -> Option<RegexBuilder> {
|
||||
if self.prefixes.all_complete() && !self.prefixes.is_empty() {
|
||||
debug!("literal prefixes detected: {:?}", self.prefixes);
|
||||
// When this is true, the regex engine will do a literal scan.
|
||||
@@ -79,14 +79,16 @@ impl LiteralSets {
|
||||
debug!("required literals found: {:?}", req_lits);
|
||||
let alts: Vec<String> =
|
||||
req_lits.into_iter().map(|x| bytes_to_regex(x)).collect();
|
||||
// Literals always compile.
|
||||
Some(Regex::new(&alts.join("|")).unwrap())
|
||||
let mut builder = RegexBuilder::new(&alts.join("|"));
|
||||
builder.unicode(false);
|
||||
Some(builder)
|
||||
} else if lit.is_empty() {
|
||||
None
|
||||
} else {
|
||||
// Literals always compile.
|
||||
debug!("required literal found: {:?}", show(lit));
|
||||
Some(Regex::new(&bytes_to_regex(lit)).unwrap())
|
||||
let mut builder = RegexBuilder::new(&bytes_to_regex(&lit));
|
||||
builder.unicode(false);
|
||||
Some(builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,25 +44,23 @@ pub fn remove(expr: Expr, byte: u8) -> Result<Expr> {
|
||||
}
|
||||
Group { e, i, name } => {
|
||||
Group {
|
||||
e: Box::new(try!(remove(*e, byte))),
|
||||
e: Box::new(remove(*e, byte)?),
|
||||
i: i,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
Repeat { e, r, greedy } => {
|
||||
Repeat {
|
||||
e: Box::new(try!(remove(*e, byte))),
|
||||
e: Box::new(remove(*e, byte)?),
|
||||
r: r,
|
||||
greedy: greedy,
|
||||
}
|
||||
}
|
||||
Concat(exprs) => {
|
||||
Concat(try!(
|
||||
exprs.into_iter().map(|e| remove(e, byte)).collect()))
|
||||
Concat(exprs.into_iter().map(|e| remove(e, byte)).collect::<Result<Vec<Expr>>>()?)
|
||||
}
|
||||
Alternate(exprs) => {
|
||||
Alternate(try!(
|
||||
exprs.into_iter().map(|e| remove(e, byte)).collect()))
|
||||
Alternate(exprs.into_iter().map(|e| remove(e, byte)).collect::<Result<Vec<Expr>>>()?)
|
||||
}
|
||||
e => e,
|
||||
})
|
||||
|
||||
@@ -102,9 +102,9 @@ impl GrepBuilder {
|
||||
|
||||
/// Whether to enable smart case search or not (disabled by default).
|
||||
///
|
||||
/// Smart case uses case insensitive search if the regex is contains all
|
||||
/// lowercase literal characters. Otherwise, a case sensitive search is
|
||||
/// used instead.
|
||||
/// Smart case uses case insensitive search if the pattern contains only
|
||||
/// lowercase characters (ignoring any characters which immediately follow
|
||||
/// a '\'). Otherwise, a case sensitive search is used instead.
|
||||
///
|
||||
/// Enabling the case_insensitive flag overrides this.
|
||||
pub fn case_smart(mut self, yes: bool) -> GrepBuilder {
|
||||
@@ -141,17 +141,22 @@ impl GrepBuilder {
|
||||
/// If there was a problem parsing or compiling the regex with the given
|
||||
/// options, then an error is returned.
|
||||
pub fn build(self) -> Result<Grep> {
|
||||
let expr = try!(self.parse());
|
||||
let expr = self.parse()?;
|
||||
let literals = LiteralSets::create(&expr);
|
||||
let re = try!(self.regex(&expr));
|
||||
let required = literals.to_regex().or_else(|| {
|
||||
let expr = match strip_unicode_word_boundaries(&expr) {
|
||||
None => return None,
|
||||
Some(expr) => expr,
|
||||
};
|
||||
debug!("Stripped Unicode word boundaries. New AST:\n{:?}", expr);
|
||||
self.regex(&expr).ok()
|
||||
});
|
||||
let re = self.regex(&expr)?;
|
||||
let required = match literals.to_regex_builder() {
|
||||
Some(builder) => Some(self.regex_build(builder)?),
|
||||
None => {
|
||||
match strip_unicode_word_boundaries(&expr) {
|
||||
None => None,
|
||||
Some(expr) => {
|
||||
debug!("Stripped Unicode word boundaries. \
|
||||
New AST:\n{:?}", expr);
|
||||
self.regex(&expr).ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(Grep {
|
||||
re: re,
|
||||
required: required,
|
||||
@@ -162,16 +167,18 @@ impl GrepBuilder {
|
||||
/// Creates a new regex from the given expression with the current
|
||||
/// configuration.
|
||||
fn regex(&self, expr: &Expr) -> Result<Regex> {
|
||||
let casei =
|
||||
self.opts.case_insensitive
|
||||
|| (self.opts.case_smart && !has_uppercase_literal(expr));
|
||||
RegexBuilder::new(&expr.to_string())
|
||||
.case_insensitive(casei)
|
||||
let mut builder = RegexBuilder::new(&expr.to_string());
|
||||
builder.unicode(true);
|
||||
self.regex_build(builder)
|
||||
}
|
||||
|
||||
/// Builds a new regex from the given builder using the caller's settings.
|
||||
fn regex_build(&self, mut builder: RegexBuilder) -> Result<Regex> {
|
||||
builder
|
||||
.multi_line(true)
|
||||
.unicode(true)
|
||||
.size_limit(self.opts.size_limit)
|
||||
.dfa_size_limit(self.opts.dfa_size_limit)
|
||||
.compile()
|
||||
.build()
|
||||
.map_err(From::from)
|
||||
}
|
||||
|
||||
@@ -179,15 +186,26 @@ impl GrepBuilder {
|
||||
/// the line terminator.
|
||||
fn parse(&self) -> Result<syntax::Expr> {
|
||||
let expr =
|
||||
try!(syntax::ExprBuilder::new()
|
||||
.allow_bytes(true)
|
||||
.unicode(true)
|
||||
.case_insensitive(self.opts.case_insensitive)
|
||||
.parse(&self.pattern));
|
||||
let expr = try!(nonl::remove(expr, self.opts.line_terminator));
|
||||
syntax::ExprBuilder::new()
|
||||
.allow_bytes(true)
|
||||
.unicode(true)
|
||||
.case_insensitive(self.is_case_insensitive()?)
|
||||
.parse(&self.pattern)?;
|
||||
let expr = nonl::remove(expr, self.opts.line_terminator)?;
|
||||
debug!("regex ast:\n{:#?}", expr);
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Determines whether the case insensitive flag should be enabled or not.
|
||||
fn is_case_insensitive(&self) -> Result<bool> {
|
||||
if self.opts.case_insensitive {
|
||||
return Ok(true);
|
||||
}
|
||||
if !self.opts.case_smart {
|
||||
return Ok(false);
|
||||
}
|
||||
Ok(!has_uppercase_literal(&self.pattern))
|
||||
}
|
||||
}
|
||||
|
||||
impl Grep {
|
||||
@@ -292,21 +310,26 @@ impl<'b, 's> Iterator for Iter<'b, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_uppercase_literal(expr: &Expr) -> bool {
|
||||
use syntax::Expr::*;
|
||||
match *expr {
|
||||
Literal { ref chars, casei } => {
|
||||
casei || chars.iter().any(|c| c.is_uppercase())
|
||||
/// Determine whether the pattern contains an uppercase character which should
|
||||
/// negate the effect of the smart-case option.
|
||||
///
|
||||
/// Ideally we would be able to check the AST in order to correctly handle
|
||||
/// things like '\p{Ll}' and '\p{Lu}' (which should be treated as explicitly
|
||||
/// cased), but we don't currently have that option. For now, our 'good enough'
|
||||
/// solution is to simply perform a semi-naïve scan of the input pattern and
|
||||
/// ignore all characters following a '\'. The ExprBuilder will handle any
|
||||
/// actual errors, and this at least lets us support the most common cases,
|
||||
/// like 'foo\w' and 'foo\S', in an intuitive manner.
|
||||
fn has_uppercase_literal(pattern: &str) -> bool {
|
||||
let mut chars = pattern.chars();
|
||||
while let Some(c) = chars.next() {
|
||||
if c == '\\' {
|
||||
chars.next();
|
||||
} else if c.is_uppercase() {
|
||||
return true;
|
||||
}
|
||||
LiteralBytes { ref bytes, casei } => {
|
||||
casei || bytes.iter().any(|&b| b'A' <= b && b <= b'Z')
|
||||
}
|
||||
Group { ref e, .. } => has_uppercase_literal(e),
|
||||
Repeat { ref e, .. } => has_uppercase_literal(e),
|
||||
Concat(ref es) => es.iter().any(has_uppercase_literal),
|
||||
Alternate(ref es) => es.iter().any(has_uppercase_literal),
|
||||
_ => false,
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -316,7 +339,7 @@ mod tests {
|
||||
use memchr::{memchr, memrchr};
|
||||
use regex::bytes::Regex;
|
||||
|
||||
use super::{GrepBuilder, Match};
|
||||
use super::{GrepBuilder, Match, has_uppercase_literal};
|
||||
|
||||
static SHERLOCK: &'static [u8] = include_bytes!("./data/sherlock.txt");
|
||||
|
||||
@@ -328,11 +351,11 @@ mod tests {
|
||||
fn find_lines(pat: &str, haystack: &[u8]) -> Vec<Match> {
|
||||
let re = Regex::new(pat).unwrap();
|
||||
let mut lines = vec![];
|
||||
for (s, e) in re.find_iter(haystack) {
|
||||
let start = memrchr(b'\n', &haystack[..s])
|
||||
for m in re.find_iter(haystack) {
|
||||
let start = memrchr(b'\n', &haystack[..m.start()])
|
||||
.map_or(0, |i| i + 1);
|
||||
let end = memchr(b'\n', &haystack[e..])
|
||||
.map_or(haystack.len(), |i| e + i + 1);
|
||||
let end = memchr(b'\n', &haystack[m.end()..])
|
||||
.map_or(haystack.len(), |i| m.end() + i + 1);
|
||||
lines.push(Match {
|
||||
start: start,
|
||||
end: end,
|
||||
@@ -353,4 +376,20 @@ mod tests {
|
||||
assert_eq!(expected.len(), got.len());
|
||||
assert_eq!(expected, got);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pattern_case() {
|
||||
assert_eq!(has_uppercase_literal(&"".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"Foo".to_string()), true);
|
||||
assert_eq!(has_uppercase_literal(&"foO".to_string()), true);
|
||||
assert_eq!(has_uppercase_literal(&"foo\\\\".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo\\w".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo\\S".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo\\p{Ll}".to_string()), true);
|
||||
assert_eq!(has_uppercase_literal(&"foo[a-z]".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo[A-Z]".to_string()), true);
|
||||
assert_eq!(has_uppercase_literal(&"foo[\\S\\t]".to_string()), false);
|
||||
assert_eq!(has_uppercase_literal(&"foo\\\\S".to_string()), true);
|
||||
}
|
||||
}
|
||||
|
||||
3
ignore/COPYING
Normal file
3
ignore/COPYING
Normal file
@@ -0,0 +1,3 @@
|
||||
This project is dual-licensed under the Unlicense and MIT licenses.
|
||||
|
||||
You may use this code under the terms of either license.
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ignore"
|
||||
version = "0.1.3" #:version
|
||||
version = "0.4.1" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
A fast library for efficiently matching ignore files such as `.gitignore`
|
||||
@@ -18,19 +18,22 @@ name = "ignore"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
globset = { version = "0.1.1", path = "../globset" }
|
||||
lazy_static = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
regex = "0.1.77"
|
||||
thread_local = "0.3.0"
|
||||
walkdir = "1"
|
||||
crossbeam = "0.3"
|
||||
globset = { version = "0.3.0", path = "../globset" }
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
memchr = "2"
|
||||
regex = "0.2.1"
|
||||
same-file = "1"
|
||||
thread_local = "0.3.2"
|
||||
walkdir = "2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = ["std", "winnt"]
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3.5"
|
||||
|
||||
[features]
|
||||
simd-accel = ["globset/simd-accel"]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
21
ignore/LICENSE-MIT
Normal file
21
ignore/LICENSE-MIT
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -20,7 +20,7 @@ Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ignore = "0.1"
|
||||
ignore = "0.3"
|
||||
```
|
||||
|
||||
and this to your crate root:
|
||||
|
||||
24
ignore/UNLICENSE
Normal file
24
ignore/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
@@ -1,28 +1,92 @@
|
||||
/*
|
||||
#![allow(dead_code, unused_imports, unused_mut, unused_variables)]
|
||||
|
||||
extern crate crossbeam;
|
||||
extern crate ignore;
|
||||
extern crate walkdir;
|
||||
|
||||
use std::env;
|
||||
use std::io::{self, Write};
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::thread;
|
||||
|
||||
use ignore::ignore::IgnoreBuilder;
|
||||
use crossbeam::sync::MsQueue;
|
||||
use ignore::WalkBuilder;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
fn main() {
|
||||
let path = env::args().nth(1).unwrap();
|
||||
let ig = IgnoreBuilder::new().build();
|
||||
let wd = WalkDir::new(path);
|
||||
let walker = ignore::walk::Iter::new(ig, wd);
|
||||
|
||||
let mut stdout = io::BufWriter::new(io::stdout());
|
||||
// let mut count = 0;
|
||||
for dirent in walker {
|
||||
// count += 1;
|
||||
stdout.write(dirent.path().as_os_str().as_bytes()).unwrap();
|
||||
stdout.write(b"\n").unwrap();
|
||||
let mut path = env::args().nth(1).unwrap();
|
||||
let mut parallel = false;
|
||||
let mut simple = false;
|
||||
let queue: Arc<MsQueue<Option<DirEntry>>> = Arc::new(MsQueue::new());
|
||||
if path == "parallel" {
|
||||
path = env::args().nth(2).unwrap();
|
||||
parallel = true;
|
||||
} else if path == "walkdir" {
|
||||
path = env::args().nth(2).unwrap();
|
||||
simple = true;
|
||||
}
|
||||
// println!("{}", count);
|
||||
|
||||
let stdout_queue = queue.clone();
|
||||
let stdout_thread = thread::spawn(move || {
|
||||
let mut stdout = io::BufWriter::new(io::stdout());
|
||||
while let Some(dent) = stdout_queue.pop() {
|
||||
write_path(&mut stdout, dent.path());
|
||||
}
|
||||
});
|
||||
|
||||
if parallel {
|
||||
let walker = WalkBuilder::new(path).threads(6).build_parallel();
|
||||
walker.run(|| {
|
||||
let queue = queue.clone();
|
||||
Box::new(move |result| {
|
||||
use ignore::WalkState::*;
|
||||
|
||||
queue.push(Some(DirEntry::Y(result.unwrap())));
|
||||
Continue
|
||||
})
|
||||
});
|
||||
} else if simple {
|
||||
let mut stdout = io::BufWriter::new(io::stdout());
|
||||
let walker = WalkDir::new(path);
|
||||
for result in walker {
|
||||
queue.push(Some(DirEntry::X(result.unwrap())));
|
||||
}
|
||||
} else {
|
||||
let mut stdout = io::BufWriter::new(io::stdout());
|
||||
let walker = WalkBuilder::new(path).build();
|
||||
for result in walker {
|
||||
queue.push(Some(DirEntry::Y(result.unwrap())));
|
||||
}
|
||||
}
|
||||
queue.push(None);
|
||||
stdout_thread.join().unwrap();
|
||||
}
|
||||
|
||||
enum DirEntry {
|
||||
X(walkdir::DirEntry),
|
||||
Y(ignore::DirEntry),
|
||||
}
|
||||
|
||||
impl DirEntry {
|
||||
fn path(&self) -> &Path {
|
||||
match *self {
|
||||
DirEntry::X(ref x) => x.path(),
|
||||
DirEntry::Y(ref y) => y.path(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
wtr.write(path.as_os_str().as_bytes()).unwrap();
|
||||
wtr.write(b"\n").unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
||||
wtr.write(path.to_string_lossy().as_bytes()).unwrap();
|
||||
wtr.write(b"\n").unwrap();
|
||||
}
|
||||
*/
|
||||
fn main() {}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// well.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::ffi::{OsString, OsStr};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
@@ -73,13 +73,6 @@ struct IgnoreOptions {
|
||||
git_exclude: bool,
|
||||
}
|
||||
|
||||
impl IgnoreOptions {
|
||||
/// Returns true if at least one type of ignore rules should be matched.
|
||||
fn should_ignores(&self) -> bool {
|
||||
self.ignore || self.git_global || self.git_ignore || self.git_exclude
|
||||
}
|
||||
}
|
||||
|
||||
/// Ignore is a matcher useful for recursively walking one or more directories.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Ignore(Arc<IgnoreInner>);
|
||||
@@ -109,8 +102,12 @@ struct IgnoreInner {
|
||||
/// The absolute base path of this matcher. Populated only if parent
|
||||
/// directories are added.
|
||||
absolute_base: Option<Arc<PathBuf>>,
|
||||
/// Explicit ignore matchers specified by the caller.
|
||||
/// Explicit global ignore matchers specified by the caller.
|
||||
explicit_ignores: Arc<Vec<Gitignore>>,
|
||||
/// Ignore files used in addition to `.ignore`
|
||||
custom_ignore_filenames: Arc<Vec<OsString>>,
|
||||
/// The matcher for custom ignore files
|
||||
custom_ignore_matcher: Gitignore,
|
||||
/// The matcher for .ignore files.
|
||||
ignore_matcher: Gitignore,
|
||||
/// A global gitignore matcher, usually from $XDG_CONFIG_HOME/git/ignore.
|
||||
@@ -127,7 +124,6 @@ struct IgnoreInner {
|
||||
|
||||
impl Ignore {
|
||||
/// Return the directory path of this matcher.
|
||||
#[allow(dead_code)]
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.0.dir
|
||||
}
|
||||
@@ -137,6 +133,11 @@ impl Ignore {
|
||||
self.0.parent.is_none()
|
||||
}
|
||||
|
||||
/// Returns true if this matcher was added via the `add_parents` method.
|
||||
pub fn is_absolute_parent(&self) -> bool {
|
||||
self.0.is_absolute_parent
|
||||
}
|
||||
|
||||
/// Return this matcher's parent, if one exists.
|
||||
pub fn parent(&self) -> Option<Ignore> {
|
||||
self.0.parent.clone()
|
||||
@@ -206,14 +207,19 @@ impl Ignore {
|
||||
|
||||
/// Like add_child, but takes a full path and returns an IgnoreInner.
|
||||
fn add_child_path(&self, dir: &Path) -> (IgnoreInner, Option<Error>) {
|
||||
static IG_NAMES: &'static [&'static str] = &[".rgignore", ".ignore"];
|
||||
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
let custom_ig_matcher =
|
||||
{
|
||||
let (m, err) =
|
||||
create_gitignore(&dir, &self.0.custom_ignore_filenames);
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
let ig_matcher =
|
||||
if !self.0.opts.ignore {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
let (m, err) = create_gitignore(&dir, IG_NAMES);
|
||||
let (m, err) = create_gitignore(&dir, &[".ignore"]);
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
@@ -242,6 +248,8 @@ impl Ignore {
|
||||
is_absolute_parent: false,
|
||||
absolute_base: self.0.absolute_base.clone(),
|
||||
explicit_ignores: self.0.explicit_ignores.clone(),
|
||||
custom_ignore_filenames: self.0.custom_ignore_filenames.clone(),
|
||||
custom_ignore_matcher: custom_ig_matcher,
|
||||
ignore_matcher: ig_matcher,
|
||||
git_global_matcher: self.0.git_global_matcher.clone(),
|
||||
git_ignore_matcher: gi_matcher,
|
||||
@@ -252,6 +260,15 @@ impl Ignore {
|
||||
(ig, errs.into_error_option())
|
||||
}
|
||||
|
||||
/// Returns true if at least one type of ignore rule should be matched.
|
||||
fn has_any_ignore_rules(&self) -> bool {
|
||||
let opts = self.0.opts;
|
||||
let has_custom_ignore_files = !self.0.custom_ignore_filenames.is_empty();
|
||||
|
||||
opts.ignore || opts.git_global || opts.git_ignore
|
||||
|| opts.git_exclude || has_custom_ignore_files
|
||||
}
|
||||
|
||||
/// Returns a match indicating whether the given file path should be
|
||||
/// ignored or not.
|
||||
///
|
||||
@@ -280,7 +297,7 @@ impl Ignore {
|
||||
}
|
||||
}
|
||||
let mut whitelisted = Match::None;
|
||||
if self.0.opts.should_ignores() {
|
||||
if self.has_any_ignore_rules() {
|
||||
let mat = self.matched_ignore(path, is_dir);
|
||||
if mat.is_ignore() {
|
||||
return mat;
|
||||
@@ -310,10 +327,15 @@ impl Ignore {
|
||||
path: &Path,
|
||||
is_dir: bool,
|
||||
) -> Match<IgnoreMatch<'a>> {
|
||||
let (mut m_ignore, mut m_gi, mut m_gi_exclude, mut m_explicit) =
|
||||
(Match::None, Match::None, Match::None, Match::None);
|
||||
let (mut m_custom_ignore, mut m_ignore, mut m_gi, mut m_gi_exclude, mut m_explicit) =
|
||||
(Match::None, Match::None, Match::None, Match::None, Match::None);
|
||||
let mut saw_git = false;
|
||||
for ig in self.parents().take_while(|ig| !ig.0.is_absolute_parent) {
|
||||
if m_custom_ignore.is_none() {
|
||||
m_custom_ignore =
|
||||
ig.0.custom_ignore_matcher.matched(path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if m_ignore.is_none() {
|
||||
m_ignore =
|
||||
ig.0.ignore_matcher.matched(path, is_dir)
|
||||
@@ -334,6 +356,11 @@ impl Ignore {
|
||||
if let Some(abs_parent_path) = self.absolute_base() {
|
||||
let path = abs_parent_path.join(path);
|
||||
for ig in self.parents().skip_while(|ig|!ig.0.is_absolute_parent) {
|
||||
if m_custom_ignore.is_none() {
|
||||
m_custom_ignore =
|
||||
ig.0.custom_ignore_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if m_ignore.is_none() {
|
||||
m_ignore =
|
||||
ig.0.ignore_matcher.matched(&path, is_dir)
|
||||
@@ -360,23 +387,12 @@ impl Ignore {
|
||||
}
|
||||
let m_global = self.0.git_global_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
if !m_ignore.is_none() {
|
||||
m_ignore
|
||||
} else if !m_gi.is_none() {
|
||||
m_gi
|
||||
} else if !m_gi_exclude.is_none() {
|
||||
m_gi_exclude
|
||||
} else if !m_global.is_none() {
|
||||
m_global
|
||||
} else if !m_explicit.is_none() {
|
||||
m_explicit
|
||||
} else {
|
||||
Match::None
|
||||
}
|
||||
|
||||
m_custom_ignore.or(m_ignore).or(m_gi).or(m_gi_exclude).or(m_global).or(m_explicit)
|
||||
}
|
||||
|
||||
/// Returns an iterator over parent ignore matchers, including this one.
|
||||
fn parents(&self) -> Parents {
|
||||
pub fn parents(&self) -> Parents {
|
||||
Parents(Some(self))
|
||||
}
|
||||
|
||||
@@ -387,7 +403,10 @@ impl Ignore {
|
||||
}
|
||||
}
|
||||
|
||||
struct Parents<'a>(Option<&'a Ignore>);
|
||||
/// An iterator over all parents of an ignore matcher, including itself.
|
||||
///
|
||||
/// The lifetime `'a` refers to the lifetime of the initial `Ignore` matcher.
|
||||
pub struct Parents<'a>(Option<&'a Ignore>);
|
||||
|
||||
impl<'a> Iterator for Parents<'a> {
|
||||
type Item = &'a Ignore;
|
||||
@@ -412,8 +431,10 @@ pub struct IgnoreBuilder {
|
||||
overrides: Arc<Override>,
|
||||
/// A type matcher (default is empty).
|
||||
types: Arc<Types>,
|
||||
/// Explicit ignore matchers.
|
||||
/// Explicit global ignore matchers.
|
||||
explicit_ignores: Vec<Gitignore>,
|
||||
/// Ignore files in addition to .ignore.
|
||||
custom_ignore_filenames: Vec<OsString>,
|
||||
/// Ignore config.
|
||||
opts: IgnoreOptions,
|
||||
}
|
||||
@@ -429,6 +450,7 @@ impl IgnoreBuilder {
|
||||
overrides: Arc::new(Override::empty()),
|
||||
types: Arc::new(Types::empty()),
|
||||
explicit_ignores: vec![],
|
||||
custom_ignore_filenames: vec![],
|
||||
opts: IgnoreOptions {
|
||||
hidden: true,
|
||||
ignore: true,
|
||||
@@ -454,6 +476,7 @@ impl IgnoreBuilder {
|
||||
}
|
||||
gi
|
||||
};
|
||||
|
||||
Ignore(Arc::new(IgnoreInner {
|
||||
compiled: Arc::new(RwLock::new(HashMap::new())),
|
||||
dir: self.dir.clone(),
|
||||
@@ -463,6 +486,8 @@ impl IgnoreBuilder {
|
||||
is_absolute_parent: true,
|
||||
absolute_base: None,
|
||||
explicit_ignores: Arc::new(self.explicit_ignores.clone()),
|
||||
custom_ignore_filenames: Arc::new(self.custom_ignore_filenames.clone()),
|
||||
custom_ignore_matcher: Gitignore::empty(),
|
||||
ignore_matcher: Gitignore::empty(),
|
||||
git_global_matcher: Arc::new(git_global_matcher),
|
||||
git_ignore_matcher: Gitignore::empty(),
|
||||
@@ -498,6 +523,20 @@ impl IgnoreBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a custom ignore file name
|
||||
///
|
||||
/// These ignore files have higher precedence than all other ignore files.
|
||||
///
|
||||
/// When specifying multiple names, earlier names have lower precedence than
|
||||
/// later names.
|
||||
pub fn add_custom_ignore_filename<S: AsRef<OsStr>>(
|
||||
&mut self,
|
||||
file_name: S
|
||||
) -> &mut IgnoreBuilder {
|
||||
self.custom_ignore_filenames.push(file_name.as_ref().to_os_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables ignoring hidden files.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
@@ -559,14 +598,14 @@ impl IgnoreBuilder {
|
||||
/// order given (earlier names have lower precedence than later names).
|
||||
///
|
||||
/// I/O errors are ignored.
|
||||
pub fn create_gitignore(
|
||||
pub fn create_gitignore<T: AsRef<OsStr>>(
|
||||
dir: &Path,
|
||||
names: &[&str],
|
||||
names: &[T],
|
||||
) -> (Gitignore, Option<Error>) {
|
||||
let mut builder = GitignoreBuilder::new(dir);
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
for name in names {
|
||||
let gipath = dir.join(name);
|
||||
let gipath = dir.join(name.as_ref());
|
||||
errs.maybe_push_ignore_io(builder.add(gipath));
|
||||
}
|
||||
let gi = match builder.build() {
|
||||
@@ -659,6 +698,53 @@ mod tests {
|
||||
assert!(ig.matched("baz", false).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_ignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
let custom_ignore = ".customignore";
|
||||
wfile(td.path().join(custom_ignore), "foo\n!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new()
|
||||
.add_custom_ignore_filename(custom_ignore)
|
||||
.build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("foo", false).is_ignore());
|
||||
assert!(ig.matched("bar", false).is_whitelist());
|
||||
assert!(ig.matched("baz", false).is_none());
|
||||
}
|
||||
|
||||
// Tests that a custom ignore file will override an .ignore.
|
||||
#[test]
|
||||
fn custom_ignore_over_ignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
let custom_ignore = ".customignore";
|
||||
wfile(td.path().join(".ignore"), "foo");
|
||||
wfile(td.path().join(custom_ignore), "!foo");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new()
|
||||
.add_custom_ignore_filename(custom_ignore)
|
||||
.build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("foo", false).is_whitelist());
|
||||
}
|
||||
|
||||
// Tests that earlier custom ignore files have lower precedence than later.
|
||||
#[test]
|
||||
fn custom_ignore_precedence() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
let custom_ignore1 = ".customignore1";
|
||||
let custom_ignore2 = ".customignore2";
|
||||
wfile(td.path().join(custom_ignore1), "foo");
|
||||
wfile(td.path().join(custom_ignore2), "!foo");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new()
|
||||
.add_custom_ignore_filename(custom_ignore1)
|
||||
.add_custom_ignore_filename(custom_ignore2)
|
||||
.build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("foo", false).is_whitelist());
|
||||
}
|
||||
|
||||
// Tests that an .ignore will override a .gitignore.
|
||||
#[test]
|
||||
fn ignore_over_gitignore() {
|
||||
|
||||
@@ -66,6 +66,12 @@ impl Glob {
|
||||
pub fn is_only_dir(&self) -> bool {
|
||||
self.is_only_dir
|
||||
}
|
||||
|
||||
/// Returns true if and only if this glob has a `**/` prefix.
|
||||
fn has_doublestar_prefix(&self) -> bool {
|
||||
self.actual.starts_with("**/")
|
||||
|| (self.actual == "**" && self.is_only_dir)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gitignore is a matcher for the globs in one or more gitignore files
|
||||
@@ -169,8 +175,8 @@ impl Gitignore {
|
||||
self.num_whitelists
|
||||
}
|
||||
|
||||
/// Returns whether the given file path matched a pattern in this gitignore
|
||||
/// matcher.
|
||||
/// Returns whether the given path (file or directory) matched a pattern in
|
||||
/// this gitignore matcher.
|
||||
///
|
||||
/// `is_dir` should be true if the path refers to a directory and false
|
||||
/// otherwise.
|
||||
@@ -191,6 +197,48 @@ impl Gitignore {
|
||||
self.matched_stripped(self.strip(path.as_ref()), is_dir)
|
||||
}
|
||||
|
||||
/// Returns whether the given path (file or directory, and expected to be
|
||||
/// under the root) or any of its parent directories (up to the root)
|
||||
/// matched a pattern in this gitignore matcher.
|
||||
///
|
||||
/// NOTE: This method is more expensive than walking the directory hierarchy
|
||||
/// top-to-bottom and matching the entries. But, is easier to use in cases
|
||||
/// when a list of paths are available without a hierarchy.
|
||||
///
|
||||
/// `is_dir` should be true if the path refers to a directory and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// The given path is matched relative to the path given when building
|
||||
/// the matcher. Specifically, before matching `path`, its prefix (as
|
||||
/// determined by a common suffix of the directory containing this
|
||||
/// gitignore) is stripped. If there is no common suffix/prefix overlap,
|
||||
/// then `path` is assumed to be relative to this matcher.
|
||||
pub fn matched_path_or_any_parents<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<&Glob> {
|
||||
if self.is_empty() {
|
||||
return Match::None;
|
||||
}
|
||||
let mut path = self.strip(path.as_ref());
|
||||
debug_assert!(
|
||||
!path.has_root(),
|
||||
"path is expect to be under the root"
|
||||
);
|
||||
match self.matched_stripped(path, is_dir) {
|
||||
Match::None => (), // walk up
|
||||
a_match => return a_match,
|
||||
}
|
||||
while let Some(parent) = path.parent() {
|
||||
match self.matched_stripped(parent, /* is_dir */ true) {
|
||||
Match::None => path = parent, // walk up
|
||||
a_match => return a_match,
|
||||
}
|
||||
}
|
||||
Match::None
|
||||
}
|
||||
|
||||
/// Like matched, but takes a path that has already been stripped.
|
||||
fn matched_stripped<P: AsRef<Path>>(
|
||||
&self,
|
||||
@@ -236,7 +284,10 @@ impl Gitignore {
|
||||
// BUT, a file name might not have any directory components to it,
|
||||
// in which case, we don't want to accidentally strip any part of the
|
||||
// file name.
|
||||
if !is_file_name(path) {
|
||||
//
|
||||
// As an additional special case, if the root is just `.`, then we
|
||||
// shouldn't try to strip anything, e.g., when path begins with a `.`.
|
||||
if self.root != Path::new(".") && !is_file_name(path) {
|
||||
if let Some(p) = strip_prefix(&self.root, path) {
|
||||
path = p;
|
||||
// If we're left with a leading slash, get rid of it.
|
||||
@@ -254,6 +305,7 @@ pub struct GitignoreBuilder {
|
||||
builder: GlobSetBuilder,
|
||||
root: PathBuf,
|
||||
globs: Vec<Glob>,
|
||||
case_insensitive: bool,
|
||||
}
|
||||
|
||||
impl GitignoreBuilder {
|
||||
@@ -269,6 +321,7 @@ impl GitignoreBuilder {
|
||||
builder: GlobSetBuilder::new(),
|
||||
root: strip_prefix("./", root).unwrap_or(root).to_path_buf(),
|
||||
globs: vec![],
|
||||
case_insensitive: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,8 +331,13 @@ impl GitignoreBuilder {
|
||||
pub fn build(&self) -> Result<Gitignore, Error> {
|
||||
let nignore = self.globs.iter().filter(|g| !g.is_whitelist()).count();
|
||||
let nwhite = self.globs.iter().filter(|g| g.is_whitelist()).count();
|
||||
let set = try!(
|
||||
self.builder.build().map_err(|err| Error::Glob(err.to_string())));
|
||||
let set =
|
||||
self.builder.build().map_err(|err| {
|
||||
Error::Glob {
|
||||
glob: None,
|
||||
err: err.to_string(),
|
||||
}
|
||||
})?;
|
||||
Ok(Gitignore {
|
||||
set: set,
|
||||
root: self.root.clone(),
|
||||
@@ -311,7 +369,7 @@ impl GitignoreBuilder {
|
||||
Ok(line) => line,
|
||||
Err(err) => {
|
||||
errs.push(Error::Io(err).tagged(path, lineno));
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Err(err) = self.add_line(Some(path.to_path_buf()), &line) {
|
||||
@@ -334,7 +392,7 @@ impl GitignoreBuilder {
|
||||
gitignore: &str,
|
||||
) -> Result<&mut GitignoreBuilder, Error> {
|
||||
for line in gitignore.lines() {
|
||||
try!(self.add_line(from.clone(), line));
|
||||
self.add_line(from.clone(), line)?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
@@ -367,10 +425,10 @@ impl GitignoreBuilder {
|
||||
is_only_dir: false,
|
||||
};
|
||||
let mut literal_separator = false;
|
||||
let has_slash = line.chars().any(|c| c == '/');
|
||||
let is_absolute = line.chars().nth(0).unwrap() == '/';
|
||||
let mut is_absolute = false;
|
||||
if line.starts_with("\\!") || line.starts_with("\\#") {
|
||||
line = &line[1..];
|
||||
is_absolute = line.chars().nth(0) == Some('/');
|
||||
} else {
|
||||
if line.starts_with("!") {
|
||||
glob.is_whitelist = true;
|
||||
@@ -383,6 +441,7 @@ impl GitignoreBuilder {
|
||||
// simply banning wildcards from matching /.
|
||||
literal_separator = true;
|
||||
line = &line[1..];
|
||||
is_absolute = true;
|
||||
}
|
||||
}
|
||||
// If it ends with a slash, then this should only match directories,
|
||||
@@ -396,15 +455,15 @@ impl GitignoreBuilder {
|
||||
// If there is a literal slash, then we note that so that globbing
|
||||
// doesn't let wildcards match slashes.
|
||||
glob.actual = line.to_string();
|
||||
if has_slash {
|
||||
if is_absolute || line.chars().any(|c| c == '/') {
|
||||
literal_separator = true;
|
||||
}
|
||||
// If there was a leading slash, then this is a glob that must
|
||||
// match the entire path name. Otherwise, we should let it match
|
||||
// anywhere, so use a **/ prefix.
|
||||
if !is_absolute {
|
||||
// If there was a slash, then this is a glob that must match the entire
|
||||
// path name. Otherwise, we should let it match anywhere, so use a **/
|
||||
// prefix.
|
||||
if !literal_separator {
|
||||
// ... but only if we don't already have a **/ prefix.
|
||||
if !glob.actual.starts_with("**/") {
|
||||
if !glob.has_doublestar_prefix() {
|
||||
glob.actual = format!("**/{}", glob.actual);
|
||||
}
|
||||
}
|
||||
@@ -414,15 +473,31 @@ impl GitignoreBuilder {
|
||||
if glob.actual.ends_with("/**") {
|
||||
glob.actual = format!("{}/*", glob.actual);
|
||||
}
|
||||
let parsed = try!(
|
||||
let parsed =
|
||||
GlobBuilder::new(&glob.actual)
|
||||
.literal_separator(literal_separator)
|
||||
.case_insensitive(self.case_insensitive)
|
||||
.build()
|
||||
.map_err(|err| Error::Glob(err.to_string())));
|
||||
.map_err(|err| {
|
||||
Error::Glob {
|
||||
glob: Some(glob.original.clone()),
|
||||
err: err.kind().to_string(),
|
||||
}
|
||||
})?;
|
||||
self.builder.add(parsed);
|
||||
self.globs.push(glob);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Toggle whether the globs should be matched case insensitively or not.
|
||||
///
|
||||
/// This is disabled by default.
|
||||
pub fn case_insensitive(
|
||||
&mut self, yes: bool
|
||||
) -> Result<&mut GitignoreBuilder, Error> {
|
||||
self.case_insensitive = yes;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the file path of the current environment's global gitignore file.
|
||||
@@ -453,9 +528,9 @@ fn gitconfig_contents() -> Option<Vec<u8>> {
|
||||
/// Specifically, this respects XDG_CONFIG_HOME.
|
||||
fn excludes_file_default() -> Option<PathBuf> {
|
||||
env::var_os("XDG_CONFIG_HOME")
|
||||
.and_then(|x| if x.is_empty() { None } else { Some(x) })
|
||||
.or_else(|| env::var_os("HOME"))
|
||||
.map(|x| PathBuf::from(x).join("git/ignore"))
|
||||
.and_then(|x| if x.is_empty() { None } else { Some(PathBuf::from(x)) })
|
||||
.or_else(|| env::home_dir().map(|p| p.join(".config")))
|
||||
.map(|x| x.join("git/ignore"))
|
||||
}
|
||||
|
||||
/// Extract git's `core.excludesfile` config setting from the raw file contents
|
||||
@@ -550,9 +625,16 @@ mod tests {
|
||||
ignored!(ig25, ROOT, "Cargo.lock", "./tabwriter-bin/Cargo.lock");
|
||||
ignored!(ig26, ROOT, "/foo/bar/baz", "./foo/bar/baz");
|
||||
ignored!(ig27, ROOT, "foo/", "xyz/foo", true);
|
||||
ignored!(ig28, ROOT, "src/*.rs", "src/grep/src/main.rs");
|
||||
ignored!(ig29, "./src", "/llvm/", "./src/llvm", true);
|
||||
ignored!(ig30, ROOT, "node_modules/ ", "node_modules", true);
|
||||
ignored!(ig28, "./src", "/llvm/", "./src/llvm", true);
|
||||
ignored!(ig29, ROOT, "node_modules/ ", "node_modules", true);
|
||||
ignored!(ig30, ROOT, "**/", "foo/bar", true);
|
||||
ignored!(ig31, ROOT, "path1/*", "path1/foo");
|
||||
ignored!(ig32, ROOT, ".a/b", ".a/b");
|
||||
ignored!(ig33, "./", ".a/b", ".a/b");
|
||||
ignored!(ig34, ".", ".a/b", ".a/b");
|
||||
ignored!(ig35, "./.", ".a/b", ".a/b");
|
||||
ignored!(ig36, "././", ".a/b", ".a/b");
|
||||
ignored!(ig37, "././.", ".a/b", ".a/b");
|
||||
|
||||
not_ignored!(ignot1, ROOT, "amonths", "months");
|
||||
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
||||
@@ -570,6 +652,10 @@ mod tests {
|
||||
not_ignored!(
|
||||
ignot14, "./third_party/protobuf", "m4/ltoptions.m4",
|
||||
"./third_party/protobuf/csharp/src/packages/repositories.config");
|
||||
not_ignored!(ignot15, ROOT, "!/bar", "foo/bar");
|
||||
not_ignored!(ignot16, ROOT, "*\n!**/", "foo", true);
|
||||
not_ignored!(ignot17, ROOT, "src/*.rs", "src/grep/src/main.rs");
|
||||
not_ignored!(ignot18, ROOT, "path1/*", "path2/path1/foo");
|
||||
|
||||
fn bytes(s: &str) -> Vec<u8> {
|
||||
s.to_string().into_bytes()
|
||||
@@ -604,4 +690,21 @@ mod tests {
|
||||
fn regression_106() {
|
||||
gi_from_str("/", " ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive() {
|
||||
let gi = GitignoreBuilder::new(ROOT)
|
||||
.case_insensitive(true).unwrap()
|
||||
.add_str(None, "*.html").unwrap()
|
||||
.build().unwrap();
|
||||
assert!(gi.matched("foo.html", false).is_ignore());
|
||||
assert!(gi.matched("foo.HTML", false).is_ignore());
|
||||
assert!(!gi.matched("foo.htm", false).is_ignore());
|
||||
assert!(!gi.matched("foo.HTM", false).is_ignore());
|
||||
}
|
||||
|
||||
ignored!(cs1, ROOT, "*.html", "foo.html");
|
||||
not_ignored!(cs2, ROOT, "*.html", "foo.HTML");
|
||||
not_ignored!(cs3, ROOT, "*.html", "foo.htm");
|
||||
not_ignored!(cs4, ROOT, "*.html", "foo.HTM");
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ for result in WalkBuilder::new("./").hidden(false).build() {
|
||||
See the documentation for `WalkBuilder` for many other options.
|
||||
*/
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
extern crate crossbeam;
|
||||
extern crate globset;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
@@ -51,17 +54,20 @@ extern crate lazy_static;
|
||||
extern crate log;
|
||||
extern crate memchr;
|
||||
extern crate regex;
|
||||
extern crate same_file;
|
||||
#[cfg(test)]
|
||||
extern crate tempdir;
|
||||
extern crate thread_local;
|
||||
extern crate walkdir;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub use walk::{DirEntry, Walk, WalkBuilder};
|
||||
pub use walk::{DirEntry, Walk, WalkBuilder, WalkParallel, WalkState};
|
||||
|
||||
mod dir;
|
||||
pub mod gitignore;
|
||||
@@ -77,13 +83,49 @@ pub enum Error {
|
||||
/// file partially succeeded.
|
||||
Partial(Vec<Error>),
|
||||
/// An error associated with a specific line number.
|
||||
WithLineNumber { line: u64, err: Box<Error> },
|
||||
WithLineNumber {
|
||||
/// The line number.
|
||||
line: u64,
|
||||
/// The underlying error.
|
||||
err: Box<Error>,
|
||||
},
|
||||
/// An error associated with a particular file path.
|
||||
WithPath { path: PathBuf, err: Box<Error> },
|
||||
WithPath {
|
||||
/// The file path.
|
||||
path: PathBuf,
|
||||
/// The underlying error.
|
||||
err: Box<Error>,
|
||||
},
|
||||
/// An error associated with a particular directory depth when recursively
|
||||
/// walking a directory.
|
||||
WithDepth {
|
||||
/// The directory depth.
|
||||
depth: usize,
|
||||
/// The underlying error.
|
||||
err: Box<Error>,
|
||||
},
|
||||
/// An error that occurs when a file loop is detected when traversing
|
||||
/// symbolic links.
|
||||
Loop {
|
||||
/// The ancestor file path in the loop.
|
||||
ancestor: PathBuf,
|
||||
/// The child file path in the loop.
|
||||
child: PathBuf,
|
||||
},
|
||||
/// An error that occurs when doing I/O, such as reading an ignore file.
|
||||
Io(io::Error),
|
||||
/// An error that occurs when trying to parse a glob.
|
||||
Glob(String),
|
||||
Glob {
|
||||
/// The original glob that caused this error. This glob, when
|
||||
/// available, always corresponds to the glob provided by an end user.
|
||||
/// e.g., It is the glob as written in a `.gitignore` file.
|
||||
///
|
||||
/// (This glob may be distinct from the glob that is actually
|
||||
/// compiled, after accounting for `gitignore` semantics.)
|
||||
glob: Option<String>,
|
||||
/// The underlying glob error as a string.
|
||||
err: String,
|
||||
},
|
||||
/// A type selection for a file type that is not defined.
|
||||
UnrecognizedFileType(String),
|
||||
/// A user specified file type definition could not be parsed.
|
||||
@@ -101,6 +143,7 @@ impl Error {
|
||||
Error::Partial(_) => true,
|
||||
Error::WithLineNumber { ref err, .. } => err.is_partial(),
|
||||
Error::WithPath { ref err, .. } => err.is_partial(),
|
||||
Error::WithDepth { ref err, .. } => err.is_partial(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -111,13 +154,25 @@ impl Error {
|
||||
Error::Partial(ref errs) => errs.len() == 1 && errs[0].is_io(),
|
||||
Error::WithLineNumber { ref err, .. } => err.is_io(),
|
||||
Error::WithPath { ref err, .. } => err.is_io(),
|
||||
Error::WithDepth { ref err, .. } => err.is_io(),
|
||||
Error::Loop { .. } => false,
|
||||
Error::Io(_) => true,
|
||||
Error::Glob(_) => false,
|
||||
Error::Glob { .. } => false,
|
||||
Error::UnrecognizedFileType(_) => false,
|
||||
Error::InvalidDefinition => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a depth associated with recursively walking a directory (if
|
||||
/// this error was generated from a recursive directory iterator).
|
||||
pub fn depth(&self) -> Option<usize> {
|
||||
match *self {
|
||||
Error::WithPath { ref err, .. } => err.depth(),
|
||||
Error::WithDepth { depth, .. } => Some(depth),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Turn an error into a tagged error with the given file path.
|
||||
fn with_path<P: AsRef<Path>>(self, path: P) -> Error {
|
||||
Error::WithPath {
|
||||
@@ -126,6 +181,14 @@ impl Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Turn an error into a tagged error with the given depth.
|
||||
fn with_depth(self, depth: usize) -> Error {
|
||||
Error::WithDepth {
|
||||
depth: depth,
|
||||
err: Box::new(self),
|
||||
}
|
||||
}
|
||||
|
||||
/// Turn an error into a tagged error with the given file path and line
|
||||
/// number. If path is empty, then it is omitted from the error.
|
||||
fn tagged<P: AsRef<Path>>(self, path: P, lineno: u64) -> Error {
|
||||
@@ -138,6 +201,29 @@ impl Error {
|
||||
}
|
||||
errline.with_path(path)
|
||||
}
|
||||
|
||||
/// Build an error from a walkdir error.
|
||||
fn from_walkdir(err: walkdir::Error) -> Error {
|
||||
let depth = err.depth();
|
||||
if let (Some(anc), Some(child)) = (err.loop_ancestor(), err.path()) {
|
||||
return Error::WithDepth {
|
||||
depth: depth,
|
||||
err: Box::new(Error::Loop {
|
||||
ancestor: anc.to_path_buf(),
|
||||
child: child.to_path_buf(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
let path = err.path().map(|p| p.to_path_buf());
|
||||
let mut ig_err = Error::Io(io::Error::from(err));
|
||||
if let Some(path) = path {
|
||||
ig_err = Error::WithPath {
|
||||
path: path,
|
||||
err: Box::new(ig_err),
|
||||
};
|
||||
}
|
||||
ig_err
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
@@ -146,8 +232,10 @@ impl error::Error for Error {
|
||||
Error::Partial(_) => "partial error",
|
||||
Error::WithLineNumber { ref err, .. } => err.description(),
|
||||
Error::WithPath { ref err, .. } => err.description(),
|
||||
Error::WithDepth { ref err, .. } => err.description(),
|
||||
Error::Loop { .. } => "file system loop found",
|
||||
Error::Io(ref err) => err.description(),
|
||||
Error::Glob(ref msg) => msg,
|
||||
Error::Glob { ref err, .. } => err,
|
||||
Error::UnrecognizedFileType(_) => "unrecognized file type",
|
||||
Error::InvalidDefinition => "invalid definition",
|
||||
}
|
||||
@@ -168,8 +256,17 @@ impl fmt::Display for Error {
|
||||
Error::WithPath { ref path, ref err } => {
|
||||
write!(f, "{}: {}", path.display(), err)
|
||||
}
|
||||
Error::WithDepth { ref err, .. } => err.fmt(f),
|
||||
Error::Loop { ref ancestor, ref child } => {
|
||||
write!(f, "File system loop found: \
|
||||
{} points to an ancestor {}",
|
||||
child.display(), ancestor.display())
|
||||
}
|
||||
Error::Io(ref err) => err.fmt(f),
|
||||
Error::Glob(ref msg) => write!(f, "{}", msg),
|
||||
Error::Glob { glob: None, ref err } => write!(f, "{}", err),
|
||||
Error::Glob { glob: Some(ref glob), ref err } => {
|
||||
write!(f, "error parsing glob '{}': {}", glob, err)
|
||||
}
|
||||
Error::UnrecognizedFileType(ref ty) => {
|
||||
write!(f, "unrecognized file type: {}", ty)
|
||||
}
|
||||
@@ -297,4 +394,13 @@ impl<T> Match<T> {
|
||||
Match::Whitelist(t) => Match::Whitelist(f(t)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the match if it is not none. Otherwise, return other.
|
||||
pub fn or(self, other: Self) -> Self {
|
||||
if self.is_none() {
|
||||
other
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ impl OverrideBuilder {
|
||||
///
|
||||
/// Once a matcher is built, no new globs can be added to it.
|
||||
pub fn build(&self) -> Result<Override, Error> {
|
||||
Ok(Override(try!(self.builder.build())))
|
||||
Ok(Override(self.builder.build()?))
|
||||
}
|
||||
|
||||
/// Add a glob to the set of overrides.
|
||||
@@ -134,7 +134,17 @@ impl OverrideBuilder {
|
||||
/// namely, `!` at the beginning of a glob will ignore a file. Without `!`,
|
||||
/// all matches of the glob provided are treated as whitelist matches.
|
||||
pub fn add(&mut self, glob: &str) -> Result<&mut OverrideBuilder, Error> {
|
||||
try!(self.builder.add_line(None, glob));
|
||||
self.builder.add_line(None, glob)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Toggle whether the globs should be matched case insensitively or not.
|
||||
///
|
||||
/// This is disabled by default.
|
||||
pub fn case_insensitive(
|
||||
&mut self, yes: bool
|
||||
) -> Result<&mut OverrideBuilder, Error> {
|
||||
self.builder.case_insensitive(yes)?;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
@@ -192,8 +202,9 @@ mod tests {
|
||||
#[test]
|
||||
fn gitignore() {
|
||||
let ov = ov(&["/foo", "bar/*.rs", "baz/**"]);
|
||||
assert!(ov.matched("bar/lib.rs", false).is_whitelist());
|
||||
assert!(ov.matched("bar/wat/lib.rs", false).is_ignore());
|
||||
assert!(ov.matched("wat/bar/lib.rs", false).is_whitelist());
|
||||
assert!(ov.matched("wat/bar/lib.rs", false).is_ignore());
|
||||
assert!(ov.matched("foo", false).is_whitelist());
|
||||
assert!(ov.matched("wat/foo", false).is_ignore());
|
||||
assert!(ov.matched("baz", false).is_ignore());
|
||||
@@ -214,4 +225,33 @@ mod tests {
|
||||
assert!(ov.matched("src/foo", false).is_ignore());
|
||||
assert!(ov.matched("src/foo", true).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absolute_path() {
|
||||
let ov = ov(&["!/bar"]);
|
||||
assert!(ov.matched("./foo/bar", false).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive() {
|
||||
let ov = OverrideBuilder::new(ROOT)
|
||||
.case_insensitive(true).unwrap()
|
||||
.add("*.html").unwrap()
|
||||
.build().unwrap();
|
||||
assert!(ov.matched("foo.html", false).is_whitelist());
|
||||
assert!(ov.matched("foo.HTML", false).is_whitelist());
|
||||
assert!(ov.matched("foo.htm", false).is_ignore());
|
||||
assert!(ov.matched("foo.HTM", false).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_case_sensitive() {
|
||||
let ov = OverrideBuilder::new(ROOT)
|
||||
.add("*.html").unwrap()
|
||||
.build().unwrap();
|
||||
assert!(ov.matched("foo.html", false).is_whitelist());
|
||||
assert!(ov.matched("foo.HTML", false).is_ignore());
|
||||
assert!(ov.matched("foo.htm", false).is_ignore());
|
||||
assert!(ov.matched("foo.HTM", false).is_ignore());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,22 @@ assert!(matcher.matched("x.foo", false).is_whitelist());
|
||||
// This is ignored because we only selected the `foo` file type.
|
||||
assert!(matcher.matched("x.bar", false).is_ignore());
|
||||
```
|
||||
|
||||
We can also add file type definitions based on other definitions.
|
||||
|
||||
```
|
||||
use ignore::types::TypesBuilder;
|
||||
|
||||
let mut builder = TypesBuilder::new();
|
||||
builder.add_defaults();
|
||||
builder.add("foo", "*.foo");
|
||||
builder.add_def("bar:include:foo,cpp");
|
||||
builder.select("bar");
|
||||
let matcher = builder.build().unwrap();
|
||||
|
||||
assert!(matcher.matched("x.foo", false).is_whitelist());
|
||||
assert!(matcher.matched("y.cpp", false).is_whitelist());
|
||||
```
|
||||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
@@ -74,30 +90,46 @@ use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
|
||||
use regex::Regex;
|
||||
use thread_local::ThreadLocal;
|
||||
|
||||
use pathutil::file_name;
|
||||
use {Error, Match};
|
||||
|
||||
const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
|
||||
("agda", &["*.agda", "*.lagda"]),
|
||||
("asciidoc", &["*.adoc", "*.asc", "*.asciidoc"]),
|
||||
("asm", &["*.asm", "*.s", "*.S"]),
|
||||
("avro", &["*.avdl", "*.avpr", "*.avsc"]),
|
||||
("awk", &["*.awk"]),
|
||||
("bitbake", &["*.bb", "*.bbappend", "*.bbclass", "*.conf", "*.inc"]),
|
||||
("bzip2", &["*.bz2"]),
|
||||
("c", &["*.c", "*.h", "*.H"]),
|
||||
("cabal", &["*.cabal"]),
|
||||
("cbor", &["*.cbor"]),
|
||||
("ceylon", &["*.ceylon"]),
|
||||
("clojure", &["*.clj", "*.cljc", "*.cljs", "*.cljx"]),
|
||||
("cmake", &["*.cmake", "CMakeLists.txt"]),
|
||||
("coffeescript", &["*.coffee"]),
|
||||
("config", &["*.config"]),
|
||||
("creole", &["*.creole"]),
|
||||
("config", &["*.cfg", "*.conf", "*.config", "*.ini"]),
|
||||
("cpp", &[
|
||||
"*.C", "*.cc", "*.cpp", "*.cxx",
|
||||
"*.h", "*.H", "*.hh", "*.hpp",
|
||||
"*.h", "*.H", "*.hh", "*.hpp", "*.hxx", "*.inl",
|
||||
]),
|
||||
("crystal", &["Projectfile", "*.cr"]),
|
||||
("cs", &["*.cs"]),
|
||||
("csharp", &["*.cs"]),
|
||||
("css", &["*.css"]),
|
||||
("cshtml", &["*.cshtml"]),
|
||||
("css", &["*.css", "*.scss"]),
|
||||
("csv", &["*.csv"]),
|
||||
("cython", &["*.pyx"]),
|
||||
("dart", &["*.dart"]),
|
||||
("d", &["*.d"]),
|
||||
("docker", &["*Dockerfile*"]),
|
||||
("elisp", &["*.el"]),
|
||||
("elixir", &["*.ex", "*.eex", "*.exs"]),
|
||||
("elm", &["*.elm"]),
|
||||
("erlang", &["*.erl", "*.hrl"]),
|
||||
("fish", &["*.fish"]),
|
||||
("fortran", &[
|
||||
@@ -105,56 +137,161 @@ const DEFAULT_TYPES: &'static [(&'static str, &'static [&'static str])] = &[
|
||||
"*.f90", "*.F90", "*.f95", "*.F95",
|
||||
]),
|
||||
("fsharp", &["*.fs", "*.fsx", "*.fsi"]),
|
||||
("gn", &["*.gn", "*.gni"]),
|
||||
("go", &["*.go"]),
|
||||
("gzip", &["*.gz"]),
|
||||
("groovy", &["*.groovy", "*.gradle"]),
|
||||
("h", &["*.h", "*.hpp"]),
|
||||
("hbs", &["*.hbs"]),
|
||||
("haskell", &["*.hs", "*.lhs"]),
|
||||
("html", &["*.htm", "*.html"]),
|
||||
("html", &["*.htm", "*.html", "*.ejs"]),
|
||||
("java", &["*.java"]),
|
||||
("jinja", &["*.jinja", "*.jinja2"]),
|
||||
("jinja", &["*.j2", "*.jinja", "*.jinja2"]),
|
||||
("js", &[
|
||||
"*.js", "*.jsx", "*.vue",
|
||||
]),
|
||||
("json", &["*.json"]),
|
||||
("json", &["*.json", "composer.lock"]),
|
||||
("jsonl", &["*.jsonl"]),
|
||||
("julia", &["*.jl"]),
|
||||
("jupyter", &["*.ipynb", "*.jpynb"]),
|
||||
("jl", &["*.jl"]),
|
||||
("kotlin", &["*.kt", "*.kts"]),
|
||||
("less", &["*.less"]),
|
||||
("license", &[
|
||||
// General
|
||||
"COPYING", "COPYING[.-]*",
|
||||
"COPYRIGHT", "COPYRIGHT[.-]*",
|
||||
"EULA", "EULA[.-]*",
|
||||
"licen[cs]e", "licen[cs]e.*",
|
||||
"LICEN[CS]E", "LICEN[CS]E[.-]*", "*[.-]LICEN[CS]E*",
|
||||
"NOTICE", "NOTICE[.-]*",
|
||||
"PATENTS", "PATENTS[.-]*",
|
||||
"UNLICEN[CS]E", "UNLICEN[CS]E[.-]*",
|
||||
// GPL (gpl.txt, etc.)
|
||||
"agpl[.-]*",
|
||||
"gpl[.-]*",
|
||||
"lgpl[.-]*",
|
||||
// Other license-specific (APACHE-2.0.txt, etc.)
|
||||
"AGPL-*[0-9]*",
|
||||
"APACHE-*[0-9]*",
|
||||
"BSD-*[0-9]*",
|
||||
"CC-BY-*",
|
||||
"GFDL-*[0-9]*",
|
||||
"GNU-*[0-9]*",
|
||||
"GPL-*[0-9]*",
|
||||
"LGPL-*[0-9]*",
|
||||
"MIT-*[0-9]*",
|
||||
"MPL-*[0-9]*",
|
||||
"OFL-*[0-9]*",
|
||||
]),
|
||||
("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]),
|
||||
("log", &["*.log"]),
|
||||
("lua", &["*.lua"]),
|
||||
("lzma", &["*.lzma"]),
|
||||
("m4", &["*.ac", "*.m4"]),
|
||||
("make", &["gnumakefile", "Gnumakefile", "makefile", "Makefile", "*.mk"]),
|
||||
("markdown", &["*.md"]),
|
||||
("md", &["*.md"]),
|
||||
("make", &[
|
||||
"gnumakefile", "Gnumakefile", "GNUmakefile",
|
||||
"makefile", "Makefile",
|
||||
"*.mk", "*.mak"
|
||||
]),
|
||||
("markdown", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
|
||||
("md", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
|
||||
("man", &["*.[0-9lnpx]", "*.[0-9][cEFMmpSx]"]),
|
||||
("matlab", &["*.m"]),
|
||||
("mk", &["mkfile"]),
|
||||
("ml", &["*.ml"]),
|
||||
("msbuild", &[
|
||||
"*.csproj", "*.fsproj", "*.vcxproj", "*.proj", "*.props", "*.targets"
|
||||
]),
|
||||
("nim", &["*.nim"]),
|
||||
("nix", &["*.nix"]),
|
||||
("objc", &["*.h", "*.m"]),
|
||||
("objcpp", &["*.h", "*.mm"]),
|
||||
("ocaml", &["*.ml", "*.mli", "*.mll", "*.mly"]),
|
||||
("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm"]),
|
||||
("org", &["*.org"]),
|
||||
("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm", "*.t"]),
|
||||
("pdf", &["*.pdf"]),
|
||||
("php", &["*.php", "*.php3", "*.php4", "*.php5", "*.phtml"]),
|
||||
("pod", &["*.pod"]),
|
||||
("protobuf", &["*.proto"]),
|
||||
("ps", &["*.cdxml", "*.ps1", "*.ps1xml", "*.psd1", "*.psm1"]),
|
||||
("purs", &["*.purs"]),
|
||||
("py", &["*.py"]),
|
||||
("qmake", &["*.pro", "*.pri", "*.prf"]),
|
||||
("readme", &["README*", "*README"]),
|
||||
("r", &["*.R", "*.r", "*.Rmd", "*.Rnw"]),
|
||||
("rdoc", &["*.rdoc"]),
|
||||
("rst", &["*.rst"]),
|
||||
("ruby", &["*.rb"]),
|
||||
("ruby", &["Gemfile", "*.gemspec", ".irbrc", "Rakefile", "*.rb"]),
|
||||
("rust", &["*.rs"]),
|
||||
("sass", &["*.sass", "*.scss"]),
|
||||
("scala", &["*.scala"]),
|
||||
("sh", &["*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh"]),
|
||||
("sh", &[
|
||||
// Portable/misc. init files
|
||||
".login", ".logout", ".profile", "profile",
|
||||
// bash-specific init files
|
||||
".bash_login", "bash_login",
|
||||
".bash_logout", "bash_logout",
|
||||
".bash_profile", "bash_profile",
|
||||
".bashrc", "bashrc", "*.bashrc",
|
||||
// csh-specific init files
|
||||
".cshrc", "*.cshrc",
|
||||
// ksh-specific init files
|
||||
".kshrc", "*.kshrc",
|
||||
// tcsh-specific init files
|
||||
".tcshrc",
|
||||
// zsh-specific init files
|
||||
".zshenv", "zshenv",
|
||||
".zlogin", "zlogin",
|
||||
".zlogout", "zlogout",
|
||||
".zprofile", "zprofile",
|
||||
".zshrc", "zshrc",
|
||||
// Extensions
|
||||
"*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh", "*.zsh",
|
||||
]),
|
||||
("smarty", &["*.tpl"]),
|
||||
("sml", &["*.sml", "*.sig"]),
|
||||
("soy", &["*.soy"]),
|
||||
("spark", &["*.spark"]),
|
||||
("sql", &["*.sql"]),
|
||||
("sql", &["*.sql", "*.psql"]),
|
||||
("stylus", &["*.styl"]),
|
||||
("sv", &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
|
||||
("svg", &["*.svg"]),
|
||||
("swift", &["*.swift"]),
|
||||
("swig", &["*.def", "*.i"]),
|
||||
("systemd", &[
|
||||
"*.automount", "*.conf", "*.device", "*.link", "*.mount", "*.path",
|
||||
"*.scope", "*.service", "*.slice", "*.socket", "*.swap", "*.target",
|
||||
"*.timer",
|
||||
]),
|
||||
("taskpaper", &["*.taskpaper"]),
|
||||
("tcl", &["*.tcl"]),
|
||||
("tex", &["*.tex", "*.cls", "*.sty"]),
|
||||
("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib"]),
|
||||
("textile", &["*.textile"]),
|
||||
("tf", &["*.tf"]),
|
||||
("ts", &["*.ts", "*.tsx"]),
|
||||
("txt", &["*.txt"]),
|
||||
("toml", &["*.toml", "Cargo.lock"]),
|
||||
("twig", &["*.twig"]),
|
||||
("vala", &["*.vala"]),
|
||||
("vb", &["*.vb"]),
|
||||
("vhdl", &["*.vhd", "*.vhdl"]),
|
||||
("vim", &["*.vim"]),
|
||||
("vimscript", &["*.vim"]),
|
||||
("xml", &["*.xml"]),
|
||||
("wiki", &["*.mediawiki", "*.wiki"]),
|
||||
("webidl", &["*.idl", "*.webidl", "*.widl"]),
|
||||
("xml", &["*.xml", "*.xml.dist"]),
|
||||
("xz", &["*.xz"]),
|
||||
("yacc", &["*.y"]),
|
||||
("yaml", &["*.yaml", "*.yml"]),
|
||||
("zsh", &[
|
||||
".zshenv", "zshenv",
|
||||
".zlogin", "zlogin",
|
||||
".zlogout", "zlogout",
|
||||
".zprofile", "zprofile",
|
||||
".zshrc", "zshrc",
|
||||
"*.zsh",
|
||||
]),
|
||||
];
|
||||
|
||||
/// Glob represents a single glob in a set of file type definitions.
|
||||
@@ -200,7 +337,7 @@ impl<'a> Glob<'a> {
|
||||
/// File type definitions can be retrieved in aggregate from a file type
|
||||
/// matcher. File type definitions are also reported when its responsible
|
||||
/// for a match.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct FileTypeDef {
|
||||
name: String,
|
||||
globs: Vec<String>,
|
||||
@@ -400,18 +537,23 @@ impl TypesBuilder {
|
||||
}
|
||||
};
|
||||
for (iglob, glob) in def.globs.iter().enumerate() {
|
||||
build_set.add(try!(
|
||||
build_set.add(
|
||||
GlobBuilder::new(glob)
|
||||
.literal_separator(true)
|
||||
.build()
|
||||
.map_err(|err| Error::Glob(err.to_string()))));
|
||||
.map_err(|err| {
|
||||
Error::Glob {
|
||||
glob: Some(glob.to_string()),
|
||||
err: err.kind().to_string(),
|
||||
}
|
||||
})?);
|
||||
glob_to_selection.push((isel, iglob));
|
||||
}
|
||||
selections.push(selection.clone().map(move |_| def));
|
||||
}
|
||||
let set = try!(build_set.build().map_err(|err| {
|
||||
Error::Glob(err.to_string())
|
||||
}));
|
||||
let set = build_set.build().map_err(|err| {
|
||||
Error::Glob { glob: None, err: err.to_string() }
|
||||
})?;
|
||||
Ok(Types {
|
||||
defs: defs,
|
||||
selections: selections,
|
||||
@@ -473,10 +615,13 @@ impl TypesBuilder {
|
||||
/// Add a new file type definition. `name` can be arbitrary and `pat`
|
||||
/// should be a glob recognizing file paths belonging to the `name` type.
|
||||
///
|
||||
/// If `name` is `all` or otherwise contains a `:`, then an error is
|
||||
/// returned.
|
||||
/// If `name` is `all` or otherwise contains any character that is not a
|
||||
/// Unicode letter or number, then an error is returned.
|
||||
pub fn add(&mut self, name: &str, glob: &str) -> Result<(), Error> {
|
||||
if name == "all" || name.contains(':') {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(r"^[\pL\pN]+$").unwrap();
|
||||
};
|
||||
if name == "all" || !RE.is_match(name) {
|
||||
return Err(Error::InvalidDefinition);
|
||||
}
|
||||
let (key, glob) = (name.to_string(), glob.to_string());
|
||||
@@ -486,15 +631,48 @@ impl TypesBuilder {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a new file type definition specified in string form. The format
|
||||
/// is `name:glob`. Names may not include a colon.
|
||||
/// Add a new file type definition specified in string form. There are two
|
||||
/// valid formats:
|
||||
/// 1. `{name}:{glob}`. This defines a 'root' definition that associates the
|
||||
/// given name with the given glob.
|
||||
/// 2. `{name}:include:{comma-separated list of already defined names}.
|
||||
/// This defines an 'include' definition that associates the given name
|
||||
/// with the definitions of the given existing types.
|
||||
/// Names may not include any characters that are not
|
||||
/// Unicode letters or numbers.
|
||||
pub fn add_def(&mut self, def: &str) -> Result<(), Error> {
|
||||
let name: String = def.chars().take_while(|&c| c != ':').collect();
|
||||
let pat: String = def.chars().skip(name.chars().count() + 1).collect();
|
||||
if name.is_empty() || pat.is_empty() {
|
||||
return Err(Error::InvalidDefinition);
|
||||
let parts: Vec<&str> = def.split(':').collect();
|
||||
match parts.len() {
|
||||
2 => {
|
||||
let name = parts[0];
|
||||
let glob = parts[1];
|
||||
if name.is_empty() || glob.is_empty() {
|
||||
return Err(Error::InvalidDefinition);
|
||||
}
|
||||
self.add(name, glob)
|
||||
}
|
||||
3 => {
|
||||
let name = parts[0];
|
||||
let types_string = parts[2];
|
||||
if name.is_empty() || parts[1] != "include" || types_string.is_empty() {
|
||||
return Err(Error::InvalidDefinition);
|
||||
}
|
||||
let types = types_string.split(',');
|
||||
// Check ahead of time to ensure that all types specified are
|
||||
// present and fail fast if not.
|
||||
if types.clone().any(|t| !self.types.contains_key(t)) {
|
||||
return Err(Error::InvalidDefinition);
|
||||
}
|
||||
for type_name in types {
|
||||
let globs = self.types.get(type_name).unwrap().globs.clone();
|
||||
for glob in globs {
|
||||
self.add(name, &glob)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(Error::InvalidDefinition)
|
||||
}
|
||||
self.add(&name, &pat)
|
||||
}
|
||||
|
||||
/// Add a set of default file type definitions.
|
||||
@@ -550,6 +728,7 @@ mod tests {
|
||||
"rust:*.rs",
|
||||
"js:*.js",
|
||||
"foo:*.{rs,foo}",
|
||||
"combo:include:html,rust"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -560,10 +739,35 @@ mod tests {
|
||||
matched!(match5, types(), vec![], vec![], "index.html");
|
||||
matched!(match6, types(), vec![], vec!["rust"], "index.html");
|
||||
matched!(match7, types(), vec!["foo"], vec!["rust"], "main.foo");
|
||||
matched!(match8, types(), vec!["combo"], vec![], "index.html");
|
||||
matched!(match9, types(), vec!["combo"], vec![], "lib.rs");
|
||||
|
||||
matched!(not, matchnot1, types(), vec!["rust"], vec![], "index.html");
|
||||
matched!(not, matchnot2, types(), vec![], vec!["rust"], "main.rs");
|
||||
matched!(not, matchnot3, types(), vec!["foo"], vec!["rust"], "main.rs");
|
||||
matched!(not, matchnot4, types(), vec!["rust"], vec!["foo"], "main.rs");
|
||||
matched!(not, matchnot5, types(), vec!["rust"], vec!["foo"], "main.foo");
|
||||
matched!(not, matchnot6, types(), vec!["combo"], vec![], "leftpad.js");
|
||||
|
||||
#[test]
|
||||
fn test_invalid_defs() {
|
||||
let mut btypes = TypesBuilder::new();
|
||||
for tydef in types() {
|
||||
btypes.add_def(tydef).unwrap();
|
||||
}
|
||||
// Preserve the original definitions for later comparison.
|
||||
let original_defs = btypes.definitions();
|
||||
let bad_defs = vec![
|
||||
// Reference to type that does not exist
|
||||
"combo:include:html,python",
|
||||
// Bad format
|
||||
"combo:foobar:html,rust",
|
||||
""
|
||||
];
|
||||
for def in bad_defs {
|
||||
assert!(btypes.add_def(def).is_err());
|
||||
// Ensure that nothing changed, even if some of the includes were valid.
|
||||
assert_eq!(btypes.definitions(), original_defs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1443
ignore/src/walk.rs
1443
ignore/src/walk.rs
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,216 @@
|
||||
# Based on https://github.com/behnam/gitignore-test/blob/master/.gitignore
|
||||
|
||||
### file in root
|
||||
|
||||
# MATCH /file_root_1
|
||||
file_root_00
|
||||
|
||||
# NO_MATCH
|
||||
file_root_01/
|
||||
|
||||
# NO_MATCH
|
||||
file_root_02/*
|
||||
|
||||
# NO_MATCH
|
||||
file_root_03/**
|
||||
|
||||
|
||||
# MATCH /file_root_10
|
||||
/file_root_10
|
||||
|
||||
# NO_MATCH
|
||||
/file_root_11/
|
||||
|
||||
# NO_MATCH
|
||||
/file_root_12/*
|
||||
|
||||
# NO_MATCH
|
||||
/file_root_13/**
|
||||
|
||||
|
||||
# NO_MATCH
|
||||
*/file_root_20
|
||||
|
||||
# NO_MATCH
|
||||
*/file_root_21/
|
||||
|
||||
# NO_MATCH
|
||||
*/file_root_22/*
|
||||
|
||||
# NO_MATCH
|
||||
*/file_root_23/**
|
||||
|
||||
|
||||
# MATCH /file_root_30
|
||||
**/file_root_30
|
||||
|
||||
# NO_MATCH
|
||||
**/file_root_31/
|
||||
|
||||
# NO_MATCH
|
||||
**/file_root_32/*
|
||||
|
||||
# NO_MATCH
|
||||
**/file_root_33/**
|
||||
|
||||
|
||||
### file in sub-dir
|
||||
|
||||
# MATCH /parent_dir/file_deep_1
|
||||
file_deep_00
|
||||
|
||||
# NO_MATCH
|
||||
file_deep_01/
|
||||
|
||||
# NO_MATCH
|
||||
file_deep_02/*
|
||||
|
||||
# NO_MATCH
|
||||
file_deep_03/**
|
||||
|
||||
|
||||
# NO_MATCH
|
||||
/file_deep_10
|
||||
|
||||
# NO_MATCH
|
||||
/file_deep_11/
|
||||
|
||||
# NO_MATCH
|
||||
/file_deep_12/*
|
||||
|
||||
# NO_MATCH
|
||||
/file_deep_13/**
|
||||
|
||||
|
||||
# MATCH /parent_dir/file_deep_20
|
||||
*/file_deep_20
|
||||
|
||||
# NO_MATCH
|
||||
*/file_deep_21/
|
||||
|
||||
# NO_MATCH
|
||||
*/file_deep_22/*
|
||||
|
||||
# NO_MATCH
|
||||
*/file_deep_23/**
|
||||
|
||||
|
||||
# MATCH /parent_dir/file_deep_30
|
||||
**/file_deep_30
|
||||
|
||||
# NO_MATCH
|
||||
**/file_deep_31/
|
||||
|
||||
# NO_MATCH
|
||||
**/file_deep_32/*
|
||||
|
||||
# NO_MATCH
|
||||
**/file_deep_33/**
|
||||
|
||||
|
||||
### dir in root
|
||||
|
||||
# MATCH /dir_root_00
|
||||
dir_root_00
|
||||
|
||||
# MATCH /dir_root_01
|
||||
dir_root_01/
|
||||
|
||||
# MATCH /dir_root_02
|
||||
dir_root_02/*
|
||||
|
||||
# MATCH /dir_root_03
|
||||
dir_root_03/**
|
||||
|
||||
|
||||
# MATCH /dir_root_10
|
||||
/dir_root_10
|
||||
|
||||
# MATCH /dir_root_11
|
||||
/dir_root_11/
|
||||
|
||||
# MATCH /dir_root_12
|
||||
/dir_root_12/*
|
||||
|
||||
# MATCH /dir_root_13
|
||||
/dir_root_13/**
|
||||
|
||||
|
||||
# NO_MATCH
|
||||
*/dir_root_20
|
||||
|
||||
# NO_MATCH
|
||||
*/dir_root_21/
|
||||
|
||||
# NO_MATCH
|
||||
*/dir_root_22/*
|
||||
|
||||
# NO_MATCH
|
||||
*/dir_root_23/**
|
||||
|
||||
|
||||
# MATCH /dir_root_30
|
||||
**/dir_root_30
|
||||
|
||||
# MATCH /dir_root_31
|
||||
**/dir_root_31/
|
||||
|
||||
# MATCH /dir_root_32
|
||||
**/dir_root_32/*
|
||||
|
||||
# MATCH /dir_root_33
|
||||
**/dir_root_33/**
|
||||
|
||||
|
||||
### dir in sub-dir
|
||||
|
||||
# MATCH /parent_dir/dir_deep_00
|
||||
dir_deep_00
|
||||
|
||||
# MATCH /parent_dir/dir_deep_01
|
||||
dir_deep_01/
|
||||
|
||||
# NO_MATCH
|
||||
dir_deep_02/*
|
||||
|
||||
# NO_MATCH
|
||||
dir_deep_03/**
|
||||
|
||||
|
||||
# NO_MATCH
|
||||
/dir_deep_10
|
||||
|
||||
# NO_MATCH
|
||||
/dir_deep_11/
|
||||
|
||||
# NO_MATCH
|
||||
/dir_deep_12/*
|
||||
|
||||
# NO_MATCH
|
||||
/dir_deep_13/**
|
||||
|
||||
|
||||
# MATCH /parent_dir/dir_deep_20
|
||||
*/dir_deep_20
|
||||
|
||||
# MATCH /parent_dir/dir_deep_21
|
||||
*/dir_deep_21/
|
||||
|
||||
# MATCH /parent_dir/dir_deep_22
|
||||
*/dir_deep_22/*
|
||||
|
||||
# MATCH /parent_dir/dir_deep_23
|
||||
*/dir_deep_23/**
|
||||
|
||||
|
||||
# MATCH /parent_dir/dir_deep_30
|
||||
**/dir_deep_30
|
||||
|
||||
# MATCH /parent_dir/dir_deep_31
|
||||
**/dir_deep_31/
|
||||
|
||||
# MATCH /parent_dir/dir_deep_32
|
||||
**/dir_deep_32/*
|
||||
|
||||
# MATCH /parent_dir/dir_deep_33
|
||||
**/dir_deep_33/**
|
||||
297
ignore/tests/gitignore_matched_path_or_any_parents_tests.rs
Normal file
297
ignore/tests/gitignore_matched_path_or_any_parents_tests.rs
Normal file
@@ -0,0 +1,297 @@
|
||||
extern crate ignore;
|
||||
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use ignore::gitignore::{Gitignore, GitignoreBuilder};
|
||||
|
||||
|
||||
const IGNORE_FILE: &'static str = "tests/gitignore_matched_path_or_any_parents_tests.gitignore";
|
||||
|
||||
|
||||
fn get_gitignore() -> Gitignore {
|
||||
let mut builder = GitignoreBuilder::new("ROOT");
|
||||
let error = builder.add(IGNORE_FILE);
|
||||
assert!(error.is_none(), "failed to open gitignore file");
|
||||
builder.build().unwrap()
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "path is expect to be under the root")]
|
||||
fn test_path_should_be_under_root() {
|
||||
let gitignore = get_gitignore();
|
||||
let path = "/tmp/some_file";
|
||||
gitignore.matched_path_or_any_parents(Path::new(path), false);
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_files_in_root() {
|
||||
let gitignore = get_gitignore();
|
||||
let m = |path: &str| gitignore.matched_path_or_any_parents(Path::new(path), false);
|
||||
|
||||
// 0x
|
||||
assert!(m("ROOT/file_root_00").is_ignore());
|
||||
assert!(m("ROOT/file_root_01").is_none());
|
||||
assert!(m("ROOT/file_root_02").is_none());
|
||||
assert!(m("ROOT/file_root_03").is_none());
|
||||
|
||||
// 1x
|
||||
assert!(m("ROOT/file_root_10").is_ignore());
|
||||
assert!(m("ROOT/file_root_11").is_none());
|
||||
assert!(m("ROOT/file_root_12").is_none());
|
||||
assert!(m("ROOT/file_root_13").is_none());
|
||||
|
||||
// 2x
|
||||
assert!(m("ROOT/file_root_20").is_none());
|
||||
assert!(m("ROOT/file_root_21").is_none());
|
||||
assert!(m("ROOT/file_root_22").is_none());
|
||||
assert!(m("ROOT/file_root_23").is_none());
|
||||
|
||||
// 3x
|
||||
assert!(m("ROOT/file_root_30").is_ignore());
|
||||
assert!(m("ROOT/file_root_31").is_none());
|
||||
assert!(m("ROOT/file_root_32").is_none());
|
||||
assert!(m("ROOT/file_root_33").is_none());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_files_in_deep() {
|
||||
let gitignore = get_gitignore();
|
||||
let m = |path: &str| gitignore.matched_path_or_any_parents(Path::new(path), false);
|
||||
|
||||
// 0x
|
||||
assert!(m("ROOT/parent_dir/file_deep_00").is_ignore());
|
||||
assert!(m("ROOT/parent_dir/file_deep_01").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_02").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_03").is_none());
|
||||
|
||||
// 1x
|
||||
assert!(m("ROOT/parent_dir/file_deep_10").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_11").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_12").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_13").is_none());
|
||||
|
||||
// 2x
|
||||
assert!(m("ROOT/parent_dir/file_deep_20").is_ignore());
|
||||
assert!(m("ROOT/parent_dir/file_deep_21").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_22").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_23").is_none());
|
||||
|
||||
// 3x
|
||||
assert!(m("ROOT/parent_dir/file_deep_30").is_ignore());
|
||||
assert!(m("ROOT/parent_dir/file_deep_31").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_32").is_none());
|
||||
assert!(m("ROOT/parent_dir/file_deep_33").is_none());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_dirs_in_root() {
|
||||
let gitignore = get_gitignore();
|
||||
let m =
|
||||
|path: &str, is_dir: bool| gitignore.matched_path_or_any_parents(Path::new(path), is_dir);
|
||||
|
||||
// 00
|
||||
assert!(m("ROOT/dir_root_00", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_00/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_00/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_00/child_dir/file", false).is_ignore());
|
||||
|
||||
// 01
|
||||
assert!(m("ROOT/dir_root_01", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_01/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_01/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_01/child_dir/file", false).is_ignore());
|
||||
|
||||
// 02
|
||||
assert!(m("ROOT/dir_root_02", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/dir_root_02/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_02/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_02/child_dir/file", false).is_ignore());
|
||||
|
||||
// 03
|
||||
assert!(m("ROOT/dir_root_03", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/dir_root_03/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_03/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_03/child_dir/file", false).is_ignore());
|
||||
|
||||
// 10
|
||||
assert!(m("ROOT/dir_root_10", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_10/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_10/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_10/child_dir/file", false).is_ignore());
|
||||
|
||||
// 11
|
||||
assert!(m("ROOT/dir_root_11", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_11/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_11/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_11/child_dir/file", false).is_ignore());
|
||||
|
||||
// 12
|
||||
assert!(m("ROOT/dir_root_12", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/dir_root_12/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_12/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_12/child_dir/file", false).is_ignore());
|
||||
|
||||
// 13
|
||||
assert!(m("ROOT/dir_root_13", true).is_none());
|
||||
assert!(m("ROOT/dir_root_13/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_13/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_13/child_dir/file", false).is_ignore());
|
||||
|
||||
// 20
|
||||
assert!(m("ROOT/dir_root_20", true).is_none());
|
||||
assert!(m("ROOT/dir_root_20/file", false).is_none());
|
||||
assert!(m("ROOT/dir_root_20/child_dir", true).is_none());
|
||||
assert!(m("ROOT/dir_root_20/child_dir/file", false).is_none());
|
||||
|
||||
// 21
|
||||
assert!(m("ROOT/dir_root_21", true).is_none());
|
||||
assert!(m("ROOT/dir_root_21/file", false).is_none());
|
||||
assert!(m("ROOT/dir_root_21/child_dir", true).is_none());
|
||||
assert!(m("ROOT/dir_root_21/child_dir/file", false).is_none());
|
||||
|
||||
// 22
|
||||
assert!(m("ROOT/dir_root_22", true).is_none());
|
||||
assert!(m("ROOT/dir_root_22/file", false).is_none());
|
||||
assert!(m("ROOT/dir_root_22/child_dir", true).is_none());
|
||||
assert!(m("ROOT/dir_root_22/child_dir/file", false).is_none());
|
||||
|
||||
// 23
|
||||
assert!(m("ROOT/dir_root_23", true).is_none());
|
||||
assert!(m("ROOT/dir_root_23/file", false).is_none());
|
||||
assert!(m("ROOT/dir_root_23/child_dir", true).is_none());
|
||||
assert!(m("ROOT/dir_root_23/child_dir/file", false).is_none());
|
||||
|
||||
// 30
|
||||
assert!(m("ROOT/dir_root_30", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_30/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_30/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_30/child_dir/file", false).is_ignore());
|
||||
|
||||
// 31
|
||||
assert!(m("ROOT/dir_root_31", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_31/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_31/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_31/child_dir/file", false).is_ignore());
|
||||
|
||||
// 32
|
||||
assert!(m("ROOT/dir_root_32", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/dir_root_32/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_32/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_32/child_dir/file", false).is_ignore());
|
||||
|
||||
// 33
|
||||
assert!(m("ROOT/dir_root_33", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/dir_root_33/file", false).is_ignore());
|
||||
assert!(m("ROOT/dir_root_33/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/dir_root_33/child_dir/file", false).is_ignore());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_dirs_in_deep() {
|
||||
let gitignore = get_gitignore();
|
||||
let m =
|
||||
|path: &str, is_dir: bool| gitignore.matched_path_or_any_parents(Path::new(path), is_dir);
|
||||
|
||||
// 00
|
||||
assert!(m("ROOT/parent_dir/dir_deep_00", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_00/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_00/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_00/child_dir/file", false).is_ignore());
|
||||
|
||||
// 01
|
||||
assert!(m("ROOT/parent_dir/dir_deep_01", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_01/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_01/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_01/child_dir/file", false).is_ignore());
|
||||
|
||||
// 02
|
||||
assert!(m("ROOT/parent_dir/dir_deep_02", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_02/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_02/child_dir/file", false).is_none());
|
||||
|
||||
// 03
|
||||
assert!(m("ROOT/parent_dir/dir_deep_03", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_03/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_03/child_dir/file", false).is_none());
|
||||
|
||||
// 10
|
||||
assert!(m("ROOT/parent_dir/dir_deep_10", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_10/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_10/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_10/child_dir/file", false).is_none());
|
||||
|
||||
// 11
|
||||
assert!(m("ROOT/parent_dir/dir_deep_11", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_11/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_11/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_11/child_dir/file", false).is_none());
|
||||
|
||||
// 12
|
||||
assert!(m("ROOT/parent_dir/dir_deep_12", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_12/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_12/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_12/child_dir/file", false).is_none());
|
||||
|
||||
// 13
|
||||
assert!(m("ROOT/parent_dir/dir_deep_13", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_13/file", false).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_13/child_dir", true).is_none());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_13/child_dir/file", false).is_none());
|
||||
|
||||
// 20
|
||||
assert!(m("ROOT/parent_dir/dir_deep_20", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_20/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_20/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_20/child_dir/file", false).is_ignore());
|
||||
|
||||
// 21
|
||||
assert!(m("ROOT/parent_dir/dir_deep_21", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_21/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_21/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_21/child_dir/file", false).is_ignore());
|
||||
|
||||
// 22
|
||||
assert!(m("ROOT/parent_dir/dir_deep_22", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/parent_dir/dir_deep_22/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_22/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_22/child_dir/file", false).is_ignore());
|
||||
|
||||
// 23
|
||||
assert!(m("ROOT/parent_dir/dir_deep_23", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/parent_dir/dir_deep_23/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_23/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_23/child_dir/file", false).is_ignore());
|
||||
|
||||
// 30
|
||||
assert!(m("ROOT/parent_dir/dir_deep_30", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_30/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_30/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_30/child_dir/file", false).is_ignore());
|
||||
|
||||
// 31
|
||||
assert!(m("ROOT/parent_dir/dir_deep_31", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_31/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_31/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_31/child_dir/file", false).is_ignore());
|
||||
|
||||
// 32
|
||||
assert!(m("ROOT/parent_dir/dir_deep_32", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/parent_dir/dir_deep_32/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_32/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_32/child_dir/file", false).is_ignore());
|
||||
|
||||
// 33
|
||||
assert!(m("ROOT/parent_dir/dir_deep_33", true).is_none()); // dir itself doesn't match
|
||||
assert!(m("ROOT/parent_dir/dir_deep_33/file", false).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_33/child_dir", true).is_ignore());
|
||||
assert!(m("ROOT/parent_dir/dir_deep_33/child_dir/file", false).is_ignore());
|
||||
}
|
||||
4
pkg/archlinux/.gitignore
vendored
4
pkg/archlinux/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
*.xz
|
||||
src
|
||||
pkg
|
||||
*.gz
|
||||
@@ -1,37 +0,0 @@
|
||||
# Contributor: Andrew Gallant <jamslam@gmail.com>
|
||||
# Maintainer: Andrew Gallant
|
||||
pkgname=ripgrep
|
||||
pkgver=0.2.3
|
||||
pkgrel=1
|
||||
pkgdesc="A search tool that combines the usability of The Silver Searcher with the raw speed of grep."
|
||||
arch=('i686' 'x86_64')
|
||||
url="https://github.com/BurntSushi/ripgrep"
|
||||
license=('UNLICENSE')
|
||||
makedepends=('cargo')
|
||||
source=("https://github.com/BurntSushi/$pkgname/archive/$pkgver.tar.gz")
|
||||
sha256sums=('a88531558d2023df76190ea2e52bee50d739eabece8a57df29abbad0c6bdb917')
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
if command -v rustup > /dev/null 2>&1; then
|
||||
RUSTFLAGS="-C target-cpu=native" rustup run nightly \
|
||||
cargo build --release --features simd-accel
|
||||
elif rustc --version | grep -q nightly; then
|
||||
RUSTFLAGS="-C target-cpu=native" \
|
||||
cargo build --release --features simd-accel
|
||||
else
|
||||
cargo build --release
|
||||
fi
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
install -Dm755 "target/release/rg" "$pkgdir/usr/bin/rg"
|
||||
install -Dm644 "doc/rg.1" "$pkgdir/usr/share/man/man1/rg.1"
|
||||
install -Dm644 "README.md" "$pkgdir/usr/share/doc/ripgrep/README.md"
|
||||
install -Dm644 "COPYING" "$pkgdir/usr/share/doc/ripgrep/COPYING"
|
||||
install -Dm644 "LICENSE-MIT" "$pkgdir/usr/share/doc/ripgrep/LICENSE-MIT"
|
||||
install -Dm644 "UNLICENSE" "$pkgdir/usr/share/doc/ripgrep/UNLICENSE"
|
||||
install -Dm644 "CHANGELOG.md" "$pkgdir/usr/share/doc/ripgrep/CHANGELOG.md"
|
||||
}
|
||||
@@ -1,14 +1,24 @@
|
||||
class RipgrepBin < Formula
|
||||
version '0.2.5'
|
||||
desc "Search tool like grep and The Silver Searcher."
|
||||
version '0.8.0'
|
||||
desc "Recursively search directories for a regex pattern."
|
||||
homepage "https://github.com/BurntSushi/ripgrep"
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "c6775a50c6f769de2ee66892a700961ec60a85219aa414ef6880dfcc17bf2467"
|
||||
|
||||
if OS.mac?
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "fb35e92fd57d28a1e68daf964764c3da7f027ad30cca7a07a1848224776f36b2"
|
||||
elsif OS.linux?
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-unknown-linux-musl.tar.gz"
|
||||
sha256 "621f2f16f65203aa37e7c10ecfb22384c4c01e70ebbd30a13c0d6944ffc6e59e"
|
||||
end
|
||||
|
||||
conflicts_with "ripgrep"
|
||||
|
||||
def install
|
||||
bin.install "rg"
|
||||
man1.install "rg.1"
|
||||
man1.install "doc/rg.1"
|
||||
|
||||
bash_completion.install "complete/rg.bash"
|
||||
fish_completion.install "complete/rg.fish"
|
||||
zsh_completion.install "complete/_rg"
|
||||
end
|
||||
end
|
||||
|
||||
15
snapcraft.yaml
Normal file
15
snapcraft.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
name: ripgrep # you probably want to 'snapcraft register <name>'
|
||||
version: '0.5.1' # just for humans, typically '1.2+git' or '1.3.2'
|
||||
summary: Fast file searcher # 79 char long summary
|
||||
description: |
|
||||
ripgrep combines the usability of The Silver Searcher with the raw speed of grep.
|
||||
grade: stable # must be 'stable' to release into candidate/stable channels
|
||||
confinement: classic # use 'strict' once you have the right plugs and slots
|
||||
parts:
|
||||
ripgrep:
|
||||
plugin: rust
|
||||
source: .
|
||||
apps:
|
||||
rg:
|
||||
command: env PATH=$SNAP/bin:$PATH rg
|
||||
aliases: [rg]
|
||||
1646
src/app.rs
Normal file
1646
src/app.rs
Normal file
File diff suppressed because it is too large
Load Diff
1695
src/args.rs
1695
src/args.rs
File diff suppressed because it is too large
Load Diff
69
src/atty.rs
69
src/atty.rs
@@ -1,69 +0,0 @@
|
||||
/*!
|
||||
This atty module contains functions for detecting whether ripgrep is being fed
|
||||
from (or to) a terminal. Windows and Unix do this differently, so implement
|
||||
both here.
|
||||
*/
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn stdin_is_readable() -> bool {
|
||||
use std::fs::File;
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use libc;
|
||||
|
||||
let file = unsafe { File::from_raw_fd(libc::STDIN_FILENO) };
|
||||
let md = file.metadata();
|
||||
let _ = file.into_raw_fd();
|
||||
let ft = match md {
|
||||
Err(_) => return false,
|
||||
Ok(md) => md.file_type(),
|
||||
};
|
||||
ft.is_file() || ft.is_fifo()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn stdin_is_readable() -> bool {
|
||||
// ???
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns true if there is a tty on stdin.
|
||||
#[cfg(unix)]
|
||||
pub fn on_stdin() -> bool {
|
||||
use libc;
|
||||
0 < unsafe { libc::isatty(libc::STDIN_FILENO) }
|
||||
}
|
||||
|
||||
/// Returns true if there is a tty on stdout.
|
||||
#[cfg(unix)]
|
||||
pub fn on_stdout() -> bool {
|
||||
use libc;
|
||||
0 < unsafe { libc::isatty(libc::STDOUT_FILENO) }
|
||||
}
|
||||
|
||||
/// Returns true if there is a tty on stdin.
|
||||
#[cfg(windows)]
|
||||
pub fn on_stdin() -> bool {
|
||||
// BUG: https://github.com/BurntSushi/ripgrep/issues/19
|
||||
// It's not clear to me how to determine whether there is a tty on stdin.
|
||||
// Checking GetConsoleMode(GetStdHandle(stdin)) != 0 appears to report
|
||||
// that stdin is a pipe, even if it's not in a cygwin terminal, for
|
||||
// example.
|
||||
//
|
||||
// To fix this, we just assume there is always a tty on stdin. If Windows
|
||||
// users need to search stdin, they'll have to pass -. Ug.
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns true if there is a tty on stdout.
|
||||
#[cfg(windows)]
|
||||
pub fn on_stdout() -> bool {
|
||||
use kernel32;
|
||||
use winapi;
|
||||
|
||||
unsafe {
|
||||
let fd = winapi::winbase::STD_OUTPUT_HANDLE;
|
||||
let mut out = 0;
|
||||
kernel32::GetConsoleMode(kernel32::GetStdHandle(fd), &mut out) != 0
|
||||
}
|
||||
}
|
||||
195
src/config.rs
Normal file
195
src/config.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
// This module provides routines for reading ripgrep config "rc" files. The
|
||||
// primary output of these routines is a sequence of arguments, where each
|
||||
// argument corresponds precisely to one shell argument.
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use Result;
|
||||
|
||||
/// Return a sequence of arguments derived from ripgrep rc configuration files.
|
||||
///
|
||||
/// If no_messages is false and there was a problem reading a config file,
|
||||
/// then errors are printed to stderr.
|
||||
pub fn args(no_messages: bool) -> Vec<OsString> {
|
||||
let config_path = match env::var_os("RIPGREP_CONFIG_PATH") {
|
||||
None => return vec![],
|
||||
Some(config_path) => {
|
||||
if config_path.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
PathBuf::from(config_path)
|
||||
}
|
||||
};
|
||||
let (args, errs) = match parse(&config_path) {
|
||||
Ok((args, errs)) => (args, errs),
|
||||
Err(err) => {
|
||||
if !no_messages {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
if !no_messages && !errs.is_empty() {
|
||||
for err in errs {
|
||||
eprintln!("{}:{}", config_path.display(), err);
|
||||
}
|
||||
}
|
||||
debug!(
|
||||
"{}: arguments loaded from config file: {:?}",
|
||||
config_path.display(), args);
|
||||
args
|
||||
}
|
||||
|
||||
/// Parse a single ripgrep rc file from the given path.
|
||||
///
|
||||
/// On success, this returns a set of shell arguments, in order, that should
|
||||
/// be pre-pended to the arguments given to ripgrep at the command line.
|
||||
///
|
||||
/// If the file could not be read, then an error is returned. If there was
|
||||
/// a problem parsing one or more lines in the file, then errors are returned
|
||||
/// for each line in addition to successfully parsed arguments.
|
||||
fn parse<P: AsRef<Path>>(
|
||||
path: P,
|
||||
) -> Result<(Vec<OsString>, Vec<Box<Error>>)> {
|
||||
let path = path.as_ref();
|
||||
match File::open(&path) {
|
||||
Ok(file) => parse_reader(file),
|
||||
Err(err) => errored!("{}: {}", path.display(), err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a single ripgrep rc file from the given reader.
|
||||
///
|
||||
/// Callers should not provided a buffered reader, as this routine will use its
|
||||
/// own buffer internally.
|
||||
///
|
||||
/// On success, this returns a set of shell arguments, in order, that should
|
||||
/// be pre-pended to the arguments given to ripgrep at the command line.
|
||||
///
|
||||
/// If the reader could not be read, then an error is returned. If there was a
|
||||
/// problem parsing one or more lines, then errors are returned for each line
|
||||
/// in addition to successfully parsed arguments.
|
||||
fn parse_reader<R: io::Read>(
|
||||
rdr: R,
|
||||
) -> Result<(Vec<OsString>, Vec<Box<Error>>)> {
|
||||
let mut bufrdr = io::BufReader::new(rdr);
|
||||
let (mut args, mut errs) = (vec![], vec![]);
|
||||
let mut line = vec![];
|
||||
let mut line_number = 0;
|
||||
while {
|
||||
line.clear();
|
||||
line_number += 1;
|
||||
bufrdr.read_until(b'\n', &mut line)? > 0
|
||||
} {
|
||||
trim(&mut line);
|
||||
if line.is_empty() || line[0] == b'#' {
|
||||
continue;
|
||||
}
|
||||
match bytes_to_os_string(&line) {
|
||||
Ok(osstr) => {
|
||||
args.push(osstr);
|
||||
}
|
||||
Err(err) => {
|
||||
errs.push(format!("{}: {}", line_number, err).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((args, errs))
|
||||
}
|
||||
|
||||
/// Trim the given bytes of whitespace according to the ASCII definition.
|
||||
fn trim(x: &mut Vec<u8>) {
|
||||
let upto = x.iter().take_while(|b| is_space(**b)).count();
|
||||
x.drain(..upto);
|
||||
let revto = x.len() - x.iter().rev().take_while(|b| is_space(**b)).count();
|
||||
x.drain(revto..);
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given byte is an ASCII space character.
|
||||
fn is_space(b: u8) -> bool {
|
||||
b == b'\t'
|
||||
|| b == b'\n'
|
||||
|| b == b'\x0B'
|
||||
|| b == b'\x0C'
|
||||
|| b == b'\r'
|
||||
|| b == b' '
|
||||
}
|
||||
|
||||
/// On Unix, get an OsString from raw bytes.
|
||||
#[cfg(unix)]
|
||||
fn bytes_to_os_string(bytes: &[u8]) -> Result<OsString> {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
Ok(OsString::from_vec(bytes.to_vec()))
|
||||
}
|
||||
|
||||
/// On non-Unix (like Windows), require UTF-8.
|
||||
#[cfg(not(unix))]
|
||||
fn bytes_to_os_string(bytes: &[u8]) -> Result<OsString> {
|
||||
String::from_utf8(bytes.to_vec()).map(OsString::from).map_err(From::from)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::ffi::OsString;
|
||||
use super::parse_reader;
|
||||
|
||||
#[test]
|
||||
fn basic() {
|
||||
let (args, errs) = parse_reader(&b"\
|
||||
# Test
|
||||
--context=0
|
||||
--smart-case
|
||||
-u
|
||||
|
||||
|
||||
# --bar
|
||||
--foo
|
||||
"[..]).unwrap();
|
||||
assert!(errs.is_empty());
|
||||
let args: Vec<String> =
|
||||
args.into_iter().map(|s| s.into_string().unwrap()).collect();
|
||||
assert_eq!(args, vec![
|
||||
"--context=0", "--smart-case", "-u", "--foo",
|
||||
]);
|
||||
}
|
||||
|
||||
// We test that we can handle invalid UTF-8 on Unix-like systems.
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn error() {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
let (args, errs) = parse_reader(&b"\
|
||||
quux
|
||||
foo\xFFbar
|
||||
baz
|
||||
"[..]).unwrap();
|
||||
assert!(errs.is_empty());
|
||||
assert_eq!(args, vec![
|
||||
OsString::from("quux"),
|
||||
OsString::from_vec(b"foo\xFFbar".to_vec()),
|
||||
OsString::from("baz"),
|
||||
]);
|
||||
}
|
||||
|
||||
// ... but test that invalid UTF-8 fails on Windows.
|
||||
#[test]
|
||||
#[cfg(not(unix))]
|
||||
fn error() {
|
||||
let (args, errs) = parse_reader(&b"\
|
||||
quux
|
||||
foo\xFFbar
|
||||
baz
|
||||
"[..]).unwrap();
|
||||
assert_eq!(errs.len(), 1);
|
||||
assert_eq!(args, vec![
|
||||
OsString::from("quux"),
|
||||
OsString::from("baz"),
|
||||
]);
|
||||
}
|
||||
}
|
||||
456
src/decoder.rs
Normal file
456
src/decoder.rs
Normal file
@@ -0,0 +1,456 @@
|
||||
use std::cmp;
|
||||
use std::io::{self, Read};
|
||||
|
||||
use encoding_rs::{Decoder, Encoding, UTF_8};
|
||||
|
||||
/// A BOM is at least 2 bytes and at most 3 bytes.
|
||||
///
|
||||
/// If fewer than 2 bytes are available to be read at the beginning of a
|
||||
/// reader, then a BOM is `None`.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
struct Bom {
|
||||
bytes: [u8; 3],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Bom {
|
||||
fn as_slice(&self) -> &[u8] {
|
||||
&self.bytes[0..self.len]
|
||||
}
|
||||
|
||||
fn decoder(&self) -> Option<Decoder> {
|
||||
let bom = self.as_slice();
|
||||
if bom.len() < 3 {
|
||||
return None;
|
||||
}
|
||||
if let Some((enc, _)) = Encoding::for_bom(bom) {
|
||||
if enc != UTF_8 {
|
||||
return Some(enc.new_decoder_with_bom_removal());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// `BomPeeker` wraps `R` and satisfies the `io::Read` interface while also
|
||||
/// providing a peek at the BOM if one exists. Peeking at the BOM does not
|
||||
/// advance the reader.
|
||||
struct BomPeeker<R> {
|
||||
rdr: R,
|
||||
bom: Option<Bom>,
|
||||
nread: usize,
|
||||
}
|
||||
|
||||
impl<R: io::Read> BomPeeker<R> {
|
||||
/// Create a new BomPeeker.
|
||||
///
|
||||
/// The first three bytes can be read using the `peek_bom` method, but
|
||||
/// will not advance the reader.
|
||||
fn new(rdr: R) -> BomPeeker<R> {
|
||||
BomPeeker { rdr: rdr, bom: None, nread: 0 }
|
||||
}
|
||||
|
||||
/// Peek at the first three bytes of the underlying reader.
|
||||
///
|
||||
/// This does not advance the reader provided by `BomPeeker`.
|
||||
///
|
||||
/// If the underlying reader does not have at least two bytes available,
|
||||
/// then `None` is returned.
|
||||
fn peek_bom(&mut self) -> io::Result<Bom> {
|
||||
if let Some(bom) = self.bom {
|
||||
return Ok(bom);
|
||||
}
|
||||
self.bom = Some(Bom { bytes: [0; 3], len: 0 });
|
||||
let mut buf = [0u8; 3];
|
||||
let bom_len = read_full(&mut self.rdr, &mut buf)?;
|
||||
self.bom = Some(Bom { bytes: buf, len: bom_len });
|
||||
Ok(self.bom.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: io::Read> io::Read for BomPeeker<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
if self.nread < 3 {
|
||||
let bom = self.peek_bom()?;
|
||||
let bom = bom.as_slice();
|
||||
if self.nread < bom.len() {
|
||||
let rest = &bom[self.nread..];
|
||||
let len = cmp::min(buf.len(), rest.len());
|
||||
buf[..len].copy_from_slice(&rest[..len]);
|
||||
self.nread += len;
|
||||
return Ok(len);
|
||||
}
|
||||
}
|
||||
let nread = self.rdr.read(buf)?;
|
||||
self.nread += nread;
|
||||
Ok(nread)
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `io::Read::read_exact`, except it never returns `UnexpectedEof` and
|
||||
/// instead returns the number of bytes read if EOF is seen before filling
|
||||
/// `buf`.
|
||||
fn read_full<R: io::Read>(
|
||||
mut rdr: R,
|
||||
mut buf: &mut [u8],
|
||||
) -> io::Result<usize> {
|
||||
let mut nread = 0;
|
||||
while !buf.is_empty() {
|
||||
match rdr.read(buf) {
|
||||
Ok(0) => break,
|
||||
Ok(n) => {
|
||||
nread += n;
|
||||
let tmp = buf;
|
||||
buf = &mut tmp[n..];
|
||||
}
|
||||
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(nread)
|
||||
}
|
||||
|
||||
/// A reader that transcodes to UTF-8. The source encoding is determined by
|
||||
/// inspecting the BOM from the stream read from `R`, if one exists. If a
|
||||
/// UTF-16 BOM exists, then the source stream is transcoded to UTF-8 with
|
||||
/// invalid UTF-16 sequences translated to the Unicode replacement character.
|
||||
/// In all other cases, the underlying reader is passed through unchanged.
|
||||
///
|
||||
/// `R` is the type of the underlying reader and `B` is the type of an internal
|
||||
/// buffer used to store the results of transcoding.
|
||||
///
|
||||
/// Note that not all methods on `io::Read` work with this implementation.
|
||||
/// For example, the `bytes` adapter method attempts to read a single byte at
|
||||
/// a time, but this implementation requires a buffer of size at least `4`. If
|
||||
/// a buffer of size less than 4 is given, then an error is returned.
|
||||
pub struct DecodeReader<R, B> {
|
||||
/// The underlying reader, wrapped in a peeker for reading a BOM if one
|
||||
/// exists.
|
||||
rdr: BomPeeker<R>,
|
||||
/// The internal buffer to store transcoded bytes before they are read by
|
||||
/// callers.
|
||||
buf: B,
|
||||
/// The current position in `buf`. Subsequent reads start here.
|
||||
pos: usize,
|
||||
/// The number of transcoded bytes in `buf`. Subsequent reads end here.
|
||||
buflen: usize,
|
||||
/// Whether this is the first read or not (in which we inspect the BOM).
|
||||
first: bool,
|
||||
/// Whether a "last" read has occurred. After this point, EOF will always
|
||||
/// be returned.
|
||||
last: bool,
|
||||
/// The underlying text decoder derived from the BOM, if one exists.
|
||||
decoder: Option<Decoder>,
|
||||
}
|
||||
|
||||
impl<R: io::Read, B: AsMut<[u8]>> DecodeReader<R, B> {
|
||||
/// Create a new transcoder that converts a source stream to valid UTF-8.
|
||||
///
|
||||
/// If an encoding is specified, then it is used to transcode `rdr` to
|
||||
/// UTF-8. Otherwise, if no encoding is specified, and if a UTF-16 BOM is
|
||||
/// found, then the corresponding UTF-16 encoding is used to transcode
|
||||
/// `rdr` to UTF-8. In all other cases, `rdr` is assumed to be at least
|
||||
/// ASCII-compatible and passed through untouched.
|
||||
///
|
||||
/// Errors in the encoding of `rdr` are handled with the Unicode
|
||||
/// replacement character. If no encoding of `rdr` is specified, then
|
||||
/// errors are not handled.
|
||||
pub fn new(
|
||||
rdr: R,
|
||||
buf: B,
|
||||
enc: Option<&'static Encoding>,
|
||||
) -> DecodeReader<R, B> {
|
||||
DecodeReader {
|
||||
rdr: BomPeeker::new(rdr),
|
||||
buf: buf,
|
||||
buflen: 0,
|
||||
pos: 0,
|
||||
first: enc.is_none(),
|
||||
last: false,
|
||||
decoder: enc.map(|enc| enc.new_decoder_with_bom_removal()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill the internal buffer from the underlying reader.
|
||||
///
|
||||
/// If there are unread bytes in the internal buffer, then we move them
|
||||
/// to the beginning of the internal buffer and fill the remainder.
|
||||
///
|
||||
/// If the internal buffer is too small to read additional bytes, then an
|
||||
/// error is returned.
|
||||
#[inline(always)] // massive perf benefit (???)
|
||||
fn fill(&mut self) -> io::Result<()> {
|
||||
if self.pos < self.buflen {
|
||||
if self.buflen >= self.buf.as_mut().len() {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"DecodeReader: internal buffer exhausted"));
|
||||
}
|
||||
let newlen = self.buflen - self.pos;
|
||||
let mut tmp = Vec::with_capacity(newlen);
|
||||
tmp.extend_from_slice(&self.buf.as_mut()[self.pos..self.buflen]);
|
||||
self.buf.as_mut()[..newlen].copy_from_slice(&tmp);
|
||||
self.buflen = newlen;
|
||||
} else {
|
||||
self.buflen = 0;
|
||||
}
|
||||
self.pos = 0;
|
||||
self.buflen +=
|
||||
self.rdr.read(&mut self.buf.as_mut()[self.buflen..])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Transcode the inner stream to UTF-8 in `buf`. This assumes that there
|
||||
/// is a decoder capable of transcoding the inner stream to UTF-8. This
|
||||
/// returns the number of bytes written to `buf`.
|
||||
///
|
||||
/// When this function returns, exactly one of the following things will
|
||||
/// be true:
|
||||
///
|
||||
/// 1. A non-zero number of bytes were written to `buf`.
|
||||
/// 2. The underlying reader reached EOF.
|
||||
/// 3. An error is returned: the internal buffer ran out of room.
|
||||
/// 4. An I/O error occurred.
|
||||
///
|
||||
/// Note that `buf` must have at least 4 bytes of space.
|
||||
fn transcode(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
assert!(buf.len() >= 4);
|
||||
if self.last {
|
||||
return Ok(0);
|
||||
}
|
||||
if self.pos >= self.buflen {
|
||||
self.fill()?;
|
||||
}
|
||||
let mut nwrite = 0;
|
||||
loop {
|
||||
let (_, nin, nout, _) =
|
||||
self.decoder.as_mut().unwrap().decode_to_utf8(
|
||||
&self.buf.as_mut()[self.pos..self.buflen], buf, false);
|
||||
self.pos += nin;
|
||||
nwrite += nout;
|
||||
// If we've written at least one byte to the caller-provided
|
||||
// buffer, then our mission is complete.
|
||||
if nwrite > 0 {
|
||||
break;
|
||||
}
|
||||
// Otherwise, we know that our internal buffer has insufficient
|
||||
// data to transcode at least one char, so we attempt to refill it.
|
||||
self.fill()?;
|
||||
// Quit on EOF.
|
||||
if self.buflen == 0 {
|
||||
self.pos = 0;
|
||||
self.last = true;
|
||||
let (_, _, nout, _) =
|
||||
self.decoder.as_mut().unwrap().decode_to_utf8(
|
||||
&[], buf, true);
|
||||
return Ok(nout);
|
||||
}
|
||||
}
|
||||
Ok(nwrite)
|
||||
}
|
||||
|
||||
#[inline(never)] // impacts perf...
|
||||
fn detect(&mut self) -> io::Result<()> {
|
||||
let bom = self.rdr.peek_bom()?;
|
||||
self.decoder = bom.decoder();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: io::Read, B: AsMut<[u8]>> io::Read for DecodeReader<R, B> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
if self.first {
|
||||
self.first = false;
|
||||
self.detect()?;
|
||||
}
|
||||
if self.decoder.is_none() {
|
||||
return self.rdr.read(buf);
|
||||
}
|
||||
// When decoding UTF-8, we need at least 4 bytes of space to guarantee
|
||||
// that we can decode at least one codepoint. If we don't have it, we
|
||||
// can either return `0` for the number of bytes read or return an
|
||||
// error. Since `0` would be interpreted as a possibly premature EOF,
|
||||
// we opt for an error.
|
||||
if buf.len() < 4 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"DecodeReader: byte buffer must have length at least 4"));
|
||||
}
|
||||
self.transcode(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::io::Read;
|
||||
|
||||
use encoding_rs::Encoding;
|
||||
|
||||
use super::{Bom, BomPeeker, DecodeReader};
|
||||
|
||||
fn read_to_string<R: Read>(mut rdr: R) -> String {
|
||||
let mut s = String::new();
|
||||
rdr.read_to_string(&mut s).unwrap();
|
||||
s
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_empty() {
|
||||
let buf = [];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
assert_eq!(Bom { bytes: [0; 3], len: 0}, peeker.peek_bom().unwrap());
|
||||
|
||||
let mut tmp = [0; 100];
|
||||
assert_eq!(0, peeker.read(&mut tmp).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_one() {
|
||||
let buf = [1];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
assert_eq!(
|
||||
Bom { bytes: [1, 0, 0], len: 1},
|
||||
peeker.peek_bom().unwrap());
|
||||
|
||||
let mut tmp = [0; 100];
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(1, tmp[0]);
|
||||
assert_eq!(0, peeker.read(&mut tmp).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_two() {
|
||||
let buf = [1, 2];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
assert_eq!(
|
||||
Bom { bytes: [1, 2, 0], len: 2},
|
||||
peeker.peek_bom().unwrap());
|
||||
|
||||
let mut tmp = [0; 100];
|
||||
assert_eq!(2, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(1, tmp[0]);
|
||||
assert_eq!(2, tmp[1]);
|
||||
assert_eq!(0, peeker.read(&mut tmp).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_three() {
|
||||
let buf = [1, 2, 3];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
assert_eq!(
|
||||
Bom { bytes: [1, 2, 3], len: 3},
|
||||
peeker.peek_bom().unwrap());
|
||||
|
||||
let mut tmp = [0; 100];
|
||||
assert_eq!(3, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(1, tmp[0]);
|
||||
assert_eq!(2, tmp[1]);
|
||||
assert_eq!(3, tmp[2]);
|
||||
assert_eq!(0, peeker.read(&mut tmp).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_four() {
|
||||
let buf = [1, 2, 3, 4];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
assert_eq!(
|
||||
Bom { bytes: [1, 2, 3], len: 3},
|
||||
peeker.peek_bom().unwrap());
|
||||
|
||||
let mut tmp = [0; 100];
|
||||
assert_eq!(3, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(1, tmp[0]);
|
||||
assert_eq!(2, tmp[1]);
|
||||
assert_eq!(3, tmp[2]);
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(4, tmp[0]);
|
||||
assert_eq!(0, peeker.read(&mut tmp).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peeker_one_at_a_time() {
|
||||
let buf = [1, 2, 3, 4];
|
||||
let mut peeker = BomPeeker::new(&buf[..]);
|
||||
|
||||
let mut tmp = [0; 1];
|
||||
assert_eq!(0, peeker.read(&mut tmp[..0]).unwrap());
|
||||
assert_eq!(0, tmp[0]);
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(1, tmp[0]);
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(2, tmp[0]);
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(3, tmp[0]);
|
||||
assert_eq!(1, peeker.read(&mut tmp).unwrap());
|
||||
assert_eq!(4, tmp[0]);
|
||||
}
|
||||
|
||||
// In cases where all we have is a bom, we expect the bytes to be
|
||||
// passed through unchanged.
|
||||
#[test]
|
||||
fn trans_utf16_bom() {
|
||||
let srcbuf = vec![0xFF, 0xFE];
|
||||
let mut dstbuf = vec![0; 8 * (1<<10)];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
let n = rdr.read(&mut dstbuf).unwrap();
|
||||
assert_eq!(&*srcbuf, &dstbuf[..n]);
|
||||
|
||||
let srcbuf = vec![0xFE, 0xFF];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
let n = rdr.read(&mut dstbuf).unwrap();
|
||||
assert_eq!(&*srcbuf, &dstbuf[..n]);
|
||||
|
||||
let srcbuf = vec![0xEF, 0xBB, 0xBF];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
let n = rdr.read(&mut dstbuf).unwrap();
|
||||
assert_eq!(&*srcbuf, &dstbuf[..n]);
|
||||
}
|
||||
|
||||
// Test basic UTF-16 decoding.
|
||||
#[test]
|
||||
fn trans_utf16_basic() {
|
||||
let srcbuf = vec![0xFF, 0xFE, 0x61, 0x00];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
assert_eq!("a", read_to_string(&mut rdr));
|
||||
|
||||
let srcbuf = vec![0xFE, 0xFF, 0x00, 0x61];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
assert_eq!("a", read_to_string(&mut rdr));
|
||||
}
|
||||
|
||||
// Test incomplete UTF-16 decoding. This ensures we see a replacement char
|
||||
// if the stream ends with an unpaired code unit.
|
||||
#[test]
|
||||
fn trans_utf16_incomplete() {
|
||||
let srcbuf = vec![0xFF, 0xFE, 0x61, 0x00, 0x00];
|
||||
let mut rdr = DecodeReader::new(&*srcbuf, vec![0; 8 * (1<<10)], None);
|
||||
assert_eq!("a\u{FFFD}", read_to_string(&mut rdr));
|
||||
}
|
||||
|
||||
macro_rules! test_trans_simple {
|
||||
($name:ident, $enc:expr, $srcbytes:expr, $dst:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let srcbuf = &$srcbytes[..];
|
||||
let enc = Encoding::for_label($enc.as_bytes());
|
||||
let mut rdr = DecodeReader::new(
|
||||
&*srcbuf, vec![0; 8 * (1<<10)], enc);
|
||||
assert_eq!($dst, read_to_string(&mut rdr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This isn't exhaustive obviously, but it lets us test base level support.
|
||||
test_trans_simple!(trans_simple_auto, "does not exist", b"\xD0\x96", "Ж");
|
||||
test_trans_simple!(trans_simple_utf8, "utf-8", b"\xD0\x96", "Ж");
|
||||
test_trans_simple!(trans_simple_utf16le, "utf-16le", b"\x16\x04", "Ж");
|
||||
test_trans_simple!(trans_simple_utf16be, "utf-16be", b"\x04\x16", "Ж");
|
||||
test_trans_simple!(trans_simple_chinese, "chinese", b"\xA7\xA8", "Ж");
|
||||
test_trans_simple!(trans_simple_korean, "korean", b"\xAC\xA8", "Ж");
|
||||
test_trans_simple!(
|
||||
trans_simple_big5_hkscs, "big5-hkscs", b"\xC7\xFA", "Ж");
|
||||
test_trans_simple!(trans_simple_gbk, "gbk", b"\xA7\xA8", "Ж");
|
||||
test_trans_simple!(trans_simple_sjis, "sjis", b"\x84\x47", "Ж");
|
||||
test_trans_simple!(trans_simple_eucjp, "euc-jp", b"\xA7\xA8", "Ж");
|
||||
test_trans_simple!(trans_simple_latin1, "latin1", b"\xA9", "©");
|
||||
}
|
||||
191
src/decompressor.rs
Normal file
191
src/decompressor.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
use std::process::{self, Stdio};
|
||||
|
||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||
|
||||
/// A decompression command, contains the command to be spawned as well as any
|
||||
/// necessary CLI args.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct DecompressionCommand {
|
||||
cmd: &'static str,
|
||||
args: &'static [&'static str],
|
||||
}
|
||||
|
||||
impl DecompressionCommand {
|
||||
/// Create a new decompress command
|
||||
fn new(
|
||||
cmd: &'static str,
|
||||
args: &'static [&'static str],
|
||||
) -> DecompressionCommand {
|
||||
DecompressionCommand {
|
||||
cmd, args
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DecompressionCommand {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {}", self.cmd, self.args.join(" "))
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref DECOMPRESSION_COMMANDS: HashMap<
|
||||
&'static str,
|
||||
DecompressionCommand,
|
||||
> = {
|
||||
let mut m = HashMap::new();
|
||||
|
||||
const ARGS: &[&str] = &["-d", "-c"];
|
||||
m.insert("gz", DecompressionCommand::new("gzip", ARGS));
|
||||
m.insert("bz2", DecompressionCommand::new("bzip2", ARGS));
|
||||
m.insert("xz", DecompressionCommand::new("xz", ARGS));
|
||||
|
||||
const LZMA_ARGS: &[&str] = &["--format=lzma", "-d", "-c"];
|
||||
m.insert("lzma", DecompressionCommand::new("xz", LZMA_ARGS));
|
||||
|
||||
m
|
||||
};
|
||||
static ref SUPPORTED_COMPRESSION_FORMATS: GlobSet = {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
builder.add(Glob::new("*.gz").unwrap());
|
||||
builder.add(Glob::new("*.bz2").unwrap());
|
||||
builder.add(Glob::new("*.xz").unwrap());
|
||||
builder.add(Glob::new("*.lzma").unwrap());
|
||||
builder.build().unwrap()
|
||||
};
|
||||
static ref TAR_ARCHIVE_FORMATS: GlobSet = {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
builder.add(Glob::new("*.tar.gz").unwrap());
|
||||
builder.add(Glob::new("*.tar.xz").unwrap());
|
||||
builder.add(Glob::new("*.tar.bz2").unwrap());
|
||||
builder.add(Glob::new("*.tgz").unwrap());
|
||||
builder.add(Glob::new("*.txz").unwrap());
|
||||
builder.add(Glob::new("*.tbz2").unwrap());
|
||||
builder.build().unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
/// DecompressionReader provides an `io::Read` implementation for a limited
|
||||
/// set of compression formats.
|
||||
#[derive(Debug)]
|
||||
pub struct DecompressionReader {
|
||||
cmd: DecompressionCommand,
|
||||
child: process::Child,
|
||||
done: bool,
|
||||
}
|
||||
|
||||
impl DecompressionReader {
|
||||
/// Returns a handle to the stdout of the spawned decompression process for
|
||||
/// `path`, which can be directly searched in the worker. When the returned
|
||||
/// value is exhausted, the underlying process is reaped. If the underlying
|
||||
/// process fails, then its stderr is read and converted into a normal
|
||||
/// io::Error.
|
||||
///
|
||||
/// If there is any error in spawning the decompression command, then
|
||||
/// return `None`, after outputting any necessary debug or error messages.
|
||||
pub fn from_path(path: &Path) -> Option<DecompressionReader> {
|
||||
if is_tar_archive(path) {
|
||||
debug!("{}: skipping tar archive", path.display());
|
||||
return None;
|
||||
}
|
||||
let extension = match path.extension().and_then(OsStr::to_str) {
|
||||
Some(extension) => extension,
|
||||
None => {
|
||||
debug!(
|
||||
"{}: failed to get compresson extension", path.display());
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let decompression_cmd = match DECOMPRESSION_COMMANDS.get(extension) {
|
||||
Some(cmd) => cmd,
|
||||
None => {
|
||||
debug!(
|
||||
"{}: failed to get decompression command", path.display());
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let cmd = process::Command::new(decompression_cmd.cmd)
|
||||
.args(decompression_cmd.args)
|
||||
.arg(path)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn();
|
||||
let child = match cmd {
|
||||
Ok(process) => process,
|
||||
Err(_) => {
|
||||
debug!(
|
||||
"{}: decompression command '{}' not found",
|
||||
path.display(), decompression_cmd.cmd);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(DecompressionReader::new(*decompression_cmd, child))
|
||||
}
|
||||
|
||||
fn new(
|
||||
cmd: DecompressionCommand,
|
||||
child: process::Child,
|
||||
) -> DecompressionReader {
|
||||
DecompressionReader {
|
||||
cmd: cmd,
|
||||
child: child,
|
||||
done: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn read_error(&mut self) -> io::Result<io::Error> {
|
||||
let mut errbytes = vec![];
|
||||
self.child.stderr.as_mut().unwrap().read_to_end(&mut errbytes)?;
|
||||
let errstr = String::from_utf8_lossy(&errbytes);
|
||||
let errstr = errstr.trim();
|
||||
|
||||
Ok(if errstr.is_empty() {
|
||||
let msg = format!("decompression command failed: '{}'", self.cmd);
|
||||
io::Error::new(io::ErrorKind::Other, msg)
|
||||
} else {
|
||||
let msg = format!(
|
||||
"decompression command '{}' failed: {}", self.cmd, errstr);
|
||||
io::Error::new(io::ErrorKind::Other, msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for DecompressionReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
if self.done {
|
||||
return Ok(0);
|
||||
}
|
||||
let nread = self.child.stdout.as_mut().unwrap().read(buf)?;
|
||||
if nread == 0 {
|
||||
self.done = true;
|
||||
// Reap the child now that we're done reading.
|
||||
// If the command failed, report stderr as an error.
|
||||
if !self.child.wait()?.success() {
|
||||
return Err(self.read_error()?);
|
||||
}
|
||||
}
|
||||
Ok(nread)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given path contains a supported compression format or
|
||||
/// is a TAR archive.
|
||||
pub fn is_compressed(path: &Path) -> bool {
|
||||
is_supported_compression_format(path) || is_tar_archive(path)
|
||||
}
|
||||
|
||||
/// Returns true if the given path matches any one of the supported compression
|
||||
/// formats
|
||||
fn is_supported_compression_format(path: &Path) -> bool {
|
||||
SUPPORTED_COMPRESSION_FORMATS.is_match(path)
|
||||
}
|
||||
|
||||
/// Returns true if the given path matches any of the known TAR file formats.
|
||||
fn is_tar_archive(path: &Path) -> bool {
|
||||
TAR_ARCHIVE_FORMATS.is_match(path)
|
||||
}
|
||||
57
src/logger.rs
Normal file
57
src/logger.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
// This module defines a super simple logger that works with the `log` crate.
|
||||
// We don't need anything fancy; just basic log levels and the ability to
|
||||
// print to stderr. We therefore avoid bringing in extra dependencies just
|
||||
// for this functionality.
|
||||
|
||||
use log::{self, Log};
|
||||
|
||||
/// The simplest possible logger that logs to stderr.
|
||||
///
|
||||
/// This logger does no filtering. Instead, it relies on the `log` crates
|
||||
/// filtering via its global max_level setting.
|
||||
#[derive(Debug)]
|
||||
pub struct Logger(());
|
||||
|
||||
const LOGGER: &'static Logger = &Logger(());
|
||||
|
||||
impl Logger {
|
||||
/// Create a new logger that logs to stderr and initialize it as the
|
||||
/// global logger. If there was a problem setting the logger, then an
|
||||
/// error is returned.
|
||||
pub fn init() -> Result<(), log::SetLoggerError> {
|
||||
log::set_logger(LOGGER)
|
||||
}
|
||||
}
|
||||
|
||||
impl Log for Logger {
|
||||
fn enabled(&self, _: &log::Metadata) -> bool {
|
||||
// We set the log level via log::set_max_level, so we don't need to
|
||||
// implement filtering here.
|
||||
true
|
||||
}
|
||||
|
||||
fn log(&self, record: &log::Record) {
|
||||
match (record.file(), record.line()) {
|
||||
(Some(file), Some(line)) => {
|
||||
eprintln!(
|
||||
"{}/{}/{}:{}: {}",
|
||||
record.level(), record.target(),
|
||||
file, line, record.args());
|
||||
}
|
||||
(Some(file), None) => {
|
||||
eprintln!(
|
||||
"{}/{}/{}: {}",
|
||||
record.level(), record.target(), file, record.args());
|
||||
}
|
||||
_ => {
|
||||
eprintln!(
|
||||
"{}/{}: {}",
|
||||
record.level(), record.target(), record.args());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {
|
||||
// We use eprintln! which is flushed on every call.
|
||||
}
|
||||
}
|
||||
612
src/main.rs
612
src/main.rs
@@ -1,11 +1,11 @@
|
||||
extern crate ctrlc;
|
||||
extern crate deque;
|
||||
extern crate docopt;
|
||||
extern crate env_logger;
|
||||
extern crate atty;
|
||||
extern crate bytecount;
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate encoding_rs;
|
||||
extern crate globset;
|
||||
extern crate grep;
|
||||
extern crate ignore;
|
||||
#[cfg(windows)]
|
||||
extern crate kernel32;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
@@ -15,36 +15,21 @@ extern crate memchr;
|
||||
extern crate memmap;
|
||||
extern crate num_cpus;
|
||||
extern crate regex;
|
||||
extern crate rustc_serialize;
|
||||
extern crate term;
|
||||
extern crate same_file;
|
||||
extern crate termcolor;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use std::cmp;
|
||||
|
||||
use deque::{Stealer, Stolen};
|
||||
use grep::Grep;
|
||||
use memmap::{Mmap, Protection};
|
||||
use term::Terminal;
|
||||
use ignore::DirEntry;
|
||||
|
||||
use args::Args;
|
||||
use out::{ColoredTerminal, Out};
|
||||
use pathutil::strip_prefix;
|
||||
use printer::Printer;
|
||||
use search_stream::InputBuffer;
|
||||
#[cfg(windows)]
|
||||
use terminal_win::WindowsBuffer;
|
||||
use worker::Work;
|
||||
|
||||
macro_rules! errored {
|
||||
($($tt:tt)*) => {
|
||||
@@ -52,28 +37,25 @@ macro_rules! errored {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! eprintln {
|
||||
($($tt:tt)*) => {{
|
||||
use std::io::Write;
|
||||
let _ = writeln!(&mut ::std::io::stderr(), $($tt)*);
|
||||
}}
|
||||
}
|
||||
|
||||
mod app;
|
||||
mod args;
|
||||
mod atty;
|
||||
mod out;
|
||||
mod config;
|
||||
mod decoder;
|
||||
mod decompressor;
|
||||
mod logger;
|
||||
mod pathutil;
|
||||
mod printer;
|
||||
mod search_buffer;
|
||||
mod search_stream;
|
||||
#[cfg(windows)]
|
||||
mod terminal_win;
|
||||
mod unescape;
|
||||
mod worker;
|
||||
|
||||
pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;
|
||||
pub type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
fn main() {
|
||||
match Args::parse().and_then(run) {
|
||||
Ok(count) if count == 0 => process::exit(1),
|
||||
reset_sigpipe();
|
||||
match Args::parse().map(Arc::new).and_then(run) {
|
||||
Ok(0) => process::exit(1),
|
||||
Ok(_) => process::exit(0),
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
@@ -82,95 +64,104 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
fn run(args: Args) -> Result<u64> {
|
||||
let args = Arc::new(args);
|
||||
|
||||
let handler_args = args.clone();
|
||||
ctrlc::set_handler(move || {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
let _ = handler_args.stdout().reset();
|
||||
let _ = stdout.flush();
|
||||
|
||||
process::exit(1);
|
||||
});
|
||||
|
||||
let paths = args.paths();
|
||||
let threads = cmp::max(1, args.threads() - 1);
|
||||
let isone =
|
||||
paths.len() == 1 && (paths[0] == Path::new("-") || paths[0].is_file());
|
||||
fn run(args: Arc<Args>) -> Result<u64> {
|
||||
if args.never_match() {
|
||||
return Ok(0);
|
||||
}
|
||||
let threads = args.threads();
|
||||
if args.files() {
|
||||
return run_files(args.clone());
|
||||
}
|
||||
if args.type_list() {
|
||||
return run_types(args.clone());
|
||||
}
|
||||
if threads == 1 || isone {
|
||||
return run_one_thread(args.clone());
|
||||
}
|
||||
let out = Arc::new(Mutex::new(args.out()));
|
||||
let quiet_matched = QuietMatched::new(args.quiet());
|
||||
let mut workers = vec![];
|
||||
|
||||
let workq = {
|
||||
let (workq, stealer) = deque::new();
|
||||
for _ in 0..threads {
|
||||
let worker = MultiWorker {
|
||||
chan_work: stealer.clone(),
|
||||
quiet_matched: quiet_matched.clone(),
|
||||
out: out.clone(),
|
||||
outbuf: Some(args.outbuf()),
|
||||
worker: Worker {
|
||||
args: args.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
},
|
||||
};
|
||||
workers.push(thread::spawn(move || worker.run()));
|
||||
}
|
||||
workq
|
||||
};
|
||||
let mut paths_searched: u64 = 0;
|
||||
for dent in args.walker() {
|
||||
if quiet_matched.has_match() {
|
||||
break;
|
||||
}
|
||||
paths_searched += 1;
|
||||
if dent.is_stdin() {
|
||||
workq.push(Work::Stdin);
|
||||
if threads == 1 || args.is_one_path() {
|
||||
run_files_one_thread(&args)
|
||||
} else {
|
||||
workq.push(Work::File(dent));
|
||||
run_files_parallel(args)
|
||||
}
|
||||
} else if args.type_list() {
|
||||
run_types(&args)
|
||||
} else if threads == 1 || args.is_one_path() {
|
||||
run_one_thread(&args)
|
||||
} else {
|
||||
run_parallel(&args)
|
||||
}
|
||||
if !paths.is_empty() && paths_searched == 0 {
|
||||
eprintln!("No files were searched, which means ripgrep probably \
|
||||
applied a filter you didn't expect. \
|
||||
Try running again with --debug.");
|
||||
}
|
||||
for _ in 0..workers.len() {
|
||||
workq.push(Work::Quit);
|
||||
}
|
||||
let mut match_count = 0;
|
||||
for worker in workers {
|
||||
match_count += worker.join().unwrap();
|
||||
}
|
||||
Ok(match_count)
|
||||
}
|
||||
|
||||
fn run_one_thread(args: Arc<Args>) -> Result<u64> {
|
||||
let mut worker = Worker {
|
||||
args: args.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
};
|
||||
let mut term = args.stdout();
|
||||
fn run_parallel(args: &Arc<Args>) -> Result<u64> {
|
||||
let bufwtr = Arc::new(args.buffer_writer());
|
||||
let quiet_matched = args.quiet_matched();
|
||||
let paths_searched = Arc::new(AtomicUsize::new(0));
|
||||
let match_count = Arc::new(AtomicUsize::new(0));
|
||||
|
||||
args.walker_parallel().run(|| {
|
||||
let args = Arc::clone(args);
|
||||
let quiet_matched = quiet_matched.clone();
|
||||
let paths_searched = paths_searched.clone();
|
||||
let match_count = match_count.clone();
|
||||
let bufwtr = Arc::clone(&bufwtr);
|
||||
let mut buf = bufwtr.buffer();
|
||||
let mut worker = args.worker();
|
||||
Box::new(move |result| {
|
||||
use ignore::WalkState::*;
|
||||
|
||||
if quiet_matched.has_match() {
|
||||
return Quit;
|
||||
}
|
||||
let dent = match get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.files(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
None => return Continue,
|
||||
Some(dent) => dent,
|
||||
};
|
||||
paths_searched.fetch_add(1, Ordering::SeqCst);
|
||||
buf.clear();
|
||||
{
|
||||
// This block actually executes the search and prints the
|
||||
// results into outbuf.
|
||||
let mut printer = args.printer(&mut buf);
|
||||
let count =
|
||||
if dent.is_stdin() {
|
||||
worker.run(&mut printer, Work::Stdin)
|
||||
} else {
|
||||
worker.run(&mut printer, Work::DirEntry(dent))
|
||||
};
|
||||
match_count.fetch_add(count as usize, Ordering::SeqCst);
|
||||
if quiet_matched.set_match(count > 0) {
|
||||
return Quit;
|
||||
}
|
||||
}
|
||||
// BUG(burntsushi): We should handle this error instead of ignoring
|
||||
// it. See: https://github.com/BurntSushi/ripgrep/issues/200
|
||||
let _ = bufwtr.print(&buf);
|
||||
Continue
|
||||
})
|
||||
});
|
||||
if !args.paths().is_empty() && paths_searched.load(Ordering::SeqCst) == 0 {
|
||||
if !args.no_messages() {
|
||||
eprint_nothing_searched();
|
||||
}
|
||||
}
|
||||
Ok(match_count.load(Ordering::SeqCst) as u64)
|
||||
}
|
||||
|
||||
fn run_one_thread(args: &Arc<Args>) -> Result<u64> {
|
||||
let stdout = args.stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
let mut worker = args.worker();
|
||||
let mut paths_searched: u64 = 0;
|
||||
for dent in args.walker() {
|
||||
let mut printer = args.printer(&mut term);
|
||||
if worker.match_count > 0 {
|
||||
let mut match_count = 0;
|
||||
for result in args.walker() {
|
||||
let dent = match get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.files(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
None => continue,
|
||||
Some(dent) => dent,
|
||||
};
|
||||
let mut printer = args.printer(&mut stdout);
|
||||
if match_count > 0 {
|
||||
if args.quiet() {
|
||||
break;
|
||||
}
|
||||
@@ -179,41 +170,79 @@ fn run_one_thread(args: Arc<Args>) -> Result<u64> {
|
||||
}
|
||||
}
|
||||
paths_searched += 1;
|
||||
if dent.is_stdin() {
|
||||
worker.do_work(&mut printer, WorkReady::Stdin);
|
||||
} else {
|
||||
let file = match File::open(dent.path()) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
eprintln!("{}: {}", dent.path().display(), err);
|
||||
continue;
|
||||
}
|
||||
match_count +=
|
||||
if dent.is_stdin() {
|
||||
worker.run(&mut printer, Work::Stdin)
|
||||
} else {
|
||||
worker.run(&mut printer, Work::DirEntry(dent))
|
||||
};
|
||||
worker.do_work(&mut printer, WorkReady::DirFile(dent, file));
|
||||
}
|
||||
}
|
||||
if !args.paths().is_empty() && paths_searched == 0 {
|
||||
eprintln!("No files were searched, which means ripgrep probably \
|
||||
applied a filter you didn't expect. \
|
||||
Try running again with --debug.");
|
||||
if !args.no_messages() {
|
||||
eprint_nothing_searched();
|
||||
}
|
||||
}
|
||||
Ok(worker.match_count)
|
||||
Ok(match_count)
|
||||
}
|
||||
|
||||
fn run_files(args: Arc<Args>) -> Result<u64> {
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
fn run_files_parallel(args: Arc<Args>) -> Result<u64> {
|
||||
let print_args = Arc::clone(&args);
|
||||
let (tx, rx) = mpsc::channel::<ignore::DirEntry>();
|
||||
let print_thread = thread::spawn(move || {
|
||||
let stdout = print_args.stdout();
|
||||
let mut printer = print_args.printer(stdout.lock());
|
||||
let mut file_count = 0;
|
||||
for dent in rx.iter() {
|
||||
if !print_args.quiet() {
|
||||
printer.path(dent.path());
|
||||
}
|
||||
file_count += 1;
|
||||
}
|
||||
file_count
|
||||
});
|
||||
args.walker_parallel().run(move || {
|
||||
let args = Arc::clone(&args);
|
||||
let tx = tx.clone();
|
||||
Box::new(move |result| {
|
||||
if let Some(dent) = get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.files(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
tx.send(dent).unwrap();
|
||||
}
|
||||
ignore::WalkState::Continue
|
||||
})
|
||||
});
|
||||
Ok(print_thread.join().unwrap())
|
||||
}
|
||||
|
||||
fn run_files_one_thread(args: &Arc<Args>) -> Result<u64> {
|
||||
let stdout = args.stdout();
|
||||
let mut printer = args.printer(stdout.lock());
|
||||
let mut file_count = 0;
|
||||
for dent in args.walker() {
|
||||
printer.path(dent.path());
|
||||
for result in args.walker() {
|
||||
let dent = match get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.files(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
None => continue,
|
||||
Some(dent) => dent,
|
||||
};
|
||||
if !args.quiet() {
|
||||
printer.path(dent.path());
|
||||
}
|
||||
file_count += 1;
|
||||
}
|
||||
Ok(file_count)
|
||||
}
|
||||
|
||||
fn run_types(args: Arc<Args>) -> Result<u64> {
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
fn run_types(args: &Arc<Args>) -> Result<u64> {
|
||||
let stdout = args.stdout();
|
||||
let mut printer = args.printer(stdout.lock());
|
||||
let mut ty_count = 0;
|
||||
for def in args.type_defs() {
|
||||
printer.type_def(def);
|
||||
@@ -222,167 +251,142 @@ fn run_types(args: Arc<Args>) -> Result<u64> {
|
||||
Ok(ty_count)
|
||||
}
|
||||
|
||||
enum Work {
|
||||
Stdin,
|
||||
File(DirEntry),
|
||||
Quit,
|
||||
}
|
||||
|
||||
enum WorkReady {
|
||||
Stdin,
|
||||
DirFile(DirEntry, File),
|
||||
}
|
||||
|
||||
struct MultiWorker {
|
||||
chan_work: Stealer<Work>,
|
||||
quiet_matched: QuietMatched,
|
||||
out: Arc<Mutex<Out>>,
|
||||
#[cfg(not(windows))]
|
||||
outbuf: Option<ColoredTerminal<term::TerminfoTerminal<Vec<u8>>>>,
|
||||
#[cfg(windows)]
|
||||
outbuf: Option<ColoredTerminal<WindowsBuffer>>,
|
||||
worker: Worker,
|
||||
}
|
||||
|
||||
struct Worker {
|
||||
args: Arc<Args>,
|
||||
inpbuf: InputBuffer,
|
||||
grep: Grep,
|
||||
match_count: u64,
|
||||
}
|
||||
|
||||
impl MultiWorker {
|
||||
fn run(mut self) -> u64 {
|
||||
loop {
|
||||
if self.quiet_matched.has_match() {
|
||||
break;
|
||||
}
|
||||
let work = match self.chan_work.steal() {
|
||||
Stolen::Empty | Stolen::Abort => continue,
|
||||
Stolen::Data(Work::Quit) => break,
|
||||
Stolen::Data(Work::Stdin) => WorkReady::Stdin,
|
||||
Stolen::Data(Work::File(ent)) => {
|
||||
match File::open(ent.path()) {
|
||||
Ok(file) => WorkReady::DirFile(ent, file),
|
||||
Err(err) => {
|
||||
eprintln!("{}: {}", ent.path().display(), err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let mut outbuf = self.outbuf.take().unwrap();
|
||||
outbuf.clear();
|
||||
let mut printer = self.worker.args.printer(outbuf);
|
||||
self.worker.do_work(&mut printer, work);
|
||||
if self.quiet_matched.set_match(self.worker.match_count > 0) {
|
||||
break;
|
||||
}
|
||||
let outbuf = printer.into_inner();
|
||||
if !outbuf.get_ref().is_empty() {
|
||||
let mut out = self.out.lock().unwrap();
|
||||
out.write(&outbuf);
|
||||
}
|
||||
self.outbuf = Some(outbuf);
|
||||
}
|
||||
self.worker.match_count
|
||||
}
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
fn do_work<W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
work: WorkReady,
|
||||
) {
|
||||
let result = match work {
|
||||
WorkReady::Stdin => {
|
||||
let stdin = io::stdin();
|
||||
let stdin = stdin.lock();
|
||||
self.search(printer, &Path::new("<stdin>"), stdin)
|
||||
}
|
||||
WorkReady::DirFile(ent, file) => {
|
||||
let mut path = ent.path();
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
if self.args.mmap() {
|
||||
self.search_mmap(printer, path, &file)
|
||||
} else {
|
||||
self.search(printer, path, file)
|
||||
}
|
||||
}
|
||||
};
|
||||
match result {
|
||||
Ok(count) => {
|
||||
self.match_count += count;
|
||||
}
|
||||
Err(err) => {
|
||||
fn get_or_log_dir_entry(
|
||||
result: result::Result<ignore::DirEntry, ignore::Error>,
|
||||
stdout_handle: Option<&same_file::Handle>,
|
||||
files_only: bool,
|
||||
no_messages: bool,
|
||||
) -> Option<ignore::DirEntry> {
|
||||
match result {
|
||||
Err(err) => {
|
||||
if !no_messages {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn search<R: io::Read, W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
rdr: R,
|
||||
) -> Result<u64> {
|
||||
self.args.searcher(
|
||||
&mut self.inpbuf,
|
||||
printer,
|
||||
&self.grep,
|
||||
path,
|
||||
rdr,
|
||||
).run().map_err(From::from)
|
||||
}
|
||||
|
||||
fn search_mmap<W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
file: &File,
|
||||
) -> Result<u64> {
|
||||
if try!(file.metadata()).len() == 0 {
|
||||
// Opening a memory map with an empty file results in an error.
|
||||
// However, this may not actually be an empty file! For example,
|
||||
// /proc/cpuinfo reports itself as an empty file, but it can
|
||||
// produce data when it's read from. Therefore, we fall back to
|
||||
// regular read calls.
|
||||
return self.search(printer, path, file);
|
||||
}
|
||||
let mmap = try!(Mmap::open(file, Protection::Read));
|
||||
Ok(self.args.searcher_buffer(
|
||||
printer,
|
||||
&self.grep,
|
||||
path,
|
||||
unsafe { mmap.as_slice() },
|
||||
).run())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct QuietMatched(Arc<Option<AtomicBool>>);
|
||||
|
||||
impl QuietMatched {
|
||||
fn new(quiet: bool) -> QuietMatched {
|
||||
let atomic = if quiet { Some(AtomicBool::new(false)) } else { None };
|
||||
QuietMatched(Arc::new(atomic))
|
||||
}
|
||||
|
||||
fn has_match(&self) -> bool {
|
||||
match *self.0 {
|
||||
None => false,
|
||||
Some(ref matched) => matched.load(Ordering::SeqCst),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_match(&self, yes: bool) -> bool {
|
||||
match *self.0 {
|
||||
None => false,
|
||||
Some(_) if !yes => false,
|
||||
Some(ref m) => { m.store(true, Ordering::SeqCst); true }
|
||||
Ok(dent) => {
|
||||
if let Some(err) = dent.error() {
|
||||
if !no_messages {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
}
|
||||
if dent.file_type().is_none() {
|
||||
return Some(dent); // entry is stdin
|
||||
}
|
||||
// A depth of 0 means the user gave the path explicitly, so we
|
||||
// should always try to search it.
|
||||
if dent.depth() == 0 && !ignore_entry_is_dir(&dent) {
|
||||
return Some(dent);
|
||||
} else if !ignore_entry_is_file(&dent) {
|
||||
return None;
|
||||
}
|
||||
// If we are redirecting stdout to a file, then don't search that
|
||||
// file.
|
||||
if !files_only && is_stdout_file(&dent, stdout_handle, no_messages) {
|
||||
return None;
|
||||
}
|
||||
Some(dent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given `ignore::DirEntry` points to a
|
||||
/// directory.
|
||||
///
|
||||
/// This works around a bug in Rust's standard library:
|
||||
/// https://github.com/rust-lang/rust/issues/46484
|
||||
#[cfg(windows)]
|
||||
fn ignore_entry_is_dir(dent: &ignore::DirEntry) -> bool {
|
||||
use std::os::windows::fs::MetadataExt;
|
||||
use winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
dent.metadata().map(|md| {
|
||||
md.file_attributes() & FILE_ATTRIBUTE_DIRECTORY != 0
|
||||
}).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given `ignore::DirEntry` points to a
|
||||
/// directory.
|
||||
#[cfg(not(windows))]
|
||||
fn ignore_entry_is_dir(dent: &ignore::DirEntry) -> bool {
|
||||
dent.file_type().map_or(false, |ft| ft.is_dir())
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given `ignore::DirEntry` points to a
|
||||
/// file.
|
||||
///
|
||||
/// This works around a bug in Rust's standard library:
|
||||
/// https://github.com/rust-lang/rust/issues/46484
|
||||
#[cfg(windows)]
|
||||
fn ignore_entry_is_file(dent: &ignore::DirEntry) -> bool {
|
||||
!ignore_entry_is_dir(dent)
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given `ignore::DirEntry` points to a
|
||||
/// file.
|
||||
#[cfg(not(windows))]
|
||||
fn ignore_entry_is_file(dent: &ignore::DirEntry) -> bool {
|
||||
dent.file_type().map_or(false, |ft| ft.is_file())
|
||||
}
|
||||
|
||||
fn is_stdout_file(
|
||||
dent: &ignore::DirEntry,
|
||||
stdout_handle: Option<&same_file::Handle>,
|
||||
no_messages: bool,
|
||||
) -> bool {
|
||||
let stdout_handle = match stdout_handle {
|
||||
None => return false,
|
||||
Some(stdout_handle) => stdout_handle,
|
||||
};
|
||||
// If we know for sure that these two things aren't equal, then avoid
|
||||
// the costly extra stat call to determine equality.
|
||||
if !maybe_dent_eq_handle(dent, stdout_handle) {
|
||||
return false;
|
||||
}
|
||||
match same_file::Handle::from_path(dent.path()) {
|
||||
Ok(h) => stdout_handle == &h,
|
||||
Err(err) => {
|
||||
if !no_messages {
|
||||
eprintln!("{}: {}", dent.path().display(), err);
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn maybe_dent_eq_handle(
|
||||
dent: &ignore::DirEntry,
|
||||
handle: &same_file::Handle,
|
||||
) -> bool {
|
||||
dent.ino() == Some(handle.ino())
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn maybe_dent_eq_handle(_: &ignore::DirEntry, _: &same_file::Handle) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn eprint_nothing_searched() {
|
||||
eprintln!("No files were searched, which means ripgrep probably \
|
||||
applied a filter you didn't expect. \
|
||||
Try running again with --debug.");
|
||||
}
|
||||
|
||||
// The Rust standard library suppresses the default SIGPIPE behavior, so that
|
||||
// writing to a closed pipe doesn't kill the process. The goal is to instead
|
||||
// handle errors through the normal result mechanism. Ripgrep needs some
|
||||
// refactoring before it will be able to do that, however, so we re-enable the
|
||||
// standard SIGPIPE behavior as a workaround. See
|
||||
// https://github.com/BurntSushi/ripgrep/issues/200.
|
||||
#[cfg(unix)]
|
||||
fn reset_sigpipe() {
|
||||
unsafe {
|
||||
libc::signal(libc::SIGPIPE, libc::SIG_DFL);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn reset_sigpipe() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
374
src/out.rs
374
src/out.rs
@@ -1,374 +0,0 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use term::{self, Terminal};
|
||||
#[cfg(not(windows))]
|
||||
use term::terminfo::TermInfo;
|
||||
#[cfg(windows)]
|
||||
use term::WinConsole;
|
||||
|
||||
#[cfg(windows)]
|
||||
use terminal_win::WindowsBuffer;
|
||||
|
||||
/// Out controls the actual output of all search results for a particular file
|
||||
/// to the end user.
|
||||
///
|
||||
/// (The difference between Out and Printer is that a Printer works with
|
||||
/// individual search results where as Out works with search results for each
|
||||
/// file as a whole. For example, it knows when to print a file separator.)
|
||||
pub struct Out {
|
||||
#[cfg(not(windows))]
|
||||
term: ColoredTerminal<term::TerminfoTerminal<io::BufWriter<io::Stdout>>>,
|
||||
#[cfg(windows)]
|
||||
term: ColoredTerminal<WinConsole<io::Stdout>>,
|
||||
printed: bool,
|
||||
file_separator: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Out {
|
||||
/// Create a new Out that writes to the wtr given.
|
||||
#[cfg(not(windows))]
|
||||
pub fn new(color: bool) -> Out {
|
||||
let wtr = io::BufWriter::new(io::stdout());
|
||||
Out {
|
||||
term: ColoredTerminal::new(wtr, color),
|
||||
printed: false,
|
||||
file_separator: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Out that writes to the wtr given.
|
||||
#[cfg(windows)]
|
||||
pub fn new(color: bool) -> Out {
|
||||
Out {
|
||||
term: ColoredTerminal::new_stdout(color),
|
||||
printed: false,
|
||||
file_separator: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// If set, the separator is printed between matches from different files.
|
||||
/// By default, no separator is printed.
|
||||
pub fn file_separator(mut self, sep: Vec<u8>) -> Out {
|
||||
self.file_separator = Some(sep);
|
||||
self
|
||||
}
|
||||
|
||||
/// Write the search results of a single file to the underlying wtr and
|
||||
/// flush wtr.
|
||||
#[cfg(not(windows))]
|
||||
pub fn write(
|
||||
&mut self,
|
||||
buf: &ColoredTerminal<term::TerminfoTerminal<Vec<u8>>>,
|
||||
) {
|
||||
self.write_sep();
|
||||
match *buf {
|
||||
ColoredTerminal::Colored(ref tt) => {
|
||||
let _ = self.term.write_all(tt.get_ref());
|
||||
}
|
||||
ColoredTerminal::NoColor(ref buf) => {
|
||||
let _ = self.term.write_all(buf);
|
||||
}
|
||||
}
|
||||
self.write_done();
|
||||
}
|
||||
/// Write the search results of a single file to the underlying wtr and
|
||||
/// flush wtr.
|
||||
#[cfg(windows)]
|
||||
pub fn write(
|
||||
&mut self,
|
||||
buf: &ColoredTerminal<WindowsBuffer>,
|
||||
) {
|
||||
self.write_sep();
|
||||
match *buf {
|
||||
ColoredTerminal::Colored(ref tt) => {
|
||||
tt.print_stdout(&mut self.term);
|
||||
}
|
||||
ColoredTerminal::NoColor(ref buf) => {
|
||||
let _ = self.term.write_all(buf);
|
||||
}
|
||||
}
|
||||
self.write_done();
|
||||
}
|
||||
|
||||
fn write_sep(&mut self) {
|
||||
if let Some(ref sep) = self.file_separator {
|
||||
if self.printed {
|
||||
let _ = self.term.write_all(sep);
|
||||
let _ = self.term.write_all(b"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_done(&mut self) {
|
||||
let _ = self.term.flush();
|
||||
self.printed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// ColoredTerminal provides optional colored output through the term::Terminal
|
||||
/// trait. In particular, it will dynamically configure itself to use coloring
|
||||
/// if it's available in the environment.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ColoredTerminal<T: Terminal + Send> {
|
||||
Colored(T),
|
||||
NoColor(T::Output),
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
impl<W: io::Write + Send> ColoredTerminal<term::TerminfoTerminal<W>> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new(wtr: W, color: bool) -> Self {
|
||||
lazy_static! {
|
||||
// Only pay for parsing the terminfo once.
|
||||
static ref TERMINFO: Option<TermInfo> = {
|
||||
match TermInfo::from_env() {
|
||||
Ok(info) => Some(info),
|
||||
Err(err) => {
|
||||
debug!("error loading terminfo for coloring: {}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// If we want color, build a term::TerminfoTerminal and see if the
|
||||
// current environment supports coloring. If not, bail with NoColor. To
|
||||
// avoid losing our writer (ownership), do this the long way.
|
||||
if !color {
|
||||
return ColoredTerminal::NoColor(wtr);
|
||||
}
|
||||
let terminfo = match *TERMINFO {
|
||||
None => return ColoredTerminal::NoColor(wtr),
|
||||
Some(ref ti) => {
|
||||
// Ug, this should go away with the next release of `term`.
|
||||
TermInfo {
|
||||
names: ti.names.clone(),
|
||||
bools: ti.bools.clone(),
|
||||
numbers: ti.numbers.clone(),
|
||||
strings: ti.strings.clone(),
|
||||
}
|
||||
}
|
||||
};
|
||||
let tt = term::TerminfoTerminal::new_with_terminfo(wtr, terminfo);
|
||||
if !tt.supports_color() {
|
||||
debug!("environment doesn't support coloring");
|
||||
return ColoredTerminal::NoColor(tt.into_inner());
|
||||
}
|
||||
ColoredTerminal::Colored(tt)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
impl ColoredTerminal<term::TerminfoTerminal<Vec<u8>>> {
|
||||
/// Clear the give buffer of all search results such that it is reusable
|
||||
/// in another search.
|
||||
pub fn clear(&mut self) {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut tt) => {
|
||||
tt.get_mut().clear();
|
||||
}
|
||||
ColoredTerminal::NoColor(ref mut buf) => {
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl ColoredTerminal<WindowsBuffer> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new_buffer(color: bool) -> Self {
|
||||
if !color {
|
||||
ColoredTerminal::NoColor(vec![])
|
||||
} else {
|
||||
ColoredTerminal::Colored(WindowsBuffer::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the give buffer of all search results such that it is reusable
|
||||
/// in another search.
|
||||
pub fn clear(&mut self) {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut win) => win.clear(),
|
||||
ColoredTerminal::NoColor(ref mut buf) => buf.clear(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl ColoredTerminal<WinConsole<io::Stdout>> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new_stdout(color: bool) -> Self {
|
||||
if !color {
|
||||
return ColoredTerminal::NoColor(io::stdout());
|
||||
}
|
||||
match WinConsole::new(io::stdout()) {
|
||||
Ok(win) => ColoredTerminal::Colored(win),
|
||||
Err(_) => ColoredTerminal::NoColor(io::stdout()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Terminal + Send> ColoredTerminal<T> {
|
||||
fn map_result<F>(
|
||||
&mut self,
|
||||
mut f: F,
|
||||
) -> term::Result<()>
|
||||
where F: FnMut(&mut T) -> term::Result<()> {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut w) => f(w),
|
||||
ColoredTerminal::NoColor(_) => Err(term::Error::NotSupported),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_bool<F>(
|
||||
&self,
|
||||
mut f: F,
|
||||
) -> bool
|
||||
where F: FnMut(&T) -> bool {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref w) => f(w),
|
||||
ColoredTerminal::NoColor(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Terminal + Send> io::Write for ColoredTerminal<T> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut w) => w.write(buf),
|
||||
ColoredTerminal::NoColor(ref mut w) => w.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Terminal + Send> term::Terminal for ColoredTerminal<T> {
|
||||
type Output = T::Output;
|
||||
|
||||
fn fg(&mut self, fg: term::color::Color) -> term::Result<()> {
|
||||
self.map_result(|w| w.fg(fg))
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: term::color::Color) -> term::Result<()> {
|
||||
self.map_result(|w| w.bg(bg))
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: term::Attr) -> term::Result<()> {
|
||||
self.map_result(|w| w.attr(attr))
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: term::Attr) -> bool {
|
||||
self.map_bool(|w| w.supports_attr(attr))
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.reset())
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
self.map_bool(|w| w.supports_reset())
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
self.map_bool(|w| w.supports_color())
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.cursor_up())
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.delete_line())
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.carriage_return())
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Self::Output {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref w) => w.get_ref(),
|
||||
ColoredTerminal::NoColor(ref w) => w,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Self::Output {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut w) => w.get_mut(),
|
||||
ColoredTerminal::NoColor(ref mut w) => w,
|
||||
}
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Self::Output {
|
||||
match self {
|
||||
ColoredTerminal::Colored(w) => w.into_inner(),
|
||||
ColoredTerminal::NoColor(w) => w,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Terminal + Send> term::Terminal for &'a mut ColoredTerminal<T> {
|
||||
type Output = T::Output;
|
||||
|
||||
fn fg(&mut self, fg: term::color::Color) -> term::Result<()> {
|
||||
(**self).fg(fg)
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: term::color::Color) -> term::Result<()> {
|
||||
(**self).bg(bg)
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: term::Attr) -> term::Result<()> {
|
||||
(**self).attr(attr)
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: term::Attr) -> bool {
|
||||
(**self).supports_attr(attr)
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
(**self).reset()
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
(**self).supports_reset()
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
(**self).supports_color()
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
(**self).cursor_up()
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
(**self).delete_line()
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
(**self).carriage_return()
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Self::Output {
|
||||
(**self).get_ref()
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Self::Output {
|
||||
(**self).get_mut()
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Self::Output {
|
||||
// Good golly miss molly...
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
The pathutil module provides platform specific operations on paths that are
|
||||
typically faster than the same operations as provided in std::path. In
|
||||
typically faster than the same operations as provided in `std::path`. In
|
||||
particular, we really want to avoid the costly operation of parsing the path
|
||||
into its constituent components. We give up on Windows, but on Unix, we deal
|
||||
with the raw bytes directly.
|
||||
@@ -26,7 +26,7 @@ pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
if prefix.len() > path.len() || prefix != &path[0..prefix.len()] {
|
||||
None
|
||||
} else {
|
||||
Some(&Path::new(OsStr::from_bytes(&path[prefix.len()..])))
|
||||
Some(Path::new(OsStr::from_bytes(&path[prefix.len()..])))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
780
src/printer.rs
780
src/printer.rs
@@ -1,12 +1,63 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
use regex::bytes::Regex;
|
||||
use term::{Attr, Terminal};
|
||||
use term::color;
|
||||
use regex::bytes::{Captures, Match, Regex, Replacer};
|
||||
use termcolor::{Color, ColorSpec, ParseColorError, WriteColor};
|
||||
|
||||
use pathutil::strip_prefix;
|
||||
use ignore::types::FileTypeDef;
|
||||
|
||||
/// Track the start and end of replacements to allow coloring them on output.
|
||||
#[derive(Debug)]
|
||||
struct Offset {
|
||||
start: usize,
|
||||
end: usize,
|
||||
}
|
||||
|
||||
impl Offset {
|
||||
fn new(start: usize, end: usize) -> Offset {
|
||||
Offset { start: start, end: end }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'m, 'r> From<&'m Match<'r>> for Offset {
|
||||
fn from(m: &'m Match<'r>) -> Self {
|
||||
Offset{ start: m.start(), end: m.end() }
|
||||
}
|
||||
}
|
||||
|
||||
/// `CountingReplacer` implements the Replacer interface for Regex,
|
||||
/// and counts how often replacement is being performed.
|
||||
struct CountingReplacer<'r> {
|
||||
replace: &'r [u8],
|
||||
count: &'r mut usize,
|
||||
offsets: &'r mut Vec<Offset>,
|
||||
}
|
||||
|
||||
impl<'r> CountingReplacer<'r> {
|
||||
fn new(
|
||||
replace: &'r [u8],
|
||||
count: &'r mut usize,
|
||||
offsets: &'r mut Vec<Offset>,
|
||||
) -> CountingReplacer<'r> {
|
||||
CountingReplacer { replace: replace, count: count, offsets: offsets, }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> Replacer for CountingReplacer<'r> {
|
||||
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
|
||||
*self.count += 1;
|
||||
let start = dst.len();
|
||||
caps.expand(self.replace, dst);
|
||||
let end = dst.len();
|
||||
if start != end {
|
||||
self.offsets.push(Offset::new(start, end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Printer encapsulates all output logic for searching.
|
||||
///
|
||||
/// Note that we currently ignore all write errors. It's probably worthwhile
|
||||
@@ -36,42 +87,26 @@ pub struct Printer<W> {
|
||||
/// Whether to print NUL bytes after a file path instead of new lines
|
||||
/// or `:`.
|
||||
null: bool,
|
||||
/// Print only the matched (non-empty) parts of a matching line
|
||||
only_matching: bool,
|
||||
/// A string to use as a replacement of each match in a matching line.
|
||||
replace: Option<Vec<u8>>,
|
||||
/// Whether to prefix each match with the corresponding file name.
|
||||
with_filename: bool,
|
||||
/// The choice of colors.
|
||||
color_choice: ColorChoice
|
||||
/// The color specifications.
|
||||
colors: ColorSpecs,
|
||||
/// The separator to use for file paths. If empty, this is ignored.
|
||||
path_separator: Option<u8>,
|
||||
/// Restrict lines to this many columns.
|
||||
max_columns: Option<usize>,
|
||||
/// Width of line number displayed. If the number of digits in the
|
||||
/// line number is less than this, it is left padded with
|
||||
/// spaces.
|
||||
line_number_width: Option<usize>
|
||||
}
|
||||
|
||||
struct ColorChoice {
|
||||
matched_line: color::Color,
|
||||
heading: color::Color,
|
||||
line_number: color::Color
|
||||
}
|
||||
|
||||
impl ColorChoice {
|
||||
#[cfg(unix)]
|
||||
pub fn new() -> ColorChoice {
|
||||
ColorChoice {
|
||||
matched_line: color::RED,
|
||||
heading: color::GREEN,
|
||||
line_number: color::BLUE
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
pub fn new() -> ColorChoice {
|
||||
ColorChoice {
|
||||
matched_line: color::BRIGHT_RED,
|
||||
heading: color::BRIGHT_GREEN,
|
||||
line_number: color::BRIGHT_BLUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Terminal + Send> Printer<W> {
|
||||
/// Create a new printer that writes to wtr.
|
||||
impl<W: WriteColor> Printer<W> {
|
||||
/// Create a new printer that writes to wtr with the given color settings.
|
||||
pub fn new(wtr: W) -> Printer<W> {
|
||||
Printer {
|
||||
wtr: wtr,
|
||||
@@ -83,12 +118,22 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
heading: false,
|
||||
line_per_match: false,
|
||||
null: false,
|
||||
only_matching: false,
|
||||
replace: None,
|
||||
with_filename: false,
|
||||
color_choice: ColorChoice::new()
|
||||
colors: ColorSpecs::default(),
|
||||
path_separator: None,
|
||||
max_columns: None,
|
||||
line_number_width: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the color specifications.
|
||||
pub fn colors(mut self, colors: ColorSpecs) -> Printer<W> {
|
||||
self.colors = colors;
|
||||
self
|
||||
}
|
||||
|
||||
/// When set, column numbers will be printed for the first match on each
|
||||
/// line.
|
||||
pub fn column(mut self, yes: bool) -> Printer<W> {
|
||||
@@ -136,11 +181,21 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Print only the matched (non-empty) parts of a matching line
|
||||
pub fn only_matching(mut self, yes: bool) -> Printer<W> {
|
||||
self.only_matching = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// A separator to use when printing file paths. When empty, use the
|
||||
/// default separator for the current platform. (/ on Unix, \ on Windows.)
|
||||
pub fn path_separator(mut self, sep: Option<u8>) -> Printer<W> {
|
||||
self.path_separator = sep;
|
||||
self
|
||||
}
|
||||
|
||||
/// Replace every match in each matching line with the replacement string
|
||||
/// given.
|
||||
///
|
||||
/// The replacement string syntax is documented here:
|
||||
/// https://doc.rust-lang.org/regex/regex/bytes/struct.Captures.html#method.expand
|
||||
pub fn replace(mut self, replacement: Vec<u8>) -> Printer<W> {
|
||||
self.replace = Some(replacement);
|
||||
self
|
||||
@@ -152,12 +207,25 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure the max. number of columns used for printing matching lines.
|
||||
pub fn max_columns(mut self, max_columns: Option<usize>) -> Printer<W> {
|
||||
self.max_columns = max_columns;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure the width of the displayed line number
|
||||
pub fn line_number_width(mut self, line_number_width: Option<usize>) -> Printer<W> {
|
||||
self.line_number_width = line_number_width;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns true if and only if something has been printed.
|
||||
pub fn has_printed(&self) -> bool {
|
||||
self.has_printed
|
||||
}
|
||||
|
||||
/// Flushes the underlying writer and returns it.
|
||||
#[allow(dead_code)]
|
||||
pub fn into_inner(mut self) -> W {
|
||||
let _ = self.wtr.flush();
|
||||
self.wtr
|
||||
@@ -182,22 +250,14 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
pub fn path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
|
||||
self.write_path(path);
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write_eol();
|
||||
}
|
||||
self.write_path_eol();
|
||||
}
|
||||
|
||||
/// Prints the given path and a count of the number of matches found.
|
||||
pub fn path_count<P: AsRef<Path>>(&mut self, path: P, count: u64) {
|
||||
if self.with_filename {
|
||||
self.write_path(path);
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b":");
|
||||
}
|
||||
self.write_path_sep(b':');
|
||||
}
|
||||
self.write(count.to_string().as_bytes());
|
||||
self.write_eol();
|
||||
@@ -205,13 +265,11 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
|
||||
/// Prints the context separator.
|
||||
pub fn context_separate(&mut self) {
|
||||
// N.B. We can't use `write` here because of borrowing restrictions.
|
||||
if self.context_separator.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.has_printed = true;
|
||||
let _ = self.wtr.write_all(&self.context_separator);
|
||||
let _ = self.wtr.write_all(&[self.eol]);
|
||||
self.write_eol();
|
||||
}
|
||||
|
||||
pub fn matched<P: AsRef<Path>>(
|
||||
@@ -223,21 +281,18 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
end: usize,
|
||||
line_number: Option<u64>,
|
||||
) {
|
||||
if !self.line_per_match {
|
||||
let column =
|
||||
if self.column {
|
||||
Some(re.find(&buf[start..end])
|
||||
.map(|(s, _)| s).unwrap_or(0) as u64)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if !self.line_per_match && !self.only_matching {
|
||||
let mat = re
|
||||
.find(&buf[start..end])
|
||||
.map(|m| (m.start(), m.end()))
|
||||
.unwrap_or((0, 0));
|
||||
return self.write_match(
|
||||
re, path, buf, start, end, line_number, column);
|
||||
re, path, buf, start, end, line_number, mat.0, mat.1);
|
||||
}
|
||||
for (s, _) in re.find_iter(&buf[start..end]) {
|
||||
let column = if self.column { Some(s as u64) } else { None };
|
||||
for m in re.find_iter(&buf[start..end]) {
|
||||
self.write_match(
|
||||
re, path.as_ref(), buf, start, end, line_number, column);
|
||||
re, path.as_ref(), buf, start, end,
|
||||
line_number, m.start(), m.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,48 +304,88 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
start: usize,
|
||||
end: usize,
|
||||
line_number: Option<u64>,
|
||||
column: Option<u64>,
|
||||
match_start: usize,
|
||||
match_end: usize,
|
||||
) {
|
||||
if self.heading && self.with_filename && !self.has_printed {
|
||||
self.write_file_sep();
|
||||
self.write_heading(path.as_ref());
|
||||
self.write_path(path);
|
||||
self.write_path_eol();
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write_non_heading_path(path.as_ref());
|
||||
self.write_path(path);
|
||||
self.write_path_sep(b':');
|
||||
}
|
||||
if let Some(line_number) = line_number {
|
||||
self.line_number(line_number, b':');
|
||||
}
|
||||
if let Some(c) = column {
|
||||
self.write((c + 1).to_string().as_bytes());
|
||||
self.write(b":");
|
||||
if self.column {
|
||||
self.column_number(match_start as u64 + 1, b':');
|
||||
}
|
||||
if self.replace.is_some() {
|
||||
let line = re.replace_all(
|
||||
&buf[start..end], &**self.replace.as_ref().unwrap());
|
||||
self.write(&line);
|
||||
let mut count = 0;
|
||||
let mut offsets = Vec::new();
|
||||
let line = {
|
||||
let replacer = CountingReplacer::new(
|
||||
self.replace.as_ref().unwrap(), &mut count, &mut offsets);
|
||||
if self.only_matching {
|
||||
re.replace_all(
|
||||
&buf[start + match_start..start + match_end], replacer)
|
||||
} else {
|
||||
re.replace_all(&buf[start..end], replacer)
|
||||
}
|
||||
};
|
||||
if self.max_columns.map_or(false, |m| line.len() > m) {
|
||||
let msg = format!(
|
||||
"[Omitted long line with {} replacements]", count);
|
||||
self.write_colored(msg.as_bytes(), |colors| colors.matched());
|
||||
self.write_eol();
|
||||
return;
|
||||
}
|
||||
self.write_matched_line(offsets, &*line, false);
|
||||
} else {
|
||||
self.write_matched_line(re, &buf[start..end]);
|
||||
}
|
||||
if buf[start..end].last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
let buf = if self.only_matching {
|
||||
&buf[start + match_start..start + match_end]
|
||||
} else {
|
||||
&buf[start..end]
|
||||
};
|
||||
if self.max_columns.map_or(false, |m| buf.len() > m) {
|
||||
let count = re.find_iter(buf).count();
|
||||
let msg = format!("[Omitted long line with {} matches]", count);
|
||||
self.write_colored(msg.as_bytes(), |colors| colors.matched());
|
||||
self.write_eol();
|
||||
return;
|
||||
}
|
||||
let only_match = self.only_matching;
|
||||
self.write_matched_line(
|
||||
re.find_iter(buf).map(|x| Offset::from(&x)), buf, only_match);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
|
||||
if !self.wtr.supports_color() {
|
||||
fn write_matched_line<I>(&mut self, offsets: I, buf: &[u8], only_match: bool)
|
||||
where I: IntoIterator<Item=Offset>,
|
||||
{
|
||||
if !self.wtr.supports_color() || self.colors.matched().is_none() {
|
||||
self.write(buf);
|
||||
return;
|
||||
} else if only_match {
|
||||
self.write_colored(buf, |colors| colors.matched());
|
||||
} else {
|
||||
let mut last_written = 0;
|
||||
for o in offsets {
|
||||
self.write(&buf[last_written..o.start]);
|
||||
// This conditional checks if the match is both empty *and*
|
||||
// past the end of the line. In this case, we never want to
|
||||
// emit an additional color escape.
|
||||
if o.start != o.end || o.end != buf.len() {
|
||||
self.write_colored(
|
||||
&buf[o.start..o.end], |colors| colors.matched());
|
||||
}
|
||||
last_written = o.end;
|
||||
}
|
||||
self.write(&buf[last_written..]);
|
||||
}
|
||||
let mut last_written = 0;
|
||||
for (s, e) in re.find_iter(buf) {
|
||||
self.write(&buf[last_written..s]);
|
||||
let _ = self.wtr.fg(self.color_choice.matched_line);
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
self.write(&buf[s..e]);
|
||||
let _ = self.wtr.reset();
|
||||
last_written = e;
|
||||
if buf.last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
}
|
||||
self.write(&buf[last_written..]);
|
||||
}
|
||||
|
||||
pub fn context<P: AsRef<Path>>(
|
||||
@@ -303,79 +398,87 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
) {
|
||||
if self.heading && self.with_filename && !self.has_printed {
|
||||
self.write_file_sep();
|
||||
self.write_heading(path.as_ref());
|
||||
self.write_path(path);
|
||||
self.write_path_eol();
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write_path(path.as_ref());
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b"-");
|
||||
}
|
||||
self.write_path(path);
|
||||
self.write_path_sep(b'-');
|
||||
}
|
||||
if let Some(line_number) = line_number {
|
||||
self.line_number(line_number, b'-');
|
||||
}
|
||||
if self.max_columns.map_or(false, |m| end - start > m) {
|
||||
self.write(b"[Omitted long context line]");
|
||||
self.write_eol();
|
||||
return;
|
||||
}
|
||||
self.write(&buf[start..end]);
|
||||
if buf[start..end].last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
}
|
||||
}
|
||||
|
||||
fn write_heading<P: AsRef<Path>>(&mut self, path: P) {
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.fg(self.color_choice.heading);
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
fn separator(&mut self, sep: &[u8]) {
|
||||
self.write(sep);
|
||||
}
|
||||
|
||||
fn write_path_sep(&mut self, sep: u8) {
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.separator(&[sep]);
|
||||
}
|
||||
self.write_path(path.as_ref());
|
||||
}
|
||||
|
||||
fn write_path_eol(&mut self) {
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write_eol();
|
||||
}
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
fn write_non_heading_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.fg(self.color_choice.heading);
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
}
|
||||
self.write_path(path.as_ref());
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write(b":");
|
||||
}
|
||||
}
|
||||
|
||||
fn line_number(&mut self, n: u64, sep: u8) {
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.fg(self.color_choice.line_number);
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
}
|
||||
self.write(n.to_string().as_bytes());
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
self.write(&[sep]);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
self.write(path);
|
||||
self.write_path_replace_separator(path);
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
self.write(path.as_ref().to_string_lossy().as_bytes());
|
||||
let path = path.as_ref().to_string_lossy();
|
||||
self.write_path_replace_separator(path.as_bytes());
|
||||
}
|
||||
|
||||
fn write_path_replace_separator(&mut self, path: &[u8]) {
|
||||
match self.path_separator {
|
||||
None => self.write_colored(path, |colors| colors.path()),
|
||||
Some(sep) => {
|
||||
let transformed_path: Vec<_> = path.iter().map(|&b| {
|
||||
if b == b'/' || (cfg!(windows) && b == b'\\') {
|
||||
sep
|
||||
} else {
|
||||
b
|
||||
}
|
||||
}).collect();
|
||||
self.write_colored(&transformed_path, |colors| colors.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn line_number(&mut self, n: u64, sep: u8) {
|
||||
let mut line_number = n.to_string();
|
||||
if let Some(width) = self.line_number_width {
|
||||
line_number = format!("{:>width$}", line_number, width = width);
|
||||
}
|
||||
self.write_colored(line_number.as_bytes(), |colors| colors.line());
|
||||
self.separator(&[sep]);
|
||||
}
|
||||
|
||||
fn column_number(&mut self, n: u64, sep: u8) {
|
||||
self.write_colored(n.to_string().as_bytes(), |colors| colors.column());
|
||||
self.separator(&[sep]);
|
||||
}
|
||||
|
||||
fn write(&mut self, buf: &[u8]) {
|
||||
@@ -388,6 +491,14 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self.write(&[eol]);
|
||||
}
|
||||
|
||||
fn write_colored<F>(&mut self, buf: &[u8], get_color: F)
|
||||
where F: Fn(&ColorSpecs) -> &ColorSpec
|
||||
{
|
||||
let _ = self.wtr.set_color(get_color(&self.colors));
|
||||
self.write(buf);
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
|
||||
fn write_file_sep(&mut self) {
|
||||
if let Some(ref sep) = self.file_separator {
|
||||
self.has_printed = true;
|
||||
@@ -396,3 +507,406 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can occur when parsing color specifications.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
/// This occurs when an unrecognized output type is used.
|
||||
UnrecognizedOutType(String),
|
||||
/// This occurs when an unrecognized spec type is used.
|
||||
UnrecognizedSpecType(String),
|
||||
/// This occurs when an unrecognized color name is used.
|
||||
UnrecognizedColor(String, String),
|
||||
/// This occurs when an unrecognized style attribute is used.
|
||||
UnrecognizedStyle(String),
|
||||
/// This occurs when the format of a color specification is invalid.
|
||||
InvalidFormat(String),
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::UnrecognizedOutType(_) => "unrecognized output type",
|
||||
Error::UnrecognizedSpecType(_) => "unrecognized spec type",
|
||||
Error::UnrecognizedColor(_, _) => "unrecognized color name",
|
||||
Error::UnrecognizedStyle(_) => "unrecognized style attribute",
|
||||
Error::InvalidFormat(_) => "invalid color spec",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::UnrecognizedOutType(ref name) => {
|
||||
write!(f, "Unrecognized output type '{}'. Choose from: \
|
||||
path, line, column, match.", name)
|
||||
}
|
||||
Error::UnrecognizedSpecType(ref name) => {
|
||||
write!(f, "Unrecognized spec type '{}'. Choose from: \
|
||||
fg, bg, style, none.", name)
|
||||
}
|
||||
Error::UnrecognizedColor(_, ref msg) => {
|
||||
write!(f, "{}", msg)
|
||||
}
|
||||
Error::UnrecognizedStyle(ref name) => {
|
||||
write!(f, "Unrecognized style attribute '{}'. Choose from: \
|
||||
nobold, bold, nointense, intense, nounderline, \
|
||||
underline.", name)
|
||||
}
|
||||
Error::InvalidFormat(ref original) => {
|
||||
write!(
|
||||
f,
|
||||
"Invalid color spec format: '{}'. Valid format \
|
||||
is '(path|line|column|match):(fg|bg|style):(value)'.",
|
||||
original)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseColorError> for Error {
|
||||
fn from(err: ParseColorError) -> Error {
|
||||
Error::UnrecognizedColor(err.invalid().to_string(), err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// A merged set of color specifications.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub struct ColorSpecs {
|
||||
path: ColorSpec,
|
||||
line: ColorSpec,
|
||||
column: ColorSpec,
|
||||
matched: ColorSpec,
|
||||
}
|
||||
|
||||
/// A single color specification provided by the user.
|
||||
///
|
||||
/// A `ColorSpecs` can be built by merging a sequence of `Spec`s.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// The only way to build a `Spec` is to parse it from a string. Once multiple
|
||||
/// `Spec`s have been constructed, then can be merged into a single
|
||||
/// `ColorSpecs` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// use termcolor::{Color, ColorSpecs, Spec};
|
||||
///
|
||||
/// let spec1: Spec = "path:fg:blue".parse().unwrap();
|
||||
/// let spec2: Spec = "match:bg:green".parse().unwrap();
|
||||
/// let specs = ColorSpecs::new(&[spec1, spec2]);
|
||||
///
|
||||
/// assert_eq!(specs.path().fg(), Some(Color::Blue));
|
||||
/// assert_eq!(specs.matched().bg(), Some(Color::Green));
|
||||
/// ```
|
||||
///
|
||||
/// ## Format
|
||||
///
|
||||
/// The format of a `Spec` is a triple: `{type}:{attribute}:{value}`. Each
|
||||
/// component is defined as follows:
|
||||
///
|
||||
/// * `{type}` can be one of `path`, `line`, `column` or `match`.
|
||||
/// * `{attribute}` can be one of `fg`, `bg` or `style`. `{attribute}` may also
|
||||
/// be the special value `none`, in which case, `{value}` can be omitted.
|
||||
/// * `{value}` is either a color name (for `fg`/`bg`) or a style instruction.
|
||||
///
|
||||
/// `{type}` controls which part of the output should be styled and is
|
||||
/// application dependent.
|
||||
///
|
||||
/// When `{attribute}` is `none`, then this should cause any existing color
|
||||
/// settings to be cleared.
|
||||
///
|
||||
/// `{value}` should be a color when `{attribute}` is `fg` or `bg`, or it
|
||||
/// should be a style instruction when `{attribute}` is `style`. When
|
||||
/// `{attribute}` is `none`, `{value}` must be omitted.
|
||||
///
|
||||
/// Valid colors are `black`, `blue`, `green`, `red`, `cyan`, `magenta`,
|
||||
/// `yellow`, `white`.
|
||||
///
|
||||
/// Valid style instructions are `nobold`, `bold`, `intense`, `nointense`,
|
||||
/// `underline`, `nounderline`.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Spec {
|
||||
ty: OutType,
|
||||
value: SpecValue,
|
||||
}
|
||||
|
||||
/// The actual value given by the specification.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum SpecValue {
|
||||
None,
|
||||
Fg(Color),
|
||||
Bg(Color),
|
||||
Style(Style),
|
||||
}
|
||||
|
||||
/// The set of configurable portions of ripgrep's output.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum OutType {
|
||||
Path,
|
||||
Line,
|
||||
Column,
|
||||
Match,
|
||||
}
|
||||
|
||||
/// The specification type.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum SpecType {
|
||||
Fg,
|
||||
Bg,
|
||||
Style,
|
||||
None,
|
||||
}
|
||||
|
||||
/// The set of available styles for use in the terminal.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum Style {
|
||||
Bold,
|
||||
NoBold,
|
||||
Intense,
|
||||
NoIntense,
|
||||
Underline,
|
||||
NoUnderline
|
||||
}
|
||||
|
||||
impl ColorSpecs {
|
||||
/// Create color specifications from a list of user supplied
|
||||
/// specifications.
|
||||
pub fn new(user_specs: &[Spec]) -> ColorSpecs {
|
||||
let mut specs = ColorSpecs::default();
|
||||
for user_spec in user_specs {
|
||||
match user_spec.ty {
|
||||
OutType::Path => user_spec.merge_into(&mut specs.path),
|
||||
OutType::Line => user_spec.merge_into(&mut specs.line),
|
||||
OutType::Column => user_spec.merge_into(&mut specs.column),
|
||||
OutType::Match => user_spec.merge_into(&mut specs.matched),
|
||||
}
|
||||
}
|
||||
specs
|
||||
}
|
||||
|
||||
/// Return the color specification for coloring file paths.
|
||||
fn path(&self) -> &ColorSpec {
|
||||
&self.path
|
||||
}
|
||||
|
||||
/// Return the color specification for coloring line numbers.
|
||||
fn line(&self) -> &ColorSpec {
|
||||
&self.line
|
||||
}
|
||||
|
||||
/// Return the color specification for coloring column numbers.
|
||||
fn column(&self) -> &ColorSpec {
|
||||
&self.column
|
||||
}
|
||||
|
||||
/// Return the color specification for coloring matched text.
|
||||
fn matched(&self) -> &ColorSpec {
|
||||
&self.matched
|
||||
}
|
||||
}
|
||||
|
||||
impl Spec {
|
||||
/// Merge this spec into the given color specification.
|
||||
fn merge_into(&self, cspec: &mut ColorSpec) {
|
||||
self.value.merge_into(cspec);
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecValue {
|
||||
/// Merge this spec value into the given color specification.
|
||||
fn merge_into(&self, cspec: &mut ColorSpec) {
|
||||
match *self {
|
||||
SpecValue::None => cspec.clear(),
|
||||
SpecValue::Fg(ref color) => { cspec.set_fg(Some(color.clone())); }
|
||||
SpecValue::Bg(ref color) => { cspec.set_bg(Some(color.clone())); }
|
||||
SpecValue::Style(ref style) => {
|
||||
match *style {
|
||||
Style::Bold => { cspec.set_bold(true); }
|
||||
Style::NoBold => { cspec.set_bold(false); }
|
||||
Style::Intense => { cspec.set_intense(true); }
|
||||
Style::NoIntense => { cspec.set_intense(false); }
|
||||
Style::Underline => { cspec.set_underline(true); }
|
||||
Style::NoUnderline => { cspec.set_underline(false); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Spec {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Spec, Error> {
|
||||
let pieces: Vec<&str> = s.split(':').collect();
|
||||
if pieces.len() <= 1 || pieces.len() > 3 {
|
||||
return Err(Error::InvalidFormat(s.to_string()));
|
||||
}
|
||||
let otype: OutType = pieces[0].parse()?;
|
||||
match pieces[1].parse()? {
|
||||
SpecType::None => Ok(Spec { ty: otype, value: SpecValue::None }),
|
||||
SpecType::Style => {
|
||||
if pieces.len() < 3 {
|
||||
return Err(Error::InvalidFormat(s.to_string()));
|
||||
}
|
||||
let style: Style = pieces[2].parse()?;
|
||||
Ok(Spec { ty: otype, value: SpecValue::Style(style) })
|
||||
}
|
||||
SpecType::Fg => {
|
||||
if pieces.len() < 3 {
|
||||
return Err(Error::InvalidFormat(s.to_string()));
|
||||
}
|
||||
let color: Color = pieces[2].parse()?;
|
||||
Ok(Spec { ty: otype, value: SpecValue::Fg(color) })
|
||||
}
|
||||
SpecType::Bg => {
|
||||
if pieces.len() < 3 {
|
||||
return Err(Error::InvalidFormat(s.to_string()));
|
||||
}
|
||||
let color: Color = pieces[2].parse()?;
|
||||
Ok(Spec { ty: otype, value: SpecValue::Bg(color) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for OutType {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<OutType, Error> {
|
||||
match &*s.to_lowercase() {
|
||||
"path" => Ok(OutType::Path),
|
||||
"line" => Ok(OutType::Line),
|
||||
"column" => Ok(OutType::Column),
|
||||
"match" => Ok(OutType::Match),
|
||||
_ => Err(Error::UnrecognizedOutType(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for SpecType {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<SpecType, Error> {
|
||||
match &*s.to_lowercase() {
|
||||
"fg" => Ok(SpecType::Fg),
|
||||
"bg" => Ok(SpecType::Bg),
|
||||
"style" => Ok(SpecType::Style),
|
||||
"none" => Ok(SpecType::None),
|
||||
_ => Err(Error::UnrecognizedSpecType(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Style {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Style, Error> {
|
||||
match &*s.to_lowercase() {
|
||||
"bold" => Ok(Style::Bold),
|
||||
"nobold" => Ok(Style::NoBold),
|
||||
"intense" => Ok(Style::Intense),
|
||||
"nointense" => Ok(Style::NoIntense),
|
||||
"underline" => Ok(Style::Underline),
|
||||
"nounderline" => Ok(Style::NoUnderline),
|
||||
_ => Err(Error::UnrecognizedStyle(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use termcolor::{Color, ColorSpec};
|
||||
use super::{ColorSpecs, Error, OutType, Spec, SpecValue, Style};
|
||||
|
||||
#[test]
|
||||
fn merge() {
|
||||
let user_specs: &[Spec] = &[
|
||||
"match:fg:blue".parse().unwrap(),
|
||||
"match:none".parse().unwrap(),
|
||||
"match:style:bold".parse().unwrap(),
|
||||
];
|
||||
let mut expect_matched = ColorSpec::new();
|
||||
expect_matched.set_bold(true);
|
||||
assert_eq!(ColorSpecs::new(user_specs), ColorSpecs {
|
||||
path: ColorSpec::default(),
|
||||
line: ColorSpec::default(),
|
||||
column: ColorSpec::default(),
|
||||
matched: expect_matched,
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn specs() {
|
||||
let spec: Spec = "path:fg:blue".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Path,
|
||||
value: SpecValue::Fg(Color::Blue),
|
||||
});
|
||||
|
||||
let spec: Spec = "path:bg:red".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Path,
|
||||
value: SpecValue::Bg(Color::Red),
|
||||
});
|
||||
|
||||
let spec: Spec = "match:style:bold".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Match,
|
||||
value: SpecValue::Style(Style::Bold),
|
||||
});
|
||||
|
||||
let spec: Spec = "match:style:intense".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Match,
|
||||
value: SpecValue::Style(Style::Intense),
|
||||
});
|
||||
|
||||
let spec: Spec = "match:style:underline".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Match,
|
||||
value: SpecValue::Style(Style::Underline),
|
||||
});
|
||||
|
||||
let spec: Spec = "line:none".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Line,
|
||||
value: SpecValue::None,
|
||||
});
|
||||
|
||||
let spec: Spec = "column:bg:green".parse().unwrap();
|
||||
assert_eq!(spec, Spec {
|
||||
ty: OutType::Column,
|
||||
value: SpecValue::Bg(Color::Green),
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spec_errors() {
|
||||
let err = "line:nonee".parse::<Spec>().unwrap_err();
|
||||
assert_eq!(err, Error::UnrecognizedSpecType("nonee".to_string()));
|
||||
|
||||
let err = "".parse::<Spec>().unwrap_err();
|
||||
assert_eq!(err, Error::InvalidFormat("".to_string()));
|
||||
|
||||
let err = "foo".parse::<Spec>().unwrap_err();
|
||||
assert_eq!(err, Error::InvalidFormat("foo".to_string()));
|
||||
|
||||
let err = "line:style:italic".parse::<Spec>().unwrap_err();
|
||||
assert_eq!(err, Error::UnrecognizedStyle("italic".to_string()));
|
||||
|
||||
let err = "line:fg:brown".parse::<Spec>().unwrap_err();
|
||||
match err {
|
||||
Error::UnrecognizedColor(name, _) => assert_eq!(name, "brown"),
|
||||
err => assert!(false, "unexpected error: {:?}", err),
|
||||
}
|
||||
|
||||
let err = "foo:fg:brown".parse::<Spec>().unwrap_err();
|
||||
assert_eq!(err, Error::UnrecognizedOutType("foo".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*!
|
||||
The search_buffer module is responsible for searching a single file all in a
|
||||
The `search_buffer` module is responsible for searching a single file all in a
|
||||
single buffer. Typically, the source of the buffer is a memory map. This can
|
||||
be useful for when memory maps are faster than streaming search.
|
||||
|
||||
Note that this module doesn't quite support everything that search_stream does.
|
||||
Notably, showing contexts.
|
||||
Note that this module doesn't quite support everything that `search_stream`
|
||||
does. Notably, showing contexts.
|
||||
*/
|
||||
use std::cmp;
|
||||
use std::path::Path;
|
||||
|
||||
use grep::Grep;
|
||||
use term::Terminal;
|
||||
use termcolor::WriteColor;
|
||||
|
||||
use printer::Printer;
|
||||
use search_stream::{IterLines, Options, count_lines, is_binary};
|
||||
@@ -26,7 +26,7 @@ pub struct BufferSearcher<'a, W: 'a> {
|
||||
last_line: usize,
|
||||
}
|
||||
|
||||
impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
impl<'a, W: WriteColor> BufferSearcher<'a, W> {
|
||||
pub fn new(
|
||||
printer: &'a mut Printer<W>,
|
||||
grep: &'a Grep,
|
||||
@@ -61,6 +61,15 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, searching will print the path of files that *don't* match
|
||||
/// the given pattern.
|
||||
///
|
||||
/// Disabled by default.
|
||||
pub fn files_without_matches(mut self, yes: bool) -> Self {
|
||||
self.opts.files_without_matches = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the end-of-line byte used by this searcher.
|
||||
pub fn eol(mut self, eol: u8) -> Self {
|
||||
self.opts.eol = eol;
|
||||
@@ -81,6 +90,14 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Limit the number of matches to the given count.
|
||||
///
|
||||
/// The default is None, which corresponds to no limit.
|
||||
pub fn max_count(mut self, count: Option<u64>) -> Self {
|
||||
self.opts.max_count = count;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, don't show any output and quit searching after the first
|
||||
/// match is found.
|
||||
pub fn quiet(mut self, yes: bool) -> Self {
|
||||
@@ -96,8 +113,8 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
|
||||
#[inline(never)]
|
||||
pub fn run(mut self) -> u64 {
|
||||
let binary_upto = cmp::min(4096, self.buf.len());
|
||||
if !self.opts.text && is_binary(&self.buf[..binary_upto]) {
|
||||
let binary_upto = cmp::min(10_240, self.buf.len());
|
||||
if !self.opts.text && is_binary(&self.buf[..binary_upto], true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,11 +128,11 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
self.print_match(m.start(), m.end());
|
||||
}
|
||||
last_end = m.end();
|
||||
if self.opts.stop_after_first_match() {
|
||||
if self.opts.terminate(self.match_count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if self.opts.invert_match {
|
||||
if self.opts.invert_match && !self.opts.terminate(self.match_count) {
|
||||
let upto = self.buf.len();
|
||||
self.print_inverted_matches(last_end, upto);
|
||||
}
|
||||
@@ -125,6 +142,9 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
if self.opts.files_with_matches && self.match_count > 0 {
|
||||
self.printer.path(self.path);
|
||||
}
|
||||
if self.opts.files_without_matches && self.match_count == 0 {
|
||||
self.printer.path(self.path);
|
||||
}
|
||||
self.match_count
|
||||
}
|
||||
|
||||
@@ -146,6 +166,9 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
debug_assert!(self.opts.invert_match);
|
||||
let mut it = IterLines::new(self.opts.eol, start);
|
||||
while let Some((s, e)) = it.next(&self.buf[..end]) {
|
||||
if self.opts.terminate(self.match_count) {
|
||||
return;
|
||||
}
|
||||
self.print_match(s, e);
|
||||
}
|
||||
}
|
||||
@@ -173,10 +196,9 @@ mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use grep::GrepBuilder;
|
||||
use term::{Terminal, TerminfoTerminal};
|
||||
|
||||
use out::ColoredTerminal;
|
||||
use printer::Printer;
|
||||
use termcolor;
|
||||
|
||||
use super::BufferSearcher;
|
||||
|
||||
@@ -193,15 +215,14 @@ and exhibited clearly, with a label attached.\
|
||||
&Path::new("/baz.rs")
|
||||
}
|
||||
|
||||
type TestSearcher<'a> =
|
||||
BufferSearcher<'a, ColoredTerminal<TerminfoTerminal<Vec<u8>>>>;
|
||||
type TestSearcher<'a> = BufferSearcher<'a, termcolor::NoColor<Vec<u8>>>;
|
||||
|
||||
fn search<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||
pat: &str,
|
||||
haystack: &str,
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let outbuf = termcolor::NoColor::new(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
@@ -266,6 +287,34 @@ and exhibited clearly, with a label attached.\
|
||||
assert_eq!(out, "/baz.rs\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn files_without_matches() {
|
||||
let (count, out) = search(
|
||||
"zzzz", SHERLOCK, |s| s.files_without_matches(true));
|
||||
assert_eq!(0, count);
|
||||
assert_eq!(out, "/baz.rs\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_count() {
|
||||
let (count, out) = search(
|
||||
"Sherlock", SHERLOCK, |s| s.max_count(Some(1)));
|
||||
assert_eq!(1, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_match_max_count() {
|
||||
let (count, out) = search(
|
||||
"zzzz", SHERLOCK, |s| s.invert_match(true).max_count(Some(1)));
|
||||
assert_eq!(1, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_match() {
|
||||
let (count, out) = search(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
The search_stream module is responsible for searching a single file and
|
||||
The `search_stream` module is responsible for searching a single file and
|
||||
printing matches. In particular, it searches the file in a streaming fashion
|
||||
using `read` calls and a (roughly) fixed size buffer.
|
||||
*/
|
||||
@@ -10,9 +10,10 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use bytecount;
|
||||
use grep::{Grep, Match};
|
||||
use memchr::{memchr, memrchr};
|
||||
use term::Terminal;
|
||||
use termcolor::WriteColor;
|
||||
|
||||
use printer::Printer;
|
||||
|
||||
@@ -81,9 +82,11 @@ pub struct Options {
|
||||
pub before_context: usize,
|
||||
pub count: bool,
|
||||
pub files_with_matches: bool,
|
||||
pub files_without_matches: bool,
|
||||
pub eol: u8,
|
||||
pub invert_match: bool,
|
||||
pub line_number: bool,
|
||||
pub max_count: Option<u64>,
|
||||
pub quiet: bool,
|
||||
pub text: bool,
|
||||
}
|
||||
@@ -95,9 +98,11 @@ impl Default for Options {
|
||||
before_context: 0,
|
||||
count: false,
|
||||
files_with_matches: false,
|
||||
files_without_matches: false,
|
||||
eol: b'\n',
|
||||
invert_match: false,
|
||||
line_number: false,
|
||||
max_count: None,
|
||||
quiet: false,
|
||||
text: false,
|
||||
}
|
||||
@@ -106,20 +111,32 @@ impl Default for Options {
|
||||
}
|
||||
|
||||
impl Options {
|
||||
/// Several options (--quiet, --count, --files-with-matches) imply that
|
||||
/// we shouldn't ever display matches.
|
||||
/// Several options (--quiet, --count, --files-with-matches,
|
||||
/// --files-without-match) imply that we shouldn't ever display matches.
|
||||
pub fn skip_matches(&self) -> bool {
|
||||
self.count || self.files_with_matches || self.quiet
|
||||
self.count || self.files_with_matches || self.files_without_matches
|
||||
|| self.quiet
|
||||
}
|
||||
|
||||
/// Some options (--quiet, --files-with-matches) imply that we can stop
|
||||
/// searching after the first match.
|
||||
/// Some options (--quiet, --files-with-matches, --files-without-match)
|
||||
/// imply that we can stop searching after the first match.
|
||||
pub fn stop_after_first_match(&self) -> bool {
|
||||
self.files_with_matches || self.quiet
|
||||
self.files_with_matches || self.files_without_matches || self.quiet
|
||||
}
|
||||
|
||||
/// Returns true if the search should terminate based on the match count.
|
||||
pub fn terminate(&self, match_count: u64) -> bool {
|
||||
if match_count > 0 && self.stop_after_first_match() {
|
||||
return true;
|
||||
}
|
||||
if self.max_count.map_or(false, |max| match_count >= max) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
impl<'a, R: io::Read, W: WriteColor> Searcher<'a, R, W> {
|
||||
/// Create a new searcher.
|
||||
///
|
||||
/// `inp` is a reusable input buffer that is used as scratch space by this
|
||||
@@ -185,6 +202,14 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, searching will print the path of files without any matches.
|
||||
///
|
||||
/// Disabled by default.
|
||||
pub fn files_without_matches(mut self, yes: bool) -> Self {
|
||||
self.opts.files_without_matches = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the end-of-line byte used by this searcher.
|
||||
pub fn eol(mut self, eol: u8) -> Self {
|
||||
self.opts.eol = eol;
|
||||
@@ -205,6 +230,14 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Limit the number of matches to the given count.
|
||||
///
|
||||
/// The default is None, which corresponds to no limit.
|
||||
pub fn max_count(mut self, count: Option<u64>) -> Self {
|
||||
self.opts.max_count = count;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, don't show any output and quit searching after the first
|
||||
/// match is found.
|
||||
pub fn quiet(mut self, yes: bool) -> Self {
|
||||
@@ -215,6 +248,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
/// If enabled, search binary files as if they were text.
|
||||
pub fn text(mut self, yes: bool) -> Self {
|
||||
self.opts.text = yes;
|
||||
self.inp.text(yes);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -230,16 +264,13 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
while !self.terminate() {
|
||||
let upto = self.inp.lastnl;
|
||||
self.print_after_context(upto);
|
||||
if !try!(self.fill()) {
|
||||
break;
|
||||
}
|
||||
if !self.opts.text && self.inp.is_binary {
|
||||
if !self.fill()? {
|
||||
break;
|
||||
}
|
||||
while !self.terminate() && self.inp.pos < self.inp.lastnl {
|
||||
let matched = self.grep.read_match(
|
||||
&mut self.last_match,
|
||||
&mut self.inp.buf[..self.inp.lastnl],
|
||||
&self.inp.buf[..self.inp.lastnl],
|
||||
self.inp.pos);
|
||||
if self.opts.invert_match {
|
||||
let upto =
|
||||
@@ -268,47 +299,59 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.after_context_remaining > 0 {
|
||||
if self.last_printed == self.inp.lastnl {
|
||||
self.fill()?;
|
||||
}
|
||||
let upto = self.inp.lastnl;
|
||||
if upto > 0 {
|
||||
self.print_after_context(upto);
|
||||
}
|
||||
}
|
||||
if self.match_count > 0 {
|
||||
if self.opts.count {
|
||||
self.printer.path_count(self.path, self.match_count);
|
||||
} else if self.opts.files_with_matches {
|
||||
self.printer.path(self.path);
|
||||
}
|
||||
} else if self.opts.files_without_matches {
|
||||
self.printer.path(self.path);
|
||||
}
|
||||
Ok(self.match_count)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn terminate(&self) -> bool {
|
||||
self.match_count > 0 && self.opts.stop_after_first_match()
|
||||
self.opts.terminate(self.match_count)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn fill(&mut self) -> Result<bool, Error> {
|
||||
let mut keep = self.inp.lastnl;
|
||||
if self.opts.before_context > 0 || self.opts.after_context > 0 {
|
||||
let keep = if self.opts.before_context > 0 || self.opts.after_context > 0 {
|
||||
let lines = 1 + cmp::max(
|
||||
self.opts.before_context, self.opts.after_context);
|
||||
keep = start_of_previous_lines(
|
||||
start_of_previous_lines(
|
||||
self.opts.eol,
|
||||
&self.inp.buf,
|
||||
self.inp.lastnl.saturating_sub(1),
|
||||
lines);
|
||||
}
|
||||
lines)
|
||||
} else {
|
||||
self.inp.lastnl
|
||||
};
|
||||
if keep < self.last_printed {
|
||||
self.last_printed = self.last_printed - keep;
|
||||
self.last_printed -= keep;
|
||||
} else {
|
||||
self.last_printed = 0;
|
||||
}
|
||||
if keep <= self.last_line {
|
||||
self.last_line = self.last_line - keep;
|
||||
self.last_line -= keep;
|
||||
} else {
|
||||
self.count_lines(keep);
|
||||
self.last_line = 0;
|
||||
}
|
||||
let ok = try!(self.inp.fill(&mut self.haystack, keep).map_err(|err| {
|
||||
let ok = self.inp.fill(&mut self.haystack, keep).map_err(|err| {
|
||||
Error::from_io(err, &self.path)
|
||||
}));
|
||||
})?;
|
||||
Ok(ok)
|
||||
}
|
||||
|
||||
@@ -317,6 +360,9 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
debug_assert!(self.opts.invert_match);
|
||||
let mut it = IterLines::new(self.opts.eol, self.inp.pos);
|
||||
while let Some((start, end)) = it.next(&self.inp.buf[..upto]) {
|
||||
if self.terminate() {
|
||||
return;
|
||||
}
|
||||
self.print_match(start, end);
|
||||
self.inp.pos = end;
|
||||
}
|
||||
@@ -419,7 +465,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
}
|
||||
}
|
||||
|
||||
/// InputBuffer encapsulates the logic of maintaining a ~fixed sized buffer
|
||||
/// `InputBuffer` encapsulates the logic of maintaining a ~fixed sized buffer
|
||||
/// on which to search. There are three key pieces of complexity:
|
||||
///
|
||||
/// 1. We must be able to handle lines that are longer than the size of the
|
||||
@@ -435,7 +481,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
/// may occur at the beginning of a buffer, in which case, lines at the end
|
||||
/// of the previous contents of the buffer need to be printed.
|
||||
///
|
||||
/// An InputBuffer is designed to be reused and isn't tied to any particular
|
||||
/// An `InputBuffer` is designed to be reused and isn't tied to any particular
|
||||
/// reader.
|
||||
pub struct InputBuffer {
|
||||
/// The number of bytes to attempt to read at a time. Once set, this is
|
||||
@@ -463,10 +509,8 @@ pub struct InputBuffer {
|
||||
end: usize,
|
||||
/// Set to true if and only if no reads have occurred yet.
|
||||
first: bool,
|
||||
/// Set to true if and only if the contents of buf are determined to be
|
||||
/// "binary" (i.e., not searchable text). Note that its value may be
|
||||
/// falsely negative *or* falsely positive. It is only a heuristic.
|
||||
is_binary: bool,
|
||||
/// Set to true if all binary data should be treated as if it were text.
|
||||
text: bool,
|
||||
}
|
||||
|
||||
impl InputBuffer {
|
||||
@@ -494,13 +538,23 @@ impl InputBuffer {
|
||||
lastnl: 0,
|
||||
end: 0,
|
||||
first: true,
|
||||
is_binary: false,
|
||||
text: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the end-of-line terminator used by this input buffer.
|
||||
pub fn eol(&mut self, eol: u8) {
|
||||
pub fn eol(&mut self, eol: u8) -> &mut Self {
|
||||
self.eol = eol;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, search binary files as if they were text.
|
||||
///
|
||||
/// Note that this may cause the buffer to load the entire contents of a
|
||||
/// file into memory.
|
||||
pub fn text(&mut self, yes: bool) -> &mut Self {
|
||||
self.text = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Resets this buffer so that it may be reused with a new reader.
|
||||
@@ -509,7 +563,6 @@ impl InputBuffer {
|
||||
self.lastnl = 0;
|
||||
self.end = 0;
|
||||
self.first = true;
|
||||
self.is_binary = false;
|
||||
}
|
||||
|
||||
/// Fill the contents of this buffer with the reader given. The reader
|
||||
@@ -524,9 +577,10 @@ impl InputBuffer {
|
||||
keep_from: usize,
|
||||
) -> Result<bool, io::Error> {
|
||||
// Rollover bytes from buf[keep_from..end] and update our various
|
||||
// pointers. N.B. This could be done with the unsafe ptr::copy, but
|
||||
// I haven't been able to produce a benchmark that notices a difference
|
||||
// in performance. (Invariably, ptr::copy is also clearer IMO.)
|
||||
// pointers. N.B. This could be done with the ptr::copy, but I haven't
|
||||
// been able to produce a benchmark that notices a difference in
|
||||
// performance. (Invariably, ptr::copy is seems clearer IMO, but it is
|
||||
// not safe.)
|
||||
self.tmp.clear();
|
||||
self.tmp.extend_from_slice(&self.buf[keep_from..self.end]);
|
||||
self.buf[0..self.tmp.len()].copy_from_slice(&self.tmp);
|
||||
@@ -541,10 +595,12 @@ impl InputBuffer {
|
||||
let new_len = cmp::max(min_len, self.buf.len() * 2);
|
||||
self.buf.resize(new_len, 0);
|
||||
}
|
||||
let n = try!(rdr.read(
|
||||
&mut self.buf[self.end..self.end + self.read_size]));
|
||||
if self.first && is_binary(&self.buf[self.end..self.end + n]) {
|
||||
self.is_binary = true;
|
||||
let n = rdr.read(
|
||||
&mut self.buf[self.end..self.end + self.read_size])?;
|
||||
if !self.text {
|
||||
if is_binary(&self.buf[self.end..self.end + n], self.first) {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
self.first = false;
|
||||
// We assume that reading 0 bytes means we've hit EOF.
|
||||
@@ -574,97 +630,17 @@ impl InputBuffer {
|
||||
///
|
||||
/// Note that this may return both false positives and false negatives.
|
||||
#[inline(always)]
|
||||
pub fn is_binary(buf: &[u8]) -> bool {
|
||||
if buf.len() >= 4 && &buf[0..4] == b"%PDF" {
|
||||
pub fn is_binary(buf: &[u8], first: bool) -> bool {
|
||||
if first && buf.len() >= 4 && &buf[0..4] == b"%PDF" {
|
||||
return true;
|
||||
}
|
||||
memchr(b'\x00', &buf[0..cmp::min(1024, buf.len())]).is_some()
|
||||
memchr(b'\x00', buf).is_some()
|
||||
}
|
||||
|
||||
/// Count the number of lines in the given buffer.
|
||||
#[inline(never)]
|
||||
|
||||
#[inline(never)]
|
||||
pub fn count_lines(buf: &[u8], eol: u8) -> u64 {
|
||||
// This was adapted from code in the memchr crate. The specific benefit
|
||||
// here is that we can avoid a branch in the inner loop because all we're
|
||||
// doing is counting.
|
||||
|
||||
// The technique to count EOL bytes was adapted from:
|
||||
// http://bits.stephan-brumme.com/null.html
|
||||
const LO_U64: u64 = 0x0101010101010101;
|
||||
const HI_U64: u64 = 0x8080808080808080;
|
||||
|
||||
// use truncation
|
||||
const LO_USIZE: usize = LO_U64 as usize;
|
||||
const HI_USIZE: usize = HI_U64 as usize;
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const USIZE_BYTES: usize = 4;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const USIZE_BYTES: usize = 8;
|
||||
|
||||
fn count_eol(eol: usize) -> u64 {
|
||||
// Ideally, this would compile down to a POPCNT instruction, but
|
||||
// it looks like you need to set RUSTFLAGS="-C target-cpu=native"
|
||||
// (or target-feature=+popcnt) to get that to work. Bummer.
|
||||
(eol.wrapping_sub(LO_USIZE) & !eol & HI_USIZE).count_ones() as u64
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn repeat_byte(b: u8) -> usize {
|
||||
let mut rep = (b as usize) << 8 | b as usize;
|
||||
rep = rep << 16 | rep;
|
||||
rep
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn repeat_byte(b: u8) -> usize {
|
||||
let mut rep = (b as usize) << 8 | b as usize;
|
||||
rep = rep << 16 | rep;
|
||||
rep = rep << 32 | rep;
|
||||
rep
|
||||
}
|
||||
|
||||
fn count_lines_slow(mut buf: &[u8], eol: u8) -> u64 {
|
||||
let mut count = 0;
|
||||
while let Some(pos) = memchr(eol, buf) {
|
||||
count += 1;
|
||||
buf = &buf[pos + 1..];
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
let len = buf.len();
|
||||
let ptr = buf.as_ptr();
|
||||
let mut count = 0;
|
||||
|
||||
// Search up to an aligned boundary...
|
||||
let align = (ptr as usize) & (USIZE_BYTES - 1);
|
||||
let mut i = 0;
|
||||
if align > 0 {
|
||||
i = cmp::min(USIZE_BYTES - align, len);
|
||||
count += count_lines_slow(&buf[..i], eol);
|
||||
}
|
||||
|
||||
// ... and search the rest.
|
||||
let repeated_eol = repeat_byte(eol);
|
||||
|
||||
if len >= 2 * USIZE_BYTES {
|
||||
while i <= len - (2 * USIZE_BYTES) {
|
||||
unsafe {
|
||||
let u = *(ptr.offset(i as isize) as *const usize);
|
||||
let v = *(ptr.offset((i + USIZE_BYTES) as isize)
|
||||
as *const usize);
|
||||
|
||||
count += count_eol(u ^ repeated_eol);
|
||||
count += count_eol(v ^ repeated_eol);
|
||||
}
|
||||
i += USIZE_BYTES * 2;
|
||||
}
|
||||
}
|
||||
count += count_lines_slow(&buf[i..], eol);
|
||||
count
|
||||
bytecount::count(buf, eol) as u64
|
||||
}
|
||||
|
||||
/// Replaces a with b in buf.
|
||||
@@ -804,10 +780,8 @@ mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use grep::GrepBuilder;
|
||||
use term::{Terminal, TerminfoTerminal};
|
||||
|
||||
use out::ColoredTerminal;
|
||||
use printer::Printer;
|
||||
use termcolor;
|
||||
|
||||
use super::{InputBuffer, Searcher, start_of_previous_lines};
|
||||
|
||||
@@ -847,7 +821,7 @@ fn main() {
|
||||
type TestSearcher<'a> = Searcher<
|
||||
'a,
|
||||
io::Cursor<Vec<u8>>,
|
||||
ColoredTerminal<TerminfoTerminal<Vec<u8>>>,
|
||||
termcolor::NoColor<Vec<u8>>,
|
||||
>;
|
||||
|
||||
fn search_smallcap<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||
@@ -856,7 +830,7 @@ fn main() {
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let mut inp = InputBuffer::with_capacity(1);
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let outbuf = termcolor::NoColor::new(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
@@ -873,7 +847,7 @@ fn main() {
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let mut inp = InputBuffer::with_capacity(4096);
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let outbuf = termcolor::NoColor::new(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
@@ -1040,6 +1014,34 @@ fn main() {
|
||||
assert_eq!(out, "/baz.rs\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn files_without_matches() {
|
||||
let (count, out) = search_smallcap(
|
||||
"zzzz", SHERLOCK, |s| s.files_without_matches(true));
|
||||
assert_eq!(0, count);
|
||||
assert_eq!(out, "/baz.rs\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_count() {
|
||||
let (count, out) = search_smallcap(
|
||||
"Sherlock", SHERLOCK, |s| s.max_count(Some(1)));
|
||||
assert_eq!(1, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_match_max_count() {
|
||||
let (count, out) = search(
|
||||
"zzzz", SHERLOCK, |s| s.invert_match(true).max_count(Some(1)));
|
||||
assert_eq!(1, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_match() {
|
||||
let (count, out) = search_smallcap(
|
||||
@@ -1255,6 +1257,23 @@ fn main() {
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_context_invert_one_max_count_two() {
|
||||
let (count, out) = search_smallcap("Sherlock", SHERLOCK, |s| {
|
||||
s.line_number(true)
|
||||
.invert_match(true)
|
||||
.after_context(1)
|
||||
.max_count(Some(2))
|
||||
});
|
||||
assert_eq!(2, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:2:Holmeses, success in the province of detective work must always
|
||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
/baz.rs:4:can extract a clew from a wisp of straw or a flake of cigar ash;
|
||||
/baz.rs-5-but Doctor Watson has to have it taken out for him and dusted,
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_context_two1() {
|
||||
let (count, out) = search_smallcap("Sherlock", SHERLOCK, |s| {
|
||||
@@ -1298,6 +1317,23 @@ fn main() {
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_context_two_max_count_two() {
|
||||
let (count, out) = search_smallcap(
|
||||
"Doctor", SHERLOCK, |s| {
|
||||
s.line_number(true).after_context(2).max_count(Some(2))
|
||||
});
|
||||
assert_eq!(2, count);
|
||||
assert_eq!(out, "\
|
||||
/baz.rs:1:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
/baz.rs-2-Holmeses, success in the province of detective work must always
|
||||
/baz.rs-3-be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
--
|
||||
/baz.rs:5:but Doctor Watson has to have it taken out for him and dusted,
|
||||
/baz.rs-6-and exhibited clearly, with a label attached.
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn after_context_three1() {
|
||||
let (count, out) = search_smallcap("Sherlock", SHERLOCK, |s| {
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*!
|
||||
This module contains a Windows-only *in-memory* implementation of the
|
||||
`term::Terminal` trait.
|
||||
|
||||
This particular implementation is a bit idiosyncratic, and the "in-memory"
|
||||
specification is to blame. In particular, on Windows, coloring requires
|
||||
communicating with the console synchronously as data is written to stdout.
|
||||
This is anathema to how ripgrep fundamentally works: by writing search results
|
||||
to intermediate thread local buffers in order to maximize parallelism.
|
||||
|
||||
Eliminating parallelism on Windows isn't an option, because that would negate
|
||||
a tremendous performance benefit just for coloring.
|
||||
|
||||
We've worked around this by providing an implementation of `term::Terminal`
|
||||
that records precisely where a color or a reset should be invoked, according
|
||||
to a byte offset in the in memory buffer. When the buffer is actually printed,
|
||||
we copy the bytes from the buffer to stdout incrementally while invoking the
|
||||
corresponding console APIs for coloring at the right location.
|
||||
|
||||
(Another approach would be to do ANSI coloring unconditionally, then parse that
|
||||
and translate it to console commands. The advantage of that approach is that
|
||||
it doesn't require any additional memory for storing offsets. In practice
|
||||
though, coloring is only used in the terminal, which tends to correspond to
|
||||
searches that produce very few results with respect to the corpus searched.
|
||||
Therefore, this is an acceptable trade off. Namely, we do not pay for it when
|
||||
coloring is disabled.
|
||||
*/
|
||||
use std::io;
|
||||
|
||||
use term::{self, Terminal};
|
||||
use term::color::Color;
|
||||
|
||||
/// An in-memory buffer that provides Windows console coloring.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WindowsBuffer {
|
||||
buf: Vec<u8>,
|
||||
pos: usize,
|
||||
colors: Vec<WindowsColor>,
|
||||
}
|
||||
|
||||
/// A color associated with a particular location in a buffer.
|
||||
#[derive(Clone, Debug)]
|
||||
struct WindowsColor {
|
||||
pos: usize,
|
||||
opt: WindowsOption,
|
||||
}
|
||||
|
||||
/// A color or reset directive that can be translated into an instruction to
|
||||
/// the Windows console.
|
||||
#[derive(Clone, Debug)]
|
||||
enum WindowsOption {
|
||||
Foreground(Color),
|
||||
Background(Color),
|
||||
Reset,
|
||||
}
|
||||
|
||||
impl WindowsBuffer {
|
||||
/// Create a new empty buffer for Windows console coloring.
|
||||
pub fn new() -> WindowsBuffer {
|
||||
WindowsBuffer {
|
||||
buf: vec![],
|
||||
pos: 0,
|
||||
colors: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&mut self, opt: WindowsOption) {
|
||||
let pos = self.pos;
|
||||
self.colors.push(WindowsColor { pos: pos, opt: opt });
|
||||
}
|
||||
|
||||
/// Print the contents to the given terminal.
|
||||
pub fn print_stdout<T: Terminal + Send>(&self, tt: &mut T) {
|
||||
if !tt.supports_color() {
|
||||
let _ = tt.write_all(&self.buf);
|
||||
let _ = tt.flush();
|
||||
return;
|
||||
}
|
||||
let mut last = 0;
|
||||
for col in &self.colors {
|
||||
let _ = tt.write_all(&self.buf[last..col.pos]);
|
||||
match col.opt {
|
||||
WindowsOption::Foreground(c) => {
|
||||
let _ = tt.fg(c);
|
||||
}
|
||||
WindowsOption::Background(c) => {
|
||||
let _ = tt.bg(c);
|
||||
}
|
||||
WindowsOption::Reset => {
|
||||
let _ = tt.reset();
|
||||
}
|
||||
}
|
||||
last = col.pos;
|
||||
}
|
||||
let _ = tt.write_all(&self.buf[last..]);
|
||||
let _ = tt.flush();
|
||||
}
|
||||
|
||||
/// Clear the buffer.
|
||||
pub fn clear(&mut self) {
|
||||
self.buf.clear();
|
||||
self.colors.clear();
|
||||
self.pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for WindowsBuffer {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let n = try!(self.buf.write(buf));
|
||||
self.pos += n;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Terminal for WindowsBuffer {
|
||||
type Output = Vec<u8>;
|
||||
|
||||
fn fg(&mut self, fg: Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Foreground(fg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Background(bg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn attr(&mut self, _attr: term::Attr) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn supports_attr(&self, _attr: term::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
self.push(WindowsOption::Reset);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Vec<u8> {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Vec<u8> {
|
||||
self.buf
|
||||
}
|
||||
}
|
||||
128
src/unescape.rs
Normal file
128
src/unescape.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
/// A single state in the state machine used by `unescape`.
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
enum State {
|
||||
/// The state after seeing a `\`.
|
||||
Escape,
|
||||
/// The state after seeing a `\x`.
|
||||
HexFirst,
|
||||
/// The state after seeing a `\x[0-9A-Fa-f]`.
|
||||
HexSecond(char),
|
||||
/// Default state.
|
||||
Literal,
|
||||
}
|
||||
|
||||
/// Unescapes a string given on the command line. It supports a limited set of
|
||||
/// escape sequences:
|
||||
///
|
||||
/// * `\t`, `\r` and `\n` are mapped to their corresponding ASCII bytes.
|
||||
/// * `\xZZ` hexadecimal escapes are mapped to their byte.
|
||||
pub fn unescape(s: &str) -> Vec<u8> {
|
||||
use self::State::*;
|
||||
|
||||
let mut bytes = vec![];
|
||||
let mut state = Literal;
|
||||
for c in s.chars() {
|
||||
match state {
|
||||
Escape => {
|
||||
match c {
|
||||
'n' => { bytes.push(b'\n'); state = Literal; }
|
||||
'r' => { bytes.push(b'\r'); state = Literal; }
|
||||
't' => { bytes.push(b'\t'); state = Literal; }
|
||||
'x' => { state = HexFirst; }
|
||||
c => {
|
||||
bytes.extend(format!(r"\{}", c).into_bytes());
|
||||
state = Literal;
|
||||
}
|
||||
}
|
||||
}
|
||||
HexFirst => {
|
||||
match c {
|
||||
'0'...'9' | 'A'...'F' | 'a'...'f' => {
|
||||
state = HexSecond(c);
|
||||
}
|
||||
c => {
|
||||
bytes.extend(format!(r"\x{}", c).into_bytes());
|
||||
state = Literal;
|
||||
}
|
||||
}
|
||||
}
|
||||
HexSecond(first) => {
|
||||
match c {
|
||||
'0'...'9' | 'A'...'F' | 'a'...'f' => {
|
||||
let ordinal = format!("{}{}", first, c);
|
||||
let byte = u8::from_str_radix(&ordinal, 16).unwrap();
|
||||
bytes.push(byte);
|
||||
state = Literal;
|
||||
}
|
||||
c => {
|
||||
let original = format!(r"\x{}{}", first, c);
|
||||
bytes.extend(original.into_bytes());
|
||||
state = Literal;
|
||||
}
|
||||
}
|
||||
}
|
||||
Literal => {
|
||||
match c {
|
||||
'\\' => { state = Escape; }
|
||||
c => { bytes.extend(c.to_string().as_bytes()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match state {
|
||||
Escape => bytes.push(b'\\'),
|
||||
HexFirst => bytes.extend(b"\\x"),
|
||||
HexSecond(c) => bytes.extend(format!("\\x{}", c).into_bytes()),
|
||||
Literal => {}
|
||||
}
|
||||
bytes
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::unescape;
|
||||
|
||||
fn b(bytes: &'static [u8]) -> Vec<u8> {
|
||||
bytes.to_vec()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nul() {
|
||||
assert_eq!(b(b"\x00"), unescape(r"\x00"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nl() {
|
||||
assert_eq!(b(b"\n"), unescape(r"\n"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_tab() {
|
||||
assert_eq!(b(b"\t"), unescape(r"\t"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_carriage() {
|
||||
assert_eq!(b(b"\r"), unescape(r"\r"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nothing_simple() {
|
||||
assert_eq!(b(b"\\a"), unescape(r"\a"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nothing_hex0() {
|
||||
assert_eq!(b(b"\\x"), unescape(r"\x"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nothing_hex1() {
|
||||
assert_eq!(b(b"\\xz"), unescape(r"\xz"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unescape_nothing_hex2() {
|
||||
assert_eq!(b(b"\\xzz"), unescape(r"\xzz"));
|
||||
}
|
||||
}
|
||||
360
src/worker.rs
Normal file
360
src/worker.rs
Normal file
@@ -0,0 +1,360 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
use encoding_rs::Encoding;
|
||||
use grep::Grep;
|
||||
use ignore::DirEntry;
|
||||
use memmap::Mmap;
|
||||
use termcolor::WriteColor;
|
||||
|
||||
use decoder::DecodeReader;
|
||||
use decompressor::{self, DecompressionReader};
|
||||
use pathutil::strip_prefix;
|
||||
use printer::Printer;
|
||||
use search_buffer::BufferSearcher;
|
||||
use search_stream::{InputBuffer, Searcher};
|
||||
|
||||
use Result;
|
||||
|
||||
pub enum Work {
|
||||
Stdin,
|
||||
DirEntry(DirEntry),
|
||||
}
|
||||
|
||||
pub struct WorkerBuilder {
|
||||
grep: Grep,
|
||||
opts: Options,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Options {
|
||||
mmap: bool,
|
||||
encoding: Option<&'static Encoding>,
|
||||
after_context: usize,
|
||||
before_context: usize,
|
||||
count: bool,
|
||||
files_with_matches: bool,
|
||||
files_without_matches: bool,
|
||||
eol: u8,
|
||||
invert_match: bool,
|
||||
line_number: bool,
|
||||
max_count: Option<u64>,
|
||||
no_messages: bool,
|
||||
quiet: bool,
|
||||
text: bool,
|
||||
search_zip_files: bool
|
||||
}
|
||||
|
||||
impl Default for Options {
|
||||
fn default() -> Options {
|
||||
Options {
|
||||
mmap: false,
|
||||
encoding: None,
|
||||
after_context: 0,
|
||||
before_context: 0,
|
||||
count: false,
|
||||
files_with_matches: false,
|
||||
files_without_matches: false,
|
||||
eol: b'\n',
|
||||
invert_match: false,
|
||||
line_number: false,
|
||||
max_count: None,
|
||||
no_messages: false,
|
||||
quiet: false,
|
||||
text: false,
|
||||
search_zip_files: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkerBuilder {
|
||||
/// Create a new builder for a worker.
|
||||
///
|
||||
/// A reusable input buffer and a grep matcher are required, but there
|
||||
/// are numerous additional options that can be configured on this builder.
|
||||
pub fn new(grep: Grep) -> WorkerBuilder {
|
||||
WorkerBuilder {
|
||||
grep: grep,
|
||||
opts: Options::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the worker from this builder.
|
||||
pub fn build(self) -> Worker {
|
||||
let mut inpbuf = InputBuffer::new();
|
||||
inpbuf.eol(self.opts.eol);
|
||||
Worker {
|
||||
grep: self.grep,
|
||||
inpbuf: inpbuf,
|
||||
decodebuf: vec![0; 8 * (1<<10)],
|
||||
opts: self.opts,
|
||||
}
|
||||
}
|
||||
|
||||
/// The number of contextual lines to show after each match. The default
|
||||
/// is zero.
|
||||
pub fn after_context(mut self, count: usize) -> Self {
|
||||
self.opts.after_context = count;
|
||||
self
|
||||
}
|
||||
|
||||
/// The number of contextual lines to show before each match. The default
|
||||
/// is zero.
|
||||
pub fn before_context(mut self, count: usize) -> Self {
|
||||
self.opts.before_context = count;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, searching will print a count instead of each match.
|
||||
///
|
||||
/// Disabled by default.
|
||||
pub fn count(mut self, yes: bool) -> Self {
|
||||
self.opts.count = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the encoding to use to read each file.
|
||||
///
|
||||
/// If the encoding is `None` (the default), then the encoding is
|
||||
/// automatically detected on a best-effort per-file basis.
|
||||
pub fn encoding(mut self, enc: Option<&'static Encoding>) -> Self {
|
||||
self.opts.encoding = enc;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, searching will print the path instead of each match.
|
||||
///
|
||||
/// Disabled by default.
|
||||
pub fn files_with_matches(mut self, yes: bool) -> Self {
|
||||
self.opts.files_with_matches = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, searching will print the path of files without any matches.
|
||||
///
|
||||
/// Disabled by default.
|
||||
pub fn files_without_matches(mut self, yes: bool) -> Self {
|
||||
self.opts.files_without_matches = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the end-of-line byte used by this searcher.
|
||||
pub fn eol(mut self, eol: u8) -> Self {
|
||||
self.opts.eol = eol;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, matching is inverted so that lines that *don't* match the
|
||||
/// given pattern are treated as matches.
|
||||
pub fn invert_match(mut self, yes: bool) -> Self {
|
||||
self.opts.invert_match = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, compute line numbers and prefix each line of output with
|
||||
/// them.
|
||||
pub fn line_number(mut self, yes: bool) -> Self {
|
||||
self.opts.line_number = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Limit the number of matches to the given count.
|
||||
///
|
||||
/// The default is None, which corresponds to no limit.
|
||||
pub fn max_count(mut self, count: Option<u64>) -> Self {
|
||||
self.opts.max_count = count;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, try to use memory maps for searching if possible.
|
||||
pub fn mmap(mut self, yes: bool) -> Self {
|
||||
self.opts.mmap = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, error messages are suppressed.
|
||||
///
|
||||
/// This is disabled by default.
|
||||
pub fn no_messages(mut self, yes: bool) -> Self {
|
||||
self.opts.no_messages = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, don't show any output and quit searching after the first
|
||||
/// match is found.
|
||||
pub fn quiet(mut self, yes: bool) -> Self {
|
||||
self.opts.quiet = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, search binary files as if they were text.
|
||||
pub fn text(mut self, yes: bool) -> Self {
|
||||
self.opts.text = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// If enabled, search through compressed files as well
|
||||
pub fn search_zip_files(mut self, yes: bool) -> Self {
|
||||
self.opts.search_zip_files = yes;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Worker is responsible for executing searches on file paths, while choosing
|
||||
/// streaming search or memory map search as appropriate.
|
||||
pub struct Worker {
|
||||
grep: Grep,
|
||||
inpbuf: InputBuffer,
|
||||
decodebuf: Vec<u8>,
|
||||
opts: Options,
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
/// Execute the worker with the given printer and work item.
|
||||
///
|
||||
/// A work item can either be stdin or a file path.
|
||||
pub fn run<W: WriteColor>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
work: Work,
|
||||
) -> u64 {
|
||||
let result = match work {
|
||||
Work::Stdin => {
|
||||
let stdin = io::stdin();
|
||||
let stdin = stdin.lock();
|
||||
self.search(printer, Path::new("<stdin>"), stdin)
|
||||
}
|
||||
Work::DirEntry(dent) => {
|
||||
let mut path = dent.path();
|
||||
if self.opts.search_zip_files
|
||||
&& decompressor::is_compressed(path)
|
||||
{
|
||||
match DecompressionReader::from_path(path) {
|
||||
Some(reader) => self.search(printer, path, reader),
|
||||
None => {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let file = match File::open(path) {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
if !self.opts.no_messages {
|
||||
eprintln!("{}: {}", path.display(), err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
if self.opts.mmap {
|
||||
self.search_mmap(printer, path, &file)
|
||||
} else {
|
||||
self.search(printer, path, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
match result {
|
||||
Ok(count) => {
|
||||
count
|
||||
}
|
||||
Err(err) => {
|
||||
if !self.opts.no_messages {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn search<R: io::Read, W: WriteColor>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
rdr: R,
|
||||
) -> Result<u64> {
|
||||
let rdr = DecodeReader::new(
|
||||
rdr, &mut self.decodebuf, self.opts.encoding);
|
||||
let searcher = Searcher::new(
|
||||
&mut self.inpbuf, printer, &self.grep, path, rdr);
|
||||
searcher
|
||||
.after_context(self.opts.after_context)
|
||||
.before_context(self.opts.before_context)
|
||||
.count(self.opts.count)
|
||||
.files_with_matches(self.opts.files_with_matches)
|
||||
.files_without_matches(self.opts.files_without_matches)
|
||||
.eol(self.opts.eol)
|
||||
.line_number(self.opts.line_number)
|
||||
.invert_match(self.opts.invert_match)
|
||||
.max_count(self.opts.max_count)
|
||||
.quiet(self.opts.quiet)
|
||||
.text(self.opts.text)
|
||||
.run()
|
||||
.map_err(From::from)
|
||||
}
|
||||
|
||||
fn search_mmap<W: WriteColor>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
file: &File,
|
||||
) -> Result<u64> {
|
||||
if file.metadata()?.len() == 0 {
|
||||
// Opening a memory map with an empty file results in an error.
|
||||
// However, this may not actually be an empty file! For example,
|
||||
// /proc/cpuinfo reports itself as an empty file, but it can
|
||||
// produce data when it's read from. Therefore, we fall back to
|
||||
// regular read calls.
|
||||
return self.search(printer, path, file);
|
||||
}
|
||||
let mmap = match self.mmap(file)? {
|
||||
None => return self.search(printer, path, file),
|
||||
Some(mmap) => mmap,
|
||||
};
|
||||
let buf = &*mmap;
|
||||
if buf.len() >= 3 && Encoding::for_bom(buf).is_some() {
|
||||
// If we have a UTF-16 bom in our memory map, then we need to fall
|
||||
// back to the stream reader, which will do transcoding.
|
||||
return self.search(printer, path, file);
|
||||
}
|
||||
let searcher = BufferSearcher::new(printer, &self.grep, path, buf);
|
||||
Ok(searcher
|
||||
.count(self.opts.count)
|
||||
.files_with_matches(self.opts.files_with_matches)
|
||||
.files_without_matches(self.opts.files_without_matches)
|
||||
.eol(self.opts.eol)
|
||||
.line_number(self.opts.line_number)
|
||||
.invert_match(self.opts.invert_match)
|
||||
.max_count(self.opts.max_count)
|
||||
.quiet(self.opts.quiet)
|
||||
.text(self.opts.text)
|
||||
.run())
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn mmap(&self, file: &File) -> Result<Option<Mmap>> {
|
||||
Ok(Some(mmap_readonly(file)?))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn mmap(&self, file: &File) -> Result<Option<Mmap>> {
|
||||
use libc::{ENODEV, EOVERFLOW};
|
||||
|
||||
let err = match mmap_readonly(file) {
|
||||
Ok(mmap) => return Ok(Some(mmap)),
|
||||
Err(err) => err,
|
||||
};
|
||||
let code = err.raw_os_error();
|
||||
if code == Some(ENODEV) || code == Some(EOVERFLOW) {
|
||||
return Ok(None);
|
||||
}
|
||||
Err(From::from(err))
|
||||
}
|
||||
}
|
||||
|
||||
fn mmap_readonly(file: &File) -> io::Result<Mmap> {
|
||||
unsafe { Mmap::map(file) }
|
||||
}
|
||||
3
termcolor/COPYING
Normal file
3
termcolor/COPYING
Normal file
@@ -0,0 +1,3 @@
|
||||
This project is dual-licensed under the Unlicense and MIT licenses.
|
||||
|
||||
You may use this code under the terms of either license.
|
||||
20
termcolor/Cargo.toml
Normal file
20
termcolor/Cargo.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "termcolor"
|
||||
version = "0.3.5" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
A simple cross platform library for writing colored text to a terminal.
|
||||
"""
|
||||
documentation = "https://docs.rs/termcolor"
|
||||
homepage = "https://github.com/BurntSushi/ripgrep/tree/master/termcolor"
|
||||
repository = "https://github.com/BurntSushi/ripgrep/tree/master/termcolor"
|
||||
readme = "README.md"
|
||||
keywords = ["windows", "win", "color", "ansi", "console"]
|
||||
license = "Unlicense/MIT"
|
||||
|
||||
[lib]
|
||||
name = "termcolor"
|
||||
bench = false
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
wincolor = { version = "0.1.6", path = "../wincolor" }
|
||||
21
termcolor/LICENSE-MIT
Normal file
21
termcolor/LICENSE-MIT
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Andrew Gallant
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
86
termcolor/README.md
Normal file
86
termcolor/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
termcolor
|
||||
=========
|
||||
A simple cross platform library for writing colored text to a terminal. This
|
||||
library writes colored text either using standard ANSI escape sequences or
|
||||
by interacting with the Windows console. Several convenient abstractions
|
||||
are provided for use in single-threaded or multi-threaded command line
|
||||
applications.
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
[](https://crates.io/crates/termcolor)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
### Documentation
|
||||
|
||||
[https://docs.rs/termcolor](https://docs.rs/termcolor)
|
||||
|
||||
### Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
termcolor = "0.3"
|
||||
```
|
||||
|
||||
and this to your crate root:
|
||||
|
||||
```rust
|
||||
extern crate termcolor;
|
||||
```
|
||||
|
||||
### Organization
|
||||
|
||||
The `WriteColor` trait extends the `io::Write` trait with methods for setting
|
||||
colors or resetting them.
|
||||
|
||||
`StandardStream` and `StandardStreamLock` both satisfy `WriteColor` and are
|
||||
analogous to `std::io::Stdout` and `std::io::StdoutLock`, or `std::io::Stderr`
|
||||
and `std::io::StderrLock`.
|
||||
|
||||
`Buffer` is an in memory buffer that supports colored text. In a parallel
|
||||
program, each thread might write to its own buffer. A buffer can be printed to
|
||||
stdout or stderr using a `BufferWriter`. The advantage of this design is that
|
||||
each thread can work in parallel on a buffer without having to synchronize
|
||||
access to global resources such as the Windows console. Moreover, this design
|
||||
also prevents interleaving of buffer output.
|
||||
|
||||
`Ansi` and `NoColor` both satisfy `WriteColor` for arbitrary implementors of
|
||||
`io::Write`. These types are useful when you know exactly what you need. An
|
||||
analogous type for the Windows console is not provided since it cannot exist.
|
||||
|
||||
### Example: using `StandardStream`
|
||||
|
||||
The `StandardStream` type in this crate works similarly to `std::io::Stdout`,
|
||||
except it is augmented with methods for coloring by the `WriteColor` trait.
|
||||
For example, to write some green text:
|
||||
|
||||
```rust
|
||||
use std::io::Write;
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
|
||||
let mut stdout = StandardStream::stdout(ColorChoice::Always);
|
||||
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
|
||||
writeln!(&mut stdout, "green text!")?;
|
||||
```
|
||||
|
||||
### Example: using `BufferWriter`
|
||||
|
||||
A `BufferWriter` can create buffers and write buffers to stdout or stderr. It
|
||||
does *not* implement `io::Write` or `WriteColor` itself. Instead, `Buffer`
|
||||
implements `io::Write` and `io::WriteColor`.
|
||||
|
||||
This example shows how to print some green text to stderr.
|
||||
|
||||
```rust
|
||||
use std::io::Write;
|
||||
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};
|
||||
|
||||
let mut bufwtr = BufferWriter::stderr(ColorChoice::Always);
|
||||
let mut buffer = bufwtr.buffer();
|
||||
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
|
||||
writeln!(&mut buffer, "green text!")?;
|
||||
bufwtr.print(&buffer)?;
|
||||
```
|
||||
24
termcolor/UNLICENSE
Normal file
24
termcolor/UNLICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
1697
termcolor/src/lib.rs
Normal file
1697
termcolor/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
BIN
tests/data/sherlock.bz2
Normal file
BIN
tests/data/sherlock.bz2
Normal file
Binary file not shown.
BIN
tests/data/sherlock.gz
Normal file
BIN
tests/data/sherlock.gz
Normal file
Binary file not shown.
BIN
tests/data/sherlock.lzma
Normal file
BIN
tests/data/sherlock.lzma
Normal file
Binary file not shown.
BIN
tests/data/sherlock.xz
Normal file
BIN
tests/data/sherlock.xz
Normal file
Binary file not shown.
962
tests/tests.rs
962
tests/tests.rs
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user