diff --git a/src/app.rs b/src/app.rs
index b8f25b87..44e49517 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -41,7 +41,9 @@ OPTIONS:
/// 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)
+ Arg::with_name(name)
+ .help(USAGES[name].short)
+ .long_help(USAGES[name].long)
};
let flag = |name| arg(name).long(name);
@@ -53,7 +55,7 @@ pub fn app() -> App<'static, 'static> {
.setting(AppSettings::UnifiedHelpMessage)
.usage(USAGE)
.template(TEMPLATE)
- .help_message("Prints help information. Use --help for more details.")
+ .help_message("Prints help information. Use --help for more details.")
// First, set up primary positional/flag arguments.
.arg(arg("pattern")
.required_unless_one(&[
@@ -114,6 +116,8 @@ pub fn app() -> App<'static, 'static> {
.arg(flag("column"))
.arg(flag("context-separator")
.value_name("SEPARATOR").takes_value(true))
+ .arg(flag("dfa-size-limit")
+ .value_name("NUM+SUFFIX?").takes_value(true))
.arg(flag("debug"))
.arg(flag("file").short("f")
.value_name("FILE").takes_value(true)
@@ -148,6 +152,8 @@ pub fn app() -> App<'static, 'static> {
.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("regex-size-limit")
+ .value_name("NUM+SUFFIX?").takes_value(true))
.arg(flag("case-sensitive").short("s"))
.arg(flag("smart-case").short("S"))
.arg(flag("sort-files"))
@@ -326,6 +332,13 @@ lazy_static! {
doc!(h, "debug",
"Show debug messages.",
"Show debug messages. Please use this when filing a bug report.");
+ doc!(h, "dfa-size-limit",
+ "The upper size limit of the generated dfa.",
+ "The upper size limit of the generated dfa. The default limit is \
+ 10M. This should only be changed on very large regex inputs \
+ where the (slower) fallback regex engine may otherwise be used. \
+ \n\nThe argument accepts the same size suffixes as allowed in \
+ the 'max-filesize' argument.");
doc!(h, "file",
"Search for patterns from the given file.",
"Search for patterns from the given file, with one pattern per \
@@ -444,6 +457,11 @@ lazy_static! {
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, "regex-size-limit",
+ "The upper size limit of the compiled regex.",
+ "The upper size limit of the compiled regex. The default limit \
+ is 10M. \n\nThe argument accepts the same size suffixes as \
+ allowed in the 'max-filesize' argument.");
doc!(h, "case-sensitive",
"Search case sensitively.",
"Search case sensitively. This overrides -i/--ignore-case and \
diff --git a/src/args.rs b/src/args.rs
index 34f38792..48c4ad56 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -771,12 +771,18 @@ impl<'a> ArgMatches<'a> {
let casei =
self.is_present("ignore-case")
&& !self.is_present("case-sensitive");
- GrepBuilder::new(&try!(self.pattern()))
+ let mut gb = GrepBuilder::new(&try!(self.pattern()))
.case_smart(smart)
.case_insensitive(casei)
- .line_terminator(b'\n')
- .build()
- .map_err(From::from)
+ .line_terminator(b'\n');
+
+ if let Some(limit) = try!(self.dfa_size_limit()) {
+ gb = gb.dfa_size_limit(limit);
+ }
+ if let Some(limit) = try!(self.regex_size_limit()) {
+ gb = gb.size_limit(limit);
+ }
+ gb.build().map_err(From::from)
}
/// Builds the set of glob overrides from the command line flags.
@@ -807,31 +813,64 @@ impl<'a> ArgMatches<'a> {
btypes.build().map_err(From::from)
}
- /// Parses the max-filesize argument option into a byte count.
- fn max_filesize(&self) -> Result