Compare commits
511 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
f147f3aa39 | ||
|
|
599c4fc3f3 | ||
|
|
d85a6dd5c8 | ||
|
|
40abade8ee | ||
|
|
fca4fdf6ea | ||
|
|
16975797fe | ||
|
|
6507a48f97 | ||
|
|
c8e2fa1869 | ||
|
|
f728708ce9 | ||
|
|
c302995d05 | ||
|
|
4a77cc8100 | ||
|
|
dc86666044 | ||
|
|
6b038511c7 | ||
|
|
c767bccade | ||
|
|
a075a462fa | ||
|
|
24f753c306 | ||
|
|
1aae2759ad | ||
|
|
91646f6cca | ||
|
|
031ace209d | ||
|
|
942e9c4743 | ||
|
|
12c9656b18 | ||
|
|
8bf3760cdb | ||
|
|
c96623e66a | ||
|
|
36f949633b | ||
|
|
811fcc1fe8 | ||
|
|
79a8d0ab3f | ||
|
|
fbf8265cde | ||
|
|
d79add341b | ||
|
|
12b2b1f624 | ||
|
|
3aaf550ca5 | ||
|
|
d4876cd064 | ||
|
|
867a57e176 | ||
|
|
ec4904df33 | ||
|
|
c4ea157cb7 | ||
|
|
0156967f4c | ||
|
|
3238707b0b | ||
|
|
31fbae597f | ||
|
|
f2e1711781 | ||
|
|
94d600e6e1 | ||
|
|
b904c5d9dc | ||
|
|
5a29417796 | ||
|
|
f694800768 | ||
|
|
bd1c9e9499 | ||
|
|
f04b0dd95c | ||
|
|
5487dffefa | ||
|
|
1fc6787648 | ||
|
|
11e164aec9 | ||
|
|
1c1331d926 | ||
|
|
cbe94823d2 | ||
|
|
d8712daf27 | ||
|
|
7cbbef019f | ||
|
|
4d29d886e5 | ||
|
|
247a9398f4 | ||
|
|
4c3025ab1c | ||
|
|
4981991a6e | ||
|
|
51440f59cd | ||
|
|
7b8a8d77d0 | ||
|
|
4737326ed3 | ||
|
|
a3537aa32a | ||
|
|
d3e118a786 | ||
|
|
4e52059ad6 | ||
|
|
60c016c243 | ||
|
|
4665128f25 | ||
|
|
dde5bd5a80 | ||
|
|
762ad44f71 | ||
|
|
705386934d | ||
|
|
97bbc6ef11 | ||
|
|
27a980c1bc | ||
|
|
e8645dc8ae | ||
|
|
e96d93034a | ||
|
|
bc5accc035 | ||
|
|
c9d0ca8257 | ||
|
|
45fe4aab96 | ||
|
|
97f981fbcb | ||
|
|
59329dcc61 | ||
|
|
604da8eb86 | ||
|
|
1c964372ad | ||
|
|
50a961960e | ||
|
|
7481c5fe29 | ||
|
|
3ae37b0937 | ||
|
|
4ee6dbe422 | ||
|
|
cd4bdcf810 | ||
|
|
175406df01 | ||
|
|
89811d43d4 | ||
|
|
f0053682c0 | ||
|
|
35045d6105 | ||
|
|
95f552fc06 | ||
|
|
48353bea17 | ||
|
|
703d5b558e | ||
|
|
47efea234f | ||
|
|
ca0d8998a2 | ||
|
|
fdf24317ac | ||
|
|
b9d5f22a4d | ||
|
|
67bb4f040f | ||
|
|
cee2f09a6d | ||
|
|
ced777e91f | ||
|
|
e9d9083898 | ||
|
|
46dff8f4be | ||
|
|
7aa6e87952 | ||
|
|
925d0db9f0 | ||
|
|
316ffd87b3 | ||
|
|
5943b1effe | ||
|
|
c42f97b4da | ||
|
|
0d9bba7816 | ||
|
|
3550f2e29a | ||
|
|
babe80d498 | ||
|
|
3e892a7a80 | ||
|
|
1df3f0b793 | ||
|
|
b3935935cb | ||
|
|
67abbf6f22 | ||
|
|
7b9f7d7dc6 | ||
|
|
7ab29a91d0 | ||
|
|
9fa38c6232 | ||
|
|
de79be2db2 | ||
|
|
416b69bae5 | ||
|
|
3e78fce3a3 | ||
|
|
7a3fd1f23f | ||
|
|
d306403440 | ||
|
|
ebabe1df6a | ||
|
|
f27aa3ff6f | ||
|
|
20ccd441f2 | ||
|
|
104d740f76 | ||
|
|
2da0eab2b8 | ||
|
|
b8c7864a02 | ||
|
|
ec26995655 | ||
|
|
a41235a3b5 | ||
|
|
1a91b900e7 | ||
|
|
2b15832655 | ||
|
|
b1c52b52d6 | ||
|
|
109bc3f78e | ||
|
|
b62195b33f | ||
|
|
baebfd7add | ||
|
|
19e405e5c5 | ||
|
|
f85822266f | ||
|
|
b034b77798 | ||
|
|
278e1168bf | ||
|
|
6a8051b258 | ||
|
|
a13ac3e3d4 | ||
|
|
a72467996b | ||
|
|
9395076468 | ||
|
|
a12c63957b | ||
|
|
982265af70 | ||
|
|
ed94aedf27 | ||
|
|
fd5ae2f795 | ||
|
|
3d6a39be06 | ||
|
|
e7839f2200 | ||
|
|
9dc5464c84 | ||
|
|
95edcd4d3a | ||
|
|
d97f404970 | ||
|
|
b2bbd46178 | ||
|
|
82542df5cb | ||
|
|
e4329037aa | ||
|
|
ab0d1c1c79 | ||
|
|
2015c56e8d | ||
|
|
23ad8b989d | ||
|
|
a8f3d9e87e | ||
|
|
9f1aae64f8 | ||
|
|
1595f0faf5 | ||
|
|
8eeb0c0b60 | ||
|
|
423f2a1927 | ||
|
|
4b5e789a2a | ||
|
|
37b731a048 | ||
|
|
a44735aa87 | ||
|
|
6b2efd4d88 | ||
|
|
c8227e0cf3 | ||
|
|
b941c10b90 | ||
|
|
872a107658 | ||
|
|
71ad9bf393 | ||
|
|
f733e9ebe4 | ||
|
|
ce85df1d2e | ||
|
|
a6e3cab65a | ||
|
|
7b860affbe | ||
|
|
af4dc78537 | ||
|
|
9ce0484670 | ||
|
|
346bad7dfc | ||
|
|
56fe93d343 | ||
|
|
155676b474 | ||
|
|
a3fc4cdded | ||
|
|
3bec8f3f0a | ||
|
|
3b37f12ec0 | ||
|
|
a2ed677e03 | ||
|
|
2fb9c3c42c | ||
|
|
447e1ba0e2 | ||
|
|
3b45059212 | ||
|
|
f74078af5b | ||
|
|
5ff9b2f2a2 | ||
|
|
cc90511ab2 | ||
|
|
f5d60a80a8 | ||
|
|
6fa158f6d3 | ||
|
|
ef6dea40ff | ||
|
|
9035c6b7b3 | ||
|
|
f5eb36baac | ||
|
|
6367dd61ba | ||
|
|
98892de1c1 | ||
|
|
273c14a45a | ||
|
|
b33e9cba69 | ||
|
|
d5c045469b | ||
|
|
0ce82403d4 | ||
|
|
d2f95f6e59 | ||
|
|
25c259112b | ||
|
|
dfebed6cbe | ||
|
|
9981e7883a | ||
|
|
8d202e4bcf | ||
|
|
14c194dbe1 | ||
|
|
d547b92d76 | ||
|
|
e5a9cd1b64 | ||
|
|
2115774c6e | ||
|
|
9087154b74 | ||
|
|
bb4fd9ddce | ||
|
|
d772b21f3d | ||
|
|
1b14e245be | ||
|
|
49003e8488 | ||
|
|
80c362623a | ||
|
|
c1c484d1a7 | ||
|
|
263e2b012f | ||
|
|
b80a986721 | ||
|
|
8a91d3132f | ||
|
|
525d051172 | ||
|
|
5a9883d27c | ||
|
|
f462d092e7 | ||
|
|
fe84928c85 | ||
|
|
f7eaf67fc3 | ||
|
|
c1c92e4fee | ||
|
|
5644bbe43a | ||
|
|
aeb3a5ba0f | ||
|
|
24e14a0341 | ||
|
|
2a2b1506d4 | ||
|
|
4d6b3c727e | ||
|
|
c2bf9e3d45 | ||
|
|
dad73b92eb | ||
|
|
b0d8ff6f4a | ||
|
|
0263a401f6 | ||
|
|
4cb1b9ccc0 | ||
|
|
6f80e2e126 | ||
|
|
f9bff90842 | ||
|
|
5af4ec0056 | ||
|
|
9e2f10b893 | ||
|
|
69095cf5c3 | ||
|
|
7402db7b43 | ||
|
|
7698b60256 | ||
|
|
e7fb0fd267 | ||
|
|
29b59074c7 | ||
|
|
ee5eb2d659 | ||
|
|
bf8094344a | ||
|
|
a0819978aa | ||
|
|
5b7c17e2fb | ||
|
|
bf56b3bb8e | ||
|
|
9299d84d41 | ||
|
|
2cf1a08969 | ||
|
|
665b6016e3 | ||
|
|
33231622f3 | ||
|
|
919c5c7299 | ||
|
|
f9bf1e4a22 | ||
|
|
f7ee914dd3 | ||
|
|
0a63158a61 | ||
|
|
6cb604f38f | ||
|
|
bfbbfbf979 | ||
|
|
403ba5fdc8 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@
|
||||
tags
|
||||
target
|
||||
/grep/Cargo.lock
|
||||
/globset/Cargo.lock
|
||||
/ignore/Cargo.lock
|
||||
/termcolor/Cargo.lock
|
||||
/wincolor/Cargo.lock
|
||||
|
||||
29
.travis.yml
29
.travis.yml
@@ -1,5 +1,4 @@
|
||||
language: rust
|
||||
cache: cargo
|
||||
|
||||
env:
|
||||
global:
|
||||
@@ -10,19 +9,13 @@ matrix:
|
||||
# (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
|
||||
rust: nightly-2017-03-13
|
||||
env: TARGET=i686-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: nightly
|
||||
rust: nightly-2017-03-13
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: nightly
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: nightly
|
||||
env: TARGET=i686-apple-darwin
|
||||
- os: osx
|
||||
rust: nightly
|
||||
rust: nightly-2017-03-13
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
# Beta channel.
|
||||
- os: linux
|
||||
@@ -31,19 +24,13 @@ matrix:
|
||||
- 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.
|
||||
- os: linux
|
||||
rust: 1.9.0
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: 1.9.0
|
||||
rust: 1.12.0
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: 1.9.0
|
||||
env: TARGET=x86_64-apple-darwin
|
||||
- os: linux
|
||||
rust: 1.12.0
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
|
||||
before_install:
|
||||
- export PATH="$PATH:$HOME/.cargo/bin"
|
||||
@@ -70,7 +57,7 @@ deploy:
|
||||
# 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
|
||||
condition: $TRAVIS_RUST_VERSION = nightly-2017-03-13
|
||||
tags: true
|
||||
|
||||
branches:
|
||||
|
||||
510
CHANGELOG.md
Normal file
510
CHANGELOG.md
Normal file
@@ -0,0 +1,510 @@
|
||||
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:
|
||||
|
||||
* Added or improved file type filtering for Fish.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #206](https://github.com/BurntSushi/ripgrep/issues/206):
|
||||
Fixed a regression with `-g/--glob` flag in `0.2.5`.
|
||||
|
||||
|
||||
0.2.5
|
||||
=====
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Groovy, Handlebars, Tcl, zsh and
|
||||
Python.
|
||||
* [FEATURE #9](https://github.com/BurntSushi/ripgrep/issues/9):
|
||||
Support global gitignore config and `.git/info/exclude` files.
|
||||
* [FEATURE #45](https://github.com/BurntSushi/ripgrep/issues/45):
|
||||
Add --ignore-file flag for specifying additional ignore files.
|
||||
* [FEATURE #202](https://github.com/BurntSushi/ripgrep/pull/202):
|
||||
Introduce a new
|
||||
[`ignore`](https://github.com/BurntSushi/ripgrep/tree/master/ignore)
|
||||
crate that encapsulates all of ripgrep's gitignore matching logic.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #44](https://github.com/BurntSushi/ripgrep/issues/44):
|
||||
ripgrep runs slowly when given lots of positional arguments that are
|
||||
directories.
|
||||
* [BUG #119](https://github.com/BurntSushi/ripgrep/issues/119):
|
||||
ripgrep didn't reset terminal colors if it was interrupted by `^C`.
|
||||
Fixed in [PR #187](https://github.com/BurntSushi/ripgrep/pull/187).
|
||||
* [BUG #184](https://github.com/BurntSushi/ripgrep/issues/184):
|
||||
Fixed a bug related to interpreting gitignore files in parent directories.
|
||||
|
||||
|
||||
0.2.4
|
||||
=====
|
||||
SKIPPED.
|
||||
|
||||
|
||||
0.2.3
|
||||
=====
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #164](https://github.com/BurntSushi/ripgrep/issues/164):
|
||||
Fixes a segfault on macos builds.
|
||||
* [BUG #167](https://github.com/BurntSushi/ripgrep/issues/167):
|
||||
Clarify documentation for --threads.
|
||||
|
||||
|
||||
0.2.2
|
||||
=====
|
||||
Packaging updates:
|
||||
|
||||
* `ripgrep` is now in homebrew-core. `brew install ripgrep` will do the trick
|
||||
on a Mac.
|
||||
* `ripgrep` is now in the Archlinux community repository.
|
||||
`pacman -S ripgrep` will do the trick on Archlinux.
|
||||
* Support has been discontinued for i686-darwin.
|
||||
* Glob matching has been moved out into its own crate:
|
||||
[`globset`](https://crates.io/crates/globset).
|
||||
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for CMake, config, Jinja, Markdown,
|
||||
Spark.
|
||||
* [FEATURE #109](https://github.com/BurntSushi/ripgrep/issues/109):
|
||||
Add a --max-depth flag for directory traversal.
|
||||
* [FEATURE #124](https://github.com/BurntSushi/ripgrep/issues/124):
|
||||
Add -s/--case-sensitive flag. Overrides --smart-case.
|
||||
* [FEATURE #139](https://github.com/BurntSushi/ripgrep/pull/139):
|
||||
The `ripgrep` repo is now a Homebrew tap. This is useful for installing
|
||||
SIMD accelerated binaries, which aren't available in homebrew-core.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #87](https://github.com/BurntSushi/ripgrep/issues/87),
|
||||
[BUG #127](https://github.com/BurntSushi/ripgrep/issues/127),
|
||||
[BUG #131](https://github.com/BurntSushi/ripgrep/issues/131):
|
||||
Various issues related to glob matching.
|
||||
* [BUG #116](https://github.com/BurntSushi/ripgrep/issues/116):
|
||||
--quiet should stop search after first match.
|
||||
* [BUG #121](https://github.com/BurntSushi/ripgrep/pull/121):
|
||||
--color always should show colors, even when --vimgrep is used.
|
||||
* [BUG #122](https://github.com/BurntSushi/ripgrep/pull/122):
|
||||
Colorize file path at beginning of line.
|
||||
* [BUG #134](https://github.com/BurntSushi/ripgrep/issues/134):
|
||||
Processing a large ignore file (thousands of globs) was very slow.
|
||||
* [BUG #137](https://github.com/BurntSushi/ripgrep/issues/137):
|
||||
Always follow symlinks when given as an explicit argument.
|
||||
* [BUG #147](https://github.com/BurntSushi/ripgrep/issues/147):
|
||||
Clarify documentation for --replace.
|
||||
|
||||
|
||||
0.2.1
|
||||
=====
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for Clojure and SystemVerilog.
|
||||
* [FEATURE #89](https://github.com/BurntSushi/ripgrep/issues/89):
|
||||
Add a --null flag that outputs a NUL byte after every file path.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* [BUG #98](https://github.com/BurntSushi/ripgrep/issues/98):
|
||||
Fix a bug in single threaded mode when if opening a file failed, ripgrep
|
||||
quit instead of continuing the search.
|
||||
* [BUG #99](https://github.com/BurntSushi/ripgrep/issues/99):
|
||||
Fix another bug in single threaded mode where empty lines were being printed
|
||||
by mistake.
|
||||
* [BUG #105](https://github.com/BurntSushi/ripgrep/issues/105):
|
||||
Fix an off-by-one error with --column.
|
||||
* [BUG #106](https://github.com/BurntSushi/ripgrep/issues/106):
|
||||
Fix a bug where a whitespace only line in a gitignore file caused ripgrep
|
||||
to panic (i.e., crash).
|
||||
|
||||
|
||||
0.2.0
|
||||
=====
|
||||
Feature enhancements:
|
||||
|
||||
* Added or improved file type filtering for VB, R, F#, Swift, Nim, Javascript,
|
||||
TypeScript
|
||||
* [FEATURE #20](https://github.com/BurntSushi/ripgrep/issues/20):
|
||||
Adds a --no-filename flag.
|
||||
* [FEATURE #26](https://github.com/BurntSushi/ripgrep/issues/26):
|
||||
Adds --files-with-matches flag. Like --count, but only prints file paths
|
||||
and doesn't need to count every match.
|
||||
* [FEATURE #40](https://github.com/BurntSushi/ripgrep/issues/40):
|
||||
Switch from using `.rgignore` to `.ignore`. Note that `.rgignore` is
|
||||
still supported, but deprecated.
|
||||
* [FEATURE #68](https://github.com/BurntSushi/ripgrep/issues/68):
|
||||
Add --no-ignore-vcs flag that ignores .gitignore but not .ignore.
|
||||
* [FEATURE #70](https://github.com/BurntSushi/ripgrep/issues/70):
|
||||
Add -S/--smart-case flag (but is disabled by default).
|
||||
* [FEATURE #80](https://github.com/BurntSushi/ripgrep/issues/80):
|
||||
Add support for `{foo,bar}` globs.
|
||||
|
||||
Many many bug fixes. Thanks every for reporting these and helping make
|
||||
`ripgrep` better! (Note that I haven't captured every tracking issue here,
|
||||
some were closed as duplicates.)
|
||||
|
||||
* [BUG #8](https://github.com/BurntSushi/ripgrep/issues/8):
|
||||
Don't use an intermediate buffer when --threads=1. (Permits constant memory
|
||||
usage.)
|
||||
* [BUG #15](https://github.com/BurntSushi/ripgrep/issues/15):
|
||||
Improves the documentation for --type-add.
|
||||
* [BUG #16](https://github.com/BurntSushi/ripgrep/issues/16),
|
||||
[BUG #49](https://github.com/BurntSushi/ripgrep/issues/49),
|
||||
[BUG #50](https://github.com/BurntSushi/ripgrep/issues/50),
|
||||
[BUG #65](https://github.com/BurntSushi/ripgrep/issues/65):
|
||||
Some gitignore globs were being treated as anchored when they weren't.
|
||||
* [BUG #18](https://github.com/BurntSushi/ripgrep/issues/18):
|
||||
--vimgrep reported incorrect column number.
|
||||
* [BUG #19](https://github.com/BurntSushi/ripgrep/issues/19):
|
||||
ripgrep was hanging waiting on stdin in some Windows terminals. Note that
|
||||
this introduced a new bug:
|
||||
[#94](https://github.com/BurntSushi/ripgrep/issues/94).
|
||||
* [BUG #21](https://github.com/BurntSushi/ripgrep/issues/21):
|
||||
Removes leading `./` when printing file paths.
|
||||
* [BUG #22](https://github.com/BurntSushi/ripgrep/issues/22):
|
||||
Running `rg --help | echo` caused `rg` to panic.
|
||||
* [BUG #24](https://github.com/BurntSushi/ripgrep/issues/22):
|
||||
Clarify the central purpose of rg in its usage message.
|
||||
* [BUG #25](https://github.com/BurntSushi/ripgrep/issues/25):
|
||||
Anchored gitignore globs weren't applied in subdirectories correctly.
|
||||
* [BUG #30](https://github.com/BurntSushi/ripgrep/issues/30):
|
||||
Globs like `foo/**` should match contents of `foo`, but not `foo` itself.
|
||||
* [BUG #35](https://github.com/BurntSushi/ripgrep/issues/35),
|
||||
[BUG #81](https://github.com/BurntSushi/ripgrep/issues/81):
|
||||
When automatically detecting stdin, only read if it's a file or a fifo.
|
||||
i.e., ignore stdin in `rg foo < /dev/null`.
|
||||
* [BUG #36](https://github.com/BurntSushi/ripgrep/issues/36):
|
||||
Don't automatically pick memory maps on MacOS. Ever.
|
||||
* [BUG #38](https://github.com/BurntSushi/ripgrep/issues/38):
|
||||
Trailing whitespace in gitignore wasn't being ignored.
|
||||
* [BUG #43](https://github.com/BurntSushi/ripgrep/issues/43):
|
||||
--glob didn't work with directories.
|
||||
* [BUG #46](https://github.com/BurntSushi/ripgrep/issues/46):
|
||||
Use one fewer worker thread than what is provided on CLI.
|
||||
* [BUG #47](https://github.com/BurntSushi/ripgrep/issues/47):
|
||||
--help/--version now work even if other options are set.
|
||||
* [BUG #55](https://github.com/BurntSushi/ripgrep/issues/55):
|
||||
ripgrep was refusing to search /proc/cpuinfo. Fixed by disabling memory
|
||||
maps for files with zero size.
|
||||
* [BUG #64](https://github.com/BurntSushi/ripgrep/issues/64):
|
||||
The first path given with --files set was ignored.
|
||||
* [BUG #67](https://github.com/BurntSushi/ripgrep/issues/67):
|
||||
Sometimes whitelist globs like `!/dir` weren't interpreted as anchored.
|
||||
* [BUG #77](https://github.com/BurntSushi/ripgrep/issues/77):
|
||||
When -q/--quiet flag was passed, ripgrep kept searching even after a match
|
||||
was found.
|
||||
* [BUG #90](https://github.com/BurntSushi/ripgrep/issues/90):
|
||||
Permit whitelisting hidden files.
|
||||
* [BUG #93](https://github.com/BurntSushi/ripgrep/issues/93):
|
||||
ripgrep was extracting an erroneous inner literal from a repeated pattern.
|
||||
353
Cargo.lock
generated
353
Cargo.lock
generated
@@ -1,92 +1,150 @@
|
||||
[root]
|
||||
name = "ripgrep"
|
||||
version = "0.1.2"
|
||||
version = "0.5.1"
|
||||
dependencies = [
|
||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.6.83 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"grep 0.1.1",
|
||||
"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.16 (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.2.3 (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.77 (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)",
|
||||
"walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"grep 0.1.6",
|
||||
"ignore 0.1.9",
|
||||
"lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.3"
|
||||
version = "0.6.3"
|
||||
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 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deque"
|
||||
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)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.6.83"
|
||||
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.77 (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)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.3.5"
|
||||
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.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.4"
|
||||
name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.2.5"
|
||||
name = "atty"
|
||||
version = "0.2.2"
|
||||
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.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
name = "bitflags"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "grep"
|
||||
version = "0.1.1"
|
||||
name = "bytecount"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.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.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grep"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.1.9"
|
||||
dependencies = [
|
||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"globset 0.1.4",
|
||||
"lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -100,76 +158,72 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.1"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.16"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap"
|
||||
version = "0.2.3"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs2 0.4.1 (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.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.1.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.77"
|
||||
version = "0.2.1"
|
||||
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.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.0 (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)",
|
||||
"thread_local 0.3.3 (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.5"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.19"
|
||||
name = "same-file"
|
||||
version = "0.1.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)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd"
|
||||
@@ -178,46 +232,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.5.1"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.4.4"
|
||||
name = "term_size"
|
||||
version = "0.2.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.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"wincolor 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "2.0.0"
|
||||
version = "3.0.0"
|
||||
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.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.2.7"
|
||||
version = "0.3.3"
|
||||
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)",
|
||||
"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 = "unicode-segmentation"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "0.1.8"
|
||||
version = "1.0.7"
|
||||
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)",
|
||||
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -231,31 +323,48 @@ name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wincolor"
|
||||
version = "0.1.3"
|
||||
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)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||
"checksum docopt 0.6.83 (registry+https://github.com/rust-lang/crates.io-index)" = "fc42c6077823a361410c37d47c2535b73a190cbe10838dc4f400fe87c10c8c3b"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum fnv 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e8af7b5408ab0c4910cad114c8f9eb454bf75df7afe8964307eeafb68a13a5e"
|
||||
"checksum fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd414e5a1a979b931bb92f41b7a54106d3f6d2e6c253e9ce943b7cd468251ef"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
|
||||
"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
|
||||
"checksum bytecount 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8f09fbc8c6726a4b616dcfbd4f54491068d6bb1b93ac03c78ac18ff9a5924a"
|
||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||
"checksum clap 2.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d480c39a2e5f9b3a3798c661613e1b0e7a7ae71e005102d4aa910fc3289df484"
|
||||
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
|
||||
"checksum encoding_rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a1cca0a26f904955d80d70b9bff1019e4f4cbc06f2fcbccf8bd3d889cc1c9b7"
|
||||
"checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf"
|
||||
"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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
|
||||
"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.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f20f72ed93291a72e22e8b16bb18762183bb4943f0f483da5b8be1a9e8192752"
|
||||
"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.77 (registry+https://github.com/rust-lang/crates.io-index)" = "64b03446c466d35b42f2a8b203c8e03ed8b91c0f17b56e1f84f7210a257aa665"
|
||||
"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd"
|
||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||
"checksum lazy_static 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f61b8421c7a4648c391611625d56fdd5c7567da05af1be655fd8cacc643abb3"
|
||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||
"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad"
|
||||
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
||||
"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
|
||||
"checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2"
|
||||
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
|
||||
"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
|
||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||
"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_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||
"checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
||||
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
|
||||
"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
|
||||
"checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
|
||||
"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"
|
||||
|
||||
41
Cargo.toml
41
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ripgrep"
|
||||
version = "0.1.2" #:version
|
||||
version = "0.5.1" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Line oriented search tool using Rust's regex library. Combines the raw
|
||||
@@ -11,7 +11,10 @@ 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"
|
||||
|
||||
[[bin]]
|
||||
bench = false
|
||||
@@ -23,32 +26,30 @@ name = "integration"
|
||||
path = "tests/tests.rs"
|
||||
|
||||
[dependencies]
|
||||
deque = "0.3"
|
||||
docopt = "0.6"
|
||||
env_logger = "0.3"
|
||||
fnv = "1.0"
|
||||
grep = { version = "0.1.1", path = "grep" }
|
||||
atty = "0.2.2"
|
||||
bytecount = "0.1.4"
|
||||
clap = "2.23.1"
|
||||
encoding_rs = "0.5.0"
|
||||
env_logger = { version = "0.4", default-features = false }
|
||||
grep = { version = "0.1.5", path = "grep" }
|
||||
ignore = { version = "0.1.9", path = "ignore" }
|
||||
lazy_static = "0.2"
|
||||
libc = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.2"
|
||||
memchr = "1"
|
||||
memmap = "0.5"
|
||||
num_cpus = "1"
|
||||
regex = "0.1.76"
|
||||
rustc-serialize = "0.3"
|
||||
term = "0.4"
|
||||
walkdir = "0.1"
|
||||
regex = "0.2.1"
|
||||
same-file = "0.1.1"
|
||||
termcolor = { version = "0.3.0", path = "termcolor" }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
kernel32-sys = "0.2"
|
||||
winapi = "0.2"
|
||||
[build-dependencies]
|
||||
clap = "2.23.1"
|
||||
lazy_static = "0.2"
|
||||
|
||||
[features]
|
||||
simd-accel = ["regex/simd-accel"]
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2"
|
||||
avx-accel = ["bytecount/avx-accel"]
|
||||
simd-accel = ["bytecount/simd-accel", "regex/simd-accel"]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
panic = "abort"
|
||||
|
||||
1
HomebrewFormula
Symbolic link
1
HomebrewFormula
Symbolic link
@@ -0,0 +1 @@
|
||||
pkg/brew
|
||||
440
README.md
440
README.md
@@ -1,6 +1,438 @@
|
||||
**UNDER DEVELOPMENT.**
|
||||
|
||||
ripgrep (rg)
|
||||
------------
|
||||
ripgrep combines the usability of the silver searcher with the raw speed of
|
||||
grep.
|
||||
`ripgrep` is a line oriented search tool that combines the usability of The
|
||||
Silver Searcher (similar to `ack`) with the raw speed of GNU grep. `ripgrep`
|
||||
works by recursively searching your current directory for a regex pattern.
|
||||
`ripgrep` has first class support on Windows, Mac and Linux, with binary
|
||||
downloads available for
|
||||
[every release](https://github.com/BurntSushi/ripgrep/releases).
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
[](https://crates.io/crates/ripgrep)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
### CHANGELOG
|
||||
|
||||
Please see the [CHANGELOG](CHANGELOG.md) for a release history.
|
||||
|
||||
### Screenshot of search results
|
||||
|
||||
[](http://burntsushi.net/stuff/ripgrep1.png)
|
||||
|
||||
### 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, and
|
||||
ripgrep was compiled using the `compile` script in this repo.
|
||||
|
||||
Please remember that a single benchmark is never enough! See my
|
||||
[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 (Unicode) | `rg -n -w '[A-Z]+_SUSPEND'` | 450 | **0.134s** |
|
||||
| [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](https://github.com/petdance/ack2) | `ack -w '[A-Z]+_SUSPEND'` | 1878 | 16.952s |
|
||||
|
||||
(Yes, `ack` [has](https://github.com/petdance/ack2/issues/445) a
|
||||
[bug](https://github.com/petdance/ack2/issues/14).)
|
||||
|
||||
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 ensures that they are doing equivalent work:
|
||||
|
||||
| Tool | Command | Line count | Time |
|
||||
| ---- | ------- | ---------- | ---- |
|
||||
| ripgrep | `rg -L -u -tc -n -w '[A-Z]+_SUSPEND'` | 404 | **0.108s** |
|
||||
| [ucg](https://github.com/gvansickle/ucg) | `ucg --type=cc -w '[A-Z]+_SUSPEND'` | 392 | 0.219s |
|
||||
| [GNU grep](https://www.gnu.org/software/grep/) | `egrep -R -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND'` | 404 | 0.733s |
|
||||
|
||||
(`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.520s** |
|
||||
| [GNU grep](https://www.gnu.org/software/grep/) | `LC_ALL=C egrep -w 'Sherlock [A-Z]\w+'` | 5268 | 7.143s |
|
||||
|
||||
In the above benchmark, passing the `-n` flag (for showing line numbers)
|
||||
increases the times to `3.081s` for ripgrep and `11.403s` for GNU grep.
|
||||
|
||||
### Why should I use `ripgrep`?
|
||||
|
||||
* 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
|
||||
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
|
||||
in The Silver Searcher.
|
||||
* `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
|
||||
custom matching rules.
|
||||
* `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
|
||||
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.)
|
||||
|
||||
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 look around, `ripgrep` won't give
|
||||
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 yet support searching compressed files. (Likely to be
|
||||
supported in the future.)
|
||||
* `ripgrep` doesn't have multiline search. (Unlikely to ever be supported.)
|
||||
|
||||
In other words, if you like fancy regexes, searching compressed files or
|
||||
multiline search, then `ripgrep` may not quite meet your needs (yet).
|
||||
|
||||
### Is it really faster than everything else?
|
||||
|
||||
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:
|
||||
|
||||
* It is built on top of
|
||||
[Rust's regex engine](https://github.com/rust-lang-nursery/regex).
|
||||
Rust's regex engine uses finite automata, SIMD and aggressive literal
|
||||
optimizations to make searching very fast.
|
||||
* Rust's regex library maintains performance with full Unicode support by
|
||||
building UTF-8 decoding directly into its deterministic finite automaton
|
||||
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
|
||||
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.
|
||||
* It uses a lock-free parallel recursive directory iterator, courtesy of
|
||||
[`crossbeam`](https://docs.rs/crossbeam) and
|
||||
[`ignore`](https://docs.rs/ignore).
|
||||
|
||||
### Installation
|
||||
|
||||
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)
|
||||
installed.
|
||||
|
||||
If you're a **Mac OS X Homebrew** user, then you can install ripgrep either
|
||||
from homebrew-core, (compiled with rust stable, no SIMD):
|
||||
|
||||
```
|
||||
$ brew install ripgrep
|
||||
```
|
||||
|
||||
or you can install a binary compiled with rust nightly (including SIMD and all
|
||||
optimizations) by utilizing a custom tap:
|
||||
|
||||
```
|
||||
$ brew tap burntsushi/ripgrep https://github.com/BurntSushi/ripgrep.git
|
||||
$ brew install burntsushi/ripgrep/ripgrep-bin
|
||||
```
|
||||
|
||||
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 **Gentoo** user, you can install `ripgrep` from the [official repo](https://packages.gentoo.org/packages/sys-apps/ripgrep):
|
||||
|
||||
```
|
||||
$ emerge ripgrep
|
||||
```
|
||||
|
||||
If you're a **Fedora 24+** user, you can install `ripgrep` from [copr](https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/):
|
||||
|
||||
```
|
||||
$ dnf copr enable carlgeorge/ripgrep
|
||||
$ dnf install ripgrep
|
||||
```
|
||||
|
||||
If you're a **RHEL/CentOS 7** user, you can install `ripgrep` from [copr](https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/):
|
||||
|
||||
```
|
||||
$ yum-config-manager --add-repo=https://copr.fedorainfracloud.org/coprs/carlgeorge/ripgrep/repo/epel-7/carlgeorge-ripgrep-epel-7.repo
|
||||
$ 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`.)
|
||||
```
|
||||
|
||||
If you're a **Rust programmer**, `ripgrep` can be installed with `cargo`. Note
|
||||
that this requires you to have **Rust 1.12 or newer** installed.
|
||||
|
||||
```
|
||||
$ cargo install ripgrep
|
||||
```
|
||||
|
||||
`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: generally speaking, `ripgrep` assumes the
|
||||
input is reading is UTF-8. However, if ripgrep notices a file is encoded as
|
||||
UTF-16, then it will know how to search it. For other encodings, you'll need to
|
||||
explicitly specify them with the `-E/--encoding` flag.
|
||||
|
||||
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 and return paths matching a particular glob (i.e., `-g` flag in ag/ack):
|
||||
|
||||
```
|
||||
$ rg -g 'doc*' --files
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
### Shell completions
|
||||
|
||||
Shell completion files are included in the release tarball for Bash, Fish, Zsh
|
||||
and PowerShell.
|
||||
|
||||
For **bash**, move `rg.bash-completion` to `$XDG_CONFIG_HOME/bash_completion`
|
||||
or `/etc/bash_completion.d/`.
|
||||
|
||||
For **fish**, move `rg.fish` to `$HOME/.config/fish/completions`.
|
||||
|
||||
### Building
|
||||
|
||||
`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.12 (stable) or newer. Building is easy:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/BurntSushi/ripgrep
|
||||
$ cd ripgrep
|
||||
$ cargo build --release
|
||||
$ ./target/release/rg --version
|
||||
0.1.3
|
||||
```
|
||||
|
||||
If you have a Rust nightly compiler, then you can enable optional SIMD
|
||||
acceleration like so:
|
||||
|
||||
```
|
||||
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
|
||||
tests. To run the full test suite, use:
|
||||
|
||||
```
|
||||
$ cargo test
|
||||
```
|
||||
|
||||
from the repository root.
|
||||
|
||||
### Tips
|
||||
|
||||
#### Windows Powershell
|
||||
|
||||
##### Powershell Profile
|
||||
|
||||
To customize powershell on start-up there is a special powershell script that has to be created.
|
||||
In order to find its location run command `Get-Command $profile | Select-Object -ExpandProperty Definition`
|
||||
See [more](https://technet.microsoft.com/en-us/library/bb613488(v=vs.85).aspx) for profile 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.
|
||||
|
||||
##### Setup function alias
|
||||
|
||||
Often you can find a need to make alias for the favourite utility.
|
||||
|
||||
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**
|
||||
|
||||
### Known issues
|
||||
|
||||
#### I just hit Ctrl+C in the middle of ripgrep's output and now my terminal's foreground color is wrong!
|
||||
|
||||
Type in `color` on Windows and `echo -ne "\033[0m"` on Unix to restore your
|
||||
original foreground color.
|
||||
|
||||
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][msys issue explanation].
|
||||
|
||||
[msys issue explanation]: https://github.com/BurntSushi/ripgrep/issues/281#issuecomment-269093893
|
||||
|
||||
37
appveyor.yml
37
appveyor.yml
@@ -2,27 +2,22 @@ environment:
|
||||
global:
|
||||
PROJECT_NAME: ripgrep
|
||||
matrix:
|
||||
# Nightly channel
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
|
||||
# Install Rust and Cargo
|
||||
# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
|
||||
install:
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/channel-rust-stable"
|
||||
- ps: $env:RUST_VERSION = Get-Content channel-rust-stable | select -first 1 | %{$_.split('-')[1]}
|
||||
- if NOT "%CHANNEL%" == "stable" set RUST_VERSION=%CHANNEL%
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:RUST_VERSION}-${env:TARGET}.exe"
|
||||
- rust-%RUST_VERSION%-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin
|
||||
- if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin
|
||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||
- rustup-init.exe -y --default-host %TARGET%
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
@@ -33,6 +28,11 @@ build: false
|
||||
# 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 --manifest-path wincolor/Cargo.toml
|
||||
- cargo test --verbose --manifest-path termcolor/Cargo.toml
|
||||
|
||||
before_deploy:
|
||||
# Generate artifacts for release
|
||||
@@ -40,13 +40,14 @@ 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 *
|
||||
- appveyor PushArtifact ../%PROJECT_NAME%-%APPVEYOR_REPO_TAG_NAME%-%TARGET%.zip
|
||||
|
||||
deploy:
|
||||
description: 'Windows release'
|
||||
description: 'Automatically deployed release'
|
||||
# All the zipped artifacts will be deployed
|
||||
artifact: /.*\.zip/
|
||||
auth_token:
|
||||
@@ -57,12 +58,14 @@ deploy:
|
||||
# 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
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
appveyor_repo_tag: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- appveyor
|
||||
- /\d+\.\d+\.\d+/
|
||||
except:
|
||||
- master
|
||||
# - appveyor
|
||||
# - /\d+\.\d+\.\d+/
|
||||
# except:
|
||||
# - master
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
These are internal microbenchmarks for tracking the peformance of individual
|
||||
components inside of ripgrep. At the moment, they aren't heavily used.
|
||||
|
||||
For performance benchmarks of ripgrep proper, see the sibling `benchsuite`
|
||||
directory.
|
||||
@@ -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'
|
||||
@@ -132,6 +132,7 @@ def bench_linux_literal_casei(suite_dir):
|
||||
mkcmd('rg (ignore)', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('rg (ignore) (mmap)', ['rg', '-n', '-i', '--mmap', pat]),
|
||||
mkcmd('ag (ignore) (mmap)', ['ag', '-i', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-i', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '-i', '--git', pat]),
|
||||
# It'd technically be more appropriate to set LC_ALL=en_US.UTF-8 here,
|
||||
# since that is certainly what ripgrep is doing, but this is for an
|
||||
@@ -165,6 +166,7 @@ def bench_linux_re_literal_suffix(suite_dir):
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-s', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep (ignore)',
|
||||
@@ -194,6 +196,7 @@ def bench_linux_word(suite_dir):
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg (ignore)', ['rg', '-n', '-w', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-s', '-w', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-w', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '-w', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep (ignore)',
|
||||
@@ -224,6 +227,7 @@ def bench_linux_unicode_greek(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('pt', ['pt', '-e', pat]),
|
||||
mkcmd('sift', SIFT + ['-n', '--git', pat]),
|
||||
])
|
||||
|
||||
@@ -244,6 +248,7 @@ def bench_linux_unicode_greek_casei(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('pt', ['pt', '-i', '-e', pat]),
|
||||
mkcmd('sift', SIFT + ['-n', '-i', '--git', pat]),
|
||||
])
|
||||
|
||||
@@ -268,7 +273,8 @@ def bench_linux_unicode_word(suite_dir):
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('rg (ignore) (ASCII)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('ag (ignore) (ASCII)', ['ag', '-s', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', pat]),
|
||||
mkcmd('pt (ignore) (ASCII)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
@@ -308,7 +314,8 @@ def bench_linux_no_literal(suite_dir):
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('rg (ignore) (ASCII)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('ag (ignore) (ASCII)', ['ag', '-s', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', pat]),
|
||||
mkcmd('pt (ignore) (ASCII)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
@@ -390,6 +397,7 @@ def bench_subtitles_en_literal(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', pat, en]),
|
||||
Command('rg (no mmap)', ['rg', '--no-mmap', pat, en]),
|
||||
Command('pt', ['pt', '-N', pat, en]),
|
||||
Command('sift', ['sift', pat, en]),
|
||||
Command('grep', ['grep', '-a', pat, en], env=GREP_ASCII),
|
||||
@@ -551,6 +559,7 @@ def bench_subtitles_ru_literal(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', pat, ru]),
|
||||
Command('rg (no mmap)', ['rg', '--no-mmap', pat, ru]),
|
||||
Command('pt', ['pt', '-N', pat, ru]),
|
||||
Command('sift', ['sift', pat, ru]),
|
||||
Command('grep', ['grep', '-a', pat, ru], env=GREP_ASCII),
|
||||
@@ -746,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.
|
||||
|
||||
@@ -777,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
|
||||
@@ -785,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):
|
||||
'''
|
||||
@@ -795,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)
|
||||
|
||||
@@ -812,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
|
||||
@@ -840,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
|
||||
@@ -927,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):
|
||||
'''
|
||||
@@ -1125,7 +1147,9 @@ def download(suite_dir, choices):
|
||||
|
||||
|
||||
def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
allow_missing_commands=False):
|
||||
allow_missing_commands=False,
|
||||
disabled_cmds=None,
|
||||
warmup_iter=1, bench_iter=3):
|
||||
'''
|
||||
Return an iterable of all runnable benchmarks.
|
||||
|
||||
@@ -1148,7 +1172,10 @@ def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
try:
|
||||
benchmark = globals()[fun](suite_dir)
|
||||
benchmark.name = name
|
||||
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(
|
||||
@@ -1183,6 +1210,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.')
|
||||
@@ -1193,6 +1222,14 @@ def main():
|
||||
'--raw', metavar='PATH',
|
||||
help='Dump raw data (all samples collected) in CSV format to the '
|
||||
'file path provided.')
|
||||
p.add_argument(
|
||||
'--warmup-iter', metavar='INTEGER', type=int, default=1,
|
||||
help='The number of iterations to run each command before '
|
||||
'recording measurements.')
|
||||
p.add_argument(
|
||||
'--bench-iter', metavar='INTEGER', type=int, default=3,
|
||||
help='The number of iterations to run each command while '
|
||||
'recording measurements.')
|
||||
p.add_argument(
|
||||
'bench', metavar='PAT', nargs='?',
|
||||
help='A regex pattern that will only run benchmarks that match.')
|
||||
@@ -1201,7 +1238,9 @@ def main():
|
||||
if args.list:
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing)
|
||||
allow_missing_commands=args.allow_missing,
|
||||
disabled_cmds=args.disabled.split(','),
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for b in benchmarks:
|
||||
print(b.name)
|
||||
sys.exit(0)
|
||||
@@ -1226,7 +1265,9 @@ def main():
|
||||
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing)
|
||||
allow_missing_commands=args.allow_missing,
|
||||
disabled_cmds=args.disabled.split(','),
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for i, b in enumerate(benchmarks):
|
||||
result = b.run()
|
||||
fastest_cmd = result.fastest_cmd()
|
||||
@@ -1243,8 +1284,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 = '', ''
|
||||
|
||||
@@ -1,343 +0,0 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24781584739685059,68,
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23398137092590332,68,
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23497819900512695,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11090731620788574,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.14237189292907715,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11315393447875977,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39145565032958984,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39217114448547363,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39917516708374023,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4898416996002197,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5078432559967041,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4942047595977783,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4839494228363037,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4806060791015625,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6986649036407471,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1494297981262207,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15127253532409668,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1573657989501953,68,
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.25092005729675293,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2663850784301758,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24485993385314941,68,LC_ALL=C
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24762463569641113,160,
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21982502937316895,160,
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2219092845916748,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12809348106384277,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12208032608032227,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12648415565490723,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39945435523986816,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39914917945861816,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3931403160095215,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.26180100440979,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6076450347900391,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6092875003814697,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5668354034423828,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5638954639434814,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6463086605072021,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23877739906311035,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2357316017150879,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23951983451843262,160,
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.8604335784912109,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9313437938690186,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9674036502838135,160,LC_ALL=C
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.2203836441040039,16,
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.21490192413330078,16,
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.21895813941955566,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.10370588302612305,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.12161660194396973,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.10118246078491211,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3846700191497803,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3972609043121338,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3864939212799072,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5170495510101318,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5066406726837158,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5110535621643066,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,0.5622231960296631,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,0.7810573577880859,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,1.2847375869750977,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.16497445106506348,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.16525840759277344,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.1590101718902588,16,
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.1928420066833496,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.19345307350158691,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.1954176425933838,16,LC_ALL=C
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.20350170135498047,16,
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.17547011375427246,16,
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.21206402778625488,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.14285612106323242,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.14221596717834473,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.1395282745361328,16,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.32401490211486816,370,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.26114439964294434,370,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.21575093269348145,370,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.13971185684204102,399,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.11648797988891602,399,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.11060571670532227,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.41420912742614746,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.3933844566345215,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.4015076160430908,399,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.45723628997802734,370,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.41663575172424316,370,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.4088137149810791,370,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.44587063789367676,399,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.45557403564453125,399,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.41840505599975586,399,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.1598954200744629,370,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.15562868118286133,370,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.15644288063049316,370,
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.1857764720916748,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.17730069160461426,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.18560075759887695,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.20816397666931152,399,
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.1995244026184082,399,
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.2000412940979004,399,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.21781229972839355,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.2195730209350586,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.259692907333374,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.39571118354797363,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.48991870880126953,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.49497532844543457,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.166459321975708,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.1644885540008545,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.16440844535827637,16,
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.1860334873199463,16,LC_ALL=C
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.16703486442565918,16,LC_ALL=C
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.20740580558776855,16,LC_ALL=C
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15500974655151367,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15694642066955566,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15679144859313965,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11694097518920898,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11726593971252441,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11739015579223633,16,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3873450756072998,490,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.38909482955932617,490,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4019286632537842,490,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32698678970336914,419,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3220486640930176,419,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32451391220092773,419,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2920851707458496,490,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3335237503051758,490,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28688979148864746,490,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.222395658493042,419,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.22271037101745605,419,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.23732328414916992,419,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7565908432006836,766,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.9270203113555908,766,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7432494163513184,766,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.6899797916412354,767,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7057938575744629,767,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7126791477203369,767,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.44383835792541504,416,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4448375701904297,416,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4412264823913574,416,
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.985018730163574,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.671714782714844,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.0708589553833,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.9452569484710693,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3153109550476074,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.876504898071289,490,LC_ALL=C
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.800794124603271,491,
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.91090989112854,491,
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.970277547836304,491,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.21518707275390625,1652,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.2159252166748047,1652,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.2178945541381836,1652,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.10395693778991699,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.101318359375,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.09963226318359375,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.40993452072143555,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.4102144241333008,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.3837263584136963,1653,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,1.7373137474060059,1652,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,1.7011380195617676,1652,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,0.7572276592254639,1652,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5061535835266113,1653,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5377681255340576,1653,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5237703323364258,1653,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.13993382453918457,1630,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.14264798164367676,1630,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.1370248794555664,1630,
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5916049480438232,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5460302829742432,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5453126430511475,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,4.272618055343628,1653,
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,3.953784704208374,1653,
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,4.050055742263794,1653,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2921295166015625,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2845008373260498,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.295884370803833,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8051228523254395,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.824496269226074,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8370847702026367,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.2810385227203369,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.3430476188659668,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.34683680534362793,103,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8701119422912598,23,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.9307808876037598,23,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.9754345417022705,23,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.21484971046447754,186,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.2730236053466797,186,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.21688318252563477,186,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23591041564941406,174,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23375535011291504,174,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23137831687927246,174,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.11421418190002441,186,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.11203289031982422,186,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.10834765434265137,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.39345431327819824,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.40348386764526367,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.40167927742004395,186,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9391078948974609,174,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9322304725646973,174,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9393062591552734,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.9509954452514648,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.9229059219360352,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.8915724754333496,174,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.1719198226928711,168,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.18027615547180176,168,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.17251205444335938,168,
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.980919122695923,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.995086193084717,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.941043376922607,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.5811383724212646,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.5947043895721436,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.522637128829956,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.356529951095581,174,
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.129682540893555,174,
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.098994731903076,174,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.21953463554382324,6,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.2401576042175293,6,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.21302008628845215,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.14854192733764648,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.09938955307006836,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.1005239486694336,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.3981668949127197,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.3999497890472412,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.38619542121887207,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.6837906837463379,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.6158981323242188,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.41248440742492676,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.42545604705810547,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.4142575263977051,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.4717123508453369,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.1639394760131836,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.16333961486816406,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.16097497940063477,6,
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.17300987243652344,6,LC_ALL=C
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.171494722366333,6,LC_ALL=C
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.19692277908325195,6,LC_ALL=C
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.190856695175171,6,
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.1970269680023193,6,
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.094048500061035,6,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.41990160942077637,629,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5151379108428955,629,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5245285034179688,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2494678497314453,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2570071220397949,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20493078231811523,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0035574436187744,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.004251003265381,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.998549222946167,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.750638484954834,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7518937587738037,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6610665321350098,629,
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9856901168823242,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0250558853149414,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0195670127868652,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5834128856658936,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5891468524932861,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5075380802154541,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6499581336975098,629,
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.667529821395874,629,
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6895508766174316,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4941000938415527,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.670578956604004,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6264257431030273,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7577519416809082,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7018873691558838,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5913088321685791,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2632462978363037,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2749521732330322,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27170491218566895,629,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6460118293762207,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5819060802459717,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.7640905380249023,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2313611507415771,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3044109344482422,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3338491916656494,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.3752894401550293,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.370604991912842,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.399735689163208,691,
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.716331243515015,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.910337448120117,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.955447435379028,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.488590240478516,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.247926950454712,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.541552305221558,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.170270681381226,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.186170816421509,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.001753807067871,735,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.2377853393554688,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.361377477645874,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.4316565990448,691,
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.9808149337768555,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.773010015487671,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.952658414840698,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.799196481704712,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.990447282791138,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.916130781173706,691,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.824413537979126,583,
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8357686996459961,583,
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8958892822265625,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2959728240966797,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3027801513671875,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3133840560913086,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.8583695888519287,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.0803942680358887,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.092284679412842,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5811631679534912,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5879406929016113,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5010735988616943,583,
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3335914611816406,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3385870456695557,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3321411609649658,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8784911632537842,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8721048831939697,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8763093948364258,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.429335355758667,583,
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.938883543014526,583,
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.5893049240112305,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.522632598876953,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.237533330917358,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.215710401535034,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.944578170776367,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.835101127624512,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.847816228866577,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.25161075592041,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.299700736999512,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.38068151473999,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6576766967773438,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4723634719848633,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.775054931640625,604,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5934054851531982,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.597702980041504,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5229814052581787,583,
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.458112478256226,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.91841197013855,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.809293508529663,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3416473865509033,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1377508640289307,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.146819829940796,583,LC_ALL=C
|
||||
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} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7402286529541016,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} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.872703790664673,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} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8877029418945312,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.414641857147217,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4537253379821777,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.460618019104004,41,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.290541648864746,,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.311371088027954,,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.1349129676818848,,
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8941442966461182,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8850946426391602,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.074228525161743,,LC_ALL=C
|
||||
|
93
benchsuite/runs/2016-09-17-ubuntu1604-ec2/README.SETUP
Normal file
93
benchsuite/runs/2016-09-17-ubuntu1604-ec2/README.SETUP
Normal file
@@ -0,0 +1,93 @@
|
||||
Ubuntu 16.04 HVM AMI
|
||||
c3.2xlarge, Xeon E5-2680, 2.8 GHz, 8 CPUs, 16 GB memory, 80 GB SSD
|
||||
|
||||
# Generic system setup
|
||||
|
||||
mkfs.ext4 /dev/xvdb
|
||||
sudo mount /dev/xvdb /mnt
|
||||
sudo chown ubuntu /mnt
|
||||
sudo apt-get update
|
||||
sudo apt-get install \ # for building Linux kernel
|
||||
make gcc bc
|
||||
sudo apt-get install \ # for the silver searcher
|
||||
automake pkg-config zlib1g-dev liblzma-dev libpcre3 libpcre3-dev
|
||||
sudo apt-get install \ # for Universal Code Grep
|
||||
libtool libpcre2-8-0 libpcre2-dev
|
||||
sudo apt-get install \ # for sift and the platinum searcher
|
||||
go
|
||||
|
||||
# Get benchmark corpora
|
||||
|
||||
cd /mnt
|
||||
mkdir /mnt/bench
|
||||
git clone git://github.com/BurntSushi/ripgrep
|
||||
cd ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --download all # takes around 15 minutes
|
||||
|
||||
# Install search tools
|
||||
mkdir /mnt/bin/
|
||||
|
||||
## ripgrep
|
||||
|
||||
cd /mnt
|
||||
mkdir ripgrep-bin
|
||||
cd ripgrep-bin
|
||||
curl -LO 'https://github.com/BurntSushi/ripgrep/releases/download/0.1.2/ripgrep-0.1.2-x86_64-unknown-linux-musl.tar.gz'
|
||||
cp ripgrep-0.1.2-x86_64-unknown-linux-musl/rg /mnt/bin/
|
||||
|
||||
## The Silver Searcher
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/ggreer/the_silver_searcher
|
||||
cd the_silver_searcher
|
||||
git checkout cda635
|
||||
./build.sh
|
||||
cp ag /mnt/bin/
|
||||
|
||||
## Universal Code Grep
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/gvansickle/ucg
|
||||
cd ucg
|
||||
git checkout 487bfb
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ucg /mnt/bin/
|
||||
|
||||
## The Platinum Searcher
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/monochromegane/the_platinum_searcher
|
||||
cd /mnt/go/src/github.com/monochromegane/the_platinum_searcher
|
||||
git checkout 509368
|
||||
go install github.com/monochromegane/the_platinum_searcher/cmd/...
|
||||
cp /mnt/go/bin/pt /mnt/bin/
|
||||
|
||||
## Sift
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/svent/sift
|
||||
cd /mnt/go/src/github.com/svent/sift
|
||||
git checkout 2d175c
|
||||
go install
|
||||
cp /mnt/go/bin/sift /mnt/bin/
|
||||
|
||||
## 'git grep' and GNU grep
|
||||
|
||||
They are part of the standard Ubuntu install, and are pretty recent (as of
|
||||
September 2016).
|
||||
|
||||
$ git --version
|
||||
git version 2.7.4
|
||||
$ grep --version
|
||||
grep (GNU grep) 2.25
|
||||
|
||||
|
||||
# Running benchmarks
|
||||
|
||||
export PATH="/mnt/bin:$PATH"
|
||||
cd /mnt/ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --raw /mnt/bench/raw.csv \
|
||||
| tee /mnt/bench/summary
|
||||
# The above took around 30 minutes to run to completion.
|
||||
457
benchsuite/runs/2016-09-17-ubuntu1604-ec2/raw.csv
Normal file
457
benchsuite/runs/2016-09-17-ubuntu1604-ec2/raw.csv
Normal file
@@ -0,0 +1,457 @@
|
||||
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.30042552947998047,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3699159622192383,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2950403690338135,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7572166919708252,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7568728923797607,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7468714714050293,68,
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5062770843505859,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.49932026863098145,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5008277893066406,68,LC_ALL=C
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19775605201721191,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19699668884277344,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19636178016662598,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21344256401062012,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21743154525756836,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22065043449401855,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.31632304191589355,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3168807029724121,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4834277629852295,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9558978080749512,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9736671447753906,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9648356437683105,160,
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.0229439735412598,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.0214922428131104,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.022616147994995,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22146987915039062,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.22275280952453613,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.22226715087890625,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5290391445159912,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5196049213409424,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5219125747680664,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.2871882915496826,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.38920140266418457,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.3668382167816162,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.6073203086853027,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.6012177467346191,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.5818352699279785,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.592775583267212,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.5901448726654053,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.586061716079712,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.45094990730285645,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.47065186500549316,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.4422800540924072,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6293809413909912,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6314799785614014,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6289358139038086,16,
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.347550630569458,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.345928430557251,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.33939385414123535,16,LC_ALL=C
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.20830345153808594,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.34220385551452637,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.2077772617340088,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.21996808052062988,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.22822093963623047,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.21923017501831055,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.2988588809967041,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.5339267253875732,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.43750762939453125,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.603757381439209,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.618077278137207,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.6234121322631836,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.621368646621704,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.5698626041412354,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.6105949878692627,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.8005843162536621,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.8044955730438232,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.806922197341919,370,
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.34161829948425293,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.3455958366394043,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.3493361473083496,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.2149522304534912,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.21602368354797363,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.27021098136901855,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.22747421264648438,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.22050881385803223,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.21217584609985352,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.27482175827026367,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.2796294689178467,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.27638936042785645,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.598384141921997,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.5849597454071045,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.6000149250030518,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.2263963222503662,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.21367835998535156,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.21764111518859863,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.42263340950012207,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.467041015625,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.42820048332214355,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.33421826362609863,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.35932135581970215,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.3372631072998047,16,
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.348984956741333,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.34420299530029297,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.33880615234375,16,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.5833027362823486,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.5783836841583252,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.5806806087493896,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.4163496494293213,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.4040029048919678,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.40265560150146484,490,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3176910877227783,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3504347801208496,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.317542552947998,766,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.821982383728027,491,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.82067561149597,491,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.626302242279053,491,
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.349210023880005,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.34226369857788,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.340656995773315,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.14680290222168,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.153340578079224,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.154819011688232,490,LC_ALL=C
|
||||
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.49768829345703125,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.5121400356292725,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.49718427658081055,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.38550543785095215,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.32651591300964355,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.3246915340423584,419,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.128183126449585,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.1255216598510742,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.1268525123596191,416,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.36306214332580566,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.45077037811279297,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.3804624080657959,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.8995850086212158,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.8897662162780762,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.878380537033081,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.48949646949768,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.289165735244751,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.000468254089355,1652,
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.1080453395843506,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.10821533203125,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.105595588684082,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.2073357105255127,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.20552492141723633,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.2061319351196289,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.3013310432434082,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.3005218505859375,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.29984378814697266,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.4162716865539551,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.47885966300964355,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.5135962963104248,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.570494651794434,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.790151596069336,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.783358812332153,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.4370443820953369,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.40680766105651855,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.4011569023132324,103,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002422809600830078,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002414226531982422,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002293109893798828,,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.44771265983581543,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.3006107807159424,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.3026111125946045,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.43827080726623535,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.2931697368621826,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.33072638511657715,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.7645132541656494,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.7730333805084229,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.773383378982544,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,10.872124671936035,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,11.147738456726074,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,11.029243469238281,174,
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.047154664993286,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.025037288665771,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.081012487411499,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.98722767829895,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.987990379333496,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.988698959350586,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.21961355209350586,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.2884254455566406,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.21905040740966797,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.23966765403747559,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.21801042556762695,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.21909880638122559,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.2259504795074463,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.22269177436828613,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.2259974479675293,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.34968090057373047,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.28850769996643066,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.34809160232543945,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.6134660243988037,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.59847092628479,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.581369161605835,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.644887208938599,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.8782219886779785,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.754150152206421,6,
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.34302353858947754,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.33672142028808594,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.35193610191345215,6,LC_ALL=C
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.33329272270202637,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.25751829147338867,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.21761608123779297,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.22014284133911133,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.22314929962158203,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.2202434539794922,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.622809886932373,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6181182861328125,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6205663681030273,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7565691471099854,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7561769485473633,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7559969425201416,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.4493463039398193,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.44877028465271,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.4433801174163818,848,
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4114174842834473,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.411625862121582,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.408623456954956,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2900726795196533,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2905848026275635,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2903940677642822,848,
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.9546515941619873,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.955279588699341,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.954089403152466,848,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.169135332107544,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.174601078033447,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.1684675216674805,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4171736240386963,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4158167839050293,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4186513423919678,862,
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.531639575958252,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.526550054550171,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.528509140014648,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.722398281097412,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7225935459136963,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7222185134887695,862,
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.12151837348938,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.119963884353638,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.121079683303833,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2684764862060547,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.26811957359313965,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2684173583984375,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.435128688812256,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4362881183624268,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4399220943450928,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.32662391662597656,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.3277275562286377,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.32798290252685547,629,
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.520500659942627,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5191032886505127,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5171597003936768,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.595801830291748,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5954360961914062,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5945618152618408,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7291676998138428,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.730966329574585,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.728854179382324,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.775996208190918,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7760195732116699,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7763564586639404,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.433366060256958,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4338581562042236,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.435924768447876,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7586827278137207,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7590317726135254,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.754432201385498,629,
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9726488590240479,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9699857234954834,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9714112281799316,629,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.36658453941345215,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.3654778003692627,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.36565113067626953,642,
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.0890116691589355,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.08124852180481,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.0796849727630615,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6151647567749023,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6141552925109863,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6132988929748535,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6962459087371826,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6945579051971436,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.693866491317749,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.771639823913574,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.772296190261841,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7712018489837646,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.8068230152130127,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.80411696434021,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.8038516044616699,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5951778888702393,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5971941947937012,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5952184200286865,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7292284965515137,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.728681802749634,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7315311431884766,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.784024715423584,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.780540943145752,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7772648334503174,629,
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9744353294372559,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9781327247619629,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9798097610473633,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5965189933776855,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5960156917572021,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5975723266601562,629,
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9818971157073975,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9785251617431641,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.977081298828125,629,LC_ALL=en_US.UTF-8
|
||||
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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7750890254974365,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.774017333984375,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.783200740814209,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5396409034729004,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5404820442199707,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5400590896606445,13,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.072888612747192,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.075153350830078,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.0713791847229,48,
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.734791278839111,13,
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.7345263957977295,13,
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.73199462890625,13,
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.411367416381836,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.41072940826416,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.414730072021484,13,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6052529811859131,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6049232482910156,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6045565605163574,317,
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2849924564361572,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2837722301483154,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2847650051116943,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6005992889404297,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.600543737411499,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6009273529052734,317,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.664374113082886,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.674306869506836,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.657484769821167,323,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.650290012359619,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.651855707168579,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.649921417236328,317,
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2745037078857422,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.275665521621704,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.273988962173462,317,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9031155109405518,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9021081924438477,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9028818607330322,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.8895978927612305,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.891357660293579,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.892467975616455,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7517757415771484,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7550888061523438,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7555651664733887,691,
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.51417875289917,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.512972116470337,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.507266521453857,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.300950288772583,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.2987852096557617,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3024635314941406,691,
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.983739137649536,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.988446950912476,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.979671478271484,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.889382362365723,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.902577877044678,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.890571355819702,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7548162937164307,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.747791051864624,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7396674156188965,691,
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.58053183555603,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.594751596450806,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.561670541763306,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.833597183227539,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.831137180328369,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.830361843109131,735,
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.723876953125,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.723239183425903,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.722000360488892,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3252851963043213,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3270294666290283,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32680773735046387,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.932488679885864,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.91330337524414,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.911381006240845,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.438587427139282,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.412389755249023,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.412444353103638,583,
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7865939140319824,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7889957427978516,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7923679351806641,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9255633354187012,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9285938739776611,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9274048805236816,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.4811036586761475,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.4785168170928955,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.484618186950684,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7743628025054932,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7731456756591797,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7749128341674805,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.931540250778198,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.935162782669067,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.949711561203003,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.183809995651245,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.19060492515564,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.17626404762268,583,
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3023960590362549,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.2992589473724365,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.299330711364746,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1320264339447021,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1323668956756592,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1354515552520752,604,
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.194744348526001,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.190656423568726,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.18506383895874,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7826528549194336,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7846219539642334,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7846999168395996,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.734788179397583,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7333040237426758,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.731860637664795,604,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7297205924987793,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7314808368682861,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7289514541625977,,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7773914337158203,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.774536371231079,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7740859985351562,583,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3252553939819336,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32543301582336426,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32512736320495605,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7519562244415283,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.752692699432373,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7524521350860596,,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7868170738220215,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7786612510681152,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.776214838027954,583,
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.303652286529541,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3012151718139648,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.307457685470581,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9280951023101807,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9285900592803955,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9288535118103027,579,
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3026466369628906,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3016819953918457,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3006587028503418,579,LC_ALL=en_US.UTF-8
|
||||
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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.895586729049683,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.914353132247925,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.902980327606201,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.972637891769409,,
|
||||
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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.9723849296569824,,
|
||||
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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.9723057746887207,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.3936586380004883,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.3987748622894287,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.393911361694336,,
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8932065963745117,,
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8977222442626953,,
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.893040895462036,,
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4844722747802734,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.485093116760254,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,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} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.482459306716919,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9564735889434814,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9561436176300049,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9558789730072021,278,
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6620113849639893,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6624438762664795,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6610260009765625,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4094629287719727,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.409822702407837,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4094691276550293,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.866976261138916,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8666067123413086,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.865297317504883,,
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.602109670639038,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.598329782485962,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.5975282192230225,,LC_ALL=C
|
||||
|
226
benchsuite/runs/2016-09-17-ubuntu1604-ec2/summary
Normal file
226
benchsuite/runs/2016-09-17-ubuntu1604-ec2/summary
Normal file
@@ -0,0 +1,226 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.322 +/- 0.042 (lines: 68)
|
||||
ag (ignore) 1.754 +/- 0.006 (lines: 68)
|
||||
git grep (ignore) 0.502 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.197 +/- 0.001 (lines: 68)*
|
||||
ucg (whitelist) 0.217 +/- 0.004 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.372 +/- 0.096 (lines: 160)
|
||||
ag (ignore) 1.965 +/- 0.009 (lines: 160)
|
||||
git grep (ignore) 2.022 +/- 0.001 (lines: 160)
|
||||
rg (whitelist)* 0.222 +/- 0.001 (lines: 160)*
|
||||
ucg (whitelist) 0.524 +/- 0.005 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.348 +/- 0.054 (lines: 16)
|
||||
rg (ignore) (mmap) 1.597 +/- 0.013 (lines: 16)
|
||||
ag (ignore) (mmap) 1.590 +/- 0.003 (lines: 16)
|
||||
pt (ignore) 0.455 +/- 0.015 (lines: 16)
|
||||
sift (ignore) 0.630 +/- 0.001 (lines: 16)
|
||||
git grep (ignore) 0.344 +/- 0.004 (lines: 16)
|
||||
rg (whitelist)* 0.253 +/- 0.077 (lines: 16)
|
||||
ucg (whitelist) 0.222 +/- 0.005 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.423 +/- 0.118 (lines: 370)
|
||||
rg (ignore) (mmap) 1.615 +/- 0.010 (lines: 370)
|
||||
ag (ignore) (mmap) 1.601 +/- 0.027 (lines: 370)
|
||||
sift (ignore) 0.804 +/- 0.003 (lines: 370)
|
||||
git grep (ignore) 0.346 +/- 0.004 (lines: 370)
|
||||
rg (whitelist) 0.234 +/- 0.032 (lines: 370)
|
||||
ucg (whitelist)* 0.220 +/- 0.008 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.277 +/- 0.002 (lines: 16)
|
||||
ag 1.594 +/- 0.008 (lines: 16)
|
||||
ucg* 0.219 +/- 0.007 (lines: 16)*
|
||||
pt 0.439 +/- 0.024 (lines: 16)
|
||||
sift 0.344 +/- 0.014 (lines: 16)
|
||||
git grep 0.344 +/- 0.005 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.581 +/- 0.002 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.408 +/- 0.008 (lines: 490)
|
||||
ag (ignore) (ASCII) 2.329 +/- 0.019 (lines: 766)
|
||||
sift (ignore) (ASCII) 25.756 +/- 0.113 (lines: 491)
|
||||
git grep (ignore) 26.344 +/- 0.005 (lines: 490)
|
||||
git grep (ignore) (ASCII) 4.152 +/- 0.004 (lines: 490)
|
||||
rg (whitelist) 0.502 +/- 0.008 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.346 +/- 0.035 (lines: 419)*
|
||||
ucg (whitelist) (ASCII) 1.127 +/- 0.001 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.398 +/- 0.046 (lines: 1652)
|
||||
ag (ignore) 1.889 +/- 0.011 (lines: 1652)
|
||||
sift (ignore) 10.260 +/- 0.246 (lines: 1652)
|
||||
git grep (ignore) 1.107 +/- 0.001 (lines: 1652)
|
||||
rg (whitelist)* 0.206 +/- 0.001 (lines: 1630)*
|
||||
ucg (whitelist) 0.301 +/- 0.001 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.470 +/- 0.049 (lines: 23)*
|
||||
sift 7.715 +/- 0.125 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.415 +/- 0.019 (lines: 103)
|
||||
sift* 0.002 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.350 +/- 0.084 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.354 +/- 0.075 (lines: 174)
|
||||
ag (ignore) (ASCII) 1.770 +/- 0.005 (lines: 174)
|
||||
sift (ignore) (ASCII) 11.016 +/- 0.138 (lines: 174)
|
||||
git grep (ignore) 13.051 +/- 0.028 (lines: 186)
|
||||
git grep (ignore) (ASCII) 2.988 +/- 0.001 (lines: 174)
|
||||
rg (whitelist) 0.242 +/- 0.040 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.226 +/- 0.012 (lines: 168)
|
||||
ucg (ASCII) 0.225 +/- 0.002 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.329 +/- 0.035 (lines: 6)
|
||||
ag (ignore) 1.598 +/- 0.016 (lines: 6)
|
||||
sift (ignore) 7.759 +/- 0.117 (lines: 6)
|
||||
git grep (ignore) 0.344 +/- 0.008 (lines: 6)
|
||||
rg (whitelist)* 0.269 +/- 0.059 (lines: 6)
|
||||
ucg (whitelist) 0.221 +/- 0.002 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.620 +/- 0.002 (lines: 848)
|
||||
ag (lines) 3.756 +/- 0.000 (lines: 848)
|
||||
ucg (lines) 1.447 +/- 0.003 (lines: 848)
|
||||
grep (lines) 3.411 +/- 0.002 (lines: 848)
|
||||
rg* 0.290 +/- 0.000 (lines: 848)*
|
||||
grep 2.955 +/- 0.001 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.171 +/- 0.003 (lines: 862)
|
||||
ucg (ASCII) 3.417 +/- 0.001 (lines: 862)
|
||||
grep (ASCII) 4.529 +/- 0.003 (lines: 862)
|
||||
rg* 2.722 +/- 0.000 (lines: 862)*
|
||||
grep 5.121 +/- 0.001 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.268 +/- 0.000 (lines: 629)*
|
||||
pt 3.437 +/- 0.003 (lines: 629)
|
||||
sift 0.327 +/- 0.001 (lines: 629)
|
||||
grep 0.519 +/- 0.002 (lines: 629)
|
||||
rg (lines) 0.595 +/- 0.001 (lines: 629)
|
||||
ag (lines) 2.730 +/- 0.001 (lines: 629)
|
||||
ucg (lines) 0.776 +/- 0.000 (lines: 629)
|
||||
pt (lines) 3.434 +/- 0.001 (lines: 629)
|
||||
sift (lines) 0.757 +/- 0.003 (lines: 629)
|
||||
grep (lines) 0.971 +/- 0.001 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.366 +/- 0.001 (lines: 642)*
|
||||
grep 4.083 +/- 0.005 (lines: 642)
|
||||
grep (ASCII) 0.614 +/- 0.001 (lines: 642)
|
||||
rg (lines) 0.695 +/- 0.001 (lines: 642)
|
||||
ag (lines) (ASCII) 2.772 +/- 0.001 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.805 +/- 0.002 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.596 +/- 0.001 (lines: 629)*
|
||||
ag (ASCII) 2.730 +/- 0.002 (lines: 629)
|
||||
ucg (ASCII) 0.781 +/- 0.003 (lines: 629)
|
||||
grep (ASCII) 0.977 +/- 0.003 (lines: 629)
|
||||
rg 0.597 +/- 0.001 (lines: 629)
|
||||
grep 0.979 +/- 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 2.777 +/- 0.005 (lines: 13)
|
||||
rg (ASCII)* 2.540 +/- 0.000 (lines: 13)*
|
||||
ag (ASCII) 10.073 +/- 0.002 (lines: 48)
|
||||
ucg (ASCII) 7.734 +/- 0.002 (lines: 13)
|
||||
grep (ASCII) 4.412 +/- 0.002 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.605 +/- 0.000 (lines: 317)
|
||||
grep 1.285 +/- 0.001 (lines: 317)
|
||||
rg (ASCII)* 0.601 +/- 0.000 (lines: 317)*
|
||||
ag (ASCII) 11.665 +/- 0.008 (lines: 323)
|
||||
ucg (ASCII) 4.651 +/- 0.001 (lines: 317)
|
||||
grep (ASCII) 1.275 +/- 0.001 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.903 +/- 0.001 (lines: 691)
|
||||
ag (lines) 5.891 +/- 0.001 (lines: 691)
|
||||
ucg (lines) 2.754 +/- 0.002 (lines: 691)
|
||||
grep (lines) 8.511 +/- 0.004 (lines: 691)
|
||||
rg* 1.301 +/- 0.002 (lines: 691)*
|
||||
grep 7.984 +/- 0.004 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.894 +/- 0.007 (lines: 691)
|
||||
ucg (ASCII)* 2.747 +/- 0.008 (lines: 691)*
|
||||
grep (ASCII) 8.579 +/- 0.017 (lines: 691)
|
||||
rg 4.832 +/- 0.002 (lines: 735)
|
||||
grep 8.723 +/- 0.001 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.326 +/- 0.001 (lines: 583)*
|
||||
pt 12.919 +/- 0.012 (lines: 583)
|
||||
sift 16.421 +/- 0.015 (lines: 583)
|
||||
grep 0.789 +/- 0.003 (lines: 583)
|
||||
rg (lines) 0.927 +/- 0.002 (lines: 583)
|
||||
ag (lines) 4.481 +/- 0.003 (lines: 583)
|
||||
ucg (lines) 1.774 +/- 0.001 (lines: 583)
|
||||
pt (lines) 12.939 +/- 0.010 (lines: 583)
|
||||
sift (lines) 17.184 +/- 0.007 (lines: 583)
|
||||
grep (lines) 1.300 +/- 0.002 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.133 +/- 0.002 (lines: 604)
|
||||
grep 8.190 +/- 0.005 (lines: 604)
|
||||
grep (ASCII) 0.784 +/- 0.001 (lines: 583)
|
||||
rg (lines) 1.733 +/- 0.001 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.730 +/- 0.001 (lines: 0)*
|
||||
ucg (lines) (ASCII) 1.775 +/- 0.002 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.325 +/- 0.000 (lines: 0)*
|
||||
ag (ASCII) 0.752 +/- 0.000 (lines: 0)
|
||||
ucg (ASCII) 1.781 +/- 0.006 (lines: 583)
|
||||
grep (ASCII) 1.304 +/- 0.003 (lines: 583)
|
||||
rg 0.929 +/- 0.000 (lines: 579)
|
||||
grep 1.302 +/- 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 4.904 +/- 0.009 (lines: 41)
|
||||
rg (ASCII) 3.972 +/- 0.000 (lines: 0)
|
||||
ag (ASCII)* 2.395 +/- 0.003 (lines: 0)*
|
||||
ucg (ASCII) 2.895 +/- 0.003 (lines: 0)
|
||||
grep (ASCII) 2.484 +/- 0.001 (lines: 0)
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.956 +/- 0.000 (lines: 278)*
|
||||
grep 1.662 +/- 0.001 (lines: 278)
|
||||
ag (ASCII) 2.410 +/- 0.000 (lines: 0)
|
||||
ucg (ASCII) 2.866 +/- 0.001 (lines: 0)
|
||||
grep (ASCII) 1.599 +/- 0.002 (lines: 0)
|
||||
93
benchsuite/runs/2016-09-20-ubuntu1604-ec2/README.SETUP
Normal file
93
benchsuite/runs/2016-09-20-ubuntu1604-ec2/README.SETUP
Normal file
@@ -0,0 +1,93 @@
|
||||
Ubuntu 16.04 HVM AMI
|
||||
c3.2xlarge, Xeon E5-2680, 2.8 GHz, 8 CPUs, 16 GB memory, 80 GB SSD
|
||||
|
||||
# Generic system setup
|
||||
|
||||
mkfs.ext4 /dev/xvdb
|
||||
sudo mount /dev/xvdb /mnt
|
||||
sudo chown ubuntu /mnt
|
||||
sudo apt-get update
|
||||
sudo apt-get install \ # for building Linux kernel
|
||||
make gcc bc
|
||||
sudo apt-get install \ # for the silver searcher
|
||||
automake pkg-config zlib1g-dev liblzma-dev libpcre3 libpcre3-dev
|
||||
sudo apt-get install \ # for Universal Code Grep
|
||||
libtool libpcre2-8-0 libpcre2-dev
|
||||
sudo apt-get install \ # for sift and the platinum searcher
|
||||
go
|
||||
|
||||
# Get benchmark corpora
|
||||
|
||||
cd /mnt
|
||||
mkdir /mnt/bench
|
||||
git clone git://github.com/BurntSushi/ripgrep
|
||||
cd ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --download all # takes around 15 minutes
|
||||
|
||||
# Install search tools
|
||||
mkdir /mnt/bin/
|
||||
|
||||
## ripgrep
|
||||
|
||||
cd /mnt
|
||||
mkdir ripgrep-bin
|
||||
cd ripgrep-bin
|
||||
curl -LO 'https://github.com/BurntSushi/ripgrep/releases/download/0.1.2/ripgrep-0.1.2-x86_64-unknown-linux-musl.tar.gz'
|
||||
cp ripgrep-0.1.2-x86_64-unknown-linux-musl/rg /mnt/bin/
|
||||
|
||||
## The Silver Searcher
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/ggreer/the_silver_searcher
|
||||
cd the_silver_searcher
|
||||
git checkout cda635
|
||||
./build.sh
|
||||
cp ag /mnt/bin/
|
||||
|
||||
## Universal Code Grep
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/gvansickle/ucg
|
||||
cd ucg
|
||||
git checkout 487bfb
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ucg /mnt/bin/
|
||||
|
||||
## The Platinum Searcher
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/monochromegane/the_platinum_searcher
|
||||
cd /mnt/go/src/github.com/monochromegane/the_platinum_searcher
|
||||
git checkout 509368
|
||||
go install github.com/monochromegane/the_platinum_searcher/cmd/...
|
||||
cp /mnt/go/bin/pt /mnt/bin/
|
||||
|
||||
## Sift
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/svent/sift
|
||||
cd /mnt/go/src/github.com/svent/sift
|
||||
git checkout 2d175c
|
||||
go install
|
||||
cp /mnt/go/bin/sift /mnt/bin/
|
||||
|
||||
## 'git grep' and GNU grep
|
||||
|
||||
They are part of the standard Ubuntu install, and are pretty recent (as of
|
||||
September 2016).
|
||||
|
||||
$ git --version
|
||||
git version 2.7.4
|
||||
$ grep --version
|
||||
grep (GNU grep) 2.25
|
||||
|
||||
|
||||
# Running benchmarks
|
||||
|
||||
export PATH="/mnt/bin:$PATH"
|
||||
cd /mnt/ripgrep/benchsuite
|
||||
./benchsuite \
|
||||
--dir /mnt/bench/ --raw /mnt/bench/raw.csv --warmup-iter 3 --bench-iter 10
|
||||
# The above took around 120 minutes to run to completion.
|
||||
1611
benchsuite/runs/2016-09-20-ubuntu1604-ec2/raw.csv
Normal file
1611
benchsuite/runs/2016-09-20-ubuntu1604-ec2/raw.csv
Normal file
File diff suppressed because it is too large
Load Diff
235
benchsuite/runs/2016-09-20-ubuntu1604-ec2/summary
Normal file
235
benchsuite/runs/2016-09-20-ubuntu1604-ec2/summary
Normal file
@@ -0,0 +1,235 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.351 +/- 0.074 (lines: 68)
|
||||
ag (ignore) 1.747 +/- 0.005 (lines: 68)
|
||||
git grep (ignore) 0.501 +/- 0.003 (lines: 68)
|
||||
rg (whitelist)* 0.216 +/- 0.031 (lines: 68)
|
||||
ucg (whitelist) 0.214 +/- 0.008 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.391 +/- 0.078 (lines: 160)
|
||||
ag (ignore) 1.968 +/- 0.009 (lines: 160)
|
||||
git grep (ignore) 2.018 +/- 0.006 (lines: 160)
|
||||
rg (whitelist)* 0.222 +/- 0.001 (lines: 160)*
|
||||
ucg (whitelist) 0.522 +/- 0.002 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.334 +/- 0.053 (lines: 16)
|
||||
rg (ignore) (mmap) 1.611 +/- 0.009 (lines: 16)
|
||||
ag (ignore) (mmap) 1.588 +/- 0.011 (lines: 16)
|
||||
pt (ignore) 0.456 +/- 0.025 (lines: 16)
|
||||
sift (ignore) 0.630 +/- 0.004 (lines: 16)
|
||||
git grep (ignore) 0.345 +/- 0.007 (lines: 16)
|
||||
rg (whitelist)* 0.228 +/- 0.042 (lines: 16)
|
||||
ucg (whitelist) 0.218 +/- 0.007 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.345 +/- 0.073 (lines: 370)
|
||||
rg (ignore) (mmap) 1.612 +/- 0.011 (lines: 370)
|
||||
ag (ignore) (mmap) 1.609 +/- 0.015 (lines: 370)
|
||||
pt (ignore) 17.204 +/- 0.126 (lines: 370)
|
||||
sift (ignore) 0.805 +/- 0.005 (lines: 370)
|
||||
git grep (ignore) 0.343 +/- 0.007 (lines: 370)
|
||||
rg (whitelist)* 0.222 +/- 0.021 (lines: 370)
|
||||
ucg (whitelist) 0.217 +/- 0.006 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.349 +/- 0.104 (lines: 16)
|
||||
ag 1.589 +/- 0.009 (lines: 16)
|
||||
ucg* 0.218 +/- 0.007 (lines: 16)*
|
||||
pt 0.462 +/- 0.012 (lines: 16)
|
||||
sift 0.352 +/- 0.018 (lines: 16)
|
||||
git grep 0.342 +/- 0.005 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.577 +/- 0.003 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.416 +/- 0.025 (lines: 490)
|
||||
ag (ignore) (ASCII) 2.339 +/- 0.010 (lines: 766)
|
||||
pt (ignore) (ASCII) 22.066 +/- 0.057 (lines: 490)
|
||||
sift (ignore) (ASCII) 25.563 +/- 0.108 (lines: 490)
|
||||
git grep (ignore) 26.382 +/- 0.044 (lines: 490)
|
||||
git grep (ignore) (ASCII) 4.153 +/- 0.010 (lines: 490)
|
||||
rg (whitelist) 0.503 +/- 0.011 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.343 +/- 0.038 (lines: 419)*
|
||||
ucg (whitelist) (ASCII) 1.130 +/- 0.003 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.318 +/- 0.034 (lines: 1652)
|
||||
ag (ignore) 1.899 +/- 0.008 (lines: 1652)
|
||||
pt (ignore) 13.713 +/- 0.241 (lines: 1652)
|
||||
sift (ignore) 10.172 +/- 0.186 (lines: 1652)
|
||||
git grep (ignore) 1.108 +/- 0.004 (lines: 1652)
|
||||
rg (whitelist)* 0.221 +/- 0.022 (lines: 1630)*
|
||||
ucg (whitelist) 0.301 +/- 0.001 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.414 +/- 0.021 (lines: 23)*
|
||||
pt 12.745 +/- 0.166 (lines: 23)
|
||||
sift 7.767 +/- 0.264 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.425 +/- 0.027 (lines: 103)
|
||||
pt 12.612 +/- 0.217 (lines: 23)
|
||||
sift* 0.002 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.355 +/- 0.073 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.329 +/- 0.060 (lines: 174)
|
||||
ag (ignore) (ASCII) 1.774 +/- 0.011 (lines: 174)
|
||||
pt (ignore) (ASCII) 14.180 +/- 0.180 (lines: 174)
|
||||
sift (ignore) (ASCII) 11.087 +/- 0.108 (lines: 174)
|
||||
git grep (ignore) 13.045 +/- 0.008 (lines: 186)
|
||||
git grep (ignore) (ASCII) 2.991 +/- 0.004 (lines: 174)
|
||||
rg (whitelist) 0.235 +/- 0.031 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.225 +/- 0.023 (lines: 168)*
|
||||
ucg (ASCII) 0.229 +/- 0.007 (lines: 168)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.362 +/- 0.080 (lines: 6)
|
||||
ag (ignore) 1.603 +/- 0.009 (lines: 6)
|
||||
pt (ignore) 14.417 +/- 0.144 (lines: 6)
|
||||
sift (ignore) 7.840 +/- 0.123 (lines: 6)
|
||||
git grep (ignore) 0.341 +/- 0.005 (lines: 6)
|
||||
rg (whitelist)* 0.220 +/- 0.026 (lines: 6)*
|
||||
ucg (whitelist) 0.221 +/- 0.007 (lines: 6)
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.619 +/- 0.001 (lines: 848)
|
||||
ag (lines) 3.757 +/- 0.001 (lines: 848)
|
||||
ucg (lines) 1.479 +/- 0.002 (lines: 848)
|
||||
grep (lines) 3.412 +/- 0.004 (lines: 848)
|
||||
rg* 0.294 +/- 0.001 (lines: 848)*
|
||||
grep 2.955 +/- 0.003 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.170 +/- 0.004 (lines: 862)
|
||||
ucg (ASCII) 3.453 +/- 0.005 (lines: 862)
|
||||
grep (ASCII) 4.537 +/- 0.025 (lines: 862)
|
||||
rg* 2.724 +/- 0.002 (lines: 862)*
|
||||
grep 5.125 +/- 0.006 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.268 +/- 0.000 (lines: 629)*
|
||||
rg (no mmap) 0.336 +/- 0.001 (lines: 629)
|
||||
pt 3.433 +/- 0.002 (lines: 629)
|
||||
sift 0.326 +/- 0.002 (lines: 629)
|
||||
grep 0.516 +/- 0.001 (lines: 629)
|
||||
rg (lines) 0.595 +/- 0.001 (lines: 629)
|
||||
ag (lines) 2.730 +/- 0.003 (lines: 629)
|
||||
ucg (lines) 0.745 +/- 0.001 (lines: 629)
|
||||
pt (lines) 3.434 +/- 0.005 (lines: 629)
|
||||
sift (lines) 0.756 +/- 0.002 (lines: 629)
|
||||
grep (lines) 0.969 +/- 0.001 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.366 +/- 0.001 (lines: 642)*
|
||||
grep 4.084 +/- 0.005 (lines: 642)
|
||||
grep (ASCII) 0.614 +/- 0.001 (lines: 642)
|
||||
rg (lines) 0.696 +/- 0.002 (lines: 642)
|
||||
ag (lines) (ASCII) 2.775 +/- 0.004 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.841 +/- 0.002 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII) 0.596 +/- 0.001 (lines: 629)
|
||||
ag (ASCII) 2.729 +/- 0.001 (lines: 629)
|
||||
ucg (ASCII) 0.810 +/- 0.002 (lines: 629)
|
||||
grep (ASCII) 0.970 +/- 0.000 (lines: 629)
|
||||
rg* 0.596 +/- 0.001 (lines: 629)*
|
||||
grep 0.972 +/- 0.003 (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.777 +/- 0.003 (lines: 13)
|
||||
rg (ASCII)* 2.541 +/- 0.005 (lines: 13)*
|
||||
ag (ASCII) 10.076 +/- 0.005 (lines: 48)
|
||||
ucg (ASCII) 7.771 +/- 0.004 (lines: 13)
|
||||
grep (ASCII) 4.411 +/- 0.004 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.605 +/- 0.000 (lines: 317)
|
||||
grep 1.286 +/- 0.002 (lines: 317)
|
||||
rg (ASCII)* 0.602 +/- 0.000 (lines: 317)*
|
||||
ag (ASCII) 11.663 +/- 0.008 (lines: 323)
|
||||
ucg (ASCII) 4.690 +/- 0.002 (lines: 317)
|
||||
grep (ASCII) 1.276 +/- 0.002 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.902 +/- 0.002 (lines: 691)
|
||||
ag (lines) 5.892 +/- 0.003 (lines: 691)
|
||||
ucg (lines) 2.864 +/- 0.006 (lines: 691)
|
||||
grep (lines) 8.511 +/- 0.005 (lines: 691)
|
||||
rg* 1.300 +/- 0.002 (lines: 691)*
|
||||
grep 7.994 +/- 0.017 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.891 +/- 0.001 (lines: 691)
|
||||
ucg (ASCII)* 2.868 +/- 0.005 (lines: 691)*
|
||||
grep (ASCII) 8.572 +/- 0.009 (lines: 691)
|
||||
rg 4.834 +/- 0.004 (lines: 735)
|
||||
grep 8.729 +/- 0.004 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.325 +/- 0.001 (lines: 583)*
|
||||
rg (no mmap) 0.452 +/- 0.002 (lines: 583)
|
||||
pt 12.917 +/- 0.009 (lines: 583)
|
||||
sift 16.418 +/- 0.008 (lines: 583)
|
||||
grep 0.780 +/- 0.001 (lines: 583)
|
||||
rg (lines) 0.926 +/- 0.001 (lines: 583)
|
||||
ag (lines) 4.481 +/- 0.003 (lines: 583)
|
||||
ucg (lines) 1.889 +/- 0.004 (lines: 583)
|
||||
pt (lines) 12.935 +/- 0.011 (lines: 583)
|
||||
sift (lines) 17.177 +/- 0.010 (lines: 583)
|
||||
grep (lines) 1.300 +/- 0.003 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.131 +/- 0.001 (lines: 604)
|
||||
grep 8.187 +/- 0.006 (lines: 604)
|
||||
grep (ASCII) 0.785 +/- 0.001 (lines: 583)
|
||||
rg (lines) 1.733 +/- 0.002 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.729 +/- 0.001 (lines: 0)*
|
||||
ucg (lines) (ASCII) 1.896 +/- 0.005 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.325 +/- 0.000 (lines: 0)*
|
||||
ag (ASCII) 0.753 +/- 0.001 (lines: 0)
|
||||
ucg (ASCII) 1.891 +/- 0.004 (lines: 583)
|
||||
grep (ASCII) 1.303 +/- 0.004 (lines: 583)
|
||||
rg 0.929 +/- 0.001 (lines: 579)
|
||||
grep 1.304 +/- 0.003 (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 4.905 +/- 0.003 (lines: 41)
|
||||
rg (ASCII) 3.973 +/- 0.002 (lines: 0)
|
||||
ag (ASCII)* 2.395 +/- 0.004 (lines: 0)*
|
||||
ucg (ASCII) 3.006 +/- 0.005 (lines: 0)
|
||||
grep (ASCII) 2.483 +/- 0.005 (lines: 0)
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.957 +/- 0.001 (lines: 278)*
|
||||
grep 1.660 +/- 0.002 (lines: 278)
|
||||
ag (ASCII) 2.411 +/- 0.001 (lines: 0)
|
||||
ucg (ASCII) 2.980 +/- 0.002 (lines: 0)
|
||||
grep (ASCII) 1.596 +/- 0.003 (lines: 0)
|
||||
484
benchsuite/runs/2016-09-22-archlinux-cheetah/raw.csv
Normal file
484
benchsuite/runs/2016-09-22-archlinux-cheetah/raw.csv
Normal file
@@ -0,0 +1,484 @@
|
||||
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.16187143325805664,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15862464904785156,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15711188316345215,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5682125091552734,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.551994800567627,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5516140460968018,68,
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24930572509765625,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.25743985176086426,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24960589408874512,68,LC_ALL=C
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1039431095123291,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10251975059509277,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.10156440734863281,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15678954124450684,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15236687660217285,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1554563045501709,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.16192197799682617,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15988397598266602,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1610555648803711,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6026794910430908,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6083211898803711,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.674222469329834,160,
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.0635485649108887,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.8944556713104248,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.860692024230957,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11778616905212402,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.11570453643798828,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.13424015045166016,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2392585277557373,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2421557903289795,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2390902042388916,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.14362168312072754,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.16165685653686523,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.1725757122039795,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3785591125488281,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3961794376373291,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,0.3924229145050049,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,0.5462315082550049,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,0.7240490913391113,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,0.4528837203979492,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.16354584693908691,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.15301966667175293,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.15467524528503418,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.33901119232177734,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.34641242027282715,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.3532230854034424,16,
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.1970062255859375,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.21334624290466309,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.19323515892028809,16,LC_ALL=C
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.10708379745483398,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.10089921951293945,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.10404157638549805,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.17191362380981445,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.1670548915863037,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.16875147819519043,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.16549420356750488,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.14867877960205078,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.1509239673614502,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.38896727561950684,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.39926719665527344,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,0.3912012577056885,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,0.48294734954833984,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,0.4827127456665039,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,0.4216601848602295,370,
|
||||
linux_literal_casei,1,3,pt (ignore),pt -i PM_RESUME,11.884198665618896,370,
|
||||
linux_literal_casei,1,3,pt (ignore),pt -i PM_RESUME,12.05774974822998,370,
|
||||
linux_literal_casei,1,3,pt (ignore),pt -i PM_RESUME,11.864668130874634,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.3698842525482178,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.3745250701904297,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.3670051097869873,370,
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.18896126747131348,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.19655537605285645,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.183945894241333,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.11336517333984375,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.10497522354125977,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.10771870613098145,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.1626441478729248,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.16270971298217773,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.1596980094909668,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.14002084732055664,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.13782882690429688,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.13794231414794922,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.4623262882232666,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.419907808303833,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.44193005561828613,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.1634502410888672,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.17029428482055664,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.16076922416687012,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15809178352355957,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.1554114818572998,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15415430068969727,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.1160738468170166,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11754369735717773,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11825299263000488,16,
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.18619132041931152,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.16708111763000488,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.20236515998840332,16,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.34000611305236816,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.36969494819641113,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.3622872829437256,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.2572669982910156,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.3148176670074463,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.3092081546783447,490,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7651598453521729,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7487096786499023,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7506840229034424,766,
|
||||
linux_no_literal,1,3,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.426137685775757,490,
|
||||
linux_no_literal,1,3,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.454124450683594,490,
|
||||
linux_no_literal,1,3,pt (ignore) (ASCII),pt -e \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},12.573740243911743,490,
|
||||
linux_no_literal,1,3,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.734328746795654,490,
|
||||
linux_no_literal,1,3,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.95349931716919,490,
|
||||
linux_no_literal,1,3,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.97816801071167,490,
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.792009830474854,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.744960308074951,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.04098892211914,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.8596012592315674,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.824751853942871,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.9543235301971436,490,LC_ALL=C
|
||||
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.31849026679992676,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.3028290271759033,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.31795716285705566,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.22214102745056152,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.2748534679412842,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.2098088264465332,419,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4494349956512451,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.44551706314086914,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4425935745239258,416,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.19018173217773438,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.1422746181488037,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.14041566848754883,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,0.5190994739532471,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,0.5290501117706299,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,0.5360753536224365,1652,
|
||||
linux_re_literal_suffix,1,3,pt (ignore),pt -e [A-Z]+_RESUME,11.900719404220581,1652,
|
||||
linux_re_literal_suffix,1,3,pt (ignore),pt -e [A-Z]+_RESUME,11.905181646347046,1652,
|
||||
linux_re_literal_suffix,1,3,pt (ignore),pt -e [A-Z]+_RESUME,11.878832817077637,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,3.9338936805725098,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,3.971776247024536,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,4.010965585708618,1652,
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.553400993347168,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.5757920742034912,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,0.6472165584564209,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.10109567642211914,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.1010751724243164,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.10259413719177246,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13558602333068848,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.13765740394592285,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.14018011093139648,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2655603885650635,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2579922676086426,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2389824390411377,23,
|
||||
linux_unicode_greek,1,3,pt,pt -e \p{Greek},11.789764881134033,23,
|
||||
linux_unicode_greek,1,3,pt,pt -e \p{Greek},11.717109680175781,23,
|
||||
linux_unicode_greek,1,3,pt,pt -e \p{Greek},11.714937448501587,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.732529401779175,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.782707452774048,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},2.8073642253875732,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.29653406143188477,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.24062681198120117,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.24714946746826172,103,
|
||||
linux_unicode_greek_casei,1,3,pt,pt -i -e \p{Greek},11.754312515258789,23,
|
||||
linux_unicode_greek_casei,1,3,pt,pt -i -e \p{Greek},11.742995500564575,23,
|
||||
linux_unicode_greek_casei,1,3,pt,pt -i -e \p{Greek},11.763852596282959,23,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.0018308162689208984,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.0017769336700439453,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.0018434524536132812,,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.19392776489257812,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.14665579795837402,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.15625548362731934,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.14500045776367188,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.15199685096740723,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.14606475830078125,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,0.47933006286621094,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,0.4965095520019531,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,0.4971892833709717,174,
|
||||
linux_unicode_word,1,3,pt (ignore) (ASCII),pt -e \wAh,12.043948650360107,174,
|
||||
linux_unicode_word,1,3,pt (ignore) (ASCII),pt -e \wAh,12.024799823760986,174,
|
||||
linux_unicode_word,1,3,pt (ignore) (ASCII),pt -e \wAh,12.032919883728027,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.146677255630493,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.05977988243103,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \wAh,4.246629238128662,174,
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,4.401025772094727,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,4.499484062194824,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,4.530885934829712,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.552142858505249,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.4553732872009277,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,1.3407535552978516,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.10183477401733398,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.10535907745361328,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.10527634620666504,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.10268187522888184,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.10159945487976074,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.09854245185852051,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.17232871055603027,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.17245817184448242,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.1736738681793213,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.18302679061889648,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.14654874801635742,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.14666008949279785,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,0.43340468406677246,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,0.4431777000427246,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,0.4939415454864502,6,
|
||||
linux_word,1,3,pt (ignore),pt -w PM_RESUME,12.12212347984314,6,
|
||||
linux_word,1,3,pt (ignore),pt -w PM_RESUME,12.106850862503052,6,
|
||||
linux_word,1,3,pt (ignore),pt -w PM_RESUME,12.119231224060059,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.3320345878601074,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.2089524269104004,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,3.34165096282959,6,
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.20112895965576172,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.16607999801635742,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.2049086093902588,6,LC_ALL=C
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.10440325736999512,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.09853243827819824,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.09580087661743164,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.16874432563781738,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.16241073608398438,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.1621534824371338,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.5109667778015137,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.662921667098999,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.627272367477417,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.4915170669555664,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.294611930847168,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.475243330001831,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.450028419494629,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.266982078552246,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.429199457168579,848,
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.81933856010437,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.829207420349121,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.795469284057617,848,LC_ALL=C
|
||||
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.3135373592376709,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.47072267532348633,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.3777759075164795,848,
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.2277214527130127,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.4641876220703125,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.4201643466949463,848,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.925377368927002,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.7743782997131348,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.9031031131744385,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.902085542678833,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.9104111194610596,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.9407846927642822,862,
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.6935694217681885,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.7745134830474854,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.5532472133636475,862,LC_ALL=C
|
||||
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.3000056743621826,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.46085786819458,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.2774720191955566,862,
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.183770418167114,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.210017442703247,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.052750587463379,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2422008514404297,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.18678736686706543,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20187044143676758,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21189618110656738,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.21378588676452637,629,
|
||||
subtitles_en_literal,1,3,rg (no mmap),rg --no-mmap Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2638204097747803,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6680185794830322,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7018795013427734,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.7135086059570312,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.33170270919799805,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3204488754272461,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.3302597999572754,629,
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5119576454162598,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.48076844215393066,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6118988990783691,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6149063110351562,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.547245979309082,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5441193580627441,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.990401268005371,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.9924650192260742,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.807952642440796,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.772294282913208,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8758792877197266,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8043625354766846,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.5409111976623535,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.535851001739502,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6951041221618652,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7138817310333252,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.727524995803833,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7202486991882324,629,
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0228428840637207,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9452800750732422,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0286569595336914,629,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.36867737770080566,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.391110897064209,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.42432594299316406,642,
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.2124955654144287,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.288994789123535,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.2279436588287354,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5713660717010498,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5478014945983887,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5502541065216064,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5866222381591797,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5829083919525146,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7458250522613525,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8324756622314453,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8361680507659912,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.017822265625,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9228289127349854,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9356215000152588,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9355306625366211,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.46090102195739746,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.41375064849853516,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.4181649684906006,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8445067405700684,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.805356740951538,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.8274097442626953,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9036450386047363,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7601873874664307,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7341368198394775,629,
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.867140531539917,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8452246189117432,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8254234790802002,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.39222264289855957,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5510556697845459,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.439284086227417,629,
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8688523769378662,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0727341175079346,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.8665497303009033,629,LC_ALL=en_US.UTF-8
|
||||
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.2950611114501953,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.226304769515991,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.3140387535095215,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,2.055910587310791,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,2.032794952392578,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,2.0602478981018066,13,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \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,7.566168308258057,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \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,7.360717535018921,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \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,7.30781364440918,48,
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.13957142829895,13,
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,6.132368564605713,13,
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.929611921310425,13,
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.432003974914551,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.714038610458374,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.6915385723114014,13,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.42601513862609863,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.561565637588501,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5141217708587646,317,
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.3077969551086426,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1768431663513184,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0883615016937256,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5061089992523193,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.4004178047180176,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.5536422729492188,317,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.981522798538208,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,4.83101487159729,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,5.025806427001953,323,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.906707286834717,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.8826284408569336,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,3.852736711502075,317,
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.262470006942749,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1661438941955566,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.1648437976837158,317,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.79972243309021,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.629694938659668,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8325402736663818,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.124853849411011,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.0995543003082275,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.105457544326782,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.491947650909424,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.544341802597046,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.6295418739318848,691,
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.948693513870239,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.991183280944824,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.004202842712402,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1708271503448486,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3341143131256104,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3589985370635986,691,
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.3860955238342285,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.437295436859131,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.34372615814209,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.100299119949341,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.343926668167114,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.247299432754517,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.6179757118225098,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.438668727874756,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.6296229362487793,691,
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.816138744354248,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.005900859832764,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.96263861656189,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.222437858581543,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.260664463043213,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.040424823760986,735,
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.112156391143799,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,7.066831350326538,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.983258962631226,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3009657859802246,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.31114768981933594,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3145453929901123,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3670217990875244,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.39557576179504395,583,
|
||||
subtitles_ru_literal,1,3,rg (no mmap),rg --no-mmap Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.38857460021972656,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.653504133224487,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.440903663635254,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.604345321655273,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.333267450332642,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.3738181591033936,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.604928970336914,583,
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7382421493530273,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7205381393432617,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8509528636932373,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6589868068695068,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.857933759689331,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7283596992492676,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.111611843109131,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.1084604263305664,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.993370771408081,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8463020324707031,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8160367012023926,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.9012954235076904,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.590208530426025,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.712487697601318,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.628024339675903,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.999194145202637,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.639494895935059,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.6554951667785645,583,
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3319404125213623,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3712143898010254,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2382845878601074,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2365717887878418,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2306108474731445,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.22041654586792,604,
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.636392116546631,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.447664976119995,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.47466516494751,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8679373264312744,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8400778770446777,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8912734985351562,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6649067401885986,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.472435712814331,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5518934726715088,604,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6329071521759033,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6236186027526855,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.744124174118042,,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.842088222503662,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6797516345977783,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.86281418800354,583,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3059053421020508,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3220036029815674,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3317573070526123,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.790125846862793,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8004007339477539,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7884745597839355,,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8595643043518066,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8338594436645508,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6697683334350586,583,
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1608448028564453,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3229436874389648,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3650012016296387,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.840968132019043,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.7012484073638916,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.6782803535461426,579,
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3308250904083252,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2687301635742188,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.317870855331421,579,LC_ALL=en_US.UTF-8
|
||||
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.8553390502929688,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.6567201614379883,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.6484830379486084,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.968876838684082,,
|
||||
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.0976366996765137,,
|
||||
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.9159646034240723,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \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,1.8425374031066895,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \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.0483176708221436,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \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.0838112831115723,,
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.510307550430298,,
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.542471408843994,,
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.5069386959075928,,
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0888967514038086,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.119218349456787,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,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} /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.0531933307647705,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.792813777923584,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8660504817962646,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8515620231628418,278,
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4405500888824463,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6386635303497314,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5895426273345947,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.032708168029785,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.927478551864624,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.019101619720459,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.6226632595062256,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.5062124729156494,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.5160763263702393,,
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.613976240158081,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5636706352233887,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /data/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4378304481506348,,LC_ALL=C
|
||||
|
235
benchsuite/runs/2016-09-22-archlinux-cheetah/summary
Normal file
235
benchsuite/runs/2016-09-22-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.159 +/- 0.002 (lines: 68)
|
||||
ag (ignore) 0.557 +/- 0.009 (lines: 68)
|
||||
git grep (ignore) 0.252 +/- 0.005 (lines: 68)
|
||||
rg (whitelist)* 0.103 +/- 0.001 (lines: 68)*
|
||||
ucg (whitelist) 0.155 +/- 0.002 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.161 +/- 0.001 (lines: 160)
|
||||
ag (ignore) 0.628 +/- 0.040 (lines: 160)
|
||||
git grep (ignore) 0.940 +/- 0.109 (lines: 160)
|
||||
rg (whitelist)* 0.123 +/- 0.010 (lines: 160)*
|
||||
ucg (whitelist) 0.240 +/- 0.002 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.159 +/- 0.015 (lines: 16)
|
||||
rg (ignore) (mmap) 0.389 +/- 0.009 (lines: 16)
|
||||
ag (ignore) (mmap) 0.574 +/- 0.138 (lines: 16)
|
||||
pt (ignore) 0.157 +/- 0.006 (lines: 16)
|
||||
sift (ignore) 0.346 +/- 0.007 (lines: 16)
|
||||
git grep (ignore) 0.201 +/- 0.011 (lines: 16)
|
||||
rg (whitelist)* 0.104 +/- 0.003 (lines: 16)*
|
||||
ucg (whitelist) 0.169 +/- 0.002 (lines: 16)
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.155 +/- 0.009 (lines: 370)
|
||||
rg (ignore) (mmap) 0.393 +/- 0.005 (lines: 370)
|
||||
ag (ignore) (mmap) 0.462 +/- 0.035 (lines: 370)
|
||||
pt (ignore) 11.936 +/- 0.106 (lines: 370)
|
||||
sift (ignore) 0.370 +/- 0.004 (lines: 370)
|
||||
git grep (ignore) 0.190 +/- 0.006 (lines: 370)
|
||||
rg (whitelist)* 0.109 +/- 0.004 (lines: 370)*
|
||||
ucg (whitelist) 0.162 +/- 0.002 (lines: 370)
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.139 +/- 0.001 (lines: 16)
|
||||
ag 0.441 +/- 0.021 (lines: 16)
|
||||
ucg 0.165 +/- 0.005 (lines: 16)
|
||||
pt 0.156 +/- 0.002 (lines: 16)
|
||||
sift* 0.117 +/- 0.001 (lines: 16)*
|
||||
git grep 0.185 +/- 0.018 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.357 +/- 0.015 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.294 +/- 0.032 (lines: 490)
|
||||
ag (ignore) (ASCII) 0.755 +/- 0.009 (lines: 766)
|
||||
pt (ignore) (ASCII) 12.485 +/- 0.078 (lines: 490)
|
||||
sift (ignore) (ASCII) 8.889 +/- 0.134 (lines: 490)
|
||||
git grep (ignore) 8.859 +/- 0.159 (lines: 490)
|
||||
git grep (ignore) (ASCII) 1.880 +/- 0.067 (lines: 490)
|
||||
rg (whitelist) 0.313 +/- 0.009 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.236 +/- 0.035 (lines: 419)*
|
||||
ucg (whitelist) (ASCII) 0.446 +/- 0.003 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.158 +/- 0.028 (lines: 1652)
|
||||
ag (ignore) 0.528 +/- 0.009 (lines: 1652)
|
||||
pt (ignore) 11.895 +/- 0.014 (lines: 1652)
|
||||
sift (ignore) 3.972 +/- 0.039 (lines: 1652)
|
||||
git grep (ignore) 0.592 +/- 0.049 (lines: 1652)
|
||||
rg (whitelist)* 0.102 +/- 0.001 (lines: 1630)*
|
||||
ucg (whitelist) 0.138 +/- 0.002 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.254 +/- 0.014 (lines: 23)*
|
||||
pt 11.741 +/- 0.043 (lines: 23)
|
||||
sift 2.774 +/- 0.038 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.261 +/- 0.031 (lines: 103)
|
||||
pt 11.754 +/- 0.010 (lines: 23)
|
||||
sift* 0.002 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.166 +/- 0.025 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.148 +/- 0.004 (lines: 174)
|
||||
ag (ignore) (ASCII) 0.491 +/- 0.010 (lines: 174)
|
||||
pt (ignore) (ASCII) 12.034 +/- 0.010 (lines: 174)
|
||||
sift (ignore) (ASCII) 4.151 +/- 0.094 (lines: 174)
|
||||
git grep (ignore) 4.477 +/- 0.068 (lines: 186)
|
||||
git grep (ignore) (ASCII) 1.449 +/- 0.106 (lines: 174)
|
||||
rg (whitelist) 0.104 +/- 0.002 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.101 +/- 0.002 (lines: 168)*
|
||||
ucg (ASCII) 0.173 +/- 0.001 (lines: 168)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.159 +/- 0.021 (lines: 6)
|
||||
ag (ignore) 0.457 +/- 0.032 (lines: 6)
|
||||
pt (ignore) 12.116 +/- 0.008 (lines: 6)
|
||||
sift (ignore) 3.294 +/- 0.074 (lines: 6)
|
||||
git grep (ignore) 0.191 +/- 0.021 (lines: 6)
|
||||
rg (whitelist)* 0.100 +/- 0.004 (lines: 6)*
|
||||
ucg (whitelist) 0.164 +/- 0.004 (lines: 6)
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.600 +/- 0.079 (lines: 848)
|
||||
ag (lines) 2.420 +/- 0.109 (lines: 848)
|
||||
ucg (lines) 1.382 +/- 0.100 (lines: 848)
|
||||
grep (lines) 2.815 +/- 0.017 (lines: 848)
|
||||
rg* 0.387 +/- 0.079 (lines: 848)*
|
||||
grep 2.371 +/- 0.126 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 3.868 +/- 0.082 (lines: 862)
|
||||
ucg (ASCII) 2.918 +/- 0.020 (lines: 862)
|
||||
grep (ASCII) 3.674 +/- 0.112 (lines: 862)
|
||||
rg* 2.346 +/- 0.100 (lines: 862)*
|
||||
grep 4.149 +/- 0.084 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.210 +/- 0.029 (lines: 629)*
|
||||
rg (no mmap) 0.230 +/- 0.029 (lines: 629)
|
||||
pt 1.694 +/- 0.024 (lines: 629)
|
||||
sift 0.327 +/- 0.006 (lines: 629)
|
||||
grep 0.535 +/- 0.069 (lines: 629)
|
||||
rg (lines) 0.569 +/- 0.040 (lines: 629)
|
||||
ag (lines) 1.930 +/- 0.106 (lines: 629)
|
||||
ucg (lines) 0.818 +/- 0.053 (lines: 629)
|
||||
pt (lines) 1.591 +/- 0.091 (lines: 629)
|
||||
sift (lines) 0.721 +/- 0.007 (lines: 629)
|
||||
grep (lines) 0.999 +/- 0.047 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.395 +/- 0.028 (lines: 642)*
|
||||
grep 3.243 +/- 0.040 (lines: 642)
|
||||
grep (ASCII) 0.556 +/- 0.013 (lines: 642)
|
||||
rg (lines) 0.638 +/- 0.093 (lines: 642)
|
||||
ag (lines) (ASCII) 1.895 +/- 0.106 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.931 +/- 0.007 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII) 0.431 +/- 0.026 (lines: 629)*
|
||||
ag (ASCII) 1.826 +/- 0.020 (lines: 629)
|
||||
ucg (ASCII) 0.799 +/- 0.091 (lines: 629)
|
||||
grep (ASCII) 0.846 +/- 0.021 (lines: 629)
|
||||
rg* 0.461 +/- 0.082 (lines: 629)
|
||||
grep 0.936 +/- 0.118 (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.278 +/- 0.046 (lines: 13)
|
||||
rg (ASCII)* 2.050 +/- 0.015 (lines: 13)*
|
||||
ag (ASCII) 7.412 +/- 0.136 (lines: 48)
|
||||
ucg (ASCII) 6.067 +/- 0.119 (lines: 13)
|
||||
grep (ASCII) 3.613 +/- 0.157 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.501 +/- 0.069 (lines: 317)
|
||||
grep 1.191 +/- 0.110 (lines: 317)
|
||||
rg (ASCII)* 0.487 +/- 0.078 (lines: 317)*
|
||||
ag (ASCII) 4.946 +/- 0.102 (lines: 323)
|
||||
ucg (ASCII) 3.881 +/- 0.027 (lines: 317)
|
||||
grep (ASCII) 1.198 +/- 0.056 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.754 +/- 0.109 (lines: 691)
|
||||
ag (lines) 4.110 +/- 0.013 (lines: 691)
|
||||
ucg (lines) 2.555 +/- 0.069 (lines: 691)
|
||||
grep (lines) 6.981 +/- 0.029 (lines: 691)
|
||||
rg* 1.288 +/- 0.102 (lines: 691)*
|
||||
grep 6.389 +/- 0.047 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 4.231 +/- 0.123 (lines: 691)
|
||||
ucg (ASCII)* 2.562 +/- 0.107 (lines: 691)*
|
||||
grep (ASCII) 6.928 +/- 0.099 (lines: 691)
|
||||
rg 4.175 +/- 0.118 (lines: 735)
|
||||
grep 7.054 +/- 0.065 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.309 +/- 0.007 (lines: 583)*
|
||||
rg (no mmap) 0.384 +/- 0.015 (lines: 583)
|
||||
pt 5.566 +/- 0.111 (lines: 583)
|
||||
sift 6.437 +/- 0.147 (lines: 583)
|
||||
grep 0.770 +/- 0.071 (lines: 583)
|
||||
rg (lines) 0.748 +/- 0.101 (lines: 583)
|
||||
ag (lines) 3.071 +/- 0.067 (lines: 583)
|
||||
ucg (lines) 1.855 +/- 0.043 (lines: 583)
|
||||
pt (lines) 5.644 +/- 0.063 (lines: 583)
|
||||
sift (lines) 6.765 +/- 0.203 (lines: 583)
|
||||
grep (lines) 1.314 +/- 0.068 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.229 +/- 0.008 (lines: 604)
|
||||
grep 6.520 +/- 0.102 (lines: 604)
|
||||
grep (ASCII) 0.866 +/- 0.026 (lines: 583)
|
||||
rg (lines) 1.563 +/- 0.097 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.667 +/- 0.067 (lines: 0)*
|
||||
ucg (lines) (ASCII) 1.795 +/- 0.100 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.320 +/- 0.013 (lines: 0)*
|
||||
ag (ASCII) 0.793 +/- 0.006 (lines: 0)
|
||||
ucg (ASCII) 1.788 +/- 0.103 (lines: 583)
|
||||
grep (ASCII) 1.283 +/- 0.108 (lines: 583)
|
||||
rg 0.740 +/- 0.088 (lines: 579)
|
||||
grep 1.306 +/- 0.033 (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.720 +/- 0.117 (lines: 41)
|
||||
rg (ASCII) 2.994 +/- 0.093 (lines: 0)
|
||||
ag (ASCII)* 1.992 +/- 0.130 (lines: 0)*
|
||||
ucg (ASCII) 2.520 +/- 0.020 (lines: 0)
|
||||
grep (ASCII) 2.087 +/- 0.033 (lines: 0)
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.837 +/- 0.039 (lines: 278)*
|
||||
grep 1.556 +/- 0.103 (lines: 278)
|
||||
ag (ASCII) 1.993 +/- 0.057 (lines: 0)
|
||||
ucg (ASCII) 2.548 +/- 0.065 (lines: 0)
|
||||
grep (ASCII) 1.538 +/- 0.091 (lines: 0)
|
||||
@@ -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)*
|
||||
@@ -1,164 +0,0 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg 0.239 +/- 0.008 (lines: 68)
|
||||
rg-novcs* 0.122 +/- 0.018 (lines: 68)*
|
||||
rg-novcs-mmap 0.394 +/- 0.004 (lines: 68)
|
||||
ag 0.497 +/- 0.009 (lines: 68)
|
||||
ag-novcs 0.554 +/- 0.125 (lines: 68)
|
||||
ucg 0.153 +/- 0.004 (lines: 68)
|
||||
git grep 0.254 +/- 0.011 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg 0.230 +/- 0.015 (lines: 160)
|
||||
rg-novcs* 0.126 +/- 0.003 (lines: 160)*
|
||||
rg-novcs-mmap 0.397 +/- 0.004 (lines: 160)
|
||||
ag 0.826 +/- 0.377 (lines: 160)
|
||||
ag-novcs 0.592 +/- 0.047 (lines: 160)
|
||||
ucg 0.238 +/- 0.002 (lines: 160)
|
||||
git grep 0.920 +/- 0.054 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg 0.218 +/- 0.003 (lines: 16)
|
||||
rg-novcs* 0.109 +/- 0.011 (lines: 16)*
|
||||
rg-novcs-mmap 0.389 +/- 0.007 (lines: 16)
|
||||
ag 0.512 +/- 0.005 (lines: 16)
|
||||
ag-novcs 0.876 +/- 0.370 (lines: 16)
|
||||
ucg 0.163 +/- 0.004 (lines: 16)
|
||||
git grep 0.194 +/- 0.001 (lines: 16)
|
||||
pt 0.197 +/- 0.019 (lines: 16)
|
||||
sift 0.142 +/- 0.002 (lines: 16)
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg 0.267 +/- 0.054 (lines: 370)
|
||||
rg-novcs* 0.122 +/- 0.015 (lines: 399)*
|
||||
rg-novcs-mmap 0.403 +/- 0.010 (lines: 399)
|
||||
ag 0.428 +/- 0.026 (lines: 370)
|
||||
ag-novcs 0.440 +/- 0.019 (lines: 399)
|
||||
ucg 0.157 +/- 0.002 (lines: 370)
|
||||
git grep 0.183 +/- 0.005 (lines: 370)
|
||||
sift 0.203 +/- 0.005 (lines: 399)
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.232 +/- 0.024 (lines: 16)
|
||||
ag 0.460 +/- 0.056 (lines: 16)
|
||||
ucg 0.165 +/- 0.001 (lines: 16)
|
||||
git grep 0.187 +/- 0.020 (lines: 16)
|
||||
pt 0.156 +/- 0.001 (lines: 16)
|
||||
sift* 0.117 +/- 0.000 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg 0.393 +/- 0.008 (lines: 490)
|
||||
rg-whitelist 0.325 +/- 0.002 (lines: 419)
|
||||
rg (no Unicode) 0.304 +/- 0.026 (lines: 490)
|
||||
rg-whitelist (no Unicode)* 0.227 +/- 0.009 (lines: 419)*
|
||||
ag (no Unicode) 0.809 +/- 0.102 (lines: 766)
|
||||
ag-novcs (no Unicode) 0.703 +/- 0.012 (lines: 767)
|
||||
ucg (no Unicode) 0.443 +/- 0.002 (lines: 416)
|
||||
git grep 9.576 +/- 0.465 (lines: 490)
|
||||
git grep (no Unicode) 2.046 +/- 0.236 (lines: 490)
|
||||
sift (no Unicode) 8.894 +/- 0.086 (lines: 491)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg 0.216 +/- 0.001 (lines: 1652)
|
||||
rg-novcs* 0.102 +/- 0.002 (lines: 1653)*
|
||||
rg-novcs-mmap 0.401 +/- 0.015 (lines: 1653)
|
||||
ag 1.399 +/- 0.556 (lines: 1652)
|
||||
ag-novcs 0.523 +/- 0.016 (lines: 1653)
|
||||
ucg 0.140 +/- 0.003 (lines: 1630)
|
||||
git grep 0.561 +/- 0.027 (lines: 1652)
|
||||
sift 4.092 +/- 0.164 (lines: 1653)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.291 +/- 0.006 (lines: 23)*
|
||||
sift 2.822 +/- 0.016 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.324 +/- 0.037 (lines: 103)*
|
||||
sift 2.925 +/- 0.053 (lines: 23)
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg 0.235 +/- 0.033 (lines: 186)
|
||||
rg (no Unicode) 0.234 +/- 0.002 (lines: 174)
|
||||
rg-novcs* 0.112 +/- 0.003 (lines: 186)*
|
||||
rg-novcs-mmap 0.400 +/- 0.005 (lines: 186)
|
||||
ag (no Unicode) 0.937 +/- 0.004 (lines: 174)
|
||||
ag-novcs (no Unicode) 0.922 +/- 0.030 (lines: 174)
|
||||
ucg (no Unicode) 0.175 +/- 0.005 (lines: 168)
|
||||
git grep 4.972 +/- 0.028 (lines: 186)
|
||||
git grep (no Unicode) 1.566 +/- 0.038 (lines: 174)
|
||||
sift (no Unicode) 4.195 +/- 0.141 (lines: 174)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg 0.224 +/- 0.014 (lines: 6)
|
||||
rg-novcs* 0.116 +/- 0.028 (lines: 6)*
|
||||
rg-novcs-mmap 0.395 +/- 0.007 (lines: 6)
|
||||
ag 0.571 +/- 0.141 (lines: 6)
|
||||
ag-novcs 0.437 +/- 0.030 (lines: 6)
|
||||
ucg 0.163 +/- 0.002 (lines: 6)
|
||||
git grep 0.180 +/- 0.014 (lines: 6)
|
||||
sift 3.161 +/- 0.058 (lines: 6)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg 0.487 +/- 0.058 (lines: 629)
|
||||
rg (no line numbers)* 0.237 +/- 0.028 (lines: 629)*
|
||||
ag 2.002 +/- 0.003 (lines: 629)
|
||||
ucg 0.721 +/- 0.052 (lines: 629)
|
||||
grep 1.010 +/- 0.021 (lines: 629)
|
||||
grep (no line numbers) 0.560 +/- 0.046 (lines: 629)
|
||||
pt 1.669 +/- 0.020 (lines: 629)
|
||||
pt (no line numbers) 1.597 +/- 0.092 (lines: 629)
|
||||
sift 0.684 +/- 0.085 (lines: 629)
|
||||
sift (no line numbers) 0.270 +/- 0.006 (lines: 629)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg 1.664 +/- 0.092 (lines: 691)
|
||||
rg (no line numbers)* 1.290 +/- 0.053 (lines: 691)*
|
||||
ucg 2.382 +/- 0.016 (lines: 691)
|
||||
grep 6.861 +/- 0.127 (lines: 691)
|
||||
grep (no line numbers) 6.426 +/- 0.156 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg 4.119 +/- 0.102 (lines: 735)
|
||||
ucg (not Unicode)* 2.344 +/- 0.098 (lines: 691)*
|
||||
grep 6.902 +/- 0.113 (lines: 735)
|
||||
grep (not Unicode) 6.902 +/- 0.096 (lines: 691)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg 0.852 +/- 0.038 (lines: 583)
|
||||
rg (no line numbers)* 0.304 +/- 0.009 (lines: 583)*
|
||||
ag 3.010 +/- 0.132 (lines: 583)
|
||||
ucg 1.557 +/- 0.048 (lines: 583)
|
||||
grep 1.335 +/- 0.003 (lines: 583)
|
||||
grep (no line numbers) 0.876 +/- 0.003 (lines: 583)
|
||||
pt 5.319 +/- 0.339 (lines: 583)
|
||||
pt (no line numbers) 5.325 +/- 0.171 (lines: 583)
|
||||
sift 6.876 +/- 0.060 (lines: 583)
|
||||
sift (no line numbers) 6.311 +/- 0.065 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.635 +/- 0.153 (lines: 604)
|
||||
ucg (not Unicode) 1.571 +/- 0.042 (lines: 583)
|
||||
grep 6.729 +/- 0.241 (lines: 604)
|
||||
grep (not Unicode)* 1.209 +/- 0.115 (lines: 583)*
|
||||
|
||||
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.834 +/- 0.081 (lines: 41)
|
||||
rg (no line numbers) 3.443 +/- 0.025 (lines: 41)
|
||||
ucg (no Unicode) 2.246 +/- 0.096 (lines: 0)
|
||||
grep (no Unicode)* 1.951 +/- 0.107 (lines: 0)*
|
||||
27
build.rs
Normal file
27
build.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
use clap::Shell;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[path = "src/app.rs"]
|
||||
mod app;
|
||||
|
||||
fn main() {
|
||||
let outdir = match env::var_os("OUT_DIR") {
|
||||
None => return,
|
||||
Some(outdir) => outdir,
|
||||
};
|
||||
fs::create_dir_all(&outdir).unwrap();
|
||||
|
||||
let mut app = app::app();
|
||||
app.gen_completions("rg", Shell::Bash, &outdir);
|
||||
app.gen_completions("rg", Shell::Fish, &outdir);
|
||||
app.gen_completions("rg", Shell::Zsh, &outdir);
|
||||
app.gen_completions("rg", Shell::PowerShell, &outdir);
|
||||
}
|
||||
@@ -16,9 +16,11 @@ mk_tarball() {
|
||||
local out_dir=$(pwd)
|
||||
local name="${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}"
|
||||
mkdir "$td/$name"
|
||||
mkdir "$td/$name/complete"
|
||||
|
||||
cp target/$TARGET/release/rg "$td/$name/"
|
||||
cp {README.md,UNLICENSE,COPYING,LICENSE-MIT} "$td/$name/"
|
||||
cp {doc/rg.1,README.md,UNLICENSE,COPYING,LICENSE-MIT} "$td/$name/"
|
||||
cp target/$TARGET/release/build/ripgrep-*/out/{_rg,rg.bash-completion,rg.fish,_rg.ps1} "$td/$name/complete/"
|
||||
|
||||
pushd $td
|
||||
tar czf "$out_dir/$name.tar.gz" *
|
||||
|
||||
@@ -17,9 +17,6 @@ install_c_toolchain() {
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
rustc -V
|
||||
|
||||
@@ -16,8 +16,17 @@ disable_cross_doctests() {
|
||||
}
|
||||
|
||||
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
|
||||
cargo build --target $TARGET --verbose --manifest-path termcolor/Cargo.toml
|
||||
cargo test --target $TARGET --verbose --manifest-path termcolor/Cargo.toml
|
||||
|
||||
# sanity check the file type
|
||||
file target/$TARGET/debug/rg
|
||||
|
||||
25
ci/sha256.sh
Normal file
25
ci/sha256.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# != 1 ]; then
|
||||
echo "Usage: $(basename $0) version" >&2
|
||||
exit 1
|
||||
fi
|
||||
version="$1"
|
||||
|
||||
# Linux and Darwin builds.
|
||||
for arch in i686 x86_64; do
|
||||
for target in apple-darwin unknown-linux-musl; do
|
||||
url="https://github.com/BurntSushi/ripgrep/releases/download/$version/ripgrep-$version-$arch-$target.tar.gz"
|
||||
sha=$(curl -sfSL "$url" | sha256sum)
|
||||
echo "$version-$arch-$target $sha"
|
||||
done
|
||||
done
|
||||
|
||||
# Source.
|
||||
for ext in zip tar.gz; do
|
||||
url="https://github.com/BurntSushi/ripgrep/archive/$version.$ext"
|
||||
sha=$(curl -sfSL "$url" | sha256sum)
|
||||
echo "source.$ext $sha"
|
||||
done
|
||||
9
compile
9
compile
@@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
export RUSTFLAGS="-C target-feature=+ssse3"
|
||||
# export RUSTFLAGS="-C target-cpu=native"
|
||||
cargo build --release --features simd-accel
|
||||
# export RUSTFLAGS="-C target-feature=+ssse3"
|
||||
# cargo build --release --features 'simd-accel'
|
||||
|
||||
export RUSTFLAGS="-C target-cpu=native"
|
||||
cargo build --release --features 'simd-accel avx-accel'
|
||||
# cargo build --release --features 'simd-accel avx-accel' --target x86_64-unknown-linux-musl
|
||||
|
||||
4
doc/convert-to-man
Executable file
4
doc/convert-to-man
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
pandoc -s -t man rg.1.md -o rg.1
|
||||
sed -i 's/\.TH.*/.TH "rg" "1"/g' rg.1
|
||||
520
doc/rg.1
Normal file
520
doc/rg.1
Normal file
@@ -0,0 +1,520 @@
|
||||
.\" Automatically generated by Pandoc 1.19.2.1
|
||||
.\"
|
||||
.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[]] <\f[I]pattern\f[]> [\f[I]<\f[]path\f[I]> ...\f[]]
|
||||
.PP
|
||||
rg [\f[I]options\f[]] (\-e PATTERN | \-f FILE) ...
|
||||
[\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
|
||||
ripgrep (rg) combines the usability of The Silver Searcher (an ack
|
||||
clone) with the raw speed of grep.
|
||||
.PP
|
||||
ripgrep\[aq]s regex engine uses finite automata and guarantees linear
|
||||
time searching.
|
||||
Because of this, features like backreferences and arbitrary lookaround
|
||||
are not supported.
|
||||
.PP
|
||||
Project home page: https://github.com/BurntSushi/ripgrep
|
||||
.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.
|
||||
This is also useful when searching for patterns that start with a dash.
|
||||
.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 if there is a conflict, but
|
||||
is otherwise applied in addition to ignore files (e.g., .gitignore or
|
||||
\&.ignore).
|
||||
Multiple glob flags may be used.
|
||||
Globbing rules match .gitignore globs.
|
||||
Precede a glob with a \[aq]!\[aq] to exclude it.
|
||||
.RS
|
||||
.RE
|
||||
.PP
|
||||
The \-\-glob flag subsumes the functionality of both the \-\-include and
|
||||
\-\-exclude flags commonly found in other tools.
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
Values\ given\ to\ \-g\ must\ be\ quoted\ or\ your\ shell\ will\ expand\ them\ and\ result
|
||||
in\ unexpected\ behavior.
|
||||
|
||||
Combine\ with\ the\ \-\-files\ flag\ to\ return\ matched\ filenames
|
||||
(i.e.,\ to\ replicate\ ack/ag\[aq]s\ \-g\ flag).
|
||||
|
||||
For\ example:\ rg\ \-g\ \[aq]\\<glob\\>\[aq]\ \-\-files
|
||||
\f[]
|
||||
.fi
|
||||
.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
|
||||
.PP
|
||||
Note that the \-u flags are convenient aliases for other combinations of
|
||||
flags.
|
||||
\-u aliases \[aq]\-\-no\-ignore\[aq].
|
||||
\-uu aliases \[aq]\-\-no\-ignore \-\-hidden\[aq].
|
||||
\-uuu aliases \[aq]\-\-no\-ignore \-\-hidden \-\-text\[aq].
|
||||
.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 \-\-colors \f[I]SPEC\f[] ...
|
||||
This flag specifies color settings for use in the output.
|
||||
This flag may be provided multiple times.
|
||||
Settings are applied iteratively.
|
||||
Colors are limited to one of eight choices: red, blue, green, cyan,
|
||||
magenta, yellow, white and black.
|
||||
Styles are limited to nobold, bold, nointense or intense.
|
||||
.RS
|
||||
.PP
|
||||
The format of the flag is {type}:{attribute}:{value}.
|
||||
{type} should be one of path, line, column or match.
|
||||
{attribute} can be fg, bg or style.
|
||||
Value is either a color (for fg and bg) or a text style.
|
||||
A special format, {type}:none, will clear all color settings for {type}.
|
||||
.PP
|
||||
For example, the following command will change the match color to
|
||||
magenta and the background color for line numbers to yellow:
|
||||
.PP
|
||||
rg \-\-colors \[aq]match:fg:magenta\[aq] \-\-colors
|
||||
\[aq]line:bg:yellow\[aq] foo.
|
||||
.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.
|
||||
This implies \-\-line\-number.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-context\-separator \f[I]SEPARATOR\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 \-E, \-\-encoding \f[I]ENCODING\f[]
|
||||
Specify the text encoding that ripgrep will use on all files searched.
|
||||
The default value is \[aq]auto\[aq], which will cause ripgrep to do a
|
||||
best effort automatic detection of encoding on a per\-file basis.
|
||||
Other supported values can be found in the list of labels here:
|
||||
https://encoding.spec.whatwg.org/#concept\-encoding\-get
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-f, \-\-file FILE ...
|
||||
Search for patterns from the given file, with one pattern per line.
|
||||
When this flag is used or multiple times or in combination with the
|
||||
\-e/\-\-regexp flag, then all patterns provided are searched.
|
||||
Empty pattern lines will match all input lines, and the newline is not
|
||||
counted as part of the pattern.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-files
|
||||
Print each file that would be searched (but don\[aq]t search).
|
||||
.RS
|
||||
.PP
|
||||
Combine with the \-g flag to return matched paths, for example:
|
||||
.PP
|
||||
rg \-g \[aq]<glob>\[aq] \-\-files
|
||||
.RE
|
||||
.TP
|
||||
.B \-l, \-\-files\-with\-matches
|
||||
Only show path of each file with matches.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-files\-without\-match
|
||||
Only show path of each file with no 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 instead of
|
||||
showing the file name for every match.
|
||||
This is the default mode at a tty.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-no\-heading
|
||||
Don\[aq]t group matches by each file.
|
||||
If \-H/\-\-with\-filename is enabled, then file names will be shown for
|
||||
every line matched.
|
||||
This is the default more when not at a tty.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-hidden
|
||||
Search hidden directories and files.
|
||||
(Hidden directories and files are skipped by default.)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-ignore\-file FILE ...
|
||||
Specify additional ignore files for filtering file paths.
|
||||
Ignore files should be in the gitignore format and are matched relative
|
||||
to the current working directory.
|
||||
These ignore files have lower precedence than all other ignore files.
|
||||
When specifying multiple ignore files, earlier files have lower
|
||||
precedence than later files.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-L, \-\-follow
|
||||
Follow symlinks.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-M, \-\-max\-columns \f[I]NUM\f[]
|
||||
Don\[aq]t print lines longer than this limit in bytes.
|
||||
Longer lines are omitted, and only the number of matches in that line is
|
||||
printed.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-m, \-\-max\-count \f[I]NUM\f[]
|
||||
Limit the number of matching lines per file searched to NUM.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-max\-filesize \f[I]NUM\f[]+\f[I]SUFFIX\f[]?
|
||||
Ignore files larger than \f[I]NUM\f[] in size.
|
||||
Directories will never be ignored.
|
||||
.RS
|
||||
.PP
|
||||
\f[I]SUFFIX\f[] is optional and may be one of K, M or G.
|
||||
These correspond to kilobytes, megabytes and gigabytes respectively.
|
||||
If omitted the input is treated as bytes.
|
||||
.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\-messages
|
||||
Suppress all error messages.
|
||||
.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 \-0, \-\-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 \-o, \-\-only\-matching
|
||||
Print only the matched (non\-empty) parts of a matching line, with each
|
||||
such part on a separate output line.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-path\-separator \f[I]SEPARATOR\f[]
|
||||
The path separator to use when printing file paths.
|
||||
This defaults to your platform\[aq]s path separator, which is / on Unix
|
||||
and \\ on Windows.
|
||||
This flag is intended for overriding the default when the environment
|
||||
demands it (e.g., cygwin).
|
||||
A path separator is limited to a single byte.
|
||||
.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.
|
||||
.PP
|
||||
Note that the replacement by default replaces each match, and NOT the
|
||||
entire line.
|
||||
To replace the entire line, you should match the entire line.
|
||||
For example, to emit only the first phone numbers in each line:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
rg\ \[aq]^.*([0\-9]{3}\-[0\-9]{3}\-[0\-9]{4}).*$\[aq]\ \-\-replace\ \[aq]$1\[aq]
|
||||
\f[]
|
||||
.fi
|
||||
.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 \-\-sort\-files
|
||||
Sort results by file path.
|
||||
Note that this currently disables all parallelism and runs search in a
|
||||
single thread.
|
||||
.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 12).
|
||||
[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
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ Example:\ `rg\ \-\-type\-add\ \[aq]foo:*.foo\[aq]\ \-tfoo\ PATTERN`
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
\-\-type\-add can also be used to include rules from other types with
|
||||
the special include directive.
|
||||
The include directive permits specifying one or more other type names
|
||||
(separated by a comma) that have been defined and its rules will
|
||||
automatically be imported into the type specified.
|
||||
For example, to create a type called src that matches C++, Python and
|
||||
Markdown files, one can use:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ `\-\-type\-add\ \[aq]src:include:cpp,py,md\[aq]`
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
Additional glob rules can still be added to the src type by using the
|
||||
\-\-type\-add flag again:
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
\ \ `\-\-type\-add\ \[aq]src:include:cpp,py,md\[aq]\ \-\-type\-add\ \[aq]src:*.foo\[aq]`
|
||||
\f[]
|
||||
.fi
|
||||
.PP
|
||||
Note that type names must consist only of Unicode letters or numbers.
|
||||
Punctuation characters are not allowed.
|
||||
.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
|
||||
.SH SHELL COMPLETION
|
||||
.PP
|
||||
Shell completion files are included in the release tarball for Bash,
|
||||
Fish, Zsh and PowerShell.
|
||||
.PP
|
||||
For \f[B]bash\f[], move \f[C]rg.bash\-completion\f[] to
|
||||
\f[C]$XDG_CONFIG_HOME/bash_completion\f[] or
|
||||
\f[C]/etc/bash_completion.d/\f[].
|
||||
.PP
|
||||
For \f[B]fish\f[], move \f[C]rg.fish\f[] to
|
||||
\f[C]$HOME/.config/fish/completions\f[].
|
||||
347
doc/rg.1.md
Normal file
347
doc/rg.1.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# NAME
|
||||
|
||||
rg - recursively search current directory for lines matching a pattern
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
rg [*options*] <*pattern*> [*<*path*> ...*]
|
||||
|
||||
rg [*options*] (-e PATTERN | -f FILE) ... [*<*path*> ...*]
|
||||
|
||||
rg [*options*] --files [*<*path*> ...*]
|
||||
|
||||
rg [*options*] --type-list
|
||||
|
||||
rg [*options*] --help
|
||||
|
||||
rg [*options*] --version
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
ripgrep (rg) combines the usability of The Silver Searcher (an ack clone) with
|
||||
the raw speed of grep.
|
||||
|
||||
ripgrep's regex engine uses finite automata and guarantees linear time
|
||||
searching. Because of this, features like backreferences and arbitrary
|
||||
lookaround are not supported.
|
||||
|
||||
Project home page: https://github.com/BurntSushi/ripgrep
|
||||
|
||||
# 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. This is also useful when searching for patterns
|
||||
that start with a dash.
|
||||
|
||||
-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 if there is a conflict, but is otherwise
|
||||
applied in addition to ignore files (e.g., .gitignore or .ignore). Multiple
|
||||
glob flags may be used. Globbing rules match .gitignore globs. Precede a
|
||||
glob with a '!' to exclude it.
|
||||
|
||||
The --glob flag subsumes the functionality of both the --include and
|
||||
--exclude flags commonly found in other tools.
|
||||
|
||||
Values given to -g must be quoted or your shell will expand them and result
|
||||
in unexpected behavior.
|
||||
|
||||
Combine with the --files flag to return matched filenames
|
||||
(i.e., to replicate ack/ag's -g flag).
|
||||
|
||||
For example: rg -g '\<glob\>' --files
|
||||
|
||||
-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.
|
||||
|
||||
Note that the -u flags are convenient aliases for other combinations of
|
||||
flags. -u aliases '--no-ignore'. -uu aliases '--no-ignore --hidden'.
|
||||
-uuu aliases '--no-ignore --hidden --text'.
|
||||
|
||||
-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.
|
||||
|
||||
--colors *SPEC* ...
|
||||
: This flag specifies color settings for use in the output. This flag may be
|
||||
provided multiple times. Settings are applied iteratively. Colors are limited
|
||||
to one of eight choices: red, blue, green, cyan, magenta, yellow, white and
|
||||
black. Styles are limited to nobold, bold, nointense or intense.
|
||||
|
||||
The format of the flag is {type}:{attribute}:{value}. {type} should be one
|
||||
of path, line, column or match. {attribute} can be fg, bg or style. Value
|
||||
is either a color (for fg and bg) or a text style. A special format,
|
||||
{type}:none, will clear all color settings for {type}.
|
||||
|
||||
For example, the following command will change the match color to magenta
|
||||
and the background color for line numbers to yellow:
|
||||
|
||||
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.
|
||||
|
||||
--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. This implies
|
||||
--line-number.
|
||||
|
||||
--context-separator *SEPARATOR*
|
||||
: The string to use when separating non-continuous context lines. Escape
|
||||
sequences may be used. [default: --]
|
||||
|
||||
--debug
|
||||
: Show debug messages.
|
||||
|
||||
-E, --encoding *ENCODING*
|
||||
: Specify the text encoding that ripgrep will use on all files
|
||||
searched. The default value is 'auto', which will cause ripgrep to do
|
||||
a best effort automatic detection of encoding on a per-file basis.
|
||||
Other supported values can be found in the list of labels here:
|
||||
https://encoding.spec.whatwg.org/#concept-encoding-get
|
||||
|
||||
-f, --file FILE ...
|
||||
: Search for patterns from the given file, with one pattern per line. When this
|
||||
flag is used or multiple times or in combination with the -e/--regexp flag,
|
||||
then all patterns provided are searched. Empty pattern lines will match all
|
||||
input lines, and the newline is not counted as part of the pattern.
|
||||
|
||||
--files
|
||||
: Print each file that would be searched (but don't search).
|
||||
|
||||
Combine with the -g flag to return matched paths, for example:
|
||||
|
||||
rg -g '\<glob\>' --files
|
||||
|
||||
-l, --files-with-matches
|
||||
: Only show path of each file with matches.
|
||||
|
||||
--files-without-match
|
||||
: Only show path of each file with no 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 instead of
|
||||
showing the file name for every match. This is the default mode at a tty.
|
||||
|
||||
--no-heading
|
||||
: Don't group matches by each file. If -H/--with-filename is enabled, then
|
||||
file names will be shown for every line matched. This is the default more
|
||||
when not at a tty.
|
||||
|
||||
--hidden
|
||||
: Search hidden directories and files. (Hidden directories and files are
|
||||
skipped by default.)
|
||||
|
||||
--ignore-file FILE ...
|
||||
: Specify additional ignore files for filtering file paths.
|
||||
Ignore files should be in the gitignore format and are matched
|
||||
relative to the current working directory. These ignore files
|
||||
have lower precedence than all other ignore files. When
|
||||
specifying multiple ignore files, earlier files have lower
|
||||
precedence than later files.
|
||||
|
||||
-L, --follow
|
||||
: Follow symlinks.
|
||||
|
||||
-M, --max-columns *NUM*
|
||||
: Don't print lines longer than this limit in bytes. Longer lines are omitted,
|
||||
and only the number of matches in that line is printed.
|
||||
|
||||
-m, --max-count *NUM*
|
||||
: Limit the number of matching lines per file searched to NUM.
|
||||
|
||||
--max-filesize *NUM*+*SUFFIX*?
|
||||
: Ignore files larger than *NUM* in size. Directories will never be ignored.
|
||||
|
||||
*SUFFIX* is optional and may be one of K, M or G. These correspond to
|
||||
kilobytes, megabytes and gigabytes respectively. If omitted the input is
|
||||
treated as bytes.
|
||||
|
||||
--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-messages
|
||||
: Suppress all error messages.
|
||||
|
||||
--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.
|
||||
|
||||
-0, --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.
|
||||
|
||||
-o, --only-matching
|
||||
: Print only the matched (non-empty) parts of a matching line, with each such
|
||||
part on a separate output line.
|
||||
|
||||
--path-separator *SEPARATOR*
|
||||
: The path separator to use when printing file paths. This defaults to your
|
||||
platform's path separator, which is / on Unix and \\ on Windows. This flag is
|
||||
intended for overriding the default when the environment demands it (e.g.,
|
||||
cygwin). A path separator is limited to a single byte.
|
||||
|
||||
-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.
|
||||
|
||||
Note that the replacement by default replaces each match, and NOT the
|
||||
entire line. To replace the entire line, you should match the entire line.
|
||||
For example, to emit only the first phone numbers in each line:
|
||||
|
||||
rg '^.*([0-9]{3}-[0-9]{3}-[0-9]{4}).*$' --replace '$1'
|
||||
|
||||
-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.
|
||||
|
||||
--sort-files
|
||||
: Sort results by file path. Note that this currently
|
||||
disables all parallelism and runs search in a single thread.
|
||||
|
||||
-j, --threads *ARG*
|
||||
: The number of threads to use. 0 means use the number of logical CPUs
|
||||
(capped at 12). [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-add can also be used to include rules from other types
|
||||
with the special include directive. The include directive
|
||||
permits specifying one or more other type names (separated by a
|
||||
comma) that have been defined and its rules will automatically
|
||||
be imported into the type specified. For example, to create a
|
||||
type called src that matches C++, Python and Markdown files, one
|
||||
can use:
|
||||
|
||||
`--type-add 'src:include:cpp,py,md'`
|
||||
|
||||
Additional glob rules can still be added to the src type by
|
||||
using the --type-add flag again:
|
||||
|
||||
`--type-add 'src:include:cpp,py,md' --type-add 'src:*.foo'`
|
||||
|
||||
Note that type names must consist only of Unicode letters or
|
||||
numbers. Punctuation characters are not allowed.
|
||||
|
||||
--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.
|
||||
|
||||
# SHELL COMPLETION
|
||||
|
||||
Shell completion files are included in the release tarball for Bash, Fish, Zsh
|
||||
and PowerShell.
|
||||
|
||||
For **bash**, move `rg.bash-completion` to `$XDG_CONFIG_HOME/bash_completion`
|
||||
or `/etc/bash_completion.d/`.
|
||||
|
||||
For **fish**, move `rg.fish` to `$HOME/.config/fish/completions`.
|
||||
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.
|
||||
32
globset/Cargo.toml
Normal file
32
globset/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "globset"
|
||||
version = "0.1.4" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Cross platform single glob and glob set matching. Glob set matching is the
|
||||
process of matching one or more glob patterns against a single candidate path
|
||||
simultaneously, and returning all of the globs that matched.
|
||||
"""
|
||||
documentation = "https://docs.rs/globset"
|
||||
homepage = "https://github.com/BurntSushi/ripgrep/tree/master/globset"
|
||||
repository = "https://github.com/BurntSushi/ripgrep/tree/master/globset"
|
||||
readme = "README.md"
|
||||
keywords = ["regex", "glob", "multiple", "set", "pattern"]
|
||||
license = "Unlicense/MIT"
|
||||
|
||||
[lib]
|
||||
name = "globset"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
aho-corasick = "0.6.0"
|
||||
fnv = "1.0"
|
||||
log = "0.3"
|
||||
memchr = "1"
|
||||
regex = "0.2.1"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2"
|
||||
|
||||
[features]
|
||||
simd-accel = ["regex/simd-accel"]
|
||||
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.
|
||||
122
globset/README.md
Normal file
122
globset/README.md
Normal file
@@ -0,0 +1,122 @@
|
||||
globset
|
||||
=======
|
||||
Cross platform single glob and glob set matching. Glob set matching is the
|
||||
process of matching one or more glob patterns against a single candidate path
|
||||
simultaneously, and returning all of the globs that matched.
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
[](https://crates.io/crates/globset)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
### Documentation
|
||||
|
||||
[https://docs.rs/globset](https://docs.rs/globset)
|
||||
|
||||
### Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
globset = "0.1"
|
||||
```
|
||||
|
||||
and this to your crate root:
|
||||
|
||||
```rust
|
||||
extern crate globset;
|
||||
```
|
||||
|
||||
### Example: one glob
|
||||
|
||||
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();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(glob.is_match("foo/bar.rs"));
|
||||
assert!(!glob.is_match("Cargo.toml"));
|
||||
```
|
||||
|
||||
### Example: configuring a glob matcher
|
||||
|
||||
This example shows how to use a `GlobBuilder` to configure aspects of match
|
||||
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();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(!glob.is_match("foo/bar.rs")); // no longer matches
|
||||
assert!(!glob.is_match("Cargo.toml"));
|
||||
```
|
||||
|
||||
### Example: match multiple globs at once
|
||||
|
||||
This example shows how to match multiple glob patterns at once.
|
||||
|
||||
```rust
|
||||
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());
|
||||
|
||||
assert_eq!(set.matches("src/bar/baz/foo.rs"), vec![0, 2]);
|
||||
```
|
||||
|
||||
### Performance
|
||||
|
||||
This crate implements globs by converting them to regular expressions, and
|
||||
executing them with the
|
||||
[`regex`](https://github.com/rust-lang-nursery/regex)
|
||||
crate.
|
||||
|
||||
For single glob matching, performance of this crate should be roughly on par
|
||||
with the performance of the
|
||||
[`glob`](https://github.com/rust-lang-nursery/glob)
|
||||
crate. (`*_regex` correspond to benchmarks for this library while `*_glob`
|
||||
correspond to benchmarks for the `glob` library.)
|
||||
Optimizations in the `regex` crate may propel this library past `glob`,
|
||||
particularly when matching longer paths.
|
||||
|
||||
```
|
||||
test ext_glob ... bench: 425 ns/iter (+/- 21)
|
||||
test ext_regex ... bench: 175 ns/iter (+/- 10)
|
||||
test long_glob ... bench: 182 ns/iter (+/- 11)
|
||||
test long_regex ... bench: 173 ns/iter (+/- 10)
|
||||
test short_glob ... bench: 69 ns/iter (+/- 4)
|
||||
test short_regex ... bench: 83 ns/iter (+/- 2)
|
||||
```
|
||||
|
||||
The primary performance advantage of this crate is when matching multiple
|
||||
globs against a single path. With the `glob` crate, one must match each glob
|
||||
synchronously, one after the other. In this crate, many can be matched
|
||||
simultaneously. For example:
|
||||
|
||||
```
|
||||
test many_short_glob ... bench: 1,063 ns/iter (+/- 47)
|
||||
test many_short_regex_set ... bench: 186 ns/iter (+/- 11)
|
||||
```
|
||||
|
||||
### Comparison with the [`glob`](https://github.com/rust-lang-nursery/glob) crate
|
||||
|
||||
* Supports alternate "or" globs, e.g., `*.{foo,bar}`.
|
||||
* Can match non-UTF-8 file paths correctly.
|
||||
* Supports matching multiple globs at once.
|
||||
* Doesn't provide a recursive directory iterator of matching file paths,
|
||||
although I believe this crate should grow one eventually.
|
||||
* Supports case insensitive and require-literal-separator match options, but
|
||||
**doesn't** support the require-literal-leading-dot option.
|
||||
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/>
|
||||
@@ -5,37 +5,53 @@ tool itself, see the benchsuite directory.
|
||||
#![feature(test)]
|
||||
|
||||
extern crate glob;
|
||||
extern crate globset;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate regex;
|
||||
extern crate test;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
use globset::{Candidate, Glob, GlobMatcher, GlobSet, GlobSetBuilder};
|
||||
|
||||
const EXT: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
|
||||
const EXT_PAT: &'static str = "*.txt";
|
||||
|
||||
const SHORT: &'static str = "some/needle.txt";
|
||||
const SHORT_PAT: &'static str = "some/**/needle.txt";
|
||||
|
||||
const LONG: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
|
||||
const LONG_PAT: &'static str = "some/**/needle.txt";
|
||||
|
||||
#[allow(dead_code, unused_variables)]
|
||||
#[path = "../src/glob.rs"]
|
||||
mod reglob;
|
||||
|
||||
fn new_glob(pat: &str) -> glob::Pattern {
|
||||
glob::Pattern::new(pat).unwrap()
|
||||
}
|
||||
|
||||
fn new_reglob(pat: &str) -> reglob::Set {
|
||||
let mut builder = reglob::SetBuilder::new();
|
||||
builder.add(pat).unwrap();
|
||||
fn new_reglob(pat: &str) -> GlobMatcher {
|
||||
Glob::new(pat).unwrap().compile_matcher()
|
||||
}
|
||||
|
||||
fn new_reglob_many(pats: &[&str]) -> GlobSet {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
for pat in pats {
|
||||
builder.add(Glob::new(pat).unwrap());
|
||||
}
|
||||
builder.build().unwrap()
|
||||
}
|
||||
|
||||
fn new_reglob_many(pats: &[&str]) -> reglob::Set {
|
||||
let mut builder = reglob::SetBuilder::new();
|
||||
for pat in pats {
|
||||
builder.add(pat).unwrap();
|
||||
}
|
||||
builder.build().unwrap()
|
||||
#[bench]
|
||||
fn ext_glob(b: &mut test::Bencher) {
|
||||
let pat = new_glob(EXT_PAT);
|
||||
b.iter(|| assert!(pat.matches(EXT)));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn ext_regex(b: &mut test::Bencher) {
|
||||
let set = new_reglob(EXT_PAT);
|
||||
let cand = Candidate::new(EXT);
|
||||
b.iter(|| assert!(set.is_match_candidate(&cand)));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@@ -47,7 +63,8 @@ fn short_glob(b: &mut test::Bencher) {
|
||||
#[bench]
|
||||
fn short_regex(b: &mut test::Bencher) {
|
||||
let set = new_reglob(SHORT_PAT);
|
||||
b.iter(|| assert!(set.is_match(SHORT)));
|
||||
let cand = Candidate::new(SHORT);
|
||||
b.iter(|| assert!(set.is_match_candidate(&cand)));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@@ -59,7 +76,8 @@ fn long_glob(b: &mut test::Bencher) {
|
||||
#[bench]
|
||||
fn long_regex(b: &mut test::Bencher) {
|
||||
let set = new_reglob(LONG_PAT);
|
||||
b.iter(|| assert!(set.is_match(LONG)));
|
||||
let cand = Candidate::new(LONG);
|
||||
b.iter(|| assert!(set.is_match_candidate(&cand)));
|
||||
}
|
||||
|
||||
const MANY_SHORT_GLOBS: &'static [&'static str] = &[
|
||||
@@ -101,26 +119,3 @@ fn many_short_regex_set(b: &mut test::Bencher) {
|
||||
let set = new_reglob_many(MANY_SHORT_GLOBS);
|
||||
b.iter(|| assert_eq!(2, set.matches(MANY_SHORT_SEARCH).iter().count()));
|
||||
}
|
||||
|
||||
// This is the fastest on my system (beating many_glob by about 2x). This
|
||||
// suggests that a RegexSet needs quite a few regexes (or a larger haystack)
|
||||
// in order for it to scale.
|
||||
//
|
||||
// TODO(burntsushi): come up with a benchmark that uses more complex patterns
|
||||
// or a longer haystack.
|
||||
#[bench]
|
||||
fn many_short_regex_pattern(b: &mut test::Bencher) {
|
||||
let pats: Vec<_> = MANY_SHORT_GLOBS.iter().map(|&s| {
|
||||
let pat = reglob::Pattern::new(s).unwrap();
|
||||
regex::Regex::new(&pat.to_regex()).unwrap()
|
||||
}).collect();
|
||||
b.iter(|| {
|
||||
let mut count = 0;
|
||||
for pat in &pats {
|
||||
if pat.is_match(MANY_SHORT_SEARCH) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(2, count);
|
||||
})
|
||||
}
|
||||
1323
globset/src/glob.rs
Normal file
1323
globset/src/glob.rs
Normal file
File diff suppressed because it is too large
Load Diff
787
globset/src/lib.rs
Normal file
787
globset/src/lib.rs
Normal file
@@ -0,0 +1,787 @@
|
||||
/*!
|
||||
The globset crate provides cross platform single glob and glob set matching.
|
||||
|
||||
Glob set matching is the process of matching one or more glob patterns against
|
||||
a single candidate path simultaneously, and returning all of the globs that
|
||||
matched. For example, given this set of globs:
|
||||
|
||||
```ignore
|
||||
*.rs
|
||||
src/lib.rs
|
||||
src/**/foo.rs
|
||||
```
|
||||
|
||||
and a path `src/bar/baz/foo.rs`, then the set would report the first and third
|
||||
globs as matching.
|
||||
|
||||
# Example: one glob
|
||||
|
||||
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();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(glob.is_match("foo/bar.rs"));
|
||||
assert!(!glob.is_match("Cargo.toml"));
|
||||
# Ok(()) } example().unwrap();
|
||||
```
|
||||
|
||||
# Example: configuring a glob matcher
|
||||
|
||||
This example shows how to use a `GlobBuilder` to configure aspects of match
|
||||
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();
|
||||
|
||||
assert!(glob.is_match("foo.rs"));
|
||||
assert!(!glob.is_match("foo/bar.rs")); // no longer matches
|
||||
assert!(!glob.is_match("Cargo.toml"));
|
||||
# Ok(()) } example().unwrap();
|
||||
```
|
||||
|
||||
# Example: match multiple globs at once
|
||||
|
||||
This example shows how to match multiple glob patterns at once.
|
||||
|
||||
```
|
||||
# fn example() -> Result<(), globset::Error> {
|
||||
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());
|
||||
|
||||
assert_eq!(set.matches("src/bar/baz/foo.rs"), vec![0, 2]);
|
||||
# Ok(()) } example().unwrap();
|
||||
```
|
||||
|
||||
# Syntax
|
||||
|
||||
Standard Unix-style glob syntax is supported:
|
||||
|
||||
* `?` matches any single character. (If the `literal_separator` option is
|
||||
enabled, then `?` can never match a path separator.)
|
||||
* `*` matches zero or more characters. (If the `literal_separator` option is
|
||||
enabled, then `*` can never match a path separator.)
|
||||
* `**` recursively matches directories but are only legal in three situations.
|
||||
First, if the glob starts with <code>\*\*/</code>, then it matches
|
||||
all directories. For example, <code>\*\*/foo</code> matches `foo`
|
||||
and `bar/foo` but not `foo/bar`. Secondly, if the glob ends with
|
||||
<code>/\*\*</code>, then it matches all sub-entries. For example,
|
||||
<code>foo/\*\*</code> matches `foo/a` and `foo/a/b`, but not `foo`.
|
||||
Thirdly, if the glob contains <code>/\*\*/</code> anywhere within
|
||||
the pattern, then it matches zero or more directories. Using `**` anywhere
|
||||
else is illegal (N.B. the glob `**` is allowed and means "match everything").
|
||||
* `{a,b}` matches `a` or `b` where `a` and `b` are arbitrary glob patterns.
|
||||
(N.B. Nesting `{...}` is not currently allowed.)
|
||||
* `[ab]` matches `a` or `b` where `a` and `b` are characters. Use
|
||||
`[!ab]` to match any character except for `a` and `b`.
|
||||
* Metacharacters such as `*` and `?` can be escaped with character class
|
||||
notation. e.g., `[*]` matches `*`.
|
||||
|
||||
A `GlobBuilder` can be used to prevent wildcards from matching path separators,
|
||||
or to enable case insensitive matching.
|
||||
*/
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
extern crate aho_corasick;
|
||||
extern crate fnv;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate memchr;
|
||||
extern crate regex;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::error::Error as StdError;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
|
||||
use aho_corasick::{Automaton, AcAutomaton, FullAcAutomaton};
|
||||
use regex::bytes::{Regex, RegexBuilder, RegexSet};
|
||||
|
||||
use pathutil::{
|
||||
file_name, file_name_ext, normalize_path, os_str_bytes, path_bytes,
|
||||
};
|
||||
use glob::MatchStrategy;
|
||||
pub use glob::{Glob, GlobBuilder, GlobMatcher};
|
||||
|
||||
mod glob;
|
||||
mod pathutil;
|
||||
|
||||
/// Represents an error that can occur when parsing a glob pattern.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
/// Occurs when a use of `**` is invalid. Namely, `**` can only appear
|
||||
/// adjacent to a path separator, or the beginning/end of a glob.
|
||||
InvalidRecursive,
|
||||
/// Occurs when a character class (e.g., `[abc]`) is not closed.
|
||||
UnclosedClass,
|
||||
/// Occurs when a range in a character (e.g., `[a-z]`) is invalid. For
|
||||
/// example, if the range starts with a lexicographically larger character
|
||||
/// than it ends with.
|
||||
InvalidRange(char, char),
|
||||
/// Occurs when a `}` is found without a matching `{`.
|
||||
UnopenedAlternates,
|
||||
/// Occurs when a `{` is found without a matching `}`.
|
||||
UnclosedAlternates,
|
||||
/// Occurs when an alternating group is nested inside another alternating
|
||||
/// group, e.g., `{{a,b},{c,d}}`.
|
||||
NestedAlternates,
|
||||
/// An error associated with parsing or compiling a regex.
|
||||
Regex(String),
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::InvalidRecursive => {
|
||||
"invalid use of **; must be one path component"
|
||||
}
|
||||
Error::UnclosedClass => {
|
||||
"unclosed character class; missing ']'"
|
||||
}
|
||||
Error::InvalidRange(_, _) => {
|
||||
"invalid character range"
|
||||
}
|
||||
Error::UnopenedAlternates => {
|
||||
"unopened alternate group; missing '{' \
|
||||
(maybe escape '}' with '[}]'?)"
|
||||
}
|
||||
Error::UnclosedAlternates => {
|
||||
"unclosed alternate group; missing '}' \
|
||||
(maybe escape '{' with '[{]'?)"
|
||||
}
|
||||
Error::NestedAlternates => {
|
||||
"nested alternate groups are not allowed"
|
||||
}
|
||||
Error::Regex(ref err) => err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::InvalidRecursive
|
||||
| Error::UnclosedClass
|
||||
| Error::UnopenedAlternates
|
||||
| Error::UnclosedAlternates
|
||||
| Error::NestedAlternates
|
||||
| Error::Regex(_) => {
|
||||
write!(f, "{}", self.description())
|
||||
}
|
||||
Error::InvalidRange(s, e) => {
|
||||
write!(f, "invalid range; '{}' > '{}'", s, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_regex(pat: &str) -> Result<Regex, Error> {
|
||||
RegexBuilder::new(pat)
|
||||
.dot_matches_new_line(true)
|
||||
.size_limit(10 * (1 << 20))
|
||||
.dfa_size_limit(10 * (1 << 20))
|
||||
.build()
|
||||
.map_err(|err| Error::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()))
|
||||
}
|
||||
|
||||
type Fnv = hash::BuildHasherDefault<fnv::FnvHasher>;
|
||||
|
||||
/// GlobSet represents a group of globs that can be matched together in a
|
||||
/// single pass.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GlobSet {
|
||||
len: usize,
|
||||
strats: Vec<GlobSetMatchStrategy>,
|
||||
}
|
||||
|
||||
impl GlobSet {
|
||||
/// Returns true if this set is empty, and therefore matches nothing.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len == 0
|
||||
}
|
||||
|
||||
/// Returns the number of globs in this set.
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
/// Returns true if any glob in this set matches the path given.
|
||||
pub fn is_match<P: AsRef<Path>>(&self, path: P) -> bool {
|
||||
self.is_match_candidate(&Candidate::new(path.as_ref()))
|
||||
}
|
||||
|
||||
/// Returns true if any glob in this set matches the path given.
|
||||
///
|
||||
/// This takes a Candidate as input, which can be used to amortize the
|
||||
/// cost of preparing a path for matching.
|
||||
pub fn is_match_candidate(&self, path: &Candidate) -> bool {
|
||||
if self.is_empty() {
|
||||
return false;
|
||||
}
|
||||
for strat in &self.strats {
|
||||
if strat.is_match(path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns the sequence number of every glob pattern that matches the
|
||||
/// given path.
|
||||
pub fn matches<P: AsRef<Path>>(&self, path: P) -> Vec<usize> {
|
||||
self.matches_candidate(&Candidate::new(path.as_ref()))
|
||||
}
|
||||
|
||||
/// Returns the sequence number of every glob pattern that matches the
|
||||
/// given path.
|
||||
///
|
||||
/// This takes a Candidate as input, which can be used to amortize the
|
||||
/// cost of preparing a path for matching.
|
||||
pub fn matches_candidate(&self, path: &Candidate) -> Vec<usize> {
|
||||
let mut into = vec![];
|
||||
if self.is_empty() {
|
||||
return into;
|
||||
}
|
||||
self.matches_candidate_into(path, &mut into);
|
||||
into
|
||||
}
|
||||
|
||||
/// Adds the sequence number of every glob pattern that matches the given
|
||||
/// path to the vec given.
|
||||
///
|
||||
/// `into` is is cleared before matching begins, and contains the set of
|
||||
/// sequence numbers (in ascending order) after matching ends. If no globs
|
||||
/// were matched, then `into` will be empty.
|
||||
pub fn matches_into<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
into: &mut Vec<usize>,
|
||||
) {
|
||||
self.matches_candidate_into(&Candidate::new(path.as_ref()), into);
|
||||
}
|
||||
|
||||
/// Adds the sequence number of every glob pattern that matches the given
|
||||
/// path to the vec given.
|
||||
///
|
||||
/// `into` is is cleared before matching begins, and contains the set of
|
||||
/// sequence numbers (in ascending order) after matching ends. If no globs
|
||||
/// were matched, then `into` will be empty.
|
||||
///
|
||||
/// This takes a Candidate as input, which can be used to amortize the
|
||||
/// cost of preparing a path for matching.
|
||||
pub fn matches_candidate_into(
|
||||
&self,
|
||||
path: &Candidate,
|
||||
into: &mut Vec<usize>,
|
||||
) {
|
||||
into.clear();
|
||||
if self.is_empty() {
|
||||
return;
|
||||
}
|
||||
for strat in &self.strats {
|
||||
strat.matches_into(path, into);
|
||||
}
|
||||
into.sort();
|
||||
into.dedup();
|
||||
}
|
||||
|
||||
fn new(pats: &[Glob]) -> Result<GlobSet, Error> {
|
||||
if pats.is_empty() {
|
||||
return Ok(GlobSet { len: 0, strats: vec![] });
|
||||
}
|
||||
let mut lits = LiteralStrategy::new();
|
||||
let mut base_lits = BasenameLiteralStrategy::new();
|
||||
let mut exts = ExtensionStrategy::new();
|
||||
let mut prefixes = MultiStrategyBuilder::new();
|
||||
let mut suffixes = MultiStrategyBuilder::new();
|
||||
let mut required_exts = RequiredExtensionStrategyBuilder::new();
|
||||
let mut regexes = MultiStrategyBuilder::new();
|
||||
for (i, p) in pats.iter().enumerate() {
|
||||
match MatchStrategy::new(p) {
|
||||
MatchStrategy::Literal(lit) => {
|
||||
lits.add(i, lit);
|
||||
}
|
||||
MatchStrategy::BasenameLiteral(lit) => {
|
||||
base_lits.add(i, lit);
|
||||
}
|
||||
MatchStrategy::Extension(ext) => {
|
||||
exts.add(i, ext);
|
||||
}
|
||||
MatchStrategy::Prefix(prefix) => {
|
||||
prefixes.add(i, prefix);
|
||||
}
|
||||
MatchStrategy::Suffix { suffix, component } => {
|
||||
if component {
|
||||
lits.add(i, suffix[1..].to_string());
|
||||
}
|
||||
suffixes.add(i, suffix);
|
||||
}
|
||||
MatchStrategy::RequiredExtension(ext) => {
|
||||
required_exts.add(i, ext, p.regex().to_owned());
|
||||
}
|
||||
MatchStrategy::Regex => {
|
||||
debug!("glob converted to regex: {:?}", p);
|
||||
regexes.add(i, p.regex().to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("built glob set; {} literals, {} basenames, {} extensions, \
|
||||
{} prefixes, {} suffixes, {} required extensions, {} regexes",
|
||||
lits.0.len(), base_lits.0.len(), exts.0.len(),
|
||||
prefixes.literals.len(), suffixes.literals.len(),
|
||||
required_exts.0.len(), regexes.literals.len());
|
||||
Ok(GlobSet {
|
||||
len: pats.len(),
|
||||
strats: vec![
|
||||
GlobSetMatchStrategy::Extension(exts),
|
||||
GlobSetMatchStrategy::BasenameLiteral(base_lits),
|
||||
GlobSetMatchStrategy::Literal(lits),
|
||||
GlobSetMatchStrategy::Suffix(suffixes.suffix()),
|
||||
GlobSetMatchStrategy::Prefix(prefixes.prefix()),
|
||||
GlobSetMatchStrategy::RequiredExtension(
|
||||
try!(required_exts.build())),
|
||||
GlobSetMatchStrategy::Regex(try!(regexes.regex_set())),
|
||||
],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// GlobSetBuilder builds a group of patterns that can be used to
|
||||
/// simultaneously match a file path.
|
||||
pub struct GlobSetBuilder {
|
||||
pats: Vec<Glob>,
|
||||
}
|
||||
|
||||
impl GlobSetBuilder {
|
||||
/// Create a new GlobSetBuilder. A GlobSetBuilder can be used to add new
|
||||
/// patterns. Once all patterns have been added, `build` should be called
|
||||
/// to produce a `GlobSet`, which can then be used for matching.
|
||||
pub fn new() -> GlobSetBuilder {
|
||||
GlobSetBuilder { pats: vec![] }
|
||||
}
|
||||
|
||||
/// Builds a new matcher from all of the glob patterns added so far.
|
||||
///
|
||||
/// Once a matcher is built, no new patterns can be added to it.
|
||||
pub fn build(&self) -> Result<GlobSet, Error> {
|
||||
GlobSet::new(&self.pats)
|
||||
}
|
||||
|
||||
/// Add a new pattern to this set.
|
||||
#[allow(dead_code)]
|
||||
pub fn add(&mut self, pat: Glob) -> &mut GlobSetBuilder {
|
||||
self.pats.push(pat);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A candidate path for matching.
|
||||
///
|
||||
/// All glob matching in this crate operates on `Candidate` values.
|
||||
/// Constructing candidates has a very small cost associated with it, so
|
||||
/// callers may find it beneficial to amortize that cost when matching a single
|
||||
/// path against multiple globs or sets of globs.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Candidate<'a> {
|
||||
path: Cow<'a, [u8]>,
|
||||
basename: Cow<'a, [u8]>,
|
||||
ext: &'a OsStr,
|
||||
}
|
||||
|
||||
impl<'a> Candidate<'a> {
|
||||
/// Create a new candidate for matching from the given path.
|
||||
pub fn new<P: AsRef<Path> + ?Sized>(path: &'a P) -> Candidate<'a> {
|
||||
let path = path.as_ref();
|
||||
let basename = file_name(path).unwrap_or(OsStr::new(""));
|
||||
Candidate {
|
||||
path: normalize_path(path_bytes(path)),
|
||||
basename: os_str_bytes(basename),
|
||||
ext: file_name_ext(basename).unwrap_or(OsStr::new("")),
|
||||
}
|
||||
}
|
||||
|
||||
fn path_prefix(&self, max: usize) -> &[u8] {
|
||||
if self.path.len() <= max {
|
||||
&*self.path
|
||||
} else {
|
||||
&self.path[..max]
|
||||
}
|
||||
}
|
||||
|
||||
fn path_suffix(&self, max: usize) -> &[u8] {
|
||||
if self.path.len() <= max {
|
||||
&*self.path
|
||||
} else {
|
||||
&self.path[self.path.len() - max..]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum GlobSetMatchStrategy {
|
||||
Literal(LiteralStrategy),
|
||||
BasenameLiteral(BasenameLiteralStrategy),
|
||||
Extension(ExtensionStrategy),
|
||||
Prefix(PrefixStrategy),
|
||||
Suffix(SuffixStrategy),
|
||||
RequiredExtension(RequiredExtensionStrategy),
|
||||
Regex(RegexSetStrategy),
|
||||
}
|
||||
|
||||
impl GlobSetMatchStrategy {
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
use self::GlobSetMatchStrategy::*;
|
||||
match *self {
|
||||
Literal(ref s) => s.is_match(candidate),
|
||||
BasenameLiteral(ref s) => s.is_match(candidate),
|
||||
Extension(ref s) => s.is_match(candidate),
|
||||
Prefix(ref s) => s.is_match(candidate),
|
||||
Suffix(ref s) => s.is_match(candidate),
|
||||
RequiredExtension(ref s) => s.is_match(candidate),
|
||||
Regex(ref s) => s.is_match(candidate),
|
||||
}
|
||||
}
|
||||
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
use self::GlobSetMatchStrategy::*;
|
||||
match *self {
|
||||
Literal(ref s) => s.matches_into(candidate, matches),
|
||||
BasenameLiteral(ref s) => s.matches_into(candidate, matches),
|
||||
Extension(ref s) => s.matches_into(candidate, matches),
|
||||
Prefix(ref s) => s.matches_into(candidate, matches),
|
||||
Suffix(ref s) => s.matches_into(candidate, matches),
|
||||
RequiredExtension(ref s) => s.matches_into(candidate, matches),
|
||||
Regex(ref s) => s.matches_into(candidate, matches),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct LiteralStrategy(BTreeMap<Vec<u8>, Vec<usize>>);
|
||||
|
||||
impl LiteralStrategy {
|
||||
fn new() -> LiteralStrategy {
|
||||
LiteralStrategy(BTreeMap::new())
|
||||
}
|
||||
|
||||
fn add(&mut self, global_index: usize, lit: String) {
|
||||
self.0.entry(lit.into_bytes()).or_insert(vec![]).push(global_index);
|
||||
}
|
||||
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
self.0.contains_key(&*candidate.path)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
if let Some(hits) = self.0.get(&*candidate.path) {
|
||||
matches.extend(hits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct BasenameLiteralStrategy(BTreeMap<Vec<u8>, Vec<usize>>);
|
||||
|
||||
impl BasenameLiteralStrategy {
|
||||
fn new() -> BasenameLiteralStrategy {
|
||||
BasenameLiteralStrategy(BTreeMap::new())
|
||||
}
|
||||
|
||||
fn add(&mut self, global_index: usize, lit: String) {
|
||||
self.0.entry(lit.into_bytes()).or_insert(vec![]).push(global_index);
|
||||
}
|
||||
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
if candidate.basename.is_empty() {
|
||||
return false;
|
||||
}
|
||||
self.0.contains_key(&*candidate.basename)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
if candidate.basename.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(hits) = self.0.get(&*candidate.basename) {
|
||||
matches.extend(hits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ExtensionStrategy(HashMap<OsString, 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 is_match(&self, candidate: &Candidate) -> bool {
|
||||
if candidate.ext.is_empty() {
|
||||
return false;
|
||||
}
|
||||
self.0.contains_key(candidate.ext)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
if candidate.ext.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(hits) = self.0.get(candidate.ext) {
|
||||
matches.extend(hits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct PrefixStrategy {
|
||||
matcher: FullAcAutomaton<Vec<u8>>,
|
||||
map: Vec<usize>,
|
||||
longest: usize,
|
||||
}
|
||||
|
||||
impl PrefixStrategy {
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
let path = candidate.path_prefix(self.longest);
|
||||
for m in self.matcher.find_overlapping(path) {
|
||||
if m.start == 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
let path = candidate.path_prefix(self.longest);
|
||||
for m in self.matcher.find_overlapping(path) {
|
||||
if m.start == 0 {
|
||||
matches.push(self.map[m.pati]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct SuffixStrategy {
|
||||
matcher: FullAcAutomaton<Vec<u8>>,
|
||||
map: Vec<usize>,
|
||||
longest: usize,
|
||||
}
|
||||
|
||||
impl SuffixStrategy {
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
let path = candidate.path_suffix(self.longest);
|
||||
for m in self.matcher.find_overlapping(path) {
|
||||
if m.end == path.len() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
let path = candidate.path_suffix(self.longest);
|
||||
for m in self.matcher.find_overlapping(path) {
|
||||
if m.end == path.len() {
|
||||
matches.push(self.map[m.pati]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct RequiredExtensionStrategy(HashMap<OsString, 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) {
|
||||
None => false,
|
||||
Some(regexes) => {
|
||||
for &(_, ref re) in regexes {
|
||||
if re.is_match(&*candidate.path) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
if candidate.ext.is_empty() {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct RegexSetStrategy {
|
||||
matcher: RegexSet,
|
||||
map: Vec<usize>,
|
||||
}
|
||||
|
||||
impl RegexSetStrategy {
|
||||
fn is_match(&self, candidate: &Candidate) -> bool {
|
||||
self.matcher.is_match(&*candidate.path)
|
||||
}
|
||||
|
||||
fn matches_into(&self, candidate: &Candidate, matches: &mut Vec<usize>) {
|
||||
for i in self.matcher.matches(&*candidate.path) {
|
||||
matches.push(self.map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct MultiStrategyBuilder {
|
||||
literals: Vec<String>,
|
||||
map: Vec<usize>,
|
||||
longest: usize,
|
||||
}
|
||||
|
||||
impl MultiStrategyBuilder {
|
||||
fn new() -> MultiStrategyBuilder {
|
||||
MultiStrategyBuilder {
|
||||
literals: vec![],
|
||||
map: vec![],
|
||||
longest: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&mut self, global_index: usize, literal: String) {
|
||||
if literal.len() > self.longest {
|
||||
self.longest = literal.len();
|
||||
}
|
||||
self.map.push(global_index);
|
||||
self.literals.push(literal);
|
||||
}
|
||||
|
||||
fn prefix(self) -> PrefixStrategy {
|
||||
let it = self.literals.into_iter().map(|s| s.into_bytes());
|
||||
PrefixStrategy {
|
||||
matcher: AcAutomaton::new(it).into_full(),
|
||||
map: self.map,
|
||||
longest: self.longest,
|
||||
}
|
||||
}
|
||||
|
||||
fn suffix(self) -> SuffixStrategy {
|
||||
let it = self.literals.into_iter().map(|s| s.into_bytes());
|
||||
SuffixStrategy {
|
||||
matcher: AcAutomaton::new(it).into_full(),
|
||||
map: self.map,
|
||||
longest: self.longest,
|
||||
}
|
||||
}
|
||||
|
||||
fn regex_set(self) -> Result<RegexSetStrategy, Error> {
|
||||
Ok(RegexSetStrategy {
|
||||
matcher: try!(new_regex_set(self.literals)),
|
||||
map: self.map,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct RequiredExtensionStrategyBuilder(
|
||||
HashMap<OsString, Vec<(usize, String)>>,
|
||||
);
|
||||
|
||||
impl RequiredExtensionStrategyBuilder {
|
||||
fn new() -> 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 build(self) -> Result<RequiredExtensionStrategy, Error> {
|
||||
let mut exts = HashMap::with_hasher(Fnv::default());
|
||||
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));
|
||||
exts.get_mut(&ext).unwrap().push((global_index, compiled));
|
||||
}
|
||||
}
|
||||
Ok(RequiredExtensionStrategy(exts))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::GlobSetBuilder;
|
||||
use glob::Glob;
|
||||
|
||||
#[test]
|
||||
fn set_works() {
|
||||
let mut builder = GlobSetBuilder::new();
|
||||
builder.add(Glob::new("src/**/*.rs").unwrap());
|
||||
builder.add(Glob::new("*.c").unwrap());
|
||||
builder.add(Glob::new("src/lib.rs").unwrap());
|
||||
let set = builder.build().unwrap();
|
||||
|
||||
assert!(set.is_match("foo.c"));
|
||||
assert!(set.is_match("src/foo.c"));
|
||||
assert!(!set.is_match("foo.rs"));
|
||||
assert!(!set.is_match("tests/foo.rs"));
|
||||
assert!(set.is_match("src/foo.rs"));
|
||||
assert!(set.is_match("src/grep/src/main.rs"));
|
||||
|
||||
let matches = set.matches("src/lib.rs");
|
||||
assert_eq!(2, matches.len());
|
||||
assert_eq!(0, matches[0]);
|
||||
assert_eq!(2, matches[1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_set_works() {
|
||||
let set = GlobSetBuilder::new().build().unwrap();
|
||||
assert!(!set.is_match(""));
|
||||
assert!(!set.is_match("a"));
|
||||
}
|
||||
}
|
||||
178
globset/src/pathutil.rs
Normal file
178
globset/src/pathutil.rs
Normal file
@@ -0,0 +1,178 @@
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(unix)]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use memchr::memrchr;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
} else if path.len() == 1 && path[0] == b'.' {
|
||||
return None;
|
||||
} else if path.last() == Some(&b'.') {
|
||||
return None;
|
||||
} else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] {
|
||||
return None;
|
||||
}
|
||||
let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0);
|
||||
Some(OsStr::from_bytes(&path[last_slash..]))
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(not(unix))]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
path.as_ref().file_name()
|
||||
}
|
||||
|
||||
/// Return a file extension given a path's file name.
|
||||
///
|
||||
/// Note that this does NOT match the semantics of std::path::Path::extension.
|
||||
/// Namely, the extension includes the `.` and matching is otherwise more
|
||||
/// liberal. Specifically, the extenion is:
|
||||
///
|
||||
/// * None, if the file name given is empty;
|
||||
/// * None, if there is no embedded `.`;
|
||||
/// * Otherwise, the portion of the file name starting with the final `.`.
|
||||
///
|
||||
/// e.g., A file name of `.rs` has an extension `.rs`.
|
||||
///
|
||||
/// N.B. This is done to make certain glob match optimizations easier. Namely,
|
||||
/// 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)
|
||||
}
|
||||
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..]) });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Return raw bytes of a path, transcoded to UTF-8 if necessary.
|
||||
pub fn path_bytes(path: &Path) -> Cow<[u8]> {
|
||||
os_str_bytes(path.as_os_str())
|
||||
}
|
||||
|
||||
/// Return the raw bytes of the given OS string, possibly transcoded to UTF-8.
|
||||
#[cfg(unix)]
|
||||
pub fn os_str_bytes(s: &OsStr) -> Cow<[u8]> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
Cow::Borrowed(s.as_bytes())
|
||||
}
|
||||
|
||||
/// Return the raw bytes of the given OS string, possibly transcoded to UTF-8.
|
||||
#[cfg(not(unix))]
|
||||
pub fn os_str_bytes(s: &OsStr) -> Cow<[u8]> {
|
||||
// TODO(burntsushi): On Windows, OS strings are WTF-8, which is a superset
|
||||
// of UTF-8, so even if we could get at the raw bytes, they wouldn't
|
||||
// be useful. We *must* convert to UTF-8 before doing path matching.
|
||||
// Unfortunate, but necessary.
|
||||
match s.to_string_lossy() {
|
||||
Cow::Owned(s) => Cow::Owned(s.into_bytes()),
|
||||
Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizes a path to use `/` as a separator everywhere, even on platforms
|
||||
/// that recognize other characters as separators.
|
||||
#[cfg(unix)]
|
||||
pub fn normalize_path(path: Cow<[u8]>) -> Cow<[u8]> {
|
||||
// UNIX only uses /, so we're good.
|
||||
path
|
||||
}
|
||||
|
||||
/// Normalizes a path to use `/` as a separator everywhere, even on platforms
|
||||
/// that recognize other characters as separators.
|
||||
#[cfg(not(unix))]
|
||||
pub fn normalize_path(mut path: Cow<[u8]>) -> Cow<[u8]> {
|
||||
use std::path::is_separator;
|
||||
|
||||
for i in 0..path.len() {
|
||||
if path[i] == b'/' || !is_separator(path[i] as char) {
|
||||
continue;
|
||||
}
|
||||
path.to_mut()[i] = b'/';
|
||||
}
|
||||
path
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
use super::{file_name_ext, normalize_path};
|
||||
|
||||
macro_rules! ext {
|
||||
($name:ident, $file_name:expr, $ext:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let got = file_name_ext(OsStr::new($file_name));
|
||||
assert_eq!($ext.map(OsStr::new), got);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ext!(ext1, "foo.rs", Some(".rs"));
|
||||
ext!(ext2, ".rs", Some(".rs"));
|
||||
ext!(ext3, "..rs", Some(".rs"));
|
||||
ext!(ext4, "", None::<&str>);
|
||||
ext!(ext5, "foo", None::<&str>);
|
||||
|
||||
macro_rules! normalize {
|
||||
($name:ident, $path:expr, $expected:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let got = normalize_path(Cow::Owned($path.to_vec()));
|
||||
assert_eq!($expected.to_vec(), got.into_owned());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
normalize!(normal1, b"foo", b"foo");
|
||||
normalize!(normal2, b"foo/bar", b"foo/bar");
|
||||
#[cfg(unix)]
|
||||
normalize!(normal3, b"foo\\bar", b"foo\\bar");
|
||||
#[cfg(not(unix))]
|
||||
normalize!(normal3, b"foo\\bar", b"foo/bar");
|
||||
#[cfg(unix)]
|
||||
normalize!(normal4, b"foo\\bar/baz", b"foo\\bar/baz");
|
||||
#[cfg(not(unix))]
|
||||
normalize!(normal4, b"foo\\bar/baz", b"foo/bar/baz");
|
||||
}
|
||||
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.1" #:version
|
||||
version = "0.1.6" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Fast line oriented regex searching as a library.
|
||||
@@ -14,7 +14,6 @@ license = "Unlicense/MIT"
|
||||
|
||||
[dependencies]
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.2"
|
||||
regex = "0.1.76"
|
||||
regex-syntax = "0.3.5"
|
||||
memchr = "1"
|
||||
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/>
|
||||
@@ -19,6 +19,7 @@ pub use search::{Grep, GrepBuilder, Iter, Match};
|
||||
mod literals;
|
||||
mod nonl;
|
||||
mod search;
|
||||
mod word_boundary;
|
||||
|
||||
/// Result is a convenient type alias that fixes the type of the error to
|
||||
/// the `Error` type defined in this crate.
|
||||
@@ -77,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()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ Note that this implementation is incredibly suspicious. We need something more
|
||||
principled.
|
||||
*/
|
||||
use std::cmp;
|
||||
use std::iter;
|
||||
|
||||
use regex::bytes::Regex;
|
||||
use regex::bytes::RegexBuilder;
|
||||
use syntax::{
|
||||
Expr, Literals, Lit,
|
||||
ByteClass, ByteRange, CharClass, ClassRange, Repeater,
|
||||
@@ -34,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.
|
||||
@@ -80,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,8 +182,6 @@ fn repeat_range_literals<F: FnMut(&Expr, &mut Literals)>(
|
||||
lits: &mut Literals,
|
||||
mut f: F,
|
||||
) {
|
||||
use syntax::Expr::*;
|
||||
|
||||
if min == 0 {
|
||||
// This is a bit conservative. If `max` is set, then we could
|
||||
// treat this as a finite set of alternations. For now, we
|
||||
@@ -190,8 +189,12 @@ fn repeat_range_literals<F: FnMut(&Expr, &mut Literals)>(
|
||||
lits.cut();
|
||||
} else {
|
||||
let n = cmp::min(lits.limit_size(), min as usize);
|
||||
let es = iter::repeat(e.clone()).take(n).collect();
|
||||
f(&Concat(es), lits);
|
||||
// We only extract literals from a single repetition, even though
|
||||
// we could do more. e.g., `a{3}` will have `a` extracted instead of
|
||||
// `aaa`. The reason is that inner literal extraction can't be unioned
|
||||
// across repetitions. e.g., extracting `foofoofoo` from `(\w+foo){3}`
|
||||
// is wrong.
|
||||
f(e, lits);
|
||||
if n < min as usize {
|
||||
lits.cut();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ use syntax;
|
||||
|
||||
use literals::LiteralSets;
|
||||
use nonl;
|
||||
use syntax::Expr;
|
||||
use word_boundary::strip_unicode_word_boundaries;
|
||||
use Result;
|
||||
|
||||
/// A matched line.
|
||||
@@ -50,6 +52,7 @@ pub struct GrepBuilder {
|
||||
#[derive(Clone, Debug)]
|
||||
struct Options {
|
||||
case_insensitive: bool,
|
||||
case_smart: bool,
|
||||
line_terminator: u8,
|
||||
size_limit: usize,
|
||||
dfa_size_limit: usize,
|
||||
@@ -59,6 +62,7 @@ impl Default for Options {
|
||||
fn default() -> Options {
|
||||
Options {
|
||||
case_insensitive: false,
|
||||
case_smart: false,
|
||||
line_terminator: b'\n',
|
||||
size_limit: 10 * (1 << 20),
|
||||
dfa_size_limit: 10 * (1 << 20),
|
||||
@@ -96,6 +100,18 @@ impl GrepBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// Enabling the case_insensitive flag overrides this.
|
||||
pub fn case_smart(mut self, yes: bool) -> GrepBuilder {
|
||||
self.opts.case_smart = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the approximate size limit of the compiled regular expression.
|
||||
///
|
||||
/// This roughly corresponds to the number of bytes occupied by a
|
||||
@@ -127,22 +143,45 @@ impl GrepBuilder {
|
||||
pub fn build(self) -> Result<Grep> {
|
||||
let expr = try!(self.parse());
|
||||
let literals = LiteralSets::create(&expr);
|
||||
let re = try!(
|
||||
RegexBuilder::new(&expr.to_string())
|
||||
.case_insensitive(self.opts.case_insensitive)
|
||||
.multi_line(true)
|
||||
.unicode(true)
|
||||
.size_limit(self.opts.size_limit)
|
||||
.dfa_size_limit(self.opts.dfa_size_limit)
|
||||
.compile()
|
||||
);
|
||||
let re = try!(self.regex(&expr));
|
||||
let required = match literals.to_regex_builder() {
|
||||
Some(builder) => Some(try!(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: literals.to_regex(),
|
||||
required: required,
|
||||
opts: self.opts,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a new regex from the given expression with the current
|
||||
/// configuration.
|
||||
fn regex(&self, expr: &Expr) -> Result<Regex> {
|
||||
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)
|
||||
.size_limit(self.opts.size_limit)
|
||||
.dfa_size_limit(self.opts.dfa_size_limit)
|
||||
.build()
|
||||
.map_err(From::from)
|
||||
}
|
||||
|
||||
/// Parses the underlying pattern and ensures the pattern can never match
|
||||
/// the line terminator.
|
||||
fn parse(&self) -> Result<syntax::Expr> {
|
||||
@@ -150,10 +189,29 @@ impl GrepBuilder {
|
||||
try!(syntax::ExprBuilder::new()
|
||||
.allow_bytes(true)
|
||||
.unicode(true)
|
||||
.case_insensitive(self.opts.case_insensitive)
|
||||
.case_insensitive(try!(self.is_case_insensitive()))
|
||||
.parse(&self.pattern));
|
||||
let expr = try!(nonl::remove(expr, self.opts.line_terminator));
|
||||
debug!("regex ast:\n{:#?}", expr);
|
||||
Ok(try!(nonl::remove(expr, self.opts.line_terminator)))
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Determines whether the case insensitive flag should be enabled or not.
|
||||
///
|
||||
/// An error is returned if the regex could not be parsed.
|
||||
fn is_case_insensitive(&self) -> Result<bool> {
|
||||
if self.opts.case_insensitive {
|
||||
return Ok(true);
|
||||
}
|
||||
if !self.opts.case_smart {
|
||||
return Ok(false);
|
||||
}
|
||||
let expr =
|
||||
try!(syntax::ExprBuilder::new()
|
||||
.allow_bytes(true)
|
||||
.unicode(true)
|
||||
.parse(&self.pattern));
|
||||
Ok(!has_uppercase_literal(&expr))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +317,40 @@ impl<'b, 's> Iterator for Iter<'b, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_uppercase_literal(expr: &Expr) -> bool {
|
||||
use syntax::Expr::*;
|
||||
fn byte_is_upper(b: u8) -> bool { b'A' <= b && b <= b'Z' }
|
||||
match *expr {
|
||||
Literal { ref chars, casei } => {
|
||||
casei || chars.iter().any(|c| c.is_uppercase())
|
||||
}
|
||||
LiteralBytes { ref bytes, casei } => {
|
||||
casei || bytes.iter().any(|&b| byte_is_upper(b))
|
||||
}
|
||||
Class(ref ranges) => {
|
||||
for r in ranges {
|
||||
if r.start.is_uppercase() || r.end.is_uppercase() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
ClassBytes(ref ranges) => {
|
||||
for r in ranges {
|
||||
if byte_is_upper(r.start) || byte_is_upper(r.end) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(unused_imports)]
|
||||
@@ -278,11 +370,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,
|
||||
|
||||
54
grep/src/word_boundary.rs
Normal file
54
grep/src/word_boundary.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use syntax::Expr;
|
||||
|
||||
/// Strips Unicode word boundaries from the given expression.
|
||||
///
|
||||
/// The key invariant this maintains is that the expression returned will match
|
||||
/// *at least* every where the expression given will match. Namely, a match of
|
||||
/// the returned expression can report false positives but it will never report
|
||||
/// false negatives.
|
||||
///
|
||||
/// If no word boundaries could be stripped, then None is returned.
|
||||
pub fn strip_unicode_word_boundaries(expr: &Expr) -> Option<Expr> {
|
||||
// The real reason we do this is because Unicode word boundaries are the
|
||||
// one thing that Rust's regex DFA engine can't handle. When it sees a
|
||||
// Unicode word boundary among non-ASCII text, it falls back to one of the
|
||||
// slower engines. We work around this limitation by attempting to use
|
||||
// a regex to find candidate matches without a Unicode word boundary. We'll
|
||||
// only then use the full (and slower) regex to confirm a candidate as a
|
||||
// match or not during search.
|
||||
use syntax::Expr::*;
|
||||
|
||||
match *expr {
|
||||
Concat(ref es) if !es.is_empty() => {
|
||||
let first = is_unicode_word_boundary(&es[0]);
|
||||
let last = is_unicode_word_boundary(es.last().unwrap());
|
||||
// Be careful not to strip word boundaries if there are no other
|
||||
// expressions to match.
|
||||
match (first, last) {
|
||||
(true, false) if es.len() > 1 => {
|
||||
Some(Concat(es[1..].to_vec()))
|
||||
}
|
||||
(false, true) if es.len() > 1 => {
|
||||
Some(Concat(es[..es.len() - 1].to_vec()))
|
||||
}
|
||||
(true, true) if es.len() > 2 => {
|
||||
Some(Concat(es[1..es.len() - 1].to_vec()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given expression is a Unicode word boundary.
|
||||
fn is_unicode_word_boundary(expr: &Expr) -> bool {
|
||||
use syntax::Expr::*;
|
||||
|
||||
match *expr {
|
||||
WordBoundary => true,
|
||||
NotWordBoundary => true,
|
||||
Group { ref e, .. } => is_unicode_word_boundary(e),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
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.
|
||||
37
ignore/Cargo.toml
Normal file
37
ignore/Cargo.toml
Normal file
@@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "ignore"
|
||||
version = "0.1.9" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
A fast library for efficiently matching ignore files such as `.gitignore`
|
||||
against file paths.
|
||||
"""
|
||||
documentation = "https://docs.rs/ignore"
|
||||
homepage = "https://github.com/BurntSushi/ripgrep/tree/master/ignore"
|
||||
repository = "https://github.com/BurntSushi/ripgrep/tree/master/ignore"
|
||||
readme = "README.md"
|
||||
keywords = ["glob", "ignore", "gitignore", "pattern", "file"]
|
||||
license = "Unlicense/MIT"
|
||||
|
||||
[lib]
|
||||
name = "ignore"
|
||||
bench = false
|
||||
|
||||
[dependencies]
|
||||
crossbeam = "0.2"
|
||||
globset = { version = "0.1.4", path = "../globset" }
|
||||
lazy_static = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "1"
|
||||
regex = "0.2.1"
|
||||
thread_local = "0.3.2"
|
||||
walkdir = "1.0.7"
|
||||
|
||||
[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.
|
||||
66
ignore/README.md
Normal file
66
ignore/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
ignore
|
||||
======
|
||||
The ignore crate provides a fast recursive directory iterator that respects
|
||||
various filters such as globs, file types and `.gitignore` files. This crate
|
||||
also provides lower level direct access to gitignore and file type matchers.
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
[](https://crates.io/crates/ignore)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
### Documentation
|
||||
|
||||
[https://docs.rs/ignore](https://docs.rs/ignore)
|
||||
|
||||
### Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ignore = "0.1"
|
||||
```
|
||||
|
||||
and this to your crate root:
|
||||
|
||||
```rust
|
||||
extern crate ignore;
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
This example shows the most basic usage of this crate. This code will
|
||||
recursively traverse the current directory while automatically filtering out
|
||||
files and directories according to ignore globs found in files like
|
||||
`.ignore` and `.gitignore`:
|
||||
|
||||
|
||||
```rust,no_run
|
||||
use ignore::Walk;
|
||||
|
||||
for result in Walk::new("./") {
|
||||
// Each item yielded by the iterator is either a directory entry or an
|
||||
// error, so either print the path or the error.
|
||||
match result {
|
||||
Ok(entry) => println!("{}", entry.path().display()),
|
||||
Err(err) => println!("ERROR: {}", err),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example: advanced
|
||||
|
||||
By default, the recursive directory iterator will ignore hidden files and
|
||||
directories. This can be disabled by building the iterator with `WalkBuilder`:
|
||||
|
||||
```rust,no_run
|
||||
use ignore::WalkBuilder;
|
||||
|
||||
for result in WalkBuilder::new("./").hidden(false).build() {
|
||||
println!("{:?}", result);
|
||||
}
|
||||
```
|
||||
|
||||
See the documentation for `WalkBuilder` for many other options.
|
||||
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/>
|
||||
92
ignore/examples/walk.rs
Normal file
92
ignore/examples/walk.rs
Normal file
@@ -0,0 +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::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::thread;
|
||||
|
||||
use crossbeam::sync::MsQueue;
|
||||
use ignore::WalkBuilder;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
fn main() {
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
800
ignore/src/dir.rs
Normal file
800
ignore/src/dir.rs
Normal file
@@ -0,0 +1,800 @@
|
||||
// This module provides a data structure, `Ignore`, that connects "directory
|
||||
// traversal" with "ignore matchers." Specifically, it knows about gitignore
|
||||
// semantics and precedence, and is organized based on directory hierarchy.
|
||||
// Namely, every matcher logically corresponds to ignore rules from a single
|
||||
// directory, and points to the matcher for its corresponding parent directory.
|
||||
// In this sense, `Ignore` is a *persistent* data structure.
|
||||
//
|
||||
// This design was specifically chosen to make it possible to use this data
|
||||
// structure in a parallel directory iterator.
|
||||
//
|
||||
// My initial intention was to expose this module as part of this crate's
|
||||
// public API, but I think the data structure's public API is too complicated
|
||||
// with non-obvious failure modes. Alas, such things haven't been documented
|
||||
// well.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use gitignore::{self, Gitignore, GitignoreBuilder};
|
||||
use pathutil::{is_hidden, strip_prefix};
|
||||
use overrides::{self, Override};
|
||||
use types::{self, Types};
|
||||
use {Error, Match, PartialErrorBuilder};
|
||||
|
||||
/// IgnoreMatch represents information about where a match came from when using
|
||||
/// the `Ignore` matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IgnoreMatch<'a>(IgnoreMatchInner<'a>);
|
||||
|
||||
/// IgnoreMatchInner describes precisely where the match information came from.
|
||||
/// This is private to allow expansion to more matchers in the future.
|
||||
#[derive(Clone, Debug)]
|
||||
enum IgnoreMatchInner<'a> {
|
||||
Override(overrides::Glob<'a>),
|
||||
Gitignore(&'a gitignore::Glob),
|
||||
Types(types::Glob<'a>),
|
||||
Hidden,
|
||||
}
|
||||
|
||||
impl<'a> IgnoreMatch<'a> {
|
||||
fn overrides(x: overrides::Glob<'a>) -> IgnoreMatch<'a> {
|
||||
IgnoreMatch(IgnoreMatchInner::Override(x))
|
||||
}
|
||||
|
||||
fn gitignore(x: &'a gitignore::Glob) -> IgnoreMatch<'a> {
|
||||
IgnoreMatch(IgnoreMatchInner::Gitignore(x))
|
||||
}
|
||||
|
||||
fn types(x: types::Glob<'a>) -> IgnoreMatch<'a> {
|
||||
IgnoreMatch(IgnoreMatchInner::Types(x))
|
||||
}
|
||||
|
||||
fn hidden() -> IgnoreMatch<'static> {
|
||||
IgnoreMatch(IgnoreMatchInner::Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for the ignore matcher, shared between the matcher itself and the
|
||||
/// builder.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct IgnoreOptions {
|
||||
/// Whether to ignore hidden file paths or not.
|
||||
hidden: bool,
|
||||
/// Whether to read .ignore files.
|
||||
ignore: bool,
|
||||
/// Whether to read git's global gitignore file.
|
||||
git_global: bool,
|
||||
/// Whether to read .gitignore files.
|
||||
git_ignore: bool,
|
||||
/// Whether to read .git/info/exclude files.
|
||||
git_exclude: bool,
|
||||
}
|
||||
|
||||
impl IgnoreOptions {
|
||||
/// Returns true if at least one type of ignore rules should be matched.
|
||||
fn has_any_ignore_options(&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>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct IgnoreInner {
|
||||
/// A map of all existing directories that have already been
|
||||
/// compiled into matchers.
|
||||
///
|
||||
/// Note that this is never used during matching, only when adding new
|
||||
/// parent directory matchers. This avoids needing to rebuild glob sets for
|
||||
/// parent directories if many paths are being searched.
|
||||
compiled: Arc<RwLock<HashMap<OsString, Ignore>>>,
|
||||
/// The path to the directory that this matcher was built from.
|
||||
dir: PathBuf,
|
||||
/// An override matcher (default is empty).
|
||||
overrides: Arc<Override>,
|
||||
/// A file type matcher.
|
||||
types: Arc<Types>,
|
||||
/// The parent directory to match next.
|
||||
///
|
||||
/// If this is the root directory or there are otherwise no more
|
||||
/// directories to match, then `parent` is `None`.
|
||||
parent: Option<Ignore>,
|
||||
/// Whether this is an absolute parent matcher, as added by add_parent.
|
||||
is_absolute_parent: bool,
|
||||
/// 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_ignores: Arc<Vec<Gitignore>>,
|
||||
/// The matcher for .ignore files.
|
||||
ignore_matcher: Gitignore,
|
||||
/// A global gitignore matcher, usually from $XDG_CONFIG_HOME/git/ignore.
|
||||
git_global_matcher: Arc<Gitignore>,
|
||||
/// The matcher for .gitignore files.
|
||||
git_ignore_matcher: Gitignore,
|
||||
/// Special matcher for `.git/info/exclude` files.
|
||||
git_exclude_matcher: Gitignore,
|
||||
/// Whether this directory contains a .git sub-directory.
|
||||
has_git: bool,
|
||||
/// Ignore config.
|
||||
opts: IgnoreOptions,
|
||||
}
|
||||
|
||||
impl Ignore {
|
||||
/// Return the directory path of this matcher.
|
||||
#[allow(dead_code)]
|
||||
pub fn path(&self) -> &Path {
|
||||
&self.0.dir
|
||||
}
|
||||
|
||||
/// Return true if this matcher has no parent.
|
||||
pub fn is_root(&self) -> bool {
|
||||
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()
|
||||
}
|
||||
|
||||
/// Create a new `Ignore` matcher with the parent directories of `dir`.
|
||||
///
|
||||
/// Note that this can only be called on an `Ignore` matcher with no
|
||||
/// parents (i.e., `is_root` returns `true`). This will panic otherwise.
|
||||
pub fn add_parents<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
) -> (Ignore, Option<Error>) {
|
||||
if !self.is_root() {
|
||||
panic!("Ignore::add_parents called on non-root matcher");
|
||||
}
|
||||
let absolute_base = match path.as_ref().canonicalize() {
|
||||
Ok(path) => Arc::new(path),
|
||||
Err(_) => {
|
||||
// There's not much we can do here, so just return our
|
||||
// existing matcher. We drop the error to be consistent
|
||||
// with our general pattern of ignoring I/O errors when
|
||||
// processing ignore files.
|
||||
return (self.clone(), None);
|
||||
}
|
||||
};
|
||||
// List of parents, from child to root.
|
||||
let mut parents = vec![];
|
||||
let mut path = &**absolute_base;
|
||||
while let Some(parent) = path.parent() {
|
||||
parents.push(parent);
|
||||
path = parent;
|
||||
}
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
let mut ig = self.clone();
|
||||
for parent in parents.into_iter().rev() {
|
||||
let mut compiled = self.0.compiled.write().unwrap();
|
||||
if let Some(prebuilt) = compiled.get(parent.as_os_str()) {
|
||||
ig = prebuilt.clone();
|
||||
continue;
|
||||
}
|
||||
let (mut igtmp, err) = ig.add_child_path(parent);
|
||||
errs.maybe_push(err);
|
||||
igtmp.is_absolute_parent = true;
|
||||
igtmp.absolute_base = Some(absolute_base.clone());
|
||||
ig = Ignore(Arc::new(igtmp));
|
||||
compiled.insert(parent.as_os_str().to_os_string(), ig.clone());
|
||||
}
|
||||
(ig, errs.into_error_option())
|
||||
}
|
||||
|
||||
/// Create a new `Ignore` matcher for the given child directory.
|
||||
///
|
||||
/// Since building the matcher may require reading from multiple
|
||||
/// files, it's possible that this method partially succeeds. Therefore,
|
||||
/// a matcher is always returned (which may match nothing) and an error is
|
||||
/// returned if it exists.
|
||||
///
|
||||
/// Note that all I/O errors are completely ignored.
|
||||
pub fn add_child<P: AsRef<Path>>(
|
||||
&self,
|
||||
dir: P,
|
||||
) -> (Ignore, Option<Error>) {
|
||||
let (ig, err) = self.add_child_path(dir.as_ref());
|
||||
(Ignore(Arc::new(ig)), err)
|
||||
}
|
||||
|
||||
/// 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 ig_matcher =
|
||||
if !self.0.opts.ignore {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
let (m, err) = create_gitignore(&dir, IG_NAMES);
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
let gi_matcher =
|
||||
if !self.0.opts.git_ignore {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
let (m, err) = create_gitignore(&dir, &[".gitignore"]);
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
let gi_exclude_matcher =
|
||||
if !self.0.opts.git_exclude {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
let (m, err) = create_gitignore(&dir, &[".git/info/exclude"]);
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
let ig = IgnoreInner {
|
||||
compiled: self.0.compiled.clone(),
|
||||
dir: dir.to_path_buf(),
|
||||
overrides: self.0.overrides.clone(),
|
||||
types: self.0.types.clone(),
|
||||
parent: Some(self.clone()),
|
||||
is_absolute_parent: false,
|
||||
absolute_base: self.0.absolute_base.clone(),
|
||||
explicit_ignores: self.0.explicit_ignores.clone(),
|
||||
ignore_matcher: ig_matcher,
|
||||
git_global_matcher: self.0.git_global_matcher.clone(),
|
||||
git_ignore_matcher: gi_matcher,
|
||||
git_exclude_matcher: gi_exclude_matcher,
|
||||
has_git: dir.join(".git").is_dir(),
|
||||
opts: self.0.opts,
|
||||
};
|
||||
(ig, errs.into_error_option())
|
||||
}
|
||||
|
||||
/// Returns a match indicating whether the given file path should be
|
||||
/// ignored or not.
|
||||
///
|
||||
/// The match contains information about its origin.
|
||||
pub fn matched<'a, P: AsRef<Path>>(
|
||||
&'a self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<IgnoreMatch<'a>> {
|
||||
// We need to be careful with our path. If it has a leading ./, then
|
||||
// strip it because it causes nothing but trouble.
|
||||
let mut path = path.as_ref();
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
// Match against the override patterns. If an override matches
|
||||
// regardless of whether it's whitelist/ignore, then we quit and
|
||||
// return that result immediately. Overrides have the highest
|
||||
// precedence.
|
||||
if !self.0.overrides.is_empty() {
|
||||
let mat =
|
||||
self.0.overrides.matched(path, is_dir)
|
||||
.map(IgnoreMatch::overrides);
|
||||
if !mat.is_none() {
|
||||
return mat;
|
||||
}
|
||||
}
|
||||
let mut whitelisted = Match::None;
|
||||
if self.0.opts.has_any_ignore_options() {
|
||||
let mat = self.matched_ignore(path, is_dir);
|
||||
if mat.is_ignore() {
|
||||
return mat;
|
||||
} else if mat.is_whitelist() {
|
||||
whitelisted = mat;
|
||||
}
|
||||
}
|
||||
if !self.0.types.is_empty() {
|
||||
let mat =
|
||||
self.0.types.matched(path, is_dir).map(IgnoreMatch::types);
|
||||
if mat.is_ignore() {
|
||||
return mat;
|
||||
} else if mat.is_whitelist() {
|
||||
whitelisted = mat;
|
||||
}
|
||||
}
|
||||
if whitelisted.is_none() && self.0.opts.hidden && is_hidden(path) {
|
||||
return Match::Ignore(IgnoreMatch::hidden());
|
||||
}
|
||||
whitelisted
|
||||
}
|
||||
|
||||
/// Performs matching only on the ignore files for this directory and
|
||||
/// all parent directories.
|
||||
fn matched_ignore<'a>(
|
||||
&'a self,
|
||||
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 saw_git = false;
|
||||
for ig in self.parents().take_while(|ig| !ig.0.is_absolute_parent) {
|
||||
if m_ignore.is_none() {
|
||||
m_ignore =
|
||||
ig.0.ignore_matcher.matched(path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if !saw_git && m_gi.is_none() {
|
||||
m_gi =
|
||||
ig.0.git_ignore_matcher.matched(path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if !saw_git && m_gi_exclude.is_none() {
|
||||
m_gi_exclude =
|
||||
ig.0.git_exclude_matcher.matched(path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
saw_git = saw_git || ig.0.has_git;
|
||||
}
|
||||
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_ignore.is_none() {
|
||||
m_ignore =
|
||||
ig.0.ignore_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if !saw_git && m_gi.is_none() {
|
||||
m_gi =
|
||||
ig.0.git_ignore_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
if !saw_git && m_gi_exclude.is_none() {
|
||||
m_gi_exclude =
|
||||
ig.0.git_exclude_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
}
|
||||
saw_git = saw_git || ig.0.has_git;
|
||||
}
|
||||
}
|
||||
for gi in self.0.explicit_ignores.iter().rev() {
|
||||
if !m_explicit.is_none() {
|
||||
break;
|
||||
}
|
||||
m_explicit = gi.matched(&path, is_dir).map(IgnoreMatch::gitignore);
|
||||
}
|
||||
let m_global = self.0.git_global_matcher.matched(&path, is_dir)
|
||||
.map(IgnoreMatch::gitignore);
|
||||
|
||||
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.
|
||||
pub fn parents(&self) -> Parents {
|
||||
Parents(Some(self))
|
||||
}
|
||||
|
||||
/// Returns the first absolute path of the first absolute parent, if
|
||||
/// one exists.
|
||||
fn absolute_base(&self) -> Option<&Path> {
|
||||
self.0.absolute_base.as_ref().map(|p| &***p)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
fn next(&mut self) -> Option<&'a Ignore> {
|
||||
match self.0.take() {
|
||||
None => None,
|
||||
Some(ig) => {
|
||||
self.0 = ig.0.parent.as_ref();
|
||||
Some(ig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for creating an Ignore matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IgnoreBuilder {
|
||||
/// The root directory path for this ignore matcher.
|
||||
dir: PathBuf,
|
||||
/// An override matcher (default is empty).
|
||||
overrides: Arc<Override>,
|
||||
/// A type matcher (default is empty).
|
||||
types: Arc<Types>,
|
||||
/// Explicit ignore matchers.
|
||||
explicit_ignores: Vec<Gitignore>,
|
||||
/// Ignore config.
|
||||
opts: IgnoreOptions,
|
||||
}
|
||||
|
||||
impl IgnoreBuilder {
|
||||
/// Create a new builder for an `Ignore` matcher.
|
||||
///
|
||||
/// All relative file paths are resolved with respect to the current
|
||||
/// working directory.
|
||||
pub fn new() -> IgnoreBuilder {
|
||||
IgnoreBuilder {
|
||||
dir: Path::new("").to_path_buf(),
|
||||
overrides: Arc::new(Override::empty()),
|
||||
types: Arc::new(Types::empty()),
|
||||
explicit_ignores: vec![],
|
||||
opts: IgnoreOptions {
|
||||
hidden: true,
|
||||
ignore: true,
|
||||
git_global: true,
|
||||
git_ignore: true,
|
||||
git_exclude: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a new `Ignore` matcher.
|
||||
///
|
||||
/// The matcher returned won't match anything until ignore rules from
|
||||
/// directories are added to it.
|
||||
pub fn build(&self) -> Ignore {
|
||||
let git_global_matcher =
|
||||
if !self.opts.git_global {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
let (gi, err) = Gitignore::global();
|
||||
if let Some(err) = err {
|
||||
debug!("{}", err);
|
||||
}
|
||||
gi
|
||||
};
|
||||
Ignore(Arc::new(IgnoreInner {
|
||||
compiled: Arc::new(RwLock::new(HashMap::new())),
|
||||
dir: self.dir.clone(),
|
||||
overrides: self.overrides.clone(),
|
||||
types: self.types.clone(),
|
||||
parent: None,
|
||||
is_absolute_parent: true,
|
||||
absolute_base: None,
|
||||
explicit_ignores: Arc::new(self.explicit_ignores.clone()),
|
||||
ignore_matcher: Gitignore::empty(),
|
||||
git_global_matcher: Arc::new(git_global_matcher),
|
||||
git_ignore_matcher: Gitignore::empty(),
|
||||
git_exclude_matcher: Gitignore::empty(),
|
||||
has_git: false,
|
||||
opts: self.opts,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Add an override matcher.
|
||||
///
|
||||
/// By default, no override matcher is used.
|
||||
///
|
||||
/// This overrides any previous setting.
|
||||
pub fn overrides(&mut self, overrides: Override) -> &mut IgnoreBuilder {
|
||||
self.overrides = Arc::new(overrides);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a file type matcher.
|
||||
///
|
||||
/// By default, no file type matcher is used.
|
||||
///
|
||||
/// This overrides any previous setting.
|
||||
pub fn types(&mut self, types: Types) -> &mut IgnoreBuilder {
|
||||
self.types = Arc::new(types);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a new global ignore matcher from the ignore file path given.
|
||||
pub fn add_ignore(&mut self, ig: Gitignore) -> &mut IgnoreBuilder {
|
||||
self.explicit_ignores.push(ig);
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables ignoring hidden files.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
pub fn hidden(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||
self.opts.hidden = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables reading `.ignore` files.
|
||||
///
|
||||
/// `.ignore` files have the same semantics as `gitignore` files and are
|
||||
/// supported by search tools such as ripgrep and The Silver Searcher.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
pub fn ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||
self.opts.ignore = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a global gitignore matcher.
|
||||
///
|
||||
/// Its precedence is lower than both normal `.gitignore` files and
|
||||
/// `.git/info/exclude` files.
|
||||
///
|
||||
/// This overwrites any previous global gitignore setting.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
pub fn git_global(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||
self.opts.git_global = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables reading `.gitignore` files.
|
||||
///
|
||||
/// `.gitignore` files have match semantics as described in the `gitignore`
|
||||
/// man page.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
pub fn git_ignore(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||
self.opts.git_ignore = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables reading `.git/info/exclude` files.
|
||||
///
|
||||
/// `.git/info/exclude` files have match semantics as described in the
|
||||
/// `gitignore` man page.
|
||||
///
|
||||
/// This is enabled by default.
|
||||
pub fn git_exclude(&mut self, yes: bool) -> &mut IgnoreBuilder {
|
||||
self.opts.git_exclude = yes;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new gitignore matcher for the directory given.
|
||||
///
|
||||
/// Ignore globs are extracted from each of the file names in `dir` in the
|
||||
/// order given (earlier names have lower precedence than later names).
|
||||
///
|
||||
/// I/O errors are ignored.
|
||||
pub fn create_gitignore(
|
||||
dir: &Path,
|
||||
names: &[&str],
|
||||
) -> (Gitignore, Option<Error>) {
|
||||
let mut builder = GitignoreBuilder::new(dir);
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
for name in names {
|
||||
let gipath = dir.join(name);
|
||||
errs.maybe_push_ignore_io(builder.add(gipath));
|
||||
}
|
||||
let gi = match builder.build() {
|
||||
Ok(gi) => gi,
|
||||
Err(err) => {
|
||||
errs.push(err);
|
||||
GitignoreBuilder::new(dir).build().unwrap()
|
||||
}
|
||||
};
|
||||
(gi, errs.into_error_option())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use tempdir::TempDir;
|
||||
|
||||
use dir::IgnoreBuilder;
|
||||
use gitignore::Gitignore;
|
||||
use Error;
|
||||
|
||||
fn wfile<P: AsRef<Path>>(path: P, contents: &str) {
|
||||
let mut file = File::create(path).unwrap();
|
||||
file.write_all(contents.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn mkdirp<P: AsRef<Path>>(path: P) {
|
||||
fs::create_dir_all(path).unwrap();
|
||||
}
|
||||
|
||||
fn partial(err: Error) -> Vec<Error> {
|
||||
match err {
|
||||
Error::Partial(errs) => errs,
|
||||
_ => panic!("expected partial error but got {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_ignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join("not-an-ignore"), "foo\n!bar");
|
||||
|
||||
let (gi, err) = Gitignore::new(td.path().join("not-an-ignore"));
|
||||
assert!(err.is_none());
|
||||
let (ig, err) = IgnoreBuilder::new()
|
||||
.add_ignore(gi).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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn git_exclude() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
mkdirp(td.path().join(".git/info"));
|
||||
wfile(td.path().join(".git/info/exclude"), "foo\n!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "foo\n!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".ignore"), "foo\n!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().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 an .ignore will override a .gitignore.
|
||||
#[test]
|
||||
fn ignore_over_gitignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "foo");
|
||||
wfile(td.path().join(".ignore"), "!foo");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("foo", false).is_whitelist());
|
||||
}
|
||||
|
||||
// Tests that exclude has lower precedent than both .ignore and .gitignore.
|
||||
#[test]
|
||||
fn exclude_lowest() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "!foo");
|
||||
wfile(td.path().join(".ignore"), "!bar");
|
||||
mkdirp(td.path().join(".git/info"));
|
||||
wfile(td.path().join(".git/info/exclude"), "foo\nbar\nbaz");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("baz", false).is_ignore());
|
||||
assert!(ig.matched("foo", false).is_whitelist());
|
||||
assert!(ig.matched("bar", false).is_whitelist());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errored() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "f**oo");
|
||||
|
||||
let (_, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errored_both() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "f**oo");
|
||||
wfile(td.path().join(".ignore"), "fo**o");
|
||||
|
||||
let (_, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert_eq!(2, partial(err.expect("an error")).len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errored_partial() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "f**oo\nbar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_some());
|
||||
assert!(ig.matched("bar", false).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errored_partial_and_ignore() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
wfile(td.path().join(".gitignore"), "f**oo\nbar");
|
||||
wfile(td.path().join(".ignore"), "!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_some());
|
||||
assert!(ig.matched("bar", false).is_whitelist());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_present_empty() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
|
||||
let (_, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stops_at_git_dir() {
|
||||
// This tests that .gitignore files beyond a .git barrier aren't
|
||||
// matched, but .ignore files are.
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
mkdirp(td.path().join(".git"));
|
||||
mkdirp(td.path().join("foo/.git"));
|
||||
wfile(td.path().join(".gitignore"), "foo");
|
||||
wfile(td.path().join(".ignore"), "bar");
|
||||
|
||||
let ig0 = IgnoreBuilder::new().build();
|
||||
let (ig1, err) = ig0.add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
let (ig2, err) = ig1.add_child(ig1.path().join("foo"));
|
||||
assert!(err.is_none());
|
||||
|
||||
assert!(ig1.matched("foo", false).is_ignore());
|
||||
assert!(ig2.matched("foo", false).is_none());
|
||||
|
||||
assert!(ig1.matched("bar", false).is_ignore());
|
||||
assert!(ig2.matched("bar", false).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absolute_parent() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
mkdirp(td.path().join(".git"));
|
||||
mkdirp(td.path().join("foo"));
|
||||
wfile(td.path().join(".gitignore"), "bar");
|
||||
|
||||
// First, check that the parent gitignore file isn't detected if the
|
||||
// parent isn't added. This establishes a baseline.
|
||||
let ig0 = IgnoreBuilder::new().build();
|
||||
let (ig1, err) = ig0.add_child(td.path().join("foo"));
|
||||
assert!(err.is_none());
|
||||
assert!(ig1.matched("bar", false).is_none());
|
||||
|
||||
// Second, check that adding a parent directory actually works.
|
||||
let ig0 = IgnoreBuilder::new().build();
|
||||
let (ig1, err) = ig0.add_parents(td.path().join("foo"));
|
||||
assert!(err.is_none());
|
||||
let (ig2, err) = ig1.add_child(td.path().join("foo"));
|
||||
assert!(err.is_none());
|
||||
assert!(ig2.matched("bar", false).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absolute_parent_anchored() {
|
||||
let td = TempDir::new("ignore-test-").unwrap();
|
||||
mkdirp(td.path().join(".git"));
|
||||
mkdirp(td.path().join("src/llvm"));
|
||||
wfile(td.path().join(".gitignore"), "/llvm/\nfoo");
|
||||
|
||||
let ig0 = IgnoreBuilder::new().build();
|
||||
let (ig1, err) = ig0.add_parents(td.path().join("src"));
|
||||
assert!(err.is_none());
|
||||
let (ig2, err) = ig1.add_child("src");
|
||||
assert!(err.is_none());
|
||||
|
||||
assert!(ig1.matched("llvm", true).is_none());
|
||||
assert!(ig2.matched("llvm", true).is_none());
|
||||
assert!(ig2.matched("src/llvm", true).is_none());
|
||||
assert!(ig2.matched("foo", false).is_ignore());
|
||||
assert!(ig2.matched("src/foo", false).is_ignore());
|
||||
}
|
||||
}
|
||||
610
ignore/src/gitignore.rs
Normal file
610
ignore/src/gitignore.rs
Normal file
@@ -0,0 +1,610 @@
|
||||
/*!
|
||||
The gitignore module provides a way to match globs from a gitignore file
|
||||
against file paths.
|
||||
|
||||
Note that this module implements the specification as described in the
|
||||
`gitignore` man page from scratch. That is, this module does *not* shell out to
|
||||
the `git` command line tool.
|
||||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
|
||||
use globset::{Candidate, GlobBuilder, GlobSet, GlobSetBuilder};
|
||||
use regex::bytes::Regex;
|
||||
use thread_local::ThreadLocal;
|
||||
|
||||
use pathutil::{is_file_name, strip_prefix};
|
||||
use {Error, Match, PartialErrorBuilder};
|
||||
|
||||
/// Glob represents a single glob in a gitignore file.
|
||||
///
|
||||
/// This is used to report information about the highest precedent glob that
|
||||
/// matched in one or more gitignore files.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Glob {
|
||||
/// The file path that this glob was extracted from.
|
||||
from: Option<PathBuf>,
|
||||
/// The original glob string.
|
||||
original: String,
|
||||
/// The actual glob string used to convert to a regex.
|
||||
actual: String,
|
||||
/// Whether this is a whitelisted glob or not.
|
||||
is_whitelist: bool,
|
||||
/// Whether this glob should only match directories or not.
|
||||
is_only_dir: bool,
|
||||
}
|
||||
|
||||
impl Glob {
|
||||
/// Returns the file path that defined this glob.
|
||||
pub fn from(&self) -> Option<&Path> {
|
||||
self.from.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// The original glob as it was defined in a gitignore file.
|
||||
pub fn original(&self) -> &str {
|
||||
&self.original
|
||||
}
|
||||
|
||||
/// The actual glob that was compiled to respect gitignore
|
||||
/// semantics.
|
||||
pub fn actual(&self) -> &str {
|
||||
&self.actual
|
||||
}
|
||||
|
||||
/// Whether this was a whitelisted glob or not.
|
||||
pub fn is_whitelist(&self) -> bool {
|
||||
self.is_whitelist
|
||||
}
|
||||
|
||||
/// Whether this glob must match a directory or not.
|
||||
pub fn is_only_dir(&self) -> bool {
|
||||
self.is_only_dir
|
||||
}
|
||||
}
|
||||
|
||||
/// Gitignore is a matcher for the globs in one or more gitignore files
|
||||
/// in the same directory.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Gitignore {
|
||||
set: GlobSet,
|
||||
root: PathBuf,
|
||||
globs: Vec<Glob>,
|
||||
num_ignores: u64,
|
||||
num_whitelists: u64,
|
||||
matches: Arc<ThreadLocal<RefCell<Vec<usize>>>>,
|
||||
}
|
||||
|
||||
impl Gitignore {
|
||||
/// Creates a new gitignore matcher from the gitignore file path given.
|
||||
///
|
||||
/// If it's desirable to include multiple gitignore files in a single
|
||||
/// matcher, or read gitignore globs from a different source, then
|
||||
/// use `GitignoreBuilder`.
|
||||
///
|
||||
/// This always returns a valid matcher, even if it's empty. In particular,
|
||||
/// a Gitignore file can be partially valid, e.g., when one glob is invalid
|
||||
/// but the rest aren't.
|
||||
///
|
||||
/// Note that I/O errors are ignored. For more granular control over
|
||||
/// errors, use `GitignoreBuilder`.
|
||||
pub fn new<P: AsRef<Path>>(
|
||||
gitignore_path: P,
|
||||
) -> (Gitignore, Option<Error>) {
|
||||
let path = gitignore_path.as_ref();
|
||||
let parent = path.parent().unwrap_or(Path::new("/"));
|
||||
let mut builder = GitignoreBuilder::new(parent);
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
errs.maybe_push_ignore_io(builder.add(path));
|
||||
match builder.build() {
|
||||
Ok(gi) => (gi, errs.into_error_option()),
|
||||
Err(err) => {
|
||||
errs.push(err);
|
||||
(Gitignore::empty(), errs.into_error_option())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new gitignore matcher from the global ignore file, if one
|
||||
/// exists.
|
||||
///
|
||||
/// The global config file path is specified by git's `core.excludesFile`
|
||||
/// config option.
|
||||
///
|
||||
/// Git's config file location is `$HOME/.gitconfig`. If `$HOME/.gitconfig`
|
||||
/// does not exist or does not specify `core.excludesFile`, then
|
||||
/// `$XDG_CONFIG_HOME/git/ignore` is read. If `$XDG_CONFIG_HOME` is not
|
||||
/// set or is empty, then `$HOME/.config/git/ignore` is used instead.
|
||||
pub fn global() -> (Gitignore, Option<Error>) {
|
||||
match gitconfig_excludes_path() {
|
||||
None => (Gitignore::empty(), None),
|
||||
Some(path) => {
|
||||
if !path.is_file() {
|
||||
(Gitignore::empty(), None)
|
||||
} else {
|
||||
Gitignore::new(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new empty gitignore matcher that never matches anything.
|
||||
///
|
||||
/// Its path is empty.
|
||||
pub fn empty() -> Gitignore {
|
||||
GitignoreBuilder::new("").build().unwrap()
|
||||
}
|
||||
|
||||
/// Returns the directory containing this gitignore matcher.
|
||||
///
|
||||
/// All matches are done relative to this path.
|
||||
pub fn path(&self) -> &Path {
|
||||
&*self.root
|
||||
}
|
||||
|
||||
/// Returns true if and only if this gitignore has zero globs, and
|
||||
/// therefore never matches any file path.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.set.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the total number of globs, which should be equivalent to
|
||||
/// `num_ignores + num_whitelists`.
|
||||
pub fn len(&self) -> usize {
|
||||
self.set.len()
|
||||
}
|
||||
|
||||
/// Returns the total number of ignore globs.
|
||||
pub fn num_ignores(&self) -> u64 {
|
||||
self.num_ignores
|
||||
}
|
||||
|
||||
/// Returns the total number of whitelisted globs.
|
||||
pub fn num_whitelists(&self) -> u64 {
|
||||
self.num_whitelists
|
||||
}
|
||||
|
||||
/// Returns whether the given file path matched a pattern in this gitignore
|
||||
/// matcher.
|
||||
///
|
||||
/// `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<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<&Glob> {
|
||||
if self.is_empty() {
|
||||
return Match::None;
|
||||
}
|
||||
self.matched_stripped(self.strip(path.as_ref()), is_dir)
|
||||
}
|
||||
|
||||
/// Like matched, but takes a path that has already been stripped.
|
||||
fn matched_stripped<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<&Glob> {
|
||||
if self.is_empty() {
|
||||
return Match::None;
|
||||
}
|
||||
let path = path.as_ref();
|
||||
let _matches = self.matches.get_default();
|
||||
let mut matches = _matches.borrow_mut();
|
||||
let candidate = Candidate::new(path);
|
||||
self.set.matches_candidate_into(&candidate, &mut *matches);
|
||||
for &i in matches.iter().rev() {
|
||||
let glob = &self.globs[i];
|
||||
if !glob.is_only_dir() || is_dir {
|
||||
return if glob.is_whitelist() {
|
||||
Match::Whitelist(glob)
|
||||
} else {
|
||||
Match::Ignore(glob)
|
||||
};
|
||||
}
|
||||
}
|
||||
Match::None
|
||||
}
|
||||
|
||||
/// Strips the given path such that it's suitable for matching with this
|
||||
/// gitignore matcher.
|
||||
fn strip<'a, P: 'a + AsRef<Path> + ?Sized>(
|
||||
&'a self,
|
||||
path: &'a P,
|
||||
) -> &'a Path {
|
||||
let mut path = path.as_ref();
|
||||
// A leading ./ is completely superfluous. We also strip it from
|
||||
// our gitignore root path, so we need to strip it from our candidate
|
||||
// path too.
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
// Strip any common prefix between the candidate path and the root
|
||||
// of the gitignore, to make sure we get relative matching right.
|
||||
// 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) {
|
||||
if let Some(p) = strip_prefix(&self.root, path) {
|
||||
path = p;
|
||||
// If we're left with a leading slash, get rid of it.
|
||||
if let Some(p) = strip_prefix("/", path) {
|
||||
path = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a matcher for a single set of globs from a .gitignore file.
|
||||
pub struct GitignoreBuilder {
|
||||
builder: GlobSetBuilder,
|
||||
root: PathBuf,
|
||||
globs: Vec<Glob>,
|
||||
}
|
||||
|
||||
impl GitignoreBuilder {
|
||||
/// Create a new builder for a gitignore file.
|
||||
///
|
||||
/// The path given should be the path at which the globs for this gitignore
|
||||
/// file should be matched. Note that paths are always matched relative
|
||||
/// to the root path given here. Generally, the root path should correspond
|
||||
/// to the *directory* containing a `.gitignore` file.
|
||||
pub fn new<P: AsRef<Path>>(root: P) -> GitignoreBuilder {
|
||||
let root = root.as_ref();
|
||||
GitignoreBuilder {
|
||||
builder: GlobSetBuilder::new(),
|
||||
root: strip_prefix("./", root).unwrap_or(root).to_path_buf(),
|
||||
globs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a new matcher from the globs added so far.
|
||||
///
|
||||
/// Once a matcher is built, no new globs can be added to it.
|
||||
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())));
|
||||
Ok(Gitignore {
|
||||
set: set,
|
||||
root: self.root.clone(),
|
||||
globs: self.globs.clone(),
|
||||
num_ignores: nignore as u64,
|
||||
num_whitelists: nwhite as u64,
|
||||
matches: Arc::new(ThreadLocal::default()),
|
||||
})
|
||||
}
|
||||
|
||||
/// Add each glob from the file path given.
|
||||
///
|
||||
/// The file given should be formatted as a `gitignore` file.
|
||||
///
|
||||
/// Note that partial errors can be returned. For example, if there was
|
||||
/// a problem adding one glob, an error for that will be returned, but
|
||||
/// all other valid globs will still be added.
|
||||
pub fn add<P: AsRef<Path>>(&mut self, path: P) -> Option<Error> {
|
||||
let path = path.as_ref();
|
||||
let file = match File::open(path) {
|
||||
Err(err) => return Some(Error::Io(err).with_path(path)),
|
||||
Ok(file) => file,
|
||||
};
|
||||
let rdr = io::BufReader::new(file);
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
for (i, line) in rdr.lines().enumerate() {
|
||||
let lineno = (i + 1) as u64;
|
||||
let line = match line {
|
||||
Ok(line) => line,
|
||||
Err(err) => {
|
||||
errs.push(Error::Io(err).tagged(path, lineno));
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Err(err) = self.add_line(Some(path.to_path_buf()), &line) {
|
||||
errs.push(err.tagged(path, lineno));
|
||||
}
|
||||
}
|
||||
errs.into_error_option()
|
||||
}
|
||||
|
||||
/// Add each glob line from the string given.
|
||||
///
|
||||
/// If this string came from a particular `gitignore` file, then its path
|
||||
/// should be provided here.
|
||||
///
|
||||
/// The string given should be formatted as a `gitignore` file.
|
||||
#[cfg(test)]
|
||||
fn add_str(
|
||||
&mut self,
|
||||
from: Option<PathBuf>,
|
||||
gitignore: &str,
|
||||
) -> Result<&mut GitignoreBuilder, Error> {
|
||||
for line in gitignore.lines() {
|
||||
try!(self.add_line(from.clone(), line));
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Add a line from a gitignore file to this builder.
|
||||
///
|
||||
/// If this line came from a particular `gitignore` file, then its path
|
||||
/// should be provided here.
|
||||
///
|
||||
/// If the line could not be parsed as a glob, then an error is returned.
|
||||
pub fn add_line(
|
||||
&mut self,
|
||||
from: Option<PathBuf>,
|
||||
mut line: &str,
|
||||
) -> Result<&mut GitignoreBuilder, Error> {
|
||||
if line.starts_with("#") {
|
||||
return Ok(self);
|
||||
}
|
||||
if !line.ends_with("\\ ") {
|
||||
line = line.trim_right();
|
||||
}
|
||||
if line.is_empty() {
|
||||
return Ok(self);
|
||||
}
|
||||
let mut glob = Glob {
|
||||
from: from,
|
||||
original: line.to_string(),
|
||||
actual: String::new(),
|
||||
is_whitelist: false,
|
||||
is_only_dir: false,
|
||||
};
|
||||
let mut literal_separator = false;
|
||||
let has_slash = line.chars().any(|c| c == '/');
|
||||
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;
|
||||
line = &line[1..];
|
||||
}
|
||||
if line.starts_with("/") {
|
||||
// `man gitignore` says that if a glob starts with a slash,
|
||||
// then the glob can only match the beginning of a path
|
||||
// (relative to the location of gitignore). We achieve this by
|
||||
// simply banning wildcards from matching /.
|
||||
literal_separator = true;
|
||||
line = &line[1..];
|
||||
is_absolute = true;
|
||||
}
|
||||
}
|
||||
// If it ends with a slash, then this should only match directories,
|
||||
// but the slash should otherwise not be used while globbing.
|
||||
if let Some((i, c)) = line.char_indices().rev().nth(0) {
|
||||
if c == '/' {
|
||||
glob.is_only_dir = true;
|
||||
line = &line[..i];
|
||||
}
|
||||
}
|
||||
// If there is a literal slash, then we note that so that globbing
|
||||
// doesn't let wildcards match slashes.
|
||||
glob.actual = line.to_string();
|
||||
if has_slash {
|
||||
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 {
|
||||
// ... but only if we don't already have a **/ prefix.
|
||||
if !glob.actual.starts_with("**/") {
|
||||
glob.actual = format!("**/{}", glob.actual);
|
||||
}
|
||||
}
|
||||
// If the glob ends with `/**`, then we should only match everything
|
||||
// inside a directory, but not the directory itself. Standard globs
|
||||
// will match the directory. So we add `/*` to force the issue.
|
||||
if glob.actual.ends_with("/**") {
|
||||
glob.actual = format!("{}/*", glob.actual);
|
||||
}
|
||||
let parsed = try!(
|
||||
GlobBuilder::new(&glob.actual)
|
||||
.literal_separator(literal_separator)
|
||||
.build()
|
||||
.map_err(|err| Error::Glob(err.to_string())));
|
||||
self.builder.add(parsed);
|
||||
self.globs.push(glob);
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the file path of the current environment's global gitignore file.
|
||||
///
|
||||
/// Note that the file path returned may not exist.
|
||||
fn gitconfig_excludes_path() -> Option<PathBuf> {
|
||||
gitconfig_contents()
|
||||
.and_then(|data| parse_excludes_file(&data))
|
||||
.or_else(excludes_file_default)
|
||||
}
|
||||
|
||||
/// Returns the file contents of git's global config file, if one exists.
|
||||
fn gitconfig_contents() -> Option<Vec<u8>> {
|
||||
let home = match env::var_os("HOME") {
|
||||
None => return None,
|
||||
Some(home) => PathBuf::from(home),
|
||||
};
|
||||
let mut file = match File::open(home.join(".gitconfig")) {
|
||||
Err(_) => return None,
|
||||
Ok(file) => io::BufReader::new(file),
|
||||
};
|
||||
let mut contents = vec![];
|
||||
file.read_to_end(&mut contents).ok().map(|_| contents)
|
||||
}
|
||||
|
||||
/// Returns the default file path for a global .gitignore file.
|
||||
///
|
||||
/// 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(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
|
||||
/// given.
|
||||
fn parse_excludes_file(data: &[u8]) -> Option<PathBuf> {
|
||||
// N.B. This is the lazy approach, and isn't technically correct, but
|
||||
// probably works in more circumstances. I guess we would ideally have
|
||||
// a full INI parser. Yuck.
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(
|
||||
r"(?ium)^\s*excludesfile\s*=\s*(.+)\s*$").unwrap();
|
||||
};
|
||||
let caps = match RE.captures(data) {
|
||||
None => return None,
|
||||
Some(caps) => caps,
|
||||
};
|
||||
str::from_utf8(&caps[1]).ok().map(|s| PathBuf::from(expand_tilde(s)))
|
||||
}
|
||||
|
||||
/// Expands ~ in file paths to the value of $HOME.
|
||||
fn expand_tilde(path: &str) -> String {
|
||||
let home = match env::var("HOME") {
|
||||
Err(_) => return path.to_string(),
|
||||
Ok(home) => home,
|
||||
};
|
||||
path.replace("~", &home)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
use super::{Gitignore, GitignoreBuilder};
|
||||
|
||||
fn gi_from_str<P: AsRef<Path>>(root: P, s: &str) -> Gitignore {
|
||||
let mut builder = GitignoreBuilder::new(root);
|
||||
builder.add_str(None, s).unwrap();
|
||||
builder.build().unwrap()
|
||||
}
|
||||
|
||||
macro_rules! ignored {
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr) => {
|
||||
ignored!($name, $root, $gi, $path, false);
|
||||
};
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr, $is_dir:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let gi = gi_from_str($root, $gi);
|
||||
assert!(gi.matched($path, $is_dir).is_ignore());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! not_ignored {
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr) => {
|
||||
not_ignored!($name, $root, $gi, $path, false);
|
||||
};
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr, $is_dir:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let gi = gi_from_str($root, $gi);
|
||||
assert!(!gi.matched($path, $is_dir).is_ignore());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const ROOT: &'static str = "/home/foobar/rust/rg";
|
||||
|
||||
ignored!(ig1, ROOT, "months", "months");
|
||||
ignored!(ig2, ROOT, "*.lock", "Cargo.lock");
|
||||
ignored!(ig3, ROOT, "*.rs", "src/main.rs");
|
||||
ignored!(ig4, ROOT, "src/*.rs", "src/main.rs");
|
||||
ignored!(ig5, ROOT, "/*.c", "cat-file.c");
|
||||
ignored!(ig6, ROOT, "/src/*.rs", "src/main.rs");
|
||||
ignored!(ig7, ROOT, "!src/main.rs\n*.rs", "src/main.rs");
|
||||
ignored!(ig8, ROOT, "foo/", "foo", true);
|
||||
ignored!(ig9, ROOT, "**/foo", "foo");
|
||||
ignored!(ig10, ROOT, "**/foo", "src/foo");
|
||||
ignored!(ig11, ROOT, "**/foo/**", "src/foo/bar");
|
||||
ignored!(ig12, ROOT, "**/foo/**", "wat/src/foo/bar/baz");
|
||||
ignored!(ig13, ROOT, "**/foo/bar", "foo/bar");
|
||||
ignored!(ig14, ROOT, "**/foo/bar", "src/foo/bar");
|
||||
ignored!(ig15, ROOT, "abc/**", "abc/x");
|
||||
ignored!(ig16, ROOT, "abc/**", "abc/x/y");
|
||||
ignored!(ig17, ROOT, "abc/**", "abc/x/y/z");
|
||||
ignored!(ig18, ROOT, "a/**/b", "a/b");
|
||||
ignored!(ig19, ROOT, "a/**/b", "a/x/b");
|
||||
ignored!(ig20, ROOT, "a/**/b", "a/x/y/b");
|
||||
ignored!(ig21, ROOT, r"\!xy", "!xy");
|
||||
ignored!(ig22, ROOT, r"\#foo", "#foo");
|
||||
ignored!(ig23, ROOT, "foo", "./foo");
|
||||
ignored!(ig24, ROOT, "target", "grep/target");
|
||||
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);
|
||||
|
||||
not_ignored!(ignot1, ROOT, "amonths", "months");
|
||||
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
||||
not_ignored!(ignot3, ROOT, "/src/*.rs", "src/grep/src/main.rs");
|
||||
not_ignored!(ignot4, ROOT, "/*.c", "mozilla-sha1/sha1.c");
|
||||
not_ignored!(ignot5, ROOT, "/src/*.rs", "src/grep/src/main.rs");
|
||||
not_ignored!(ignot6, ROOT, "*.rs\n!src/main.rs", "src/main.rs");
|
||||
not_ignored!(ignot7, ROOT, "foo/", "foo", false);
|
||||
not_ignored!(ignot8, ROOT, "**/foo/**", "wat/src/afoo/bar/baz");
|
||||
not_ignored!(ignot9, ROOT, "**/foo/**", "wat/src/fooa/bar/baz");
|
||||
not_ignored!(ignot10, ROOT, "**/foo/bar", "foo/src/bar");
|
||||
not_ignored!(ignot11, ROOT, "#foo", "#foo");
|
||||
not_ignored!(ignot12, ROOT, "\n\n\n", "foo");
|
||||
not_ignored!(ignot13, ROOT, "foo/**", "foo", true);
|
||||
not_ignored!(
|
||||
ignot14, "./third_party/protobuf", "m4/ltoptions.m4",
|
||||
"./third_party/protobuf/csharp/src/packages/repositories.config");
|
||||
not_ignored!(ignot15, ROOT, "!/bar", "foo/bar");
|
||||
|
||||
fn bytes(s: &str) -> Vec<u8> {
|
||||
s.to_string().into_bytes()
|
||||
}
|
||||
|
||||
fn path_string<P: AsRef<Path>>(path: P) -> String {
|
||||
path.as_ref().to_str().unwrap().to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_excludes_file1() {
|
||||
let data = bytes("[core]\nexcludesFile = /foo/bar");
|
||||
let got = super::parse_excludes_file(&data).unwrap();
|
||||
assert_eq!(path_string(got), "/foo/bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_excludes_file2() {
|
||||
let data = bytes("[core]\nexcludesFile = ~/foo/bar");
|
||||
let got = super::parse_excludes_file(&data).unwrap();
|
||||
assert_eq!(path_string(got), super::expand_tilde("~/foo/bar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_excludes_file3() {
|
||||
let data = bytes("[core]\nexcludeFile = /foo/bar");
|
||||
assert!(super::parse_excludes_file(&data).is_none());
|
||||
}
|
||||
|
||||
// See: https://github.com/BurntSushi/ripgrep/issues/106
|
||||
#[test]
|
||||
fn regression_106() {
|
||||
gi_from_str("/", " ");
|
||||
}
|
||||
}
|
||||
391
ignore/src/lib.rs
Normal file
391
ignore/src/lib.rs
Normal file
@@ -0,0 +1,391 @@
|
||||
/*!
|
||||
The ignore crate provides a fast recursive directory iterator that respects
|
||||
various filters such as globs, file types and `.gitignore` files. The precise
|
||||
matching rules and precedence is explained in the documentation for
|
||||
`WalkBuilder`.
|
||||
|
||||
Secondarily, this crate exposes gitignore and file type matchers for use cases
|
||||
that demand more fine-grained control.
|
||||
|
||||
# Example
|
||||
|
||||
This example shows the most basic usage of this crate. This code will
|
||||
recursively traverse the current directory while automatically filtering out
|
||||
files and directories according to ignore globs found in files like
|
||||
`.ignore` and `.gitignore`:
|
||||
|
||||
|
||||
```rust,no_run
|
||||
use ignore::Walk;
|
||||
|
||||
for result in Walk::new("./") {
|
||||
// Each item yielded by the iterator is either a directory entry or an
|
||||
// error, so either print the path or the error.
|
||||
match result {
|
||||
Ok(entry) => println!("{}", entry.path().display()),
|
||||
Err(err) => println!("ERROR: {}", err),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Example: advanced
|
||||
|
||||
By default, the recursive directory iterator will ignore hidden files and
|
||||
directories. This can be disabled by building the iterator with `WalkBuilder`:
|
||||
|
||||
```rust,no_run
|
||||
use ignore::WalkBuilder;
|
||||
|
||||
for result in WalkBuilder::new("./").hidden(false).build() {
|
||||
println!("{:?}", result);
|
||||
}
|
||||
```
|
||||
|
||||
See the documentation for `WalkBuilder` for many other options.
|
||||
*/
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
extern crate crossbeam;
|
||||
extern crate globset;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate memchr;
|
||||
extern crate regex;
|
||||
#[cfg(test)]
|
||||
extern crate tempdir;
|
||||
extern crate thread_local;
|
||||
extern crate walkdir;
|
||||
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub use walk::{DirEntry, Walk, WalkBuilder, WalkParallel, WalkState};
|
||||
|
||||
mod dir;
|
||||
pub mod gitignore;
|
||||
mod pathutil;
|
||||
pub mod overrides;
|
||||
pub mod types;
|
||||
mod walk;
|
||||
|
||||
/// Represents an error that can occur when parsing a gitignore file.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// A collection of "soft" errors. These occur when adding an ignore
|
||||
/// file partially succeeded.
|
||||
Partial(Vec<Error>),
|
||||
/// An error associated with a specific line number.
|
||||
WithLineNumber {
|
||||
/// The line number.
|
||||
line: u64,
|
||||
/// The underlying error.
|
||||
err: Box<Error>,
|
||||
},
|
||||
/// An error associated with a particular file path.
|
||||
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),
|
||||
/// A type selection for a file type that is not defined.
|
||||
UnrecognizedFileType(String),
|
||||
/// A user specified file type definition could not be parsed.
|
||||
InvalidDefinition,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
/// Returns true if this is a partial error.
|
||||
///
|
||||
/// A partial error occurs when only some operations failed while others
|
||||
/// may have succeeded. For example, an ignore file may contain an invalid
|
||||
/// glob among otherwise valid globs.
|
||||
pub fn is_partial(&self) -> bool {
|
||||
match *self {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this error is exclusively an I/O error.
|
||||
pub fn is_io(&self) -> bool {
|
||||
match *self {
|
||||
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::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 {
|
||||
path: path.as_ref().to_path_buf(),
|
||||
err: Box::new(self),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
let errline = Error::WithLineNumber {
|
||||
line: lineno,
|
||||
err: Box::new(self),
|
||||
};
|
||||
if path.as_ref().as_os_str().is_empty() {
|
||||
return errline;
|
||||
}
|
||||
errline.with_path(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
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::UnrecognizedFileType(_) => "unrecognized file type",
|
||||
Error::InvalidDefinition => "invalid definition",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Partial(ref errs) => {
|
||||
let msgs: Vec<String> =
|
||||
errs.iter().map(|err| err.to_string()).collect();
|
||||
write!(f, "{}", msgs.join("\n"))
|
||||
}
|
||||
Error::WithLineNumber { line, ref err } => {
|
||||
write!(f, "line {}: {}", line, err)
|
||||
}
|
||||
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::UnrecognizedFileType(ref ty) => {
|
||||
write!(f, "unrecognized file type: {}", ty)
|
||||
}
|
||||
Error::InvalidDefinition => {
|
||||
write!(f, "invalid definition (format is type:glob, e.g., \
|
||||
html:*.html)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Error {
|
||||
Error::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<walkdir::Error> for Error {
|
||||
fn from(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
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct PartialErrorBuilder(Vec<Error>);
|
||||
|
||||
impl PartialErrorBuilder {
|
||||
fn push(&mut self, err: Error) {
|
||||
self.0.push(err);
|
||||
}
|
||||
|
||||
fn push_ignore_io(&mut self, err: Error) {
|
||||
if !err.is_io() {
|
||||
self.push(err);
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_push(&mut self, err: Option<Error>) {
|
||||
if let Some(err) = err {
|
||||
self.push(err);
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_push_ignore_io(&mut self, err: Option<Error>) {
|
||||
if let Some(err) = err {
|
||||
self.push_ignore_io(err);
|
||||
}
|
||||
}
|
||||
|
||||
fn into_error_option(mut self) -> Option<Error> {
|
||||
if self.0.is_empty() {
|
||||
None
|
||||
} else if self.0.len() == 1 {
|
||||
Some(self.0.pop().unwrap())
|
||||
} else {
|
||||
Some(Error::Partial(self.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of a glob match.
|
||||
///
|
||||
/// The type parameter `T` typically refers to a type that provides more
|
||||
/// information about a particular match. For example, it might identify
|
||||
/// the specific gitignore file and the specific glob pattern that caused
|
||||
/// the match.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Match<T> {
|
||||
/// The path didn't match any glob.
|
||||
None,
|
||||
/// The highest precedent glob matched indicates the path should be
|
||||
/// ignored.
|
||||
Ignore(T),
|
||||
/// The highest precedent glob matched indicates the path should be
|
||||
/// whitelisted.
|
||||
Whitelist(T),
|
||||
}
|
||||
|
||||
impl<T> Match<T> {
|
||||
/// Returns true if the match result didn't match any globs.
|
||||
pub fn is_none(&self) -> bool {
|
||||
match *self {
|
||||
Match::None => true,
|
||||
Match::Ignore(_) | Match::Whitelist(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the match result implies the path should be ignored.
|
||||
pub fn is_ignore(&self) -> bool {
|
||||
match *self {
|
||||
Match::Ignore(_) => true,
|
||||
Match::None | Match::Whitelist(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the match result implies the path should be
|
||||
/// whitelisted.
|
||||
pub fn is_whitelist(&self) -> bool {
|
||||
match *self {
|
||||
Match::Whitelist(_) => true,
|
||||
Match::None | Match::Ignore(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inverts the match so that `Ignore` becomes `Whitelist` and
|
||||
/// `Whitelist` becomes `Ignore`. A non-match remains the same.
|
||||
pub fn invert(self) -> Match<T> {
|
||||
match self {
|
||||
Match::None => Match::None,
|
||||
Match::Ignore(t) => Match::Whitelist(t),
|
||||
Match::Whitelist(t) => Match::Ignore(t),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the value inside this match if it exists.
|
||||
pub fn inner(&self) -> Option<&T> {
|
||||
match *self {
|
||||
Match::None => None,
|
||||
Match::Ignore(ref t) => Some(t),
|
||||
Match::Whitelist(ref t) => Some(t),
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply the given function to the value inside this match.
|
||||
///
|
||||
/// If the match has no value, then return the match unchanged.
|
||||
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Match<U> {
|
||||
match self {
|
||||
Match::None => Match::None,
|
||||
Match::Ignore(t) => Match::Ignore(f(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
|
||||
}
|
||||
}
|
||||
}
|
||||
223
ignore/src/overrides.rs
Normal file
223
ignore/src/overrides.rs
Normal file
@@ -0,0 +1,223 @@
|
||||
/*!
|
||||
The overrides module provides a way to specify a set of override globs.
|
||||
This provides functionality similar to `--include` or `--exclude` in command
|
||||
line tools.
|
||||
*/
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use gitignore::{self, Gitignore, GitignoreBuilder};
|
||||
use {Error, Match};
|
||||
|
||||
/// Glob represents a single glob in an override matcher.
|
||||
///
|
||||
/// This is used to report information about the highest precedent glob
|
||||
/// that matched.
|
||||
///
|
||||
/// Note that not all matches necessarily correspond to a specific glob. For
|
||||
/// example, if there are one or more whitelist globs and a file path doesn't
|
||||
/// match any glob in the set, then the file path is considered to be ignored.
|
||||
///
|
||||
/// The lifetime `'a` refers to the lifetime of the matcher that produced
|
||||
/// this glob.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Glob<'a>(GlobInner<'a>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum GlobInner<'a> {
|
||||
/// No glob matched, but the file path should still be ignored.
|
||||
UnmatchedIgnore,
|
||||
/// A glob matched.
|
||||
Matched(&'a gitignore::Glob),
|
||||
}
|
||||
|
||||
impl<'a> Glob<'a> {
|
||||
fn unmatched() -> Glob<'a> {
|
||||
Glob(GlobInner::UnmatchedIgnore)
|
||||
}
|
||||
}
|
||||
|
||||
/// Manages a set of overrides provided explicitly by the end user.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Override(Gitignore);
|
||||
|
||||
impl Override {
|
||||
/// Returns an empty matcher that never matches any file path.
|
||||
pub fn empty() -> Override {
|
||||
Override(Gitignore::empty())
|
||||
}
|
||||
|
||||
/// Returns the directory of this override set.
|
||||
///
|
||||
/// All matches are done relative to this path.
|
||||
pub fn path(&self) -> &Path {
|
||||
self.0.path()
|
||||
}
|
||||
|
||||
/// Returns true if and only if this matcher is empty.
|
||||
///
|
||||
/// When a matcher is empty, it will never match any file path.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the total number of ignore globs.
|
||||
pub fn num_ignores(&self) -> u64 {
|
||||
self.0.num_whitelists()
|
||||
}
|
||||
|
||||
/// Returns the total number of whitelisted globs.
|
||||
pub fn num_whitelists(&self) -> u64 {
|
||||
self.0.num_ignores()
|
||||
}
|
||||
|
||||
/// Returns whether the given file path matched a pattern in this override
|
||||
/// matcher.
|
||||
///
|
||||
/// `is_dir` should be true if the path refers to a directory and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// If there are no overrides, then this always returns `Match::None`.
|
||||
///
|
||||
/// If there is at least one whitelist override and `is_dir` is false, then
|
||||
/// this never returns `Match::None`, since non-matches are interpreted as
|
||||
/// ignored.
|
||||
///
|
||||
/// The given path is matched to the globs relative to the path given
|
||||
/// when building the override matcher. Specifically, before matching
|
||||
/// `path`, its prefix (as determined by a common suffix of the directory
|
||||
/// given) is stripped. If there is no common suffix/prefix overlap, then
|
||||
/// `path` is assumed to reside in the same directory as the root path for
|
||||
/// this set of overrides.
|
||||
pub fn matched<'a, P: AsRef<Path>>(
|
||||
&'a self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<Glob<'a>> {
|
||||
if self.is_empty() {
|
||||
return Match::None;
|
||||
}
|
||||
let mat = self.0.matched(path, is_dir).invert();
|
||||
if mat.is_none() && self.num_whitelists() > 0 && !is_dir {
|
||||
return Match::Ignore(Glob::unmatched());
|
||||
}
|
||||
mat.map(move |giglob| Glob(GlobInner::Matched(giglob)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a matcher for a set of glob overrides.
|
||||
pub struct OverrideBuilder {
|
||||
builder: GitignoreBuilder,
|
||||
}
|
||||
|
||||
impl OverrideBuilder {
|
||||
/// Create a new override builder.
|
||||
///
|
||||
/// Matching is done relative to the directory path provided.
|
||||
pub fn new<P: AsRef<Path>>(path: P) -> OverrideBuilder {
|
||||
OverrideBuilder {
|
||||
builder: GitignoreBuilder::new(path),
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a new override matcher from the globs added so far.
|
||||
///
|
||||
/// 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())))
|
||||
}
|
||||
|
||||
/// Add a glob to the set of overrides.
|
||||
///
|
||||
/// Globs provided here have precisely the same semantics as a single
|
||||
/// line in a `gitignore` file, where the meaning of `!` is inverted:
|
||||
/// 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));
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Override, OverrideBuilder};
|
||||
|
||||
const ROOT: &'static str = "/home/andrew/foo";
|
||||
|
||||
fn ov(globs: &[&str]) -> Override {
|
||||
let mut builder = OverrideBuilder::new(ROOT);
|
||||
for glob in globs {
|
||||
builder.add(glob).unwrap();
|
||||
}
|
||||
builder.build().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let ov = ov(&[]);
|
||||
assert!(ov.matched("a.foo", false).is_none());
|
||||
assert!(ov.matched("a", false).is_none());
|
||||
assert!(ov.matched("", false).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple() {
|
||||
let ov = ov(&["*.foo", "!*.bar"]);
|
||||
assert!(ov.matched("a.foo", false).is_whitelist());
|
||||
assert!(ov.matched("a.foo", true).is_whitelist());
|
||||
assert!(ov.matched("a.rs", false).is_ignore());
|
||||
assert!(ov.matched("a.rs", true).is_none());
|
||||
assert!(ov.matched("a.bar", false).is_ignore());
|
||||
assert!(ov.matched("a.bar", true).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_ignores() {
|
||||
let ov = ov(&["!*.bar"]);
|
||||
assert!(ov.matched("a.rs", false).is_none());
|
||||
assert!(ov.matched("a.rs", true).is_none());
|
||||
assert!(ov.matched("a.bar", false).is_ignore());
|
||||
assert!(ov.matched("a.bar", true).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn precedence() {
|
||||
let ov = ov(&["*.foo", "!*.bar.foo"]);
|
||||
assert!(ov.matched("a.foo", false).is_whitelist());
|
||||
assert!(ov.matched("a.baz", false).is_ignore());
|
||||
assert!(ov.matched("a.bar.foo", false).is_ignore());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitignore() {
|
||||
let ov = ov(&["/foo", "bar/*.rs", "baz/**"]);
|
||||
assert!(ov.matched("bar/wat/lib.rs", false).is_ignore());
|
||||
assert!(ov.matched("wat/bar/lib.rs", false).is_whitelist());
|
||||
assert!(ov.matched("foo", false).is_whitelist());
|
||||
assert!(ov.matched("wat/foo", false).is_ignore());
|
||||
assert!(ov.matched("baz", false).is_ignore());
|
||||
assert!(ov.matched("baz/a", false).is_whitelist());
|
||||
assert!(ov.matched("baz/a/b", false).is_whitelist());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_directories() {
|
||||
// This tests that directories are NOT ignored when they are unmatched.
|
||||
let ov = ov(&["*.rs"]);
|
||||
assert!(ov.matched("foo.rs", false).is_whitelist());
|
||||
assert!(ov.matched("foo.c", false).is_ignore());
|
||||
assert!(ov.matched("foo", false).is_ignore());
|
||||
assert!(ov.matched("foo", true).is_none());
|
||||
assert!(ov.matched("src/foo.rs", false).is_whitelist());
|
||||
assert!(ov.matched("src/foo.c", false).is_ignore());
|
||||
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());
|
||||
}
|
||||
}
|
||||
108
ignore/src/pathutil.rs
Normal file
108
ignore/src/pathutil.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(unix)]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
if let Some(name) = file_name(path.as_ref()) {
|
||||
name.as_bytes().get(0) == Some(&b'.')
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(not(unix))]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
if let Some(name) = file_name(path.as_ref()) {
|
||||
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip `prefix` from the `path` and return the remainder.
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(unix)]
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let prefix = prefix.as_ref().as_os_str().as_bytes();
|
||||
let path = path.as_os_str().as_bytes();
|
||||
if prefix.len() > path.len() || prefix != &path[0..prefix.len()] {
|
||||
None
|
||||
} else {
|
||||
Some(&Path::new(OsStr::from_bytes(&path[prefix.len()..])))
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip `prefix` from the `path` and return the remainder.
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(not(unix))]
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
path.strip_prefix(prefix).ok()
|
||||
}
|
||||
|
||||
/// Returns true if this file path is just a file name. i.e., Its parent is
|
||||
/// the empty string.
|
||||
#[cfg(unix)]
|
||||
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use memchr::memchr;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
memchr(b'/', path).is_none()
|
||||
}
|
||||
|
||||
/// Returns true if this file path is just a file name. i.e., Its parent is
|
||||
/// the empty string.
|
||||
#[cfg(not(unix))]
|
||||
pub fn is_file_name<P: AsRef<Path>>(path: P) -> bool {
|
||||
path.as_ref().parent().map(|p| p.as_os_str().is_empty()).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(unix)]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use memchr::memrchr;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
} else if path.len() == 1 && path[0] == b'.' {
|
||||
return None;
|
||||
} else if path.last() == Some(&b'.') {
|
||||
return None;
|
||||
} else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] {
|
||||
return None;
|
||||
}
|
||||
let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0);
|
||||
Some(OsStr::from_bytes(&path[last_slash..]))
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(not(unix))]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
path.as_ref().file_name()
|
||||
}
|
||||
674
ignore/src/types.rs
Normal file
674
ignore/src/types.rs
Normal file
@@ -0,0 +1,674 @@
|
||||
/*!
|
||||
The types module provides a way of associating globs on file names to file
|
||||
types.
|
||||
|
||||
This can be used to match specific types of files. For example, among
|
||||
the default file types provided, the Rust file type is defined to be `*.rs`
|
||||
with name `rust`. Similarly, the C file type is defined to be `*.{c,h}` with
|
||||
name `c`.
|
||||
|
||||
Note that the set of default types may change over time.
|
||||
|
||||
# Example
|
||||
|
||||
This shows how to create and use a simple file type matcher using the default
|
||||
file types defined in this crate.
|
||||
|
||||
```
|
||||
use ignore::types::TypesBuilder;
|
||||
|
||||
let mut builder = TypesBuilder::new();
|
||||
builder.add_defaults();
|
||||
builder.select("rust");
|
||||
let matcher = builder.build().unwrap();
|
||||
|
||||
assert!(matcher.matched("foo.rs", false).is_whitelist());
|
||||
assert!(matcher.matched("foo.c", false).is_ignore());
|
||||
```
|
||||
|
||||
# Example: negation
|
||||
|
||||
This is like the previous example, but shows how negating a file type works.
|
||||
That is, this will let us match file paths that *don't* correspond to a
|
||||
particular file type.
|
||||
|
||||
```
|
||||
use ignore::types::TypesBuilder;
|
||||
|
||||
let mut builder = TypesBuilder::new();
|
||||
builder.add_defaults();
|
||||
builder.negate("c");
|
||||
let matcher = builder.build().unwrap();
|
||||
|
||||
assert!(matcher.matched("foo.rs", false).is_none());
|
||||
assert!(matcher.matched("foo.c", false).is_ignore());
|
||||
```
|
||||
|
||||
# Example: custom file type definitions
|
||||
|
||||
This shows how to extend this library default file type definitions with
|
||||
your own.
|
||||
|
||||
```
|
||||
use ignore::types::TypesBuilder;
|
||||
|
||||
let mut builder = TypesBuilder::new();
|
||||
builder.add_defaults();
|
||||
builder.add("foo", "*.foo");
|
||||
// Another way of adding a file type definition.
|
||||
// This is useful when accepting input from an end user.
|
||||
builder.add_def("bar:*.bar");
|
||||
// Note: we only select `foo`, not `bar`.
|
||||
builder.select("foo");
|
||||
let matcher = builder.build().unwrap();
|
||||
|
||||
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;
|
||||
use std::collections::HashMap;
|
||||
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"]),
|
||||
("awk", &["*.awk"]),
|
||||
("c", &["*.c", "*.h", "*.H"]),
|
||||
("cbor", &["*.cbor"]),
|
||||
("ceylon", &["*.ceylon"]),
|
||||
("clojure", &["*.clj", "*.cljc", "*.cljs", "*.cljx"]),
|
||||
("cmake", &["*.cmake", "CMakeLists.txt"]),
|
||||
("coffeescript", &["*.coffee"]),
|
||||
("creole", &["*.creole"]),
|
||||
("config", &["*.config"]),
|
||||
("cpp", &[
|
||||
"*.C", "*.cc", "*.cpp", "*.cxx",
|
||||
"*.h", "*.H", "*.hh", "*.hpp",
|
||||
]),
|
||||
("crystal", &["Projectfile", "*.cr"]),
|
||||
("cs", &["*.cs"]),
|
||||
("csharp", &["*.cs"]),
|
||||
("css", &["*.css", "*.scss"]),
|
||||
("cython", &["*.pyx"]),
|
||||
("dart", &["*.dart"]),
|
||||
("d", &["*.d"]),
|
||||
("elisp", &["*.el"]),
|
||||
("elixir", &["*.ex", "*.eex", "*.exs"]),
|
||||
("erlang", &["*.erl", "*.hrl"]),
|
||||
("fish", &["*.fish"]),
|
||||
("fortran", &[
|
||||
"*.f", "*.F", "*.f77", "*.F77", "*.pfo",
|
||||
"*.f90", "*.F90", "*.f95", "*.F95",
|
||||
]),
|
||||
("fsharp", &["*.fs", "*.fsx", "*.fsi"]),
|
||||
("go", &["*.go"]),
|
||||
("groovy", &["*.groovy", "*.gradle"]),
|
||||
("h", &["*.h", "*.hpp"]),
|
||||
("hbs", &["*.hbs"]),
|
||||
("haskell", &["*.hs", "*.lhs"]),
|
||||
("html", &["*.htm", "*.html", "*.ejs"]),
|
||||
("java", &["*.java"]),
|
||||
("jinja", &["*.jinja", "*.jinja2"]),
|
||||
("js", &[
|
||||
"*.js", "*.jsx", "*.vue",
|
||||
]),
|
||||
("json", &["*.json"]),
|
||||
("jsonl", &["*.jsonl"]),
|
||||
("kotlin", &["*.kt", "*.kts"]),
|
||||
("less", &["*.less"]),
|
||||
("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]),
|
||||
("log", &["*.log"]),
|
||||
("lua", &["*.lua"]),
|
||||
("m4", &["*.ac", "*.m4"]),
|
||||
("make", &["gnumakefile", "Gnumakefile", "makefile", "Makefile", "*.mk", "*.mak"]),
|
||||
("markdown", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
|
||||
("md", &["*.markdown", "*.md", "*.mdown", "*.mkdn"]),
|
||||
("matlab", &["*.m"]),
|
||||
("mk", &["mkfile"]),
|
||||
("ml", &["*.ml"]),
|
||||
("nim", &["*.nim"]),
|
||||
("objc", &["*.h", "*.m"]),
|
||||
("objcpp", &["*.h", "*.mm"]),
|
||||
("ocaml", &["*.ml", "*.mli", "*.mll", "*.mly"]),
|
||||
("org", &["*.org"]),
|
||||
("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm", "*.t"]),
|
||||
("pdf", &["*.pdf"]),
|
||||
("php", &["*.php", "*.php3", "*.php4", "*.php5", "*.phtml"]),
|
||||
("pod", &["*.pod"]),
|
||||
("ps", &["*.cdxml", "*.ps1", "*.ps1xml", "*.psd1", "*.psm1"]),
|
||||
("py", &["*.py"]),
|
||||
("readme", &["README*", "*README"]),
|
||||
("r", &["*.R", "*.r", "*.Rmd", "*.Rnw"]),
|
||||
("rdoc", &["*.rdoc"]),
|
||||
("rst", &["*.rst"]),
|
||||
("ruby", &["Gemfile", "*.gemspec", ".irbrc", "Rakefile", "*.rb"]),
|
||||
("rust", &["*.rs"]),
|
||||
("sass", &["*.sass", "*.scss"]),
|
||||
("scala", &["*.scala"]),
|
||||
("sh", &["*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh"]),
|
||||
("spark", &["*.spark"]),
|
||||
("stylus", &["*.styl"]),
|
||||
("sql", &["*.sql"]),
|
||||
("sv", &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
|
||||
("svg", &["*.svg"]),
|
||||
("swift", &["*.swift"]),
|
||||
("swig", &["*.def", "*.i"]),
|
||||
("taskpaper", &["*.taskpaper"]),
|
||||
("tcl", &["*.tcl"]),
|
||||
("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib"]),
|
||||
("textile", &["*.textile"]),
|
||||
("ts", &["*.ts", "*.tsx"]),
|
||||
("txt", &["*.txt"]),
|
||||
("toml", &["*.toml", "Cargo.lock"]),
|
||||
("twig", &["*.twig"]),
|
||||
("vala", &["*.vala"]),
|
||||
("vb", &["*.vb"]),
|
||||
("vim", &["*.vim"]),
|
||||
("vimscript", &["*.vim"]),
|
||||
("wiki", &["*.mediawiki", "*.wiki"]),
|
||||
("xml", &["*.xml"]),
|
||||
("yacc", &["*.y"]),
|
||||
("yaml", &["*.yaml", "*.yml"]),
|
||||
("zsh", &["zshenv", ".zshenv", "zprofile", ".zprofile", "zshrc", ".zshrc", "zlogin", ".zlogin", "zlogout", ".zlogout", "*.zsh"]),
|
||||
];
|
||||
|
||||
/// Glob represents a single glob in a set of file type definitions.
|
||||
///
|
||||
/// There may be more than one glob for a particular file type.
|
||||
///
|
||||
/// This is used to report information about the highest precedent glob
|
||||
/// that matched.
|
||||
///
|
||||
/// Note that not all matches necessarily correspond to a specific glob.
|
||||
/// For example, if there are one or more selections and a file path doesn't
|
||||
/// match any of those selections, then the file path is considered to be
|
||||
/// ignored.
|
||||
///
|
||||
/// The lifetime `'a` refers to the lifetime of the underlying file type
|
||||
/// definition, which corresponds to the lifetime of the file type matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Glob<'a>(GlobInner<'a>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum GlobInner<'a> {
|
||||
/// No glob matched, but the file path should still be ignored.
|
||||
UnmatchedIgnore,
|
||||
/// A glob matched.
|
||||
Matched {
|
||||
/// The file type definition which provided the glob.
|
||||
def: &'a FileTypeDef,
|
||||
/// The index of the glob that matched inside the file type definition.
|
||||
which: usize,
|
||||
/// Whether the selection was negated or not.
|
||||
negated: bool,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Glob<'a> {
|
||||
fn unmatched() -> Glob<'a> {
|
||||
Glob(GlobInner::UnmatchedIgnore)
|
||||
}
|
||||
}
|
||||
|
||||
/// A single file type definition.
|
||||
///
|
||||
/// 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, Eq, PartialEq)]
|
||||
pub struct FileTypeDef {
|
||||
name: String,
|
||||
globs: Vec<String>,
|
||||
}
|
||||
|
||||
impl FileTypeDef {
|
||||
/// Return the name of this file type.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// Return the globs used to recognize this file type.
|
||||
pub fn globs(&self) -> &[String] {
|
||||
&self.globs
|
||||
}
|
||||
}
|
||||
|
||||
/// Types is a file type matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Types {
|
||||
/// All of the file type definitions, sorted lexicographically by name.
|
||||
defs: Vec<FileTypeDef>,
|
||||
/// All of the selections made by the user.
|
||||
selections: Vec<Selection<FileTypeDef>>,
|
||||
/// Whether there is at least one Selection::Select in our selections.
|
||||
/// When this is true, a Match::None is converted to Match::Ignore.
|
||||
has_selected: bool,
|
||||
/// A mapping from glob index in the set to two indices. The first is an
|
||||
/// index into `selections` and the second is an index into the
|
||||
/// corresponding file type definition's list of globs.
|
||||
glob_to_selection: Vec<(usize, usize)>,
|
||||
/// The set of all glob selections, used for actual matching.
|
||||
set: GlobSet,
|
||||
/// Temporary storage for globs that match.
|
||||
matches: Arc<ThreadLocal<RefCell<Vec<usize>>>>,
|
||||
}
|
||||
|
||||
/// Indicates the type of a selection for a particular file type.
|
||||
#[derive(Clone, Debug)]
|
||||
enum Selection<T> {
|
||||
Select(String, T),
|
||||
Negate(String, T),
|
||||
}
|
||||
|
||||
impl<T> Selection<T> {
|
||||
fn is_negated(&self) -> bool {
|
||||
match *self {
|
||||
Selection::Select(..) => false,
|
||||
Selection::Negate(..) => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
match *self {
|
||||
Selection::Select(ref name, _) => name,
|
||||
Selection::Negate(ref name, _) => name,
|
||||
}
|
||||
}
|
||||
|
||||
fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Selection<U> {
|
||||
match self {
|
||||
Selection::Select(name, inner) => {
|
||||
Selection::Select(name, f(inner))
|
||||
}
|
||||
Selection::Negate(name, inner) => {
|
||||
Selection::Negate(name, f(inner))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inner(&self) -> &T {
|
||||
match *self {
|
||||
Selection::Select(_, ref inner) => inner,
|
||||
Selection::Negate(_, ref inner) => inner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Types {
|
||||
/// Creates a new file type matcher that never matches any path and
|
||||
/// contains no file type definitions.
|
||||
pub fn empty() -> Types {
|
||||
Types {
|
||||
defs: vec![],
|
||||
selections: vec![],
|
||||
has_selected: false,
|
||||
glob_to_selection: vec![],
|
||||
set: GlobSetBuilder::new().build().unwrap(),
|
||||
matches: Arc::new(ThreadLocal::default()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if this matcher has zero selections.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.selections.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the number of selections used in this matcher.
|
||||
pub fn len(&self) -> usize {
|
||||
self.selections.len()
|
||||
}
|
||||
|
||||
/// Return the set of current file type definitions.
|
||||
///
|
||||
/// Definitions and globs are sorted.
|
||||
pub fn definitions(&self) -> &[FileTypeDef] {
|
||||
&self.defs
|
||||
}
|
||||
|
||||
/// Returns a match for the given path against this file type matcher.
|
||||
///
|
||||
/// The path is considered whitelisted if it matches a selected file type.
|
||||
/// The path is considered ignored if it matches a negated file type.
|
||||
/// If at least one file type is selected and `path` doesn't match, then
|
||||
/// the path is also considered ignored.
|
||||
pub fn matched<'a, P: AsRef<Path>>(
|
||||
&'a self,
|
||||
path: P,
|
||||
is_dir: bool,
|
||||
) -> Match<Glob<'a>> {
|
||||
// File types don't apply to directories, and we can't do anything
|
||||
// if our glob set is empty.
|
||||
if is_dir || self.set.is_empty() {
|
||||
return Match::None;
|
||||
}
|
||||
// We only want to match against the file name, so extract it.
|
||||
// If one doesn't exist, then we can't match it.
|
||||
let name = match file_name(path.as_ref()) {
|
||||
Some(name) => name,
|
||||
None if self.has_selected => {
|
||||
return Match::Ignore(Glob::unmatched());
|
||||
}
|
||||
None => {
|
||||
return Match::None;
|
||||
}
|
||||
};
|
||||
let mut matches = self.matches.get_default().borrow_mut();
|
||||
self.set.matches_into(name, &mut *matches);
|
||||
// The highest precedent match is the last one.
|
||||
if let Some(&i) = matches.last() {
|
||||
let (isel, iglob) = self.glob_to_selection[i];
|
||||
let sel = &self.selections[isel];
|
||||
let glob = Glob(GlobInner::Matched {
|
||||
def: sel.inner(),
|
||||
which: iglob,
|
||||
negated: sel.is_negated(),
|
||||
});
|
||||
return if sel.is_negated() {
|
||||
Match::Ignore(glob)
|
||||
} else {
|
||||
Match::Whitelist(glob)
|
||||
};
|
||||
}
|
||||
if self.has_selected {
|
||||
Match::Ignore(Glob::unmatched())
|
||||
} else {
|
||||
Match::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// TypesBuilder builds a type matcher from a set of file type definitions and
|
||||
/// a set of file type selections.
|
||||
pub struct TypesBuilder {
|
||||
types: HashMap<String, FileTypeDef>,
|
||||
selections: Vec<Selection<()>>,
|
||||
}
|
||||
|
||||
impl TypesBuilder {
|
||||
/// Create a new builder for a file type matcher.
|
||||
///
|
||||
/// The builder contains *no* type definitions to start with. A set
|
||||
/// of default type definitions can be added with `add_defaults`, and
|
||||
/// additional type definitions can be added with `select` and `negate`.
|
||||
pub fn new() -> TypesBuilder {
|
||||
TypesBuilder {
|
||||
types: HashMap::new(),
|
||||
selections: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the current set of file type definitions *and* selections into
|
||||
/// a file type matcher.
|
||||
pub fn build(&self) -> Result<Types, Error> {
|
||||
let defs = self.definitions();
|
||||
let has_selected = self.selections.iter().any(|s| !s.is_negated());
|
||||
|
||||
let mut selections = vec![];
|
||||
let mut glob_to_selection = vec![];
|
||||
let mut build_set = GlobSetBuilder::new();
|
||||
for (isel, selection) in self.selections.iter().enumerate() {
|
||||
let def = match self.types.get(selection.name()) {
|
||||
Some(def) => def.clone(),
|
||||
None => {
|
||||
let name = selection.name().to_string();
|
||||
return Err(Error::UnrecognizedFileType(name));
|
||||
}
|
||||
};
|
||||
for (iglob, glob) in def.globs.iter().enumerate() {
|
||||
build_set.add(try!(
|
||||
GlobBuilder::new(glob)
|
||||
.literal_separator(true)
|
||||
.build()
|
||||
.map_err(|err| Error::Glob(err.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())
|
||||
}));
|
||||
Ok(Types {
|
||||
defs: defs,
|
||||
selections: selections,
|
||||
has_selected: has_selected,
|
||||
glob_to_selection: glob_to_selection,
|
||||
set: set,
|
||||
matches: Arc::new(ThreadLocal::default()),
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the set of current file type definitions.
|
||||
///
|
||||
/// Definitions and globs are sorted.
|
||||
pub fn definitions(&self) -> Vec<FileTypeDef> {
|
||||
let mut defs = vec![];
|
||||
for def in self.types.values() {
|
||||
let mut def = def.clone();
|
||||
def.globs.sort();
|
||||
defs.push(def);
|
||||
}
|
||||
defs.sort_by(|def1, def2| def1.name().cmp(def2.name()));
|
||||
defs
|
||||
}
|
||||
|
||||
/// Select the file type given by `name`.
|
||||
///
|
||||
/// If `name` is `all`, then all file types currently defined are selected.
|
||||
pub fn select(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.selections.push(Selection::Select(name.to_string(), ()));
|
||||
}
|
||||
} else {
|
||||
self.selections.push(Selection::Select(name.to_string(), ()));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Ignore the file type given by `name`.
|
||||
///
|
||||
/// If `name` is `all`, then all file types currently defined are negated.
|
||||
pub fn negate(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.selections.push(Selection::Negate(name.to_string(), ()));
|
||||
}
|
||||
} else {
|
||||
self.selections.push(Selection::Negate(name.to_string(), ()));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Clear any file type definitions for the type name given.
|
||||
pub fn clear(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
self.types.remove(name);
|
||||
self
|
||||
}
|
||||
|
||||
/// 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 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> {
|
||||
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());
|
||||
self.types.entry(key).or_insert_with(|| {
|
||||
FileTypeDef { name: name.to_string(), globs: vec![] }
|
||||
}).globs.push(glob);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 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 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 {
|
||||
try!(self.add(name, &glob));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(Error::InvalidDefinition)
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a set of default file type definitions.
|
||||
pub fn add_defaults(&mut self) -> &mut TypesBuilder {
|
||||
static MSG: &'static str = "adding a default type should never fail";
|
||||
for &(name, exts) in DEFAULT_TYPES {
|
||||
for ext in exts {
|
||||
self.add(name, ext).expect(MSG);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::TypesBuilder;
|
||||
|
||||
macro_rules! matched {
|
||||
($name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr) => {
|
||||
matched!($name, $types, $sel, $selnot, $path, true);
|
||||
};
|
||||
(not, $name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr) => {
|
||||
matched!($name, $types, $sel, $selnot, $path, false);
|
||||
};
|
||||
($name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr, $matched:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut btypes = TypesBuilder::new();
|
||||
for tydef in $types {
|
||||
btypes.add_def(tydef).unwrap();
|
||||
}
|
||||
for sel in $sel {
|
||||
btypes.select(sel);
|
||||
}
|
||||
for selnot in $selnot {
|
||||
btypes.negate(selnot);
|
||||
}
|
||||
let types = btypes.build().unwrap();
|
||||
let mat = types.matched($path, false);
|
||||
assert_eq!($matched, !mat.is_ignore());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn types() -> Vec<&'static str> {
|
||||
vec![
|
||||
"html:*.html",
|
||||
"html:*.htm",
|
||||
"rust:*.rs",
|
||||
"js:*.js",
|
||||
"foo:*.{rs,foo}",
|
||||
"combo:include:html,rust"
|
||||
]
|
||||
}
|
||||
|
||||
matched!(match1, types(), vec!["rust"], vec![], "lib.rs");
|
||||
matched!(match2, types(), vec!["html"], vec![], "index.html");
|
||||
matched!(match3, types(), vec!["html"], vec![], "index.htm");
|
||||
matched!(match4, types(), vec!["html", "rust"], vec![], "main.rs");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
1565
ignore/src/walk.rs
Normal file
1565
ignore/src/walk.rs
Normal file
File diff suppressed because it is too large
Load Diff
4
pkg/archlinux/.gitignore
vendored
Normal file
4
pkg/archlinux/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.xz
|
||||
src
|
||||
pkg
|
||||
*.gz
|
||||
37
pkg/archlinux/PKGBUILD
Normal file
37
pkg/archlinux/PKGBUILD
Normal file
@@ -0,0 +1,37 @@
|
||||
# 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"
|
||||
}
|
||||
18
pkg/brew/ripgrep-bin.rb
Normal file
18
pkg/brew/ripgrep-bin.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class RipgrepBin < Formula
|
||||
version '0.5.0'
|
||||
desc "Search tool like grep and The Silver Searcher."
|
||||
homepage "https://github.com/BurntSushi/ripgrep"
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "5bfa8872c4f2a5d010ddec1c213d518056e62d4dd3b3f23a0ef099b85343dbdd"
|
||||
|
||||
conflicts_with "ripgrep"
|
||||
|
||||
def install
|
||||
bin.install "rg"
|
||||
man1.install "rg.1"
|
||||
|
||||
bash_completion.install "complete/rg.bash-completion"
|
||||
fish_completion.install "complete/rg.fish"
|
||||
zsh_completion.install "complete/_rg"
|
||||
end
|
||||
end
|
||||
511
src/app.rs
Normal file
511
src/app.rs
Normal file
@@ -0,0 +1,511 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use clap::{App, AppSettings, Arg, ArgSettings};
|
||||
|
||||
const ABOUT: &'static str = "
|
||||
ripgrep (rg) recursively searches your current directory for a regex pattern.
|
||||
|
||||
ripgrep's regex engine uses finite automata and guarantees linear time
|
||||
searching. Because of this, features like backreferences and arbitrary
|
||||
lookaround are not supported.
|
||||
|
||||
Project home page: https://github.com/BurntSushi/ripgrep
|
||||
|
||||
Use -h for short descriptions and --help for more details.";
|
||||
|
||||
const USAGE: &'static str = "
|
||||
rg [OPTIONS] <pattern> [<path> ...]
|
||||
rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
|
||||
rg [OPTIONS] --files [<path> ...]
|
||||
rg [OPTIONS] --type-list";
|
||||
|
||||
const TEMPLATE: &'static str = "\
|
||||
{bin} {version}
|
||||
{author}
|
||||
{about}
|
||||
|
||||
USAGE:{usage}
|
||||
|
||||
ARGS:
|
||||
{positionals}
|
||||
|
||||
OPTIONS:
|
||||
{unified}";
|
||||
|
||||
/// Build a clap application parameterized by usage strings.
|
||||
///
|
||||
/// The function given should take a clap argument name and return a help
|
||||
/// string. `app` will panic if a usage string is not defined.
|
||||
///
|
||||
/// This is an intentionally stand-alone module so that it can be used easily
|
||||
/// in a `build.rs` script to build shell completion files.
|
||||
pub fn app() -> App<'static, 'static> {
|
||||
let arg = |name| {
|
||||
Arg::with_name(name).help(USAGES[name].short).long_help(USAGES[name].long)
|
||||
};
|
||||
let flag = |name| arg(name).long(name);
|
||||
|
||||
App::new("ripgrep")
|
||||
.author(crate_authors!())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.max_term_width(100)
|
||||
.setting(AppSettings::UnifiedHelpMessage)
|
||||
.usage(USAGE)
|
||||
.template(TEMPLATE)
|
||||
.help_message("Prints help information. Use --help for more details.")
|
||||
// First, set up primary positional/flag arguments.
|
||||
.arg(arg("pattern")
|
||||
.required_unless_one(&[
|
||||
"file", "files", "help-short", "help", "regexp", "type-list",
|
||||
"ripgrep-version",
|
||||
]))
|
||||
.arg(arg("path").multiple(true))
|
||||
.arg(flag("regexp").short("e")
|
||||
.takes_value(true).multiple(true).number_of_values(1)
|
||||
.set(ArgSettings::AllowLeadingHyphen)
|
||||
.value_name("pattern"))
|
||||
.arg(flag("files")
|
||||
// This should also conflict with `pattern`, but the first file
|
||||
// path will actually be in `pattern`.
|
||||
.conflicts_with_all(&["file", "regexp", "type-list"]))
|
||||
.arg(flag("type-list")
|
||||
.conflicts_with_all(&["file", "files", "pattern", "regexp"]))
|
||||
// Second, set up common flags.
|
||||
.arg(flag("text").short("a"))
|
||||
.arg(flag("count").short("c"))
|
||||
.arg(flag("color")
|
||||
.value_name("WHEN")
|
||||
.takes_value(true)
|
||||
.hide_possible_values(true)
|
||||
.possible_values(&["never", "auto", "always", "ansi"]))
|
||||
.arg(flag("colors").value_name("SPEC")
|
||||
.takes_value(true).multiple(true).number_of_values(1))
|
||||
.arg(flag("encoding").short("E").value_name("ENCODING")
|
||||
.takes_value(true).number_of_values(1))
|
||||
.arg(flag("fixed-strings").short("F"))
|
||||
.arg(flag("glob").short("g")
|
||||
.takes_value(true).multiple(true).number_of_values(1)
|
||||
.value_name("GLOB"))
|
||||
.arg(flag("ignore-case").short("i"))
|
||||
.arg(flag("line-number").short("n"))
|
||||
.arg(flag("no-line-number").short("N"))
|
||||
.arg(flag("quiet").short("q"))
|
||||
.arg(flag("type").short("t")
|
||||
.takes_value(true).multiple(true).number_of_values(1)
|
||||
.value_name("TYPE"))
|
||||
.arg(flag("type-not").short("T")
|
||||
.takes_value(true).multiple(true).number_of_values(1)
|
||||
.value_name("TYPE"))
|
||||
.arg(flag("unrestricted").short("u")
|
||||
.multiple(true))
|
||||
.arg(flag("invert-match").short("v"))
|
||||
.arg(flag("word-regexp").short("w"))
|
||||
// Third, set up less common flags.
|
||||
.arg(flag("after-context").short("A")
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("before-context").short("B")
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("context").short("C")
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("column"))
|
||||
.arg(flag("context-separator")
|
||||
.value_name("SEPARATOR").takes_value(true))
|
||||
.arg(flag("debug"))
|
||||
.arg(flag("file").short("f")
|
||||
.value_name("FILE").takes_value(true)
|
||||
.multiple(true).number_of_values(1))
|
||||
.arg(flag("files-with-matches").short("l"))
|
||||
.arg(flag("files-without-match"))
|
||||
.arg(flag("with-filename").short("H"))
|
||||
.arg(flag("no-filename"))
|
||||
.arg(flag("heading").overrides_with("no-heading"))
|
||||
.arg(flag("no-heading").overrides_with("heading"))
|
||||
.arg(flag("hidden"))
|
||||
.arg(flag("ignore-file")
|
||||
.value_name("FILE").takes_value(true)
|
||||
.multiple(true).number_of_values(1))
|
||||
.arg(flag("follow").short("L"))
|
||||
.arg(flag("max-count")
|
||||
.short("m").value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("max-filesize")
|
||||
.value_name("NUM+SUFFIX?").takes_value(true))
|
||||
.arg(flag("maxdepth")
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("mmap"))
|
||||
.arg(flag("no-messages"))
|
||||
.arg(flag("no-mmap"))
|
||||
.arg(flag("no-ignore"))
|
||||
.arg(flag("no-ignore-parent"))
|
||||
.arg(flag("no-ignore-vcs"))
|
||||
.arg(flag("null").short("0"))
|
||||
.arg(flag("only-matching").short("o").conflicts_with("replace"))
|
||||
.arg(flag("path-separator").value_name("SEPARATOR").takes_value(true))
|
||||
.arg(flag("pretty").short("p"))
|
||||
.arg(flag("replace").short("r").value_name("ARG").takes_value(true))
|
||||
.arg(flag("case-sensitive").short("s"))
|
||||
.arg(flag("smart-case").short("S"))
|
||||
.arg(flag("sort-files"))
|
||||
.arg(flag("threads")
|
||||
.short("j").value_name("ARG").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("vimgrep"))
|
||||
.arg(flag("max-columns").short("M")
|
||||
.value_name("NUM").takes_value(true)
|
||||
.validator(validate_number))
|
||||
.arg(flag("type-add")
|
||||
.value_name("TYPE").takes_value(true)
|
||||
.multiple(true).number_of_values(1))
|
||||
.arg(flag("type-clear")
|
||||
.value_name("TYPE").takes_value(true)
|
||||
.multiple(true).number_of_values(1))
|
||||
}
|
||||
|
||||
struct Usage {
|
||||
short: &'static str,
|
||||
long: &'static str,
|
||||
}
|
||||
|
||||
macro_rules! doc {
|
||||
($map:expr, $name:expr, $short:expr) => {
|
||||
doc!($map, $name, $short, $short)
|
||||
};
|
||||
($map:expr, $name:expr, $short:expr, $long:expr) => {
|
||||
$map.insert($name, Usage {
|
||||
short: $short,
|
||||
long: concat!($long, "\n "),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref USAGES: HashMap<&'static str, Usage> = {
|
||||
let mut h = HashMap::new();
|
||||
doc!(h, "help-short",
|
||||
"Show short help output.",
|
||||
"Show short help output. Use --help to show more details.");
|
||||
doc!(h, "help",
|
||||
"Show verbose help output.",
|
||||
"When given, more details about flags are provided.");
|
||||
doc!(h, "ripgrep-version",
|
||||
"Prints version information.");
|
||||
|
||||
doc!(h, "pattern",
|
||||
"A regular expression used for searching.",
|
||||
"A regular expression used for searching. Multiple patterns \
|
||||
may be given. To match a pattern beginning with a -, use [-].");
|
||||
doc!(h, "regexp",
|
||||
"A regular expression used for searching.",
|
||||
"A regular expression used for searching. Multiple patterns \
|
||||
may be given. To match a pattern beginning with a -, use [-].");
|
||||
doc!(h, "path",
|
||||
"A file or directory to search.",
|
||||
"A file or directory to search. Directories are searched \
|
||||
recursively.");
|
||||
doc!(h, "files",
|
||||
"Print each file that would be searched.",
|
||||
"Print each file that would be searched without actually \
|
||||
performing the search. This is useful to determine whether a \
|
||||
particular file is being searched or not.");
|
||||
doc!(h, "type-list",
|
||||
"Show all supported file types.",
|
||||
"Show all supported file types and their corresponding globs.");
|
||||
|
||||
doc!(h, "text",
|
||||
"Search binary files as if they were text.");
|
||||
doc!(h, "count",
|
||||
"Only show count of matches for each file.");
|
||||
doc!(h, "color",
|
||||
"When to use color. [default: auto]",
|
||||
"When to use color in the output. The possible values are \
|
||||
never, auto, always or ansi. The default is auto. When always \
|
||||
is used, coloring is attempted based on your environment. When \
|
||||
ansi used, coloring is forcefully done using ANSI escape color \
|
||||
codes.");
|
||||
doc!(h, "colors",
|
||||
"Configure color settings and styles.",
|
||||
"This flag specifies color settings for use in the output. \
|
||||
This flag may be provided multiple times. Settings are applied \
|
||||
iteratively. Colors are limited to one of eight choices: \
|
||||
red, blue, green, cyan, magenta, yellow, white and black. \
|
||||
Styles are limited to nobold, bold, nointense or intense.\n\n\
|
||||
The format of the flag is {type}:{attribute}:{value}. {type} \
|
||||
should be one of path, line, column or match. {attribute} can \
|
||||
be fg, bg or style. {value} is either a color (for fg and bg) \
|
||||
or a text style. A special format, {type}:none, will clear all \
|
||||
color settings for {type}.\n\nFor example, the following \
|
||||
command will change the match color to magenta and the \
|
||||
background color for line numbers to yellow:\n\n\
|
||||
rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo.");
|
||||
doc!(h, "encoding",
|
||||
"Specify the text encoding of files to search.",
|
||||
"Specify the text encoding that ripgrep will use on all files \
|
||||
searched. The default value is 'auto', which will cause ripgrep \
|
||||
to do a best effort automatic detection of encoding on a \
|
||||
per-file basis. Other supported values can be found in the list \
|
||||
of labels here: \
|
||||
https://encoding.spec.whatwg.org/#concept-encoding-get");
|
||||
doc!(h, "fixed-strings",
|
||||
"Treat the pattern as a literal string.",
|
||||
"Treat the pattern as a literal string instead of a regular \
|
||||
expression. When this flag is used, special regular expression \
|
||||
meta characters such as (){}*+. do not need to be escaped.");
|
||||
doc!(h, "glob",
|
||||
"Include or exclude files/directories.",
|
||||
"Include or exclude files/directories 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.");
|
||||
doc!(h, "ignore-case",
|
||||
"Case insensitive search.",
|
||||
"Case insensitive search. This is overridden by \
|
||||
--case-sensitive.");
|
||||
doc!(h, "line-number",
|
||||
"Show line numbers.",
|
||||
"Show line numbers (1-based). This is enabled by default when \
|
||||
searching in a tty.");
|
||||
doc!(h, "no-line-number",
|
||||
"Suppress line numbers.",
|
||||
"Suppress line numbers. This is enabled by default when NOT \
|
||||
searching in a tty.");
|
||||
doc!(h, "quiet",
|
||||
"Do not print anything to stdout.",
|
||||
"Do not print anything to stdout. If a match is found in a file, \
|
||||
stop searching. This is useful when ripgrep is used only for \
|
||||
its exit code.");
|
||||
doc!(h, "type",
|
||||
"Only search files matching TYPE.",
|
||||
"Only search files matching TYPE. Multiple type flags may be \
|
||||
provided. Use the --type-list flag to list all available \
|
||||
types.");
|
||||
doc!(h, "type-not",
|
||||
"Do not search files matching TYPE.",
|
||||
"Do not search files matching TYPE. Multiple type-not flags may \
|
||||
be provided. Use the --type-list flag to list all available \
|
||||
types.");
|
||||
doc!(h, "unrestricted",
|
||||
"Reduce the level of \"smart\" searching.",
|
||||
"Reduce the level of \"smart\" searching. A single -u \
|
||||
won't respect .gitignore (etc.) files. Two -u flags will \
|
||||
additionally search hidden files and directories. Three \
|
||||
-u flags will additionally search binary files. -uu is \
|
||||
roughly equivalent to grep -r and -uuu is roughly \
|
||||
equivalent to grep -a -r.");
|
||||
doc!(h, "invert-match",
|
||||
"Invert matching.",
|
||||
"Invert matching. Show lines that don't match given patterns.");
|
||||
doc!(h, "word-regexp",
|
||||
"Only show matches surrounded by word boundaries.",
|
||||
"Only show matches surrounded by word boundaries. This is \
|
||||
equivalent to putting \\b before and after all of the search \
|
||||
patterns.");
|
||||
|
||||
doc!(h, "after-context",
|
||||
"Show NUM lines after each match.");
|
||||
doc!(h, "before-context",
|
||||
"Show NUM lines before each match.");
|
||||
doc!(h, "context",
|
||||
"Show NUM lines before and after each match.");
|
||||
doc!(h, "column",
|
||||
"Show column numbers",
|
||||
"Show column numbers (1-based). This only shows the column \
|
||||
numbers for the first match on each line. This does not try \
|
||||
to account for Unicode. One byte is equal to one column. This \
|
||||
implies --line-number.");
|
||||
doc!(h, "context-separator",
|
||||
"Set the context separator string. [default: --]",
|
||||
"The string used to separate non-contiguous context lines in the \
|
||||
output. Escape sequences like \\x7F or \\t may be used. The \
|
||||
default value is --.");
|
||||
doc!(h, "debug",
|
||||
"Show debug messages.",
|
||||
"Show debug messages. Please use this when filing a bug report.");
|
||||
doc!(h, "file",
|
||||
"Search for patterns from the given file.",
|
||||
"Search for patterns from the given file, with one pattern per \
|
||||
line. When this flag is used or multiple times or in \
|
||||
combination with the -e/--regexp flag, then all patterns \
|
||||
provided are searched. Empty pattern lines will match all input \
|
||||
lines, and the newline is not counted as part of the pattern.");
|
||||
doc!(h, "files-with-matches",
|
||||
"Only show the paths with at least one match.");
|
||||
doc!(h, "files-without-match",
|
||||
"Only show the paths that contains zero matches.");
|
||||
doc!(h, "with-filename",
|
||||
"Show file name for each match.",
|
||||
"Prefix each match with the file name that contains it. This is \
|
||||
the default when more than one file is searched.");
|
||||
doc!(h, "no-filename",
|
||||
"Never show the file name for a match.",
|
||||
"Never show the file name for a match. This is the default when \
|
||||
one file is searched.");
|
||||
doc!(h, "heading",
|
||||
"Show matches grouped by each file.",
|
||||
"This shows the file name above clusters of matches from each \
|
||||
file instead of showing the file name for every match. This is \
|
||||
the default mode at a tty.");
|
||||
doc!(h, "no-heading",
|
||||
"Don't group matches by each file.",
|
||||
"Don't group matches by each file. If -H/--with-filename is \
|
||||
enabled, then file names will be shown for every line matched. \
|
||||
This is the default mode when not at a tty.");
|
||||
doc!(h, "hidden",
|
||||
"Search hidden files and directories.",
|
||||
"Search hidden files and directories. By default, hidden files \
|
||||
and directories are skipped.");
|
||||
doc!(h, "ignore-file",
|
||||
"Specify additional ignore files.",
|
||||
"Specify additional ignore files for filtering file paths. \
|
||||
Ignore files should be in the gitignore format and are matched \
|
||||
relative to the current working directory. These ignore files \
|
||||
have lower precedence than all other ignore files. When \
|
||||
specifying multiple ignore files, earlier files have lower \
|
||||
precedence than later files.");
|
||||
doc!(h, "follow",
|
||||
"Follow symbolic links.");
|
||||
doc!(h, "max-count",
|
||||
"Limit the number of matches.",
|
||||
"Limit the number of matching lines per file searched to NUM.");
|
||||
doc!(h, "max-filesize",
|
||||
"Ignore files larger than NUM in size.",
|
||||
"Ignore files larger than NUM in size. Does not ignore \
|
||||
directories. \
|
||||
\n\nThe input format accepts suffixes of K, M or G which \
|
||||
correspond to kilobytes, megabytes and gigabytes. If no suffix \
|
||||
is provided the input is treated as bytes. \
|
||||
\n\nExample: --max-filesize 50K or --max-filesize 80M");
|
||||
doc!(h, "maxdepth",
|
||||
"Descend at most NUM directories.",
|
||||
"Limit the depth of directory traversal to NUM levels beyond \
|
||||
the paths given. A value of zero only searches the \
|
||||
starting-points themselves.\n\nFor example, \
|
||||
'rg --maxdepth 0 dir/' is a no-op because dir/ will not be \
|
||||
descended into. 'rg --maxdepth 1 dir/' will search only the \
|
||||
direct children of dir/.");
|
||||
doc!(h, "mmap",
|
||||
"Searching using memory maps when possible.",
|
||||
"Search using memory maps when possible. This is enabled by \
|
||||
default when ripgrep thinks it will be faster. Note that memory \
|
||||
map searching doesn't currently support all options, so if an \
|
||||
incompatible option (e.g., --context) is given with --mmap, \
|
||||
then memory maps will not be used.");
|
||||
doc!(h, "no-messages",
|
||||
"Suppress all error messages.",
|
||||
"Suppress all error messages. This is equivalent to redirecting \
|
||||
stderr to /dev/null.");
|
||||
doc!(h, "no-mmap",
|
||||
"Never use memory maps.",
|
||||
"Never use memory maps, even when they might be faster.");
|
||||
doc!(h, "no-ignore",
|
||||
"Don't respect ignore files.",
|
||||
"Don't respect ignore files (.gitignore, .ignore, etc.). This \
|
||||
implies --no-ignore-parent and --no-ignore-vcs.");
|
||||
doc!(h, "no-ignore-parent",
|
||||
"Don't respect ignore files in parent directories.",
|
||||
"Don't respect ignore files (.gitignore, .ignore, etc.) in \
|
||||
parent directories.");
|
||||
doc!(h, "no-ignore-vcs",
|
||||
"Don't respect VCS ignore files",
|
||||
"Don't respect version control ignore files (.gitignore, etc.). \
|
||||
This implies --no-ignore-parent. Note that .ignore files will \
|
||||
continue to be respected.");
|
||||
doc!(h, "null",
|
||||
"Print NUL byte after file names",
|
||||
"Whenever a file name is printed, follow it with a NUL byte. \
|
||||
This includes printing file names before matches, and when \
|
||||
printing a list of matching files such as with --count, \
|
||||
--files-with-matches and --files. This option is useful for use \
|
||||
with xargs.");
|
||||
doc!(h, "only-matching",
|
||||
"Print only matched parts of a line.",
|
||||
"Print only the matched (non-empty) parts of a matching line, \
|
||||
with each such part on a separate output line.");
|
||||
doc!(h, "path-separator",
|
||||
"Path separator to use when printing file paths.",
|
||||
"The path separator to use when printing file paths. This \
|
||||
defaults to your platform's path separator, which is / on Unix \
|
||||
and \\ on Windows. This flag is intended for overriding the \
|
||||
default when the environment demands it (e.g., cygwin). A path \
|
||||
separator is limited to a single byte.");
|
||||
doc!(h, "pretty",
|
||||
"Alias for --color always --heading -n.");
|
||||
doc!(h, "replace",
|
||||
"Replace matches with string given.",
|
||||
"Replace every match with the string given when printing \
|
||||
results. Neither this flag nor any other flag will modify your \
|
||||
files.\n\nCapture group indices (e.g., $5) and names \
|
||||
(e.g., $foo) are supported in the replacement string.\n\n\
|
||||
Note that the replacement by default replaces each match, and \
|
||||
NOT the entire line. To replace the entire line, you should \
|
||||
match the entire line.");
|
||||
doc!(h, "case-sensitive",
|
||||
"Search case sensitively.",
|
||||
"Search case sensitively. This overrides -i/--ignore-case and \
|
||||
-S/--smart-case.");
|
||||
doc!(h, "smart-case",
|
||||
"Smart case search.",
|
||||
"Searches case insensitively if the pattern is all lowercase. \
|
||||
Search case sensitively otherwise. This is overridden by \
|
||||
either -s/--case-sensitive or -i/--ignore-case.");
|
||||
doc!(h, "sort-files",
|
||||
"Sort results by file path. Implies --threads=1.",
|
||||
"Sort results by file path. Note that this currently \
|
||||
disables all parallelism and runs search in a single thread.");
|
||||
doc!(h, "threads",
|
||||
"The approximate number of threads to use.",
|
||||
"The approximate number of threads to use. A value of 0 (which \
|
||||
is the default) causes ripgrep to choose the thread count \
|
||||
using heuristics.");
|
||||
doc!(h, "vimgrep",
|
||||
"Show results in vim compatible format.",
|
||||
"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 will be printed more than once.");
|
||||
doc!(h, "max-columns",
|
||||
"Don't print lines longer than this limit in bytes.",
|
||||
"Don't print lines longer than this limit in bytes. Longer lines \
|
||||
are omitted, and only the number of matches in that line is \
|
||||
printed.");
|
||||
|
||||
doc!(h, "type-add",
|
||||
"Add a new glob for a file type.",
|
||||
"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 defined inside of ripgrep.\n\nNote that this MUST be \
|
||||
passed to every invocation of ripgrep. Type settings are NOT \
|
||||
persisted.\n\nExample: \
|
||||
rg --type-add 'foo:*.foo' -tfoo PATTERN.\n\n\
|
||||
--type-add can also be used to include rules from other types \
|
||||
with the special include directive. The include directive \
|
||||
permits specifying one or more other type names (separated by a \
|
||||
comma) that have been defined and its rules will automatically \
|
||||
be imported into the type specified. For example, to create a \
|
||||
type called src that matches C++, Python and Markdown files, \
|
||||
one can use:\n\n\
|
||||
--type-add 'src:include:cpp,py,md'\n\n\
|
||||
Additional glob rules can still be added to the src type by \
|
||||
using the --type-add flag again:\n\n\
|
||||
--type-add 'src:include:cpp,py,md' --type-add 'src:*.foo'\n\n\
|
||||
Note that type names must consist only of Unicode letters or \
|
||||
numbers. Punctuation characters are not allowed.");
|
||||
doc!(h, "type-clear",
|
||||
"Clear globs for given file type.",
|
||||
"Clear the file type globs previously defined for TYPE. This \
|
||||
only clears the default type definitions that are found inside \
|
||||
of ripgrep.\n\nNote that this MUST be passed to every \
|
||||
invocation of ripgrep. Type settings are NOT persisted.");
|
||||
|
||||
h
|
||||
};
|
||||
}
|
||||
|
||||
fn validate_number(s: String) -> Result<(), String> {
|
||||
s.parse::<usize>().map(|_|()).map_err(|err| err.to_string())
|
||||
}
|
||||
1315
src/args.rs
1315
src/args.rs
File diff suppressed because it is too large
Load Diff
41
src/atty.rs
41
src/atty.rs
@@ -1,41 +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 on_stdin() -> bool {
|
||||
use libc;
|
||||
0 < unsafe { libc::isatty(libc::STDIN_FILENO) }
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn on_stdout() -> bool {
|
||||
use libc;
|
||||
0 < unsafe { libc::isatty(libc::STDOUT_FILENO) }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn on_stdin() -> bool {
|
||||
use kernel32;
|
||||
use winapi;
|
||||
|
||||
unsafe {
|
||||
let fd = winapi::winbase::STD_INPUT_HANDLE;
|
||||
let mut out = 0;
|
||||
kernel32::GetConsoleMode(kernel32::GetStdHandle(fd), &mut out) != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
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 = try!(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 = try!(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 = try!(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 trancoded 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 trancoding.
|
||||
///
|
||||
/// 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 +=
|
||||
try!(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 {
|
||||
try!(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.
|
||||
try!(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 = try!(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;
|
||||
try!(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", "©");
|
||||
}
|
||||
409
src/gitignore.rs
409
src/gitignore.rs
@@ -1,409 +0,0 @@
|
||||
/*!
|
||||
The gitignore module provides a way of reading a gitignore file and applying
|
||||
it to a particular file name to determine whether it should be ignore or not.
|
||||
The motivation for this submodule is performance and portability:
|
||||
|
||||
1. There is a gitignore crate on crates.io, but it uses the standard `glob`
|
||||
crate and checks patterns one-by-one. This is a reasonable implementation,
|
||||
but not suitable for the performance we need here.
|
||||
2. We could shell out to a `git` sub-command like ls-files or status, but it
|
||||
seems better to not rely on the existence of external programs for a search
|
||||
tool. Besides, we need to implement this logic anyway to support things like
|
||||
an .rgignore file.
|
||||
|
||||
The key implementation detail here is that a single gitignore file is compiled
|
||||
into a single RegexSet, which can be used to report which globs match a
|
||||
particular file name. We can then do a quick post-processing step to implement
|
||||
additional rules such as whitelists (prefix of `!`) or directory-only globs
|
||||
(suffix of `/`).
|
||||
*/
|
||||
|
||||
// TODO(burntsushi): Implement something similar, but for Mercurial. We can't
|
||||
// use this exact implementation because hgignore files are different.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use regex;
|
||||
|
||||
use glob;
|
||||
use pathutil::strip_prefix;
|
||||
|
||||
/// Represents an error that can occur when parsing a gitignore file.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Glob(glob::Error),
|
||||
Regex(regex::Error),
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Glob(ref err) => err.description(),
|
||||
Error::Regex(ref err) => err.description(),
|
||||
Error::Io(ref err) => err.description(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Glob(ref err) => err.fmt(f),
|
||||
Error::Regex(ref err) => err.fmt(f),
|
||||
Error::Io(ref err) => err.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<glob::Error> for Error {
|
||||
fn from(err: glob::Error) -> Error {
|
||||
Error::Glob(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<regex::Error> for Error {
|
||||
fn from(err: regex::Error) -> Error {
|
||||
Error::Regex(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(err: io::Error) -> Error {
|
||||
Error::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Gitignore is a matcher for the glob patterns in a single gitignore file.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Gitignore {
|
||||
set: glob::Set,
|
||||
root: PathBuf,
|
||||
patterns: Vec<Pattern>,
|
||||
num_ignores: u64,
|
||||
num_whitelist: u64,
|
||||
}
|
||||
|
||||
impl Gitignore {
|
||||
/// Create a new gitignore glob matcher from the given root directory and
|
||||
/// string containing the contents of a gitignore file.
|
||||
#[allow(dead_code)]
|
||||
fn from_str<P: AsRef<Path>>(
|
||||
root: P,
|
||||
gitignore: &str,
|
||||
) -> Result<Gitignore, Error> {
|
||||
let mut builder = GitignoreBuilder::new(root);
|
||||
try!(builder.add_str(gitignore));
|
||||
builder.build()
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given file path should be ignored
|
||||
/// according to the globs in this gitignore. `is_dir` should be true if
|
||||
/// the path refers to a directory and false otherwise.
|
||||
///
|
||||
/// 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 reside in the
|
||||
/// same directory as this gitignore file.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
let mut path = path.as_ref();
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
if let Some(p) = strip_prefix(&self.root, path) {
|
||||
path = p;
|
||||
}
|
||||
self.matched_stripped(path, is_dir)
|
||||
}
|
||||
|
||||
/// Like matched, but takes a path that has already been stripped.
|
||||
pub fn matched_stripped(&self, path: &Path, is_dir: bool) -> Match {
|
||||
thread_local! {
|
||||
static MATCHES: RefCell<Vec<usize>> = {
|
||||
RefCell::new(vec![])
|
||||
}
|
||||
};
|
||||
MATCHES.with(|matches| {
|
||||
let mut matches = matches.borrow_mut();
|
||||
self.set.matches_into(path, &mut *matches);
|
||||
for &i in matches.iter().rev() {
|
||||
let pat = &self.patterns[i];
|
||||
if !pat.only_dir || is_dir {
|
||||
return if pat.whitelist {
|
||||
Match::Whitelist(pat)
|
||||
} else {
|
||||
Match::Ignored(pat)
|
||||
};
|
||||
}
|
||||
}
|
||||
Match::None
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the total number of ignore patterns.
|
||||
pub fn num_ignores(&self) -> u64 {
|
||||
self.num_ignores
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of a glob match.
|
||||
///
|
||||
/// The lifetime `'a` refers to the lifetime of the pattern that resulted in
|
||||
/// a match (whether ignored or whitelisted).
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Match<'a> {
|
||||
/// The path didn't match any glob in the gitignore file.
|
||||
None,
|
||||
/// The last glob matched indicates the path should be ignored.
|
||||
Ignored(&'a Pattern),
|
||||
/// The last glob matched indicates the path should be whitelisted.
|
||||
Whitelist(&'a Pattern),
|
||||
}
|
||||
|
||||
impl<'a> Match<'a> {
|
||||
/// Returns true if the match result implies the path should be ignored.
|
||||
#[allow(dead_code)]
|
||||
pub fn is_ignored(&self) -> bool {
|
||||
match *self {
|
||||
Match::Ignored(_) => true,
|
||||
Match::None | Match::Whitelist(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the match result didn't match any globs.
|
||||
pub fn is_none(&self) -> bool {
|
||||
match *self {
|
||||
Match::None => true,
|
||||
Match::Ignored(_) | Match::Whitelist(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inverts the match so that Ignored becomes Whitelisted and Whitelisted
|
||||
/// becomes Ignored. A non-match remains the same.
|
||||
pub fn invert(self) -> Match<'a> {
|
||||
match self {
|
||||
Match::None => Match::None,
|
||||
Match::Ignored(pat) => Match::Whitelist(pat),
|
||||
Match::Whitelist(pat) => Match::Ignored(pat),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GitignoreBuilder constructs a matcher for a single set of globs from a
|
||||
/// .gitignore file.
|
||||
pub struct GitignoreBuilder {
|
||||
builder: glob::SetBuilder,
|
||||
root: PathBuf,
|
||||
patterns: Vec<Pattern>,
|
||||
}
|
||||
|
||||
/// Pattern represents a single pattern in a gitignore file. It doesn't
|
||||
/// know how to do glob matching directly, but it does store additional
|
||||
/// options on a pattern, such as whether it's whitelisted.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Pattern {
|
||||
/// The file path that this pattern was extracted from (may be empty).
|
||||
pub from: PathBuf,
|
||||
/// The original glob pattern string.
|
||||
pub original: String,
|
||||
/// The actual glob pattern string used to convert to a regex.
|
||||
pub pat: String,
|
||||
/// Whether this is a whitelisted pattern or not.
|
||||
pub whitelist: bool,
|
||||
/// Whether this pattern should only match directories or not.
|
||||
pub only_dir: bool,
|
||||
}
|
||||
|
||||
impl GitignoreBuilder {
|
||||
/// Create a new builder for a gitignore file.
|
||||
///
|
||||
/// The path given should be the path at which the globs for this gitignore
|
||||
/// file should be matched.
|
||||
pub fn new<P: AsRef<Path>>(root: P) -> GitignoreBuilder {
|
||||
GitignoreBuilder {
|
||||
builder: glob::SetBuilder::new(),
|
||||
root: root.as_ref().to_path_buf(),
|
||||
patterns: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a new matcher from the glob patterns added so far.
|
||||
///
|
||||
/// Once a matcher is built, no new glob patterns can be added to it.
|
||||
pub fn build(self) -> Result<Gitignore, Error> {
|
||||
let nignores = self.patterns.iter().filter(|p| !p.whitelist).count();
|
||||
let nwhitelist = self.patterns.iter().filter(|p| p.whitelist).count();
|
||||
Ok(Gitignore {
|
||||
set: try!(self.builder.build()),
|
||||
root: self.root,
|
||||
patterns: self.patterns,
|
||||
num_ignores: nignores as u64,
|
||||
num_whitelist: nwhitelist as u64,
|
||||
})
|
||||
}
|
||||
|
||||
/// Add each pattern line from the file path given.
|
||||
pub fn add_path<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||
let rdr = io::BufReader::new(try!(File::open(&path)));
|
||||
for line in rdr.lines() {
|
||||
try!(self.add(&path, &try!(line)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add each pattern line from the string given.
|
||||
pub fn add_str(&mut self, gitignore: &str) -> Result<(), Error> {
|
||||
for line in gitignore.lines() {
|
||||
try!(self.add("", line));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a line from a gitignore file to this builder.
|
||||
///
|
||||
/// If the line could not be parsed as a glob, then an error is returned.
|
||||
pub fn add<P: AsRef<Path>>(
|
||||
&mut self,
|
||||
from: P,
|
||||
mut line: &str,
|
||||
) -> Result<(), Error> {
|
||||
if line.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let mut pat = Pattern {
|
||||
from: from.as_ref().to_path_buf(),
|
||||
original: line.to_string(),
|
||||
pat: String::new(),
|
||||
whitelist: false,
|
||||
only_dir: false,
|
||||
};
|
||||
let mut opts = glob::MatchOptions::default();
|
||||
let has_slash = line.chars().any(|c| c == '/');
|
||||
// If the line starts with an escaped '!', then remove the escape.
|
||||
// Otherwise, if it starts with an unescaped '!', then this is a
|
||||
// whitelist pattern.
|
||||
match line.chars().nth(0) {
|
||||
Some('#') => return Ok(()),
|
||||
Some('\\') => {
|
||||
match line.chars().nth(1) {
|
||||
Some('!') | Some('#') => {
|
||||
line = &line[1..];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Some('!') => {
|
||||
pat.whitelist = true;
|
||||
line = &line[1..];
|
||||
}
|
||||
Some('/') => {
|
||||
// `man gitignore` says that if a glob starts with a slash,
|
||||
// then the glob can only match the beginning of a path
|
||||
// (relative to the location of gitignore). We achieve this by
|
||||
// simply banning wildcards from matching /.
|
||||
opts.require_literal_separator = true;
|
||||
line = &line[1..];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// If it ends with a slash, then this should only match directories,
|
||||
// but the slash should otherwise not be used while globbing.
|
||||
if let Some((i, c)) = line.char_indices().rev().nth(0) {
|
||||
if c == '/' {
|
||||
pat.only_dir = true;
|
||||
line = &line[..i];
|
||||
}
|
||||
}
|
||||
// If there is a literal slash, then we note that so that globbing
|
||||
// doesn't let wildcards match slashes. Otherwise, we need to let
|
||||
// the pattern match anywhere, so we add a `**/` prefix to achieve
|
||||
// that behavior.
|
||||
pat.pat = line.to_string();
|
||||
if has_slash {
|
||||
opts.require_literal_separator = true;
|
||||
} else {
|
||||
pat.pat = format!("**/{}", pat.pat);
|
||||
}
|
||||
try!(self.builder.add_with(&pat.pat, &opts));
|
||||
self.patterns.push(pat);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Gitignore;
|
||||
|
||||
macro_rules! ignored {
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr) => {
|
||||
ignored!($name, $root, $gi, $path, false);
|
||||
};
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr, $is_dir:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let gi = Gitignore::from_str($root, $gi).unwrap();
|
||||
assert!(gi.matched($path, $is_dir).is_ignored());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! not_ignored {
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr) => {
|
||||
not_ignored!($name, $root, $gi, $path, false);
|
||||
};
|
||||
($name:ident, $root:expr, $gi:expr, $path:expr, $is_dir:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let gi = Gitignore::from_str($root, $gi).unwrap();
|
||||
assert!(!gi.matched($path, $is_dir).is_ignored());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const ROOT: &'static str = "/home/foobar/rust/rg";
|
||||
|
||||
ignored!(ig1, ROOT, "months", "months");
|
||||
ignored!(ig2, ROOT, "*.lock", "Cargo.lock");
|
||||
ignored!(ig3, ROOT, "*.rs", "src/main.rs");
|
||||
ignored!(ig4, ROOT, "src/*.rs", "src/main.rs");
|
||||
ignored!(ig5, ROOT, "/*.c", "cat-file.c");
|
||||
ignored!(ig6, ROOT, "/src/*.rs", "src/main.rs");
|
||||
ignored!(ig7, ROOT, "!src/main.rs\n*.rs", "src/main.rs");
|
||||
ignored!(ig8, ROOT, "foo/", "foo", true);
|
||||
ignored!(ig9, ROOT, "**/foo", "foo");
|
||||
ignored!(ig10, ROOT, "**/foo", "src/foo");
|
||||
ignored!(ig11, ROOT, "**/foo/**", "src/foo/bar");
|
||||
ignored!(ig12, ROOT, "**/foo/**", "wat/src/foo/bar/baz");
|
||||
ignored!(ig13, ROOT, "**/foo/bar", "foo/bar");
|
||||
ignored!(ig14, ROOT, "**/foo/bar", "src/foo/bar");
|
||||
ignored!(ig15, ROOT, "abc/**", "abc/x");
|
||||
ignored!(ig16, ROOT, "abc/**", "abc/x/y");
|
||||
ignored!(ig17, ROOT, "abc/**", "abc/x/y/z");
|
||||
ignored!(ig18, ROOT, "a/**/b", "a/b");
|
||||
ignored!(ig19, ROOT, "a/**/b", "a/x/b");
|
||||
ignored!(ig20, ROOT, "a/**/b", "a/x/y/b");
|
||||
ignored!(ig21, ROOT, r"\!xy", "!xy");
|
||||
ignored!(ig22, ROOT, r"\#foo", "#foo");
|
||||
ignored!(ig23, ROOT, "foo", "./foo");
|
||||
ignored!(ig24, ROOT, "target", "grep/target");
|
||||
ignored!(ig25, ROOT, "Cargo.lock", "./tabwriter-bin/Cargo.lock");
|
||||
ignored!(ig26, ROOT, "/foo/bar/baz", "./foo/bar/baz");
|
||||
|
||||
not_ignored!(ignot1, ROOT, "amonths", "months");
|
||||
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
||||
not_ignored!(ignot3, ROOT, "src/*.rs", "src/grep/src/main.rs");
|
||||
not_ignored!(ignot4, ROOT, "/*.c", "mozilla-sha1/sha1.c");
|
||||
not_ignored!(ignot5, ROOT, "/src/*.rs", "src/grep/src/main.rs");
|
||||
not_ignored!(ignot6, ROOT, "*.rs\n!src/main.rs", "src/main.rs");
|
||||
not_ignored!(ignot7, ROOT, "foo/", "foo", false);
|
||||
not_ignored!(ignot8, ROOT, "**/foo/**", "wat/src/afoo/bar/baz");
|
||||
not_ignored!(ignot9, ROOT, "**/foo/**", "wat/src/fooa/bar/baz");
|
||||
not_ignored!(ignot10, ROOT, "**/foo/bar", "foo/src/bar");
|
||||
not_ignored!(ignot11, ROOT, "#foo", "#foo");
|
||||
not_ignored!(ignot12, ROOT, "\n\n\n", "foo");
|
||||
}
|
||||
1061
src/glob.rs
1061
src/glob.rs
File diff suppressed because it is too large
Load Diff
428
src/ignore.rs
428
src/ignore.rs
@@ -1,428 +0,0 @@
|
||||
/*!
|
||||
The ignore module is responsible for managing the state required to determine
|
||||
whether a *single* file path should be searched or not.
|
||||
|
||||
In general, there are two ways to ignore a particular file:
|
||||
|
||||
1. Specify an ignore rule in some "global" configuration, such as a
|
||||
$HOME/.rgignore or on the command line.
|
||||
2. A specific ignore file (like .gitignore) found during directory traversal.
|
||||
|
||||
The `IgnoreDir` type handles ignore patterns for any one particular directory
|
||||
(including "global" ignore patterns), while the `Ignore` type handles a stack
|
||||
of `IgnoreDir`s for use during directory traversal.
|
||||
*/
|
||||
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use gitignore::{self, Gitignore, GitignoreBuilder, Match, Pattern};
|
||||
use pathutil::is_hidden;
|
||||
use types::Types;
|
||||
|
||||
const IGNORE_NAMES: &'static [&'static str] = &[
|
||||
".gitignore",
|
||||
".rgignore",
|
||||
];
|
||||
|
||||
/// Represents an error that can occur when parsing a gitignore file.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Gitignore(gitignore::Error),
|
||||
Io {
|
||||
path: PathBuf,
|
||||
err: io::Error,
|
||||
},
|
||||
}
|
||||
|
||||
impl Error {
|
||||
fn from_io<P: AsRef<Path>>(path: P, err: io::Error) -> Error {
|
||||
Error::Io { path: path.as_ref().to_path_buf(), err: err }
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Gitignore(ref err) => err.description(),
|
||||
Error::Io { ref err, .. } => err.description(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Gitignore(ref err) => err.fmt(f),
|
||||
Error::Io { ref path, ref err } => {
|
||||
write!(f, "{}: {}", path.display(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<gitignore::Error> for Error {
|
||||
fn from(err: gitignore::Error) -> Error {
|
||||
Error::Gitignore(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Ignore represents a collection of ignore patterns organized by directory.
|
||||
/// In particular, a stack is maintained, where the top of the stack
|
||||
/// corresponds to the current directory being searched and the bottom of the
|
||||
/// stack represents the root of a search. Ignore patterns at the top of the
|
||||
/// stack take precedence over ignore patterns at the bottom of the stack.
|
||||
pub struct Ignore {
|
||||
/// A stack of ignore patterns at each directory level of traversal.
|
||||
/// A directory that contributes no ignore patterns is `None`.
|
||||
stack: Vec<Option<IgnoreDir>>,
|
||||
/// A set of override globs that are always checked first. A match (whether
|
||||
/// it's whitelist or blacklist) trumps anything in stack.
|
||||
overrides: Overrides,
|
||||
/// A file type matcher.
|
||||
types: Types,
|
||||
/// Whether to ignore hidden files or not.
|
||||
ignore_hidden: bool,
|
||||
/// When true, don't look at .gitignore or .agignore files for ignore
|
||||
/// rules.
|
||||
no_ignore: bool,
|
||||
}
|
||||
|
||||
impl Ignore {
|
||||
/// Create an empty set of ignore patterns.
|
||||
pub fn new() -> Ignore {
|
||||
Ignore {
|
||||
stack: vec![],
|
||||
overrides: Overrides::new(None),
|
||||
types: Types::empty(),
|
||||
ignore_hidden: true,
|
||||
no_ignore: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set whether hidden files/folders should be ignored (defaults to true).
|
||||
pub fn ignore_hidden(&mut self, yes: bool) -> &mut Ignore {
|
||||
self.ignore_hidden = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// When set, ignore files are ignored.
|
||||
pub fn no_ignore(&mut self, yes: bool) -> &mut Ignore {
|
||||
self.no_ignore = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a set of globs that overrides all other match logic.
|
||||
pub fn add_override(&mut self, gi: Gitignore) -> &mut Ignore {
|
||||
self.overrides = Overrides::new(Some(gi));
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a file type matcher. The file type matcher has the lowest
|
||||
/// precedence.
|
||||
pub fn add_types(&mut self, types: Types) -> &mut Ignore {
|
||||
self.types = types;
|
||||
self
|
||||
}
|
||||
|
||||
/// Push parent directories of `path` on to the stack.
|
||||
pub fn push_parents<P: AsRef<Path>>(
|
||||
&mut self,
|
||||
path: P,
|
||||
) -> Result<(), Error> {
|
||||
let path = try!(path.as_ref().canonicalize().map_err(|err| {
|
||||
Error::from_io(path.as_ref(), err)
|
||||
}));
|
||||
let mut path = &*path;
|
||||
let mut saw_git = path.join(".git").is_dir();
|
||||
let mut ignore_names = IGNORE_NAMES.to_vec();
|
||||
let mut ignore_dir_results = vec![];
|
||||
while let Some(parent) = path.parent() {
|
||||
if self.no_ignore {
|
||||
ignore_dir_results.push(Ok(None));
|
||||
} else {
|
||||
if saw_git {
|
||||
ignore_names.retain(|&name| name != ".gitignore");
|
||||
} else {
|
||||
saw_git = parent.join(".git").is_dir();
|
||||
}
|
||||
let ignore_dir_result =
|
||||
IgnoreDir::with_ignore_names(parent, ignore_names.iter());
|
||||
ignore_dir_results.push(ignore_dir_result);
|
||||
}
|
||||
path = parent;
|
||||
}
|
||||
|
||||
for ignore_dir_result in ignore_dir_results.into_iter().rev() {
|
||||
try!(self.push_ignore_dir(ignore_dir_result));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a directory to the stack.
|
||||
///
|
||||
/// Note that even if this returns an error, the directory is added to the
|
||||
/// stack (and therefore should be popped).
|
||||
pub fn push<P: AsRef<Path>>(&mut self, path: P) -> Result<(), Error> {
|
||||
if self.no_ignore {
|
||||
self.stack.push(None);
|
||||
return Ok(());
|
||||
}
|
||||
self.push_ignore_dir(IgnoreDir::new(path))
|
||||
}
|
||||
|
||||
/// Pushes the result of building a directory matcher on to the stack.
|
||||
///
|
||||
/// If the result given contains an error, then it is returned.
|
||||
pub fn push_ignore_dir(
|
||||
&mut self,
|
||||
result: Result<Option<IgnoreDir>, Error>,
|
||||
) -> Result<(), Error> {
|
||||
match result {
|
||||
Ok(id) => {
|
||||
self.stack.push(id);
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
// Don't leave the stack in an inconsistent state.
|
||||
self.stack.push(None);
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pop a directory from the stack.
|
||||
///
|
||||
/// This panics if the stack is empty.
|
||||
pub fn pop(&mut self) {
|
||||
self.stack.pop().expect("non-empty stack");
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given file path should be ignored.
|
||||
pub fn ignored<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> bool {
|
||||
let path = path.as_ref();
|
||||
let mat = self.overrides.matched(path, is_dir);
|
||||
if let Some(is_ignored) = self.ignore_match(path, mat) {
|
||||
return is_ignored;
|
||||
}
|
||||
if self.ignore_hidden && is_hidden(&path) {
|
||||
debug!("{} ignored because it is hidden", path.display());
|
||||
return true;
|
||||
}
|
||||
if !self.no_ignore {
|
||||
for id in self.stack.iter().rev().filter_map(|id| id.as_ref()) {
|
||||
let mat = id.matched(path, is_dir);
|
||||
if let Some(is_ignored) = self.ignore_match(path, mat) {
|
||||
if is_ignored {
|
||||
return true;
|
||||
}
|
||||
// If this path is whitelisted by an ignore, then
|
||||
// fallthrough and let the file type matcher have a say.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mat = self.types.matched(path, is_dir);
|
||||
if let Some(is_ignored) = self.ignore_match(path, mat) {
|
||||
return is_ignored;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns true if the given match says the given pattern should be
|
||||
/// ignored or false if the given pattern should be explicitly whitelisted.
|
||||
/// Returns None otherwise.
|
||||
pub fn ignore_match<P: AsRef<Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
mat: Match,
|
||||
) -> Option<bool> {
|
||||
let path = path.as_ref();
|
||||
match mat {
|
||||
Match::Whitelist(ref pat) => {
|
||||
debug!("{} whitelisted by {:?}", path.display(), pat);
|
||||
Some(false)
|
||||
}
|
||||
Match::Ignored(ref pat) => {
|
||||
debug!("{} ignored by {:?}", path.display(), pat);
|
||||
Some(true)
|
||||
}
|
||||
Match::None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// IgnoreDir represents a set of ignore patterns retrieved from a single
|
||||
/// directory.
|
||||
pub struct IgnoreDir {
|
||||
/// The path to this directory as given.
|
||||
path: PathBuf,
|
||||
/// A single accumulation of glob patterns for this directory, matched
|
||||
/// using gitignore semantics.
|
||||
///
|
||||
/// This will include patterns from rgignore as well. The patterns are
|
||||
/// ordered so that precedence applies automatically (e.g., rgignore
|
||||
/// patterns procede gitignore patterns).
|
||||
gi: Option<Gitignore>,
|
||||
// TODO(burntsushi): Matching other types of glob patterns that don't
|
||||
// conform to gitignore will probably require refactoring this approach.
|
||||
}
|
||||
|
||||
impl IgnoreDir {
|
||||
/// Create a new matcher for the given directory.
|
||||
///
|
||||
/// If no ignore glob patterns could be found in the directory then `None`
|
||||
/// is returned.
|
||||
pub fn new<P: AsRef<Path>>(path: P) -> Result<Option<IgnoreDir>, Error> {
|
||||
IgnoreDir::with_ignore_names(path, IGNORE_NAMES.iter())
|
||||
}
|
||||
|
||||
/// Create a new matcher for the given directory using only the ignore
|
||||
/// patterns found in the file names given.
|
||||
///
|
||||
/// If no ignore glob patterns could be found in the directory then `None`
|
||||
/// is returned.
|
||||
///
|
||||
/// Note that the order of the names given is meaningful. Names appearing
|
||||
/// later in the list have precedence over names appearing earlier in the
|
||||
/// list.
|
||||
pub fn with_ignore_names<P: AsRef<Path>, S, I>(
|
||||
path: P,
|
||||
names: I,
|
||||
) -> Result<Option<IgnoreDir>, Error>
|
||||
where P: AsRef<Path>, S: AsRef<str>, I: Iterator<Item=S> {
|
||||
let mut id = IgnoreDir {
|
||||
path: path.as_ref().to_path_buf(),
|
||||
gi: None,
|
||||
};
|
||||
let mut ok = false;
|
||||
let mut builder = GitignoreBuilder::new(&id.path);
|
||||
// The ordering here is important. Later globs have higher precedence.
|
||||
for name in names {
|
||||
ok = builder.add_path(id.path.join(name.as_ref())).is_ok() || ok;
|
||||
}
|
||||
if !ok {
|
||||
Ok(None)
|
||||
} else {
|
||||
id.gi = Some(try!(builder.build()));
|
||||
Ok(Some(id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if the given file path should be ignored
|
||||
/// according to the globs in this directory. `is_dir` should be true if
|
||||
/// the path refers to a directory and false otherwise.
|
||||
///
|
||||
/// Before matching path, its prefix (as determined by a common suffix
|
||||
/// of this directory) is stripped. If there is
|
||||
/// no common suffix/prefix overlap, then path is assumed to reside
|
||||
/// directly in this directory.
|
||||
///
|
||||
/// If the given path has a `./` prefix then it is stripped before
|
||||
/// matching.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
self.gi.as_ref()
|
||||
.map(|gi| gi.matched(path, is_dir))
|
||||
.unwrap_or(Match::None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Manages a set of overrides provided explicitly by the end user.
|
||||
struct Overrides {
|
||||
gi: Option<Gitignore>,
|
||||
unmatched_pat: Pattern,
|
||||
}
|
||||
|
||||
impl Overrides {
|
||||
/// Creates a new set of overrides from the gitignore matcher provided.
|
||||
/// If no matcher is provided, then the resulting overrides have no effect.
|
||||
fn new(gi: Option<Gitignore>) -> Overrides {
|
||||
Overrides {
|
||||
gi: gi,
|
||||
unmatched_pat: Pattern {
|
||||
from: Path::new("<argv>").to_path_buf(),
|
||||
original: "<none>".to_string(),
|
||||
pat: "<none>".to_string(),
|
||||
whitelist: false,
|
||||
only_dir: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a match for the given path against this set of overrides.
|
||||
///
|
||||
/// If there are no overrides, then this always returns Match::None.
|
||||
///
|
||||
/// If there is at least one positive override, then this never returns
|
||||
/// Match::None (and interpreting non-matches as ignored) unless is_dir
|
||||
/// is true.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
// File types don't apply to directories.
|
||||
if is_dir {
|
||||
return Match::None;
|
||||
}
|
||||
let path = path.as_ref();
|
||||
self.gi.as_ref()
|
||||
.map(|gi| {
|
||||
let mat = gi.matched_stripped(path, is_dir).invert();
|
||||
if mat.is_none() && !is_dir {
|
||||
if gi.num_ignores() > 0 {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
}
|
||||
}
|
||||
mat
|
||||
})
|
||||
.unwrap_or(Match::None)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
use gitignore::GitignoreBuilder;
|
||||
use super::IgnoreDir;
|
||||
|
||||
macro_rules! ignored_dir {
|
||||
($name:ident, $root:expr, $gi:expr, $xi:expr, $path:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut builder = GitignoreBuilder::new(&$root);
|
||||
builder.add_str($gi).unwrap();
|
||||
builder.add_str($xi).unwrap();
|
||||
let gi = builder.build().unwrap();
|
||||
let id = IgnoreDir {
|
||||
path: Path::new($root).to_path_buf(),
|
||||
gi: Some(gi),
|
||||
};
|
||||
assert!(id.matched($path, false).is_ignored());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! not_ignored_dir {
|
||||
($name:ident, $root:expr, $gi:expr, $xi:expr, $path:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut builder = GitignoreBuilder::new(&$root);
|
||||
builder.add_str($gi).unwrap();
|
||||
builder.add_str($xi).unwrap();
|
||||
let gi = builder.build().unwrap();
|
||||
let id = IgnoreDir {
|
||||
path: Path::new($root).to_path_buf(),
|
||||
gi: Some(gi),
|
||||
};
|
||||
assert!(!id.matched($path, false).is_ignored());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const ROOT: &'static str = "/home/foobar/rust/rg";
|
||||
|
||||
ignored_dir!(id1, ROOT, "src/main.rs", "", "src/main.rs");
|
||||
ignored_dir!(id2, ROOT, "", "src/main.rs", "src/main.rs");
|
||||
ignored_dir!(id3, ROOT, "!src/main.rs", "*.rs", "src/main.rs");
|
||||
|
||||
not_ignored_dir!(idnot1, ROOT, "*.rs", "!src/main.rs", "src/main.rs");
|
||||
}
|
||||
495
src/main.rs
495
src/main.rs
@@ -1,10 +1,11 @@
|
||||
extern crate deque;
|
||||
extern crate docopt;
|
||||
extern crate atty;
|
||||
extern crate bytecount;
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate encoding_rs;
|
||||
extern crate env_logger;
|
||||
extern crate fnv;
|
||||
extern crate grep;
|
||||
#[cfg(windows)]
|
||||
extern crate kernel32;
|
||||
extern crate ignore;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate libc;
|
||||
@@ -14,34 +15,19 @@ extern crate memchr;
|
||||
extern crate memmap;
|
||||
extern crate num_cpus;
|
||||
extern crate regex;
|
||||
extern crate rustc_serialize;
|
||||
extern crate term;
|
||||
extern crate walkdir;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
extern crate same_file;
|
||||
extern crate termcolor;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
|
||||
use deque::{Stealer, Stolen};
|
||||
use grep::Grep;
|
||||
use memmap::{Mmap, Protection};
|
||||
use term::Terminal;
|
||||
use walkdir::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)*) => {
|
||||
@@ -56,26 +42,21 @@ macro_rules! eprintln {
|
||||
}}
|
||||
}
|
||||
|
||||
mod app;
|
||||
mod args;
|
||||
mod atty;
|
||||
mod gitignore;
|
||||
mod glob;
|
||||
mod ignore;
|
||||
mod out;
|
||||
mod decoder;
|
||||
mod pathutil;
|
||||
mod printer;
|
||||
mod search_buffer;
|
||||
mod search_stream;
|
||||
#[cfg(windows)]
|
||||
mod terminal_win;
|
||||
mod types;
|
||||
mod walk;
|
||||
mod unescape;
|
||||
mod worker;
|
||||
|
||||
pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;
|
||||
|
||||
fn main() {
|
||||
match Args::parse().and_then(run) {
|
||||
Ok(count) if count == 0 => process::exit(1),
|
||||
match Args::parse().map(Arc::new).and_then(run) {
|
||||
Ok(0) => process::exit(1),
|
||||
Ok(_) => process::exit(0),
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
@@ -84,99 +65,177 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
fn run(args: Args) -> Result<u64> {
|
||||
let args = Arc::new(args);
|
||||
let paths = args.paths();
|
||||
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 paths.len() == 1 && (paths[0] == Path::new("-") || paths[0].is_file()) {
|
||||
return run_one(args.clone(), &paths[0]);
|
||||
}
|
||||
|
||||
let out = Arc::new(Mutex::new(args.out()));
|
||||
let mut workers = vec![];
|
||||
|
||||
let workq = {
|
||||
let (workq, stealer) = deque::new();
|
||||
for _ in 0..args.threads() {
|
||||
let worker = MultiWorker {
|
||||
chan_work: stealer.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
|
||||
};
|
||||
for p in paths {
|
||||
if p == Path::new("-") {
|
||||
workq.push(Work::Stdin)
|
||||
if threads == 1 || args.is_one_path() {
|
||||
run_files_one_thread(args)
|
||||
} else {
|
||||
for ent in try!(args.walker(p)) {
|
||||
workq.push(Work::File(ent));
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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 = args.clone();
|
||||
let quiet_matched = quiet_matched.clone();
|
||||
let paths_searched = paths_searched.clone();
|
||||
let match_count = match_count.clone();
|
||||
let bufwtr = bufwtr.clone();
|
||||
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.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;
|
||||
let mut match_count = 0;
|
||||
for result in args.walker() {
|
||||
let dent = match get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
None => continue,
|
||||
Some(dent) => dent,
|
||||
};
|
||||
let mut printer = args.printer(&mut stdout);
|
||||
if match_count > 0 {
|
||||
if args.quiet() {
|
||||
break;
|
||||
}
|
||||
if let Some(sep) = args.file_separator() {
|
||||
printer = printer.file_separator(sep);
|
||||
}
|
||||
}
|
||||
paths_searched += 1;
|
||||
match_count +=
|
||||
if dent.is_stdin() {
|
||||
worker.run(&mut printer, Work::Stdin)
|
||||
} else {
|
||||
worker.run(&mut printer, Work::DirEntry(dent))
|
||||
};
|
||||
}
|
||||
for _ in 0..workers.len() {
|
||||
workq.push(Work::Quit);
|
||||
}
|
||||
let mut match_count = 0;
|
||||
for worker in workers {
|
||||
match_count += worker.join().unwrap();
|
||||
if !args.paths().is_empty() && paths_searched == 0 {
|
||||
if !args.no_messages() {
|
||||
eprint_nothing_searched();
|
||||
}
|
||||
}
|
||||
Ok(match_count)
|
||||
}
|
||||
|
||||
fn run_one(args: Arc<Args>, path: &Path) -> Result<u64> {
|
||||
let mut worker = Worker {
|
||||
args: args.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
};
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
let work =
|
||||
if path == Path::new("-") {
|
||||
WorkReady::Stdin
|
||||
} else {
|
||||
WorkReady::PathFile(path.to_path_buf(), try!(File::open(path)))
|
||||
};
|
||||
worker.do_work(&mut printer, work);
|
||||
Ok(worker.match_count)
|
||||
fn run_files_parallel(args: Arc<Args>) -> Result<u64> {
|
||||
let print_args = args.clone();
|
||||
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() {
|
||||
printer.path(dent.path());
|
||||
file_count += 1;
|
||||
}
|
||||
file_count
|
||||
});
|
||||
args.walker_parallel().run(move || {
|
||||
let args = args.clone();
|
||||
let tx = tx.clone();
|
||||
Box::new(move |result| {
|
||||
if let Some(dent) = get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
tx.send(dent).unwrap();
|
||||
}
|
||||
ignore::WalkState::Continue
|
||||
})
|
||||
});
|
||||
Ok(print_thread.join().unwrap())
|
||||
}
|
||||
|
||||
fn run_files(args: Arc<Args>) -> Result<u64> {
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
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 p in args.paths() {
|
||||
if p == Path::new("-") {
|
||||
printer.path(&Path::new("<stdin>"));
|
||||
file_count += 1;
|
||||
} else {
|
||||
for ent in try!(args.walker(p)) {
|
||||
printer.path(ent.path());
|
||||
file_count += 1;
|
||||
}
|
||||
}
|
||||
for result in args.walker() {
|
||||
let dent = match get_or_log_dir_entry(
|
||||
result,
|
||||
args.stdout_handle(),
|
||||
args.no_messages(),
|
||||
) {
|
||||
None => continue,
|
||||
Some(dent) => dent,
|
||||
};
|
||||
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);
|
||||
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);
|
||||
@@ -185,143 +244,85 @@ fn run_types(args: Arc<Args>) -> Result<u64> {
|
||||
Ok(ty_count)
|
||||
}
|
||||
|
||||
enum Work {
|
||||
Stdin,
|
||||
File(DirEntry),
|
||||
Quit,
|
||||
}
|
||||
|
||||
enum WorkReady {
|
||||
Stdin,
|
||||
DirFile(DirEntry, File),
|
||||
PathFile(PathBuf, File),
|
||||
}
|
||||
|
||||
struct MultiWorker {
|
||||
chan_work: Stealer<Work>,
|
||||
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 {
|
||||
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);
|
||||
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)
|
||||
}
|
||||
}
|
||||
WorkReady::PathFile(path, file) => {
|
||||
let mut path = &*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>,
|
||||
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.
|
||||
return Ok(0);
|
||||
Ok(dent) => {
|
||||
if let Some(err) = dent.error() {
|
||||
if !no_messages {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
}
|
||||
let ft = match dent.file_type() {
|
||||
None => return Some(dent), // entry is stdin
|
||||
Some(ft) => ft,
|
||||
};
|
||||
// A depth of 0 means the user gave the path explicitly, so we
|
||||
// should always try to search it.
|
||||
if dent.depth() == 0 && !ft.is_dir() {
|
||||
return Some(dent);
|
||||
} else if !ft.is_file() {
|
||||
return None;
|
||||
}
|
||||
// If we are redirecting stdout to a file, then don't search that
|
||||
// file.
|
||||
if is_stdout_file(&dent, stdout_handle, no_messages) {
|
||||
return None;
|
||||
}
|
||||
Some(dent)
|
||||
}
|
||||
let mmap = try!(Mmap::open(file, Protection::Read));
|
||||
Ok(self.args.searcher_buffer(
|
||||
printer,
|
||||
&self.grep,
|
||||
path,
|
||||
unsafe { mmap.as_slice() },
|
||||
).run())
|
||||
}
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
318
src/out.rs
318
src/out.rs
@@ -1,318 +0,0 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use term::{self, Terminal};
|
||||
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.
|
||||
///
|
||||
/// If sep is empty, then no file 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -8,19 +8,17 @@ with the raw bytes directly.
|
||||
On large repositories (like chromium), this can have a ~25% performance
|
||||
improvement on just listing the files to search (!).
|
||||
*/
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
use memchr::memrchr;
|
||||
|
||||
/// Strip `prefix` from the `path` and return the remainder.
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(unix)]
|
||||
pub fn strip_prefix<'a, P: AsRef<Path>>(
|
||||
prefix: P,
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let prefix = prefix.as_ref().as_os_str().as_bytes();
|
||||
@@ -28,7 +26,7 @@ pub fn strip_prefix<'a, P: AsRef<Path>>(
|
||||
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()..])))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,63 +34,9 @@ pub fn strip_prefix<'a, P: AsRef<Path>>(
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(not(unix))]
|
||||
pub fn strip_prefix<'a>(prefix: &Path, path: &'a Path) -> Option<&'a Path> {
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
path.strip_prefix(prefix).ok()
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(unix)]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
} else if path.len() == 1 && path[0] == b'.' {
|
||||
return None;
|
||||
} else if path.last() == Some(&b'.') {
|
||||
return None;
|
||||
} else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] {
|
||||
return None;
|
||||
}
|
||||
let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0);
|
||||
Some(OsStr::from_bytes(&path[last_slash..]))
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(not(unix))]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
path.as_ref().file_name()
|
||||
}
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(unix)]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
if let Some(name) = file_name(path.as_ref()) {
|
||||
name.as_bytes().get(0) == Some(&b'.')
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(not(unix))]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
if let Some(name) = file_name(path) {
|
||||
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
728
src/printer.rs
728
src/printer.rs
@@ -1,10 +1,33 @@
|
||||
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::{Regex, Replacer, Captures};
|
||||
use termcolor::{Color, ColorSpec, ParseColorError, WriteColor};
|
||||
|
||||
use types::FileTypeDef;
|
||||
use pathutil::strip_prefix;
|
||||
use ignore::types::FileTypeDef;
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
impl<'r> CountingReplacer<'r> {
|
||||
fn new(replace: &'r [u8], count: &'r mut usize) -> CountingReplacer<'r> {
|
||||
CountingReplacer { replace: replace, count: count }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> Replacer for CountingReplacer<'r> {
|
||||
fn replace_append(&mut self, caps: &Captures, dst: &mut Vec<u8>) {
|
||||
*self.count += 1;
|
||||
caps.expand(self.replace, dst);
|
||||
}
|
||||
}
|
||||
|
||||
/// Printer encapsulates all output logic for searching.
|
||||
///
|
||||
@@ -24,20 +47,33 @@ pub struct Printer<W> {
|
||||
/// printed via the match directly, but occasionally we need to insert them
|
||||
/// ourselves (for example, to print a context separator).
|
||||
eol: u8,
|
||||
/// A file separator to show before any matches are printed.
|
||||
file_separator: Option<Vec<u8>>,
|
||||
/// Whether to show file name as a heading or not.
|
||||
///
|
||||
/// N.B. If with_filename is false, then this setting has no effect.
|
||||
heading: bool,
|
||||
/// Whether to suppress all output.
|
||||
quiet: bool,
|
||||
/// Whether to show every match on its own line.
|
||||
line_per_match: bool,
|
||||
/// 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 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>
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -45,13 +81,25 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
column: false,
|
||||
context_separator: "--".to_string().into_bytes(),
|
||||
eol: b'\n',
|
||||
file_separator: None,
|
||||
heading: false,
|
||||
quiet: false,
|
||||
line_per_match: false,
|
||||
null: false,
|
||||
only_matching: false,
|
||||
replace: None,
|
||||
with_filename: false,
|
||||
colors: ColorSpecs::default(),
|
||||
path_separator: None,
|
||||
max_columns: 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> {
|
||||
@@ -71,6 +119,13 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// If set, the separator is printed before any matches. By default, no
|
||||
/// separator is printed.
|
||||
pub fn file_separator(mut self, sep: Vec<u8>) -> Printer<W> {
|
||||
self.file_separator = Some(sep);
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to show file name as a heading or not.
|
||||
///
|
||||
/// N.B. If with_filename is false, then this setting has no effect.
|
||||
@@ -79,17 +134,34 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self
|
||||
}
|
||||
|
||||
/// When set, all output is suppressed.
|
||||
pub fn quiet(mut self, yes: bool) -> Printer<W> {
|
||||
self.quiet = yes;
|
||||
/// Whether to show every match on its own line.
|
||||
pub fn line_per_match(mut self, yes: bool) -> Printer<W> {
|
||||
self.line_per_match = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to cause NUL bytes to follow file paths instead of other
|
||||
/// visual separators (like `:`, `-` and `\n`).
|
||||
pub fn null(mut self, yes: bool) -> Printer<W> {
|
||||
self.null = yes;
|
||||
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
|
||||
@@ -101,12 +173,19 @@ 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
|
||||
}
|
||||
|
||||
/// 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
|
||||
@@ -117,11 +196,11 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
self.write(def.name().as_bytes());
|
||||
self.write(b": ");
|
||||
let mut first = true;
|
||||
for pat in def.patterns() {
|
||||
for glob in def.globs() {
|
||||
if !first {
|
||||
self.write(b", ");
|
||||
}
|
||||
self.write(pat.as_bytes());
|
||||
self.write(glob.as_bytes());
|
||||
first = false;
|
||||
}
|
||||
self.write_eol();
|
||||
@@ -129,15 +208,16 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
|
||||
/// Prints the given path.
|
||||
pub fn path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
self.write(path.as_ref().to_string_lossy().as_bytes());
|
||||
self.write_eol();
|
||||
let path = strip_prefix("./", path.as_ref()).unwrap_or(path.as_ref());
|
||||
self.write_path(path);
|
||||
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.as_ref().to_string_lossy().as_bytes());
|
||||
self.write(b":");
|
||||
self.write_path(path);
|
||||
self.write_path_sep(b':');
|
||||
}
|
||||
self.write(count.to_string().as_bytes());
|
||||
self.write_eol();
|
||||
@@ -145,16 +225,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.quiet {
|
||||
return;
|
||||
}
|
||||
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>>(
|
||||
@@ -165,48 +240,107 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
start: usize,
|
||||
end: usize,
|
||||
line_number: Option<u64>,
|
||||
) {
|
||||
if !self.line_per_match && !self.only_matching {
|
||||
let column =
|
||||
if self.column {
|
||||
Some(re.find(&buf[start..end])
|
||||
.map(|m| m.start()).unwrap_or(0) as u64)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
return self.write_match(
|
||||
re, path, buf, start, end, line_number, column);
|
||||
}
|
||||
for m in re.find_iter(&buf[start..end]) {
|
||||
let column =
|
||||
if self.column {
|
||||
Some(m.start() as u64)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.write_match(
|
||||
re, path.as_ref(), buf, start, end, line_number, column);
|
||||
}
|
||||
}
|
||||
|
||||
fn write_match<P: AsRef<Path>>(
|
||||
&mut self,
|
||||
re: &Regex,
|
||||
path: P,
|
||||
buf: &[u8],
|
||||
start: usize,
|
||||
end: usize,
|
||||
line_number: Option<u64>,
|
||||
column: Option<u64>,
|
||||
) {
|
||||
if self.heading && self.with_filename && !self.has_printed {
|
||||
self.write_heading(path.as_ref());
|
||||
self.write_file_sep();
|
||||
self.write_path(path);
|
||||
self.write_path_eol();
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write(path.as_ref().to_string_lossy().as_bytes());
|
||||
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.column {
|
||||
let c = re.find(&buf[start..end]).map(|(s, _)| s + 1).unwrap_or(0);
|
||||
self.write(c.to_string().as_bytes());
|
||||
self.write(b":");
|
||||
if let Some(c) = column {
|
||||
self.column_number(c + 1, b':');
|
||||
}
|
||||
if self.replace.is_some() {
|
||||
let line = re.replace_all(
|
||||
&buf[start..end], &**self.replace.as_ref().unwrap());
|
||||
let mut count = 0;
|
||||
let line = {
|
||||
let replacer = CountingReplacer::new(
|
||||
self.replace.as_ref().unwrap(), &mut count);
|
||||
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(&line);
|
||||
if line.last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
}
|
||||
} else {
|
||||
self.write_match(re, &buf[start..end]);
|
||||
}
|
||||
if buf[start..end].last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
let line_buf = if self.only_matching {
|
||||
let m = re.find(&buf[start..end]).unwrap();
|
||||
&buf[start + m.start()..start + m.end()]
|
||||
} else {
|
||||
&buf[start..end]
|
||||
};
|
||||
self.write_matched_line(re, line_buf);
|
||||
// write_matched_line guarantees to write a newline.
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_match(&mut self, re: &Regex, buf: &[u8]) {
|
||||
if !self.wtr.supports_color() {
|
||||
self.write(buf);
|
||||
fn write_matched_line(&mut self, re: &Regex, buf: &[u8]) {
|
||||
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 mut last_written = 0;
|
||||
for (s, e) in re.find_iter(buf) {
|
||||
self.write(&buf[last_written..s]);
|
||||
let _ = self.wtr.fg(color::BRIGHT_RED);
|
||||
let _ = self.wtr.attr(Attr::Bold);
|
||||
self.write(&buf[s..e]);
|
||||
let _ = self.wtr.reset();
|
||||
last_written = e;
|
||||
if !self.wtr.supports_color() || self.colors.matched().is_none() {
|
||||
self.write(buf);
|
||||
} else {
|
||||
let mut last_written = 0;
|
||||
for m in re.find_iter(buf) {
|
||||
self.write(&buf[last_written..m.start()]);
|
||||
self.write_colored(
|
||||
&buf[m.start()..m.end()], |colors| colors.matched());
|
||||
last_written = m.end();
|
||||
}
|
||||
self.write(&buf[last_written..]);
|
||||
}
|
||||
if buf.last() != Some(&self.eol) {
|
||||
self.write_eol();
|
||||
}
|
||||
self.write(&buf[last_written..]);
|
||||
}
|
||||
|
||||
pub fn context<P: AsRef<Path>>(
|
||||
@@ -218,48 +352,87 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
line_number: Option<u64>,
|
||||
) {
|
||||
if self.heading && self.with_filename && !self.has_printed {
|
||||
self.write_heading(path.as_ref());
|
||||
self.write_file_sep();
|
||||
self.write_path(path);
|
||||
self.write_path_eol();
|
||||
} else if !self.heading && self.with_filename {
|
||||
self.write(path.as_ref().to_string_lossy().as_bytes());
|
||||
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(format!("[Omitted long context line]").as_bytes());
|
||||
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(color::BRIGHT_GREEN);
|
||||
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.as_ref().to_string_lossy().as_bytes());
|
||||
self.write_eol();
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.reset();
|
||||
}
|
||||
|
||||
fn write_path_eol(&mut self) {
|
||||
if self.null {
|
||||
self.write(b"\x00");
|
||||
} else {
|
||||
self.write_eol();
|
||||
}
|
||||
}
|
||||
|
||||
#[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_replace_separator(path);
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn write_path<P: AsRef<Path>>(&mut self, path: P) {
|
||||
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) {
|
||||
if self.wtr.supports_color() {
|
||||
let _ = self.wtr.fg(color::BRIGHT_BLUE);
|
||||
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]);
|
||||
self.write_colored(n.to_string().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]) {
|
||||
if self.quiet {
|
||||
return;
|
||||
}
|
||||
self.has_printed = true;
|
||||
let _ = self.wtr.write_all(buf);
|
||||
}
|
||||
@@ -268,4 +441,409 @@ impl<W: Terminal + Send> Printer<W> {
|
||||
let eol = self.eol;
|
||||
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;
|
||||
let _ = self.wtr.write_all(sep);
|
||||
let _ = self.wtr.write_all(b"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.", name)
|
||||
}
|
||||
Error::InvalidFormat(ref original) => {
|
||||
write!(
|
||||
f,
|
||||
"Invalid color speci 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` and `bold`.
|
||||
#[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,
|
||||
}
|
||||
|
||||
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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = try!(pieces[0].parse());
|
||||
match try!(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 = try!(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 = try!(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 = try!(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),
|
||||
_ => 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 = "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,
|
||||
@@ -53,6 +53,23 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
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 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;
|
||||
@@ -73,6 +90,21 @@ 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 {
|
||||
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;
|
||||
@@ -81,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(10240, self.buf.len());
|
||||
if !self.opts.text && is_binary(&self.buf[..binary_upto], true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -96,21 +128,30 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
self.print_match(m.start(), m.end());
|
||||
}
|
||||
last_end = m.end();
|
||||
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);
|
||||
}
|
||||
if self.opts.count && self.match_count > 0 {
|
||||
self.printer.path_count(self.path, self.match_count);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn print_match(&mut self, start: usize, end: usize) {
|
||||
self.match_count += 1;
|
||||
if self.opts.count {
|
||||
if self.opts.skip_matches() {
|
||||
return;
|
||||
}
|
||||
self.count_lines(start);
|
||||
@@ -125,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);
|
||||
}
|
||||
}
|
||||
@@ -152,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;
|
||||
|
||||
@@ -172,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 = {
|
||||
@@ -237,6 +279,42 @@ and exhibited clearly, with a label attached.\
|
||||
assert_eq!(out, "/baz.rs:2\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn files_with_matches() {
|
||||
let (count, out) = search(
|
||||
"Sherlock", SHERLOCK, |s| s.files_with_matches(true));
|
||||
assert_eq!(1, count);
|
||||
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;
|
||||
|
||||
@@ -80,9 +81,13 @@ pub struct Options {
|
||||
pub after_context: usize,
|
||||
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,
|
||||
}
|
||||
|
||||
@@ -92,15 +97,46 @@ impl Default for Options {
|
||||
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,
|
||||
quiet: false,
|
||||
text: false,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
impl Options {
|
||||
/// 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.files_without_matches
|
||||
|| self.quiet
|
||||
}
|
||||
|
||||
/// 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.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: WriteColor> Searcher<'a, R, W> {
|
||||
/// Create a new searcher.
|
||||
///
|
||||
/// `inp` is a reusable input buffer that is used as scratch space by this
|
||||
@@ -158,6 +194,22 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
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;
|
||||
@@ -178,9 +230,25 @@ 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 {
|
||||
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.inp.text(yes);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -193,19 +261,16 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
self.line_count = if self.opts.line_number { Some(0) } else { None };
|
||||
self.last_match = Match::default();
|
||||
self.after_context_remaining = 0;
|
||||
loop {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
while self.inp.pos < self.inp.lastnl {
|
||||
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 =
|
||||
@@ -234,12 +299,23 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.opts.count && self.match_count > 0 {
|
||||
self.printer.path_count(self.path, self.match_count);
|
||||
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.opts.terminate(self.match_count)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn fill(&mut self) -> Result<bool, Error> {
|
||||
let mut keep = self.inp.lastnl;
|
||||
@@ -253,12 +329,12 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
lines);
|
||||
}
|
||||
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;
|
||||
@@ -274,6 +350,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;
|
||||
}
|
||||
@@ -281,7 +360,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
|
||||
#[inline(always)]
|
||||
fn print_before_context(&mut self, upto: usize) {
|
||||
if self.opts.count || self.opts.before_context == 0 {
|
||||
if self.opts.skip_matches() || self.opts.before_context == 0 {
|
||||
return;
|
||||
}
|
||||
let start = self.last_printed;
|
||||
@@ -304,7 +383,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
|
||||
#[inline(always)]
|
||||
fn print_after_context(&mut self, upto: usize) {
|
||||
if self.opts.count || self.after_context_remaining == 0 {
|
||||
if self.opts.skip_matches() || self.after_context_remaining == 0 {
|
||||
return;
|
||||
}
|
||||
let start = self.last_printed;
|
||||
@@ -322,7 +401,7 @@ impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
#[inline(always)]
|
||||
fn print_match(&mut self, start: usize, end: usize) {
|
||||
self.match_count += 1;
|
||||
if self.opts.count {
|
||||
if self.opts.skip_matches() {
|
||||
return;
|
||||
}
|
||||
self.print_separator(start);
|
||||
@@ -376,7 +455,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
|
||||
@@ -392,7 +471,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
|
||||
@@ -420,10 +499,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 {
|
||||
@@ -451,13 +528,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.
|
||||
@@ -466,7 +553,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
|
||||
@@ -481,9 +567,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);
|
||||
@@ -500,12 +587,10 @@ impl InputBuffer {
|
||||
}
|
||||
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;
|
||||
}
|
||||
if self.is_binary {
|
||||
replace_buf(
|
||||
&mut self.buf[self.end..self.end + n], b'\x00', self.eol);
|
||||
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.
|
||||
@@ -535,100 +620,21 @@ 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.
|
||||
#[allow(dead_code)]
|
||||
fn replace_buf(buf: &mut [u8], a: u8, b: u8) {
|
||||
if a == b {
|
||||
return;
|
||||
@@ -764,10 +770,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};
|
||||
|
||||
@@ -807,7 +811,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>(
|
||||
@@ -816,7 +820,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 = {
|
||||
@@ -833,7 +837,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 = {
|
||||
@@ -970,7 +974,7 @@ fn main() {
|
||||
let text = "Sherlock\n\x00Holmes\n";
|
||||
let (count, out) = search("Sherlock|Holmes", text, |s| s.text(true));
|
||||
assert_eq!(2, count);
|
||||
assert_eq!(out, "/baz.rs:Sherlock\n/baz.rs:Holmes\n");
|
||||
assert_eq!(out, "/baz.rs:Sherlock\n/baz.rs:\x00Holmes\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -992,6 +996,42 @@ fn main() {
|
||||
assert_eq!(out, "/baz.rs:2\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn files_with_matches() {
|
||||
let (count, out) = search_smallcap(
|
||||
"Sherlock", SHERLOCK, |s| s.files_with_matches(true));
|
||||
assert_eq!(1, count);
|
||||
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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
428
src/types.rs
428
src/types.rs
@@ -1,428 +0,0 @@
|
||||
/*!
|
||||
The types module provides a way of associating glob patterns on file names to
|
||||
file types.
|
||||
*/
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
|
||||
use regex;
|
||||
|
||||
use gitignore::{Match, Pattern};
|
||||
use glob::{self, MatchOptions};
|
||||
|
||||
const TYPE_EXTENSIONS: &'static [(&'static str, &'static [&'static str])] = &[
|
||||
("asm", &["*.asm", "*.s", "*.S"]),
|
||||
("awk", &["*.awk"]),
|
||||
("c", &["*.c", "*.h", "*.H"]),
|
||||
("cbor", &["*.cbor"]),
|
||||
("clojure", &["*.clj", "*.cljs"]),
|
||||
("cmake", &["CMakeLists.txt"]),
|
||||
("coffeescript", &["*.coffee"]),
|
||||
("cpp", &[
|
||||
"*.C", "*.cc", "*.cpp", "*.cxx",
|
||||
"*.h", "*.H", "*.hh", "*.hpp",
|
||||
]),
|
||||
("csharp", &["*.cs"]),
|
||||
("css", &["*.css"]),
|
||||
("cython", &["*.pyx"]),
|
||||
("dart", &["*.dart"]),
|
||||
("d", &["*.d"]),
|
||||
("elisp", &["*.el"]),
|
||||
("erlang", &["*.erl", "*.hrl"]),
|
||||
("fortran", &[
|
||||
"*.f", "*.F", "*.f77", "*.F77", "*.pfo",
|
||||
"*.f90", "*.F90", "*.f95", "*.F95",
|
||||
]),
|
||||
("go", &["*.go"]),
|
||||
("groovy", &["*.groovy"]),
|
||||
("haskell", &["*.hs", "*.lhs"]),
|
||||
("html", &["*.htm", "*.html"]),
|
||||
("java", &["*.java"]),
|
||||
("js", &["*.js"]),
|
||||
("json", &["*.json"]),
|
||||
("jsonl", &["*.jsonl"]),
|
||||
("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]),
|
||||
("lua", &["*.lua"]),
|
||||
("m4", &["*.ac", "*.m4"]),
|
||||
("make", &["gnumakefile", "Gnumakefile", "makefile", "Makefile", "*.mk"]),
|
||||
("markdown", &["*.md"]),
|
||||
("matlab", &["*.m"]),
|
||||
("mk", &["mkfile"]),
|
||||
("ml", &["*.ml"]),
|
||||
("objc", &["*.h", "*.m"]),
|
||||
("objcpp", &["*.h", "*.mm"]),
|
||||
("ocaml", &["*.ml", "*.mli", "*.mll", "*.mly"]),
|
||||
("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm"]),
|
||||
("php", &["*.php", "*.php3", "*.php4", "*.php5", "*.phtml"]),
|
||||
("py", &["*.py"]),
|
||||
("readme", &["README*", "*README"]),
|
||||
("rr", &["*.R"]),
|
||||
("rst", &["*.rst"]),
|
||||
("ruby", &["*.rb"]),
|
||||
("rust", &["*.rs"]),
|
||||
("scala", &["*.scala"]),
|
||||
("sh", &["*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh"]),
|
||||
("sql", &["*.sql"]),
|
||||
("tex", &["*.tex", "*.cls", "*.sty"]),
|
||||
("txt", &["*.txt"]),
|
||||
("toml", &["*.toml", "Cargo.lock"]),
|
||||
("vala", &["*.vala"]),
|
||||
("vimscript", &["*.vim"]),
|
||||
("xml", &["*.xml"]),
|
||||
("yacc", &["*.y"]),
|
||||
("yaml", &["*.yaml", "*.yml"]),
|
||||
];
|
||||
|
||||
/// Describes all the possible failure conditions for building a file type
|
||||
/// matcher.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// We tried to select (or negate) a file type that is not defined.
|
||||
UnrecognizedFileType(String),
|
||||
/// A user specified file type definition could not be parsed.
|
||||
InvalidDefinition,
|
||||
/// There was an error building the matcher (probably a bad glob).
|
||||
Glob(glob::Error),
|
||||
/// There was an error compiling a glob as a regex.
|
||||
Regex(regex::Error),
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::UnrecognizedFileType(_) => "unrecognized file type",
|
||||
Error::InvalidDefinition => "invalid definition",
|
||||
Error::Glob(ref err) => err.description(),
|
||||
Error::Regex(ref err) => err.description(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::UnrecognizedFileType(ref ty) => {
|
||||
write!(f, "unrecognized file type: {}", ty)
|
||||
}
|
||||
Error::InvalidDefinition => {
|
||||
write!(f, "invalid definition (format is type:glob, e.g., \
|
||||
html:*.html)")
|
||||
}
|
||||
Error::Glob(ref err) => err.fmt(f),
|
||||
Error::Regex(ref err) => err.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<glob::Error> for Error {
|
||||
fn from(err: glob::Error) -> Error {
|
||||
Error::Glob(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<regex::Error> for Error {
|
||||
fn from(err: regex::Error) -> Error {
|
||||
Error::Regex(err)
|
||||
}
|
||||
}
|
||||
|
||||
/// A single file type definition.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FileTypeDef {
|
||||
name: String,
|
||||
pats: Vec<String>,
|
||||
}
|
||||
|
||||
impl FileTypeDef {
|
||||
/// Return the name of this file type.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// Return the glob patterns used to recognize this file type.
|
||||
pub fn patterns(&self) -> &[String] {
|
||||
&self.pats
|
||||
}
|
||||
}
|
||||
|
||||
/// Types is a file type matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Types {
|
||||
selected: Option<glob::SetYesNo>,
|
||||
negated: Option<glob::SetYesNo>,
|
||||
has_selected: bool,
|
||||
unmatched_pat: Pattern,
|
||||
}
|
||||
|
||||
impl Types {
|
||||
/// Creates a new file type matcher from the given Gitignore matcher. If
|
||||
/// not Gitignore matcher is provided, then the file type matcher has no
|
||||
/// effect.
|
||||
///
|
||||
/// If has_selected is true, then at least one file type was selected.
|
||||
/// Therefore, any non-matches should be ignored.
|
||||
fn new(
|
||||
selected: Option<glob::SetYesNo>,
|
||||
negated: Option<glob::SetYesNo>,
|
||||
has_selected: bool,
|
||||
) -> Types {
|
||||
Types {
|
||||
selected: selected,
|
||||
negated: negated,
|
||||
has_selected: has_selected,
|
||||
unmatched_pat: Pattern {
|
||||
from: Path::new("<filetype>").to_path_buf(),
|
||||
original: "<N/A>".to_string(),
|
||||
pat: "<N/A>".to_string(),
|
||||
whitelist: false,
|
||||
only_dir: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new file type matcher that never matches.
|
||||
pub fn empty() -> Types {
|
||||
Types::new(None, None, false)
|
||||
}
|
||||
|
||||
/// Returns a match for the given path against this file type matcher.
|
||||
///
|
||||
/// The path is considered whitelisted if it matches a selected file type.
|
||||
/// The path is considered ignored if it matched a negated file type.
|
||||
/// If at least one file type is selected and path doesn't match, then
|
||||
/// the path is also considered ignored.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
// If we don't have any matcher, then we can't do anything.
|
||||
if self.negated.is_none() && self.selected.is_none() {
|
||||
return Match::None;
|
||||
}
|
||||
// File types don't apply to directories.
|
||||
if is_dir {
|
||||
return Match::None;
|
||||
}
|
||||
let path = path.as_ref();
|
||||
let name = match path.file_name() {
|
||||
Some(name) => name.to_string_lossy(),
|
||||
None if self.has_selected => {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
}
|
||||
None => {
|
||||
return Match::None;
|
||||
}
|
||||
};
|
||||
if self.negated.as_ref().map(|s| s.is_match(&*name)).unwrap_or(false) {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
}
|
||||
if self.selected.as_ref().map(|s|s.is_match(&*name)).unwrap_or(false) {
|
||||
return Match::Whitelist(&self.unmatched_pat);
|
||||
}
|
||||
if self.has_selected {
|
||||
Match::Ignored(&self.unmatched_pat)
|
||||
} else {
|
||||
Match::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// TypesBuilder builds a type matcher from a set of file type definitions and
|
||||
/// a set of file type selections.
|
||||
pub struct TypesBuilder {
|
||||
types: HashMap<String, Vec<String>>,
|
||||
selected: Vec<String>,
|
||||
negated: Vec<String>,
|
||||
}
|
||||
|
||||
impl TypesBuilder {
|
||||
/// Create a new builder for a file type matcher.
|
||||
pub fn new() -> TypesBuilder {
|
||||
TypesBuilder {
|
||||
types: HashMap::new(),
|
||||
selected: vec![],
|
||||
negated: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the current set of file type definitions *and* selections into
|
||||
/// a file type matcher.
|
||||
pub fn build(&self) -> Result<Types, Error> {
|
||||
let opts = MatchOptions {
|
||||
require_literal_separator: true, ..MatchOptions::default()
|
||||
};
|
||||
let selected_globs =
|
||||
if self.selected.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut bset = glob::SetBuilder::new();
|
||||
for name in &self.selected {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
let msg = name.to_string();
|
||||
return Err(Error::UnrecognizedFileType(msg));
|
||||
}
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bset.add_with(glob, &opts));
|
||||
}
|
||||
}
|
||||
Some(try!(bset.build_yesno()))
|
||||
};
|
||||
let negated_globs =
|
||||
if self.negated.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut bset = glob::SetBuilder::new();
|
||||
for name in &self.negated {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
let msg = name.to_string();
|
||||
return Err(Error::UnrecognizedFileType(msg));
|
||||
}
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bset.add_with(glob, &opts));
|
||||
}
|
||||
}
|
||||
Some(try!(bset.build_yesno()))
|
||||
};
|
||||
Ok(Types::new(
|
||||
selected_globs, negated_globs, !self.selected.is_empty()))
|
||||
}
|
||||
|
||||
/// Return the set of current file type definitions.
|
||||
pub fn definitions(&self) -> Vec<FileTypeDef> {
|
||||
let mut defs = vec![];
|
||||
for (ref name, ref pats) in &self.types {
|
||||
let mut pats = pats.to_vec();
|
||||
pats.sort();
|
||||
defs.push(FileTypeDef {
|
||||
name: name.to_string(),
|
||||
pats: pats,
|
||||
});
|
||||
}
|
||||
defs.sort_by(|def1, def2| def1.name().cmp(def2.name()));
|
||||
defs
|
||||
}
|
||||
|
||||
/// Select the file type given by `name`.
|
||||
///
|
||||
/// If `name` is `all`, then all file types are selected.
|
||||
pub fn select(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.selected.push(name.to_string());
|
||||
}
|
||||
} else {
|
||||
self.selected.push(name.to_string());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Ignore the file type given by `name`.
|
||||
///
|
||||
/// If `name` is `all`, then all file types are negated.
|
||||
pub fn negate(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.negated.push(name.to_string());
|
||||
}
|
||||
} else {
|
||||
self.negated.push(name.to_string());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Clear any file type definitions for the type given.
|
||||
pub fn clear(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
self.types.remove(name);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a new file type definition. `name` can be arbitrary and `pat`
|
||||
/// should be a glob recognizing file paths belonging to the `name` type.
|
||||
pub fn add(&mut self, name: &str, pat: &str) -> &mut TypesBuilder {
|
||||
self.types.entry(name.to_string())
|
||||
.or_insert(vec![]).push(pat.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a new file type definition specified in string form. The format
|
||||
/// is `name:glob`. Names may not include a colon.
|
||||
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);
|
||||
}
|
||||
self.add(&name, &pat);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a set of default file type definitions.
|
||||
pub fn add_defaults(&mut self) -> &mut TypesBuilder {
|
||||
for &(name, exts) in TYPE_EXTENSIONS {
|
||||
for ext in exts {
|
||||
self.add(name, ext);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::TypesBuilder;
|
||||
|
||||
macro_rules! matched {
|
||||
($name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr) => {
|
||||
matched!($name, $types, $sel, $selnot, $path, true);
|
||||
};
|
||||
(not, $name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr) => {
|
||||
matched!($name, $types, $sel, $selnot, $path, false);
|
||||
};
|
||||
($name:ident, $types:expr, $sel:expr, $selnot:expr,
|
||||
$path:expr, $matched:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let mut btypes = TypesBuilder::new();
|
||||
for tydef in $types {
|
||||
btypes.add_def(tydef).unwrap();
|
||||
}
|
||||
for sel in $sel {
|
||||
btypes.select(sel);
|
||||
}
|
||||
for selnot in $selnot {
|
||||
btypes.negate(selnot);
|
||||
}
|
||||
let types = btypes.build().unwrap();
|
||||
let mat = types.matched($path, false);
|
||||
assert_eq!($matched, !mat.is_ignored());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn types() -> Vec<&'static str> {
|
||||
vec![
|
||||
"html:*.html",
|
||||
"html:*.htm",
|
||||
"rust:*.rs",
|
||||
"js:*.js",
|
||||
]
|
||||
}
|
||||
|
||||
matched!(match1, types(), vec!["rust"], vec![], "lib.rs");
|
||||
matched!(match2, types(), vec!["html"], vec![], "index.html");
|
||||
matched!(match3, types(), vec!["html"], vec![], "index.htm");
|
||||
matched!(match4, types(), vec!["html", "rust"], vec![], "main.rs");
|
||||
matched!(match5, types(), vec![], vec![], "index.html");
|
||||
matched!(match6, types(), vec![], vec!["rust"], "index.html");
|
||||
|
||||
matched!(not, matchnot1, types(), vec!["rust"], vec![], "index.html");
|
||||
matched!(not, matchnot2, types(), vec![], vec!["rust"], "main.rs");
|
||||
}
|
||||
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"));
|
||||
}
|
||||
}
|
||||
140
src/walk.rs
140
src/walk.rs
@@ -1,140 +0,0 @@
|
||||
/*!
|
||||
The walk module implements a recursive directory iterator (using the `walkdir`)
|
||||
crate that can efficiently skip and ignore files and directories specified in
|
||||
a user's ignore patterns.
|
||||
*/
|
||||
|
||||
use walkdir::{self, DirEntry, WalkDir, WalkDirIterator};
|
||||
|
||||
use ignore::Ignore;
|
||||
|
||||
/// Iter is a recursive directory iterator over file paths in a directory.
|
||||
/// Only file paths should be searched are yielded.
|
||||
pub struct Iter {
|
||||
ig: Ignore,
|
||||
it: WalkEventIter,
|
||||
}
|
||||
|
||||
impl Iter {
|
||||
/// Create a new recursive directory iterator using the ignore patterns
|
||||
/// and walkdir iterator given.
|
||||
pub fn new(ig: Ignore, wd: WalkDir) -> Iter {
|
||||
Iter {
|
||||
ig: ig,
|
||||
it: WalkEventIter::from(wd),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this entry should be skipped.
|
||||
#[inline(always)]
|
||||
fn skip_entry(&self, ent: &DirEntry) -> bool {
|
||||
if ent.depth() == 0 {
|
||||
// Never skip the root directory.
|
||||
return false;
|
||||
}
|
||||
if self.ig.ignored(ent.path(), ent.file_type().is_dir()) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Iter {
|
||||
type Item = DirEntry;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<DirEntry> {
|
||||
while let Some(ev) = self.it.next() {
|
||||
match ev {
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
Ok(WalkEvent::Exit) => {
|
||||
self.ig.pop();
|
||||
}
|
||||
Ok(WalkEvent::Dir(ent)) => {
|
||||
if self.skip_entry(&ent) {
|
||||
self.it.it.skip_current_dir();
|
||||
// Still need to push this on the stack because we'll
|
||||
// get a WalkEvent::Exit event for this dir. We don't
|
||||
// care if it errors though.
|
||||
let _ = self.ig.push(ent.path());
|
||||
continue;
|
||||
}
|
||||
if let Err(err) = self.ig.push(ent.path()) {
|
||||
eprintln!("{}", err);
|
||||
self.it.it.skip_current_dir();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ok(WalkEvent::File(ent)) => {
|
||||
if self.skip_entry(&ent) {
|
||||
continue;
|
||||
}
|
||||
// If this isn't actually a file (e.g., a symlink), then
|
||||
// skip it.
|
||||
if !ent.file_type().is_file() {
|
||||
continue;
|
||||
}
|
||||
return Some(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// WalkEventIter transforms a WalkDir iterator into an iterator that more
|
||||
/// accurately describes the directory tree. Namely, it emits events that are
|
||||
/// one of three types: directory, file or "exit." An "exit" event means that
|
||||
/// the entire contents of a directory have been enumerated.
|
||||
struct WalkEventIter {
|
||||
depth: usize,
|
||||
it: walkdir::Iter,
|
||||
next: Option<Result<DirEntry, walkdir::Error>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum WalkEvent {
|
||||
Dir(DirEntry),
|
||||
File(DirEntry),
|
||||
Exit,
|
||||
}
|
||||
|
||||
impl From<WalkDir> for WalkEventIter {
|
||||
fn from(it: WalkDir) -> WalkEventIter {
|
||||
WalkEventIter { depth: 0, it: it.into_iter(), next: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for WalkEventIter {
|
||||
type Item = walkdir::Result<WalkEvent>;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<walkdir::Result<WalkEvent>> {
|
||||
let dent = self.next.take().or_else(|| self.it.next());
|
||||
let depth = match dent {
|
||||
None => 0,
|
||||
Some(Ok(ref dent)) => dent.depth(),
|
||||
Some(Err(ref err)) => err.depth(),
|
||||
};
|
||||
if depth < self.depth {
|
||||
self.depth -= 1;
|
||||
self.next = dent;
|
||||
return Some(Ok(WalkEvent::Exit));
|
||||
}
|
||||
self.depth = depth;
|
||||
match dent {
|
||||
None => None,
|
||||
Some(Err(err)) => Some(Err(err)),
|
||||
Some(Ok(dent)) => {
|
||||
if dent.file_type().is_dir() {
|
||||
self.depth += 1;
|
||||
Some(Ok(WalkEvent::Dir(dent)))
|
||||
} else {
|
||||
Some(Ok(WalkEvent::File(dent)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
313
src/worker.rs
Normal file
313
src/worker.rs
Normal file
@@ -0,0 +1,313 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
use encoding_rs::Encoding;
|
||||
use grep::Grep;
|
||||
use ignore::DirEntry;
|
||||
use memmap::{Mmap, Protection};
|
||||
use termcolor::WriteColor;
|
||||
|
||||
use decoder::DecodeReader;
|
||||
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,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
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 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));
|
||||
let buf = unsafe { mmap.as_slice() };
|
||||
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())
|
||||
}
|
||||
}
|
||||
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.2" #: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.3", 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);
|
||||
try!(stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green))));
|
||||
try!(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();
|
||||
try!(buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green))));
|
||||
try!(writeln!(&mut buffer, "green text!"));
|
||||
try!(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/>
|
||||
1322
termcolor/src/lib.rs
Normal file
1322
termcolor/src/lib.rs
Normal file
File diff suppressed because it is too large
Load Diff
1016
tests/tests.rs
1016
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