summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorkevans <kevans@FreeBSD.org>2017-08-16 17:38:37 +0000
committerkevans <kevans@FreeBSD.org>2017-08-16 17:38:37 +0000
commitdb6ebb64cc3f817db5d2be7fd2ab38ea5cc6c5b2 (patch)
treeb7a214f2e0ef1b6897a2519dadf501f0653c23c7 /usr.bin
parent3c5634d1b9ae20b0a99db710b23f5bc2c9fda9d4 (diff)
downloadFreeBSD-src-db6ebb64cc3f817db5d2be7fd2ab38ea5cc6c5b2.zip
FreeBSD-src-db6ebb64cc3f817db5d2be7fd2ab38ea5cc6c5b2.tar.gz
MFC r317254: bsdgrep: add BSD_GREP_FASTMATCH knob for built-in fastmatch
Bugs have been found in the fastmatch implementation as used in bsdgrep. Some have been fixed (r316495) while fixes for others are in review (D10098). In comparison with the fastmatch implementation, Kyle Evans found that: - regex(3)'s performance with literal expressions offers a speed improvement over fastmatch - regex(3)'s performance, both with simple BREs and EREs, seems to be comparable The regex implementation was imported in r226035, and the commit message reports: This is a temporary solution until the whole regex library is not replaced so that BSD grep development can continue and the backported code gets some review and testing. This change only improves scalability slightly, there is no big performance boost yet but several minor bugs have been found and fixed. Introduce a WITH_/WITHOUT_BSD_GREP_FASTMATCH knob to support testing of both approaches. Regenerate src.conf(5) as per the original commit PR: 175314, 194823 Approved by: emaste (mentor, blanket MFC)
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/grep/Makefile6
-rw-r--r--usr.bin/grep/grep.c25
-rw-r--r--usr.bin/grep/grep.h4
-rw-r--r--usr.bin/grep/util.c8
4 files changed, 34 insertions, 9 deletions
diff --git a/usr.bin/grep/Makefile b/usr.bin/grep/Makefile
index 7c67659..c6b25f0 100644
--- a/usr.bin/grep/Makefile
+++ b/usr.bin/grep/Makefile
@@ -15,10 +15,14 @@ bsdgrep.1: grep.1
.endif
SRCS= file.c grep.c queue.c util.c
-# Extra files ported backported form some regex improvements
+.if ${MK_BSD_GREP_FASTMATCH} == "yes"
+# Extra files ported backported for some regex improvements
.PATH: ${.CURDIR}/regex
SRCS+= fastmatch.c hashtable.c tre-compile.c tre-fastmatch.c
CFLAGS+=-I${.CURDIR}/regex
+.else
+CFLAGS+= -DWITHOUT_FASTMATCH
+.endif
CFLAGS.gcc+= --param max-inline-insns-single=500
diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c
index 47e6465..9709ce6 100644
--- a/usr.bin/grep/grep.c
+++ b/usr.bin/grep/grep.c
@@ -50,7 +50,9 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
+#ifndef WITHOUT_FASTMATCH
#include "fastmatch.h"
+#endif
#include "grep.h"
#ifndef WITHOUT_NLS
@@ -87,7 +89,9 @@ unsigned int patterns;
static unsigned int pattern_sz;
struct pat *pattern;
regex_t *r_pattern;
+#ifndef WITHOUT_FASTMATCH
fastmatch_t *fg_pattern;
+#endif
/* Filename exclusion/inclusion patterns */
unsigned int fpatterns, dpatterns;
@@ -716,20 +720,25 @@ main(int argc, char *argv[])
usage();
}
+#ifndef WITHOUT_FASTMATCH
fg_pattern = grep_calloc(patterns, sizeof(*fg_pattern));
+#endif
r_pattern = grep_calloc(patterns, sizeof(*r_pattern));
/* Check if cheating is allowed (always is for fgrep). */
for (i = 0; i < patterns; ++i) {
+#ifndef WITHOUT_FASTMATCH
+ /* Attempt compilation with fastmatch regex and fallback to
+ regex(3) if it fails. */
if (fastncomp(&fg_pattern[i], pattern[i].pat,
- pattern[i].len, cflags) != 0) {
- /* Fall back to full regex library */
- c = regcomp(&r_pattern[i], pattern[i].pat, cflags);
- if (c != 0) {
- regerror(c, &r_pattern[i], re_error,
- RE_ERROR_BUF);
- errx(2, "%s", re_error);
- }
+ pattern[i].len, cflags) == 0)
+ continue;
+#endif
+ c = regcomp(&r_pattern[i], pattern[i].pat, cflags);
+ if (c != 0) {
+ regerror(c, &r_pattern[i], re_error,
+ RE_ERROR_BUF);
+ errx(2, "%s", re_error);
}
}
diff --git a/usr.bin/grep/grep.h b/usr.bin/grep/grep.h
index c82e6bb..ea17af40 100644
--- a/usr.bin/grep/grep.h
+++ b/usr.bin/grep/grep.h
@@ -36,7 +36,9 @@
#include <stdio.h>
#include <zlib.h>
+#ifndef WITHOUT_FASTMATCH
#include "fastmatch.h"
+#endif
#ifdef WITHOUT_NLS
#define getstr(n) errstr[n]
@@ -127,7 +129,9 @@ extern unsigned int dpatterns, fpatterns, patterns;
extern struct pat *pattern;
extern struct epat *dpattern, *fpattern;
extern regex_t *er_pattern, *r_pattern;
+#ifndef WITHOUT_FASTMATCH
extern fastmatch_t *fg_pattern;
+#endif
/* For regex errors */
#define RE_ERROR_BUF 512
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 285f883..8815d4f 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -49,7 +49,9 @@ __FBSDID("$FreeBSD$");
#include <wchar.h>
#include <wctype.h>
+#ifndef WITHOUT_FASTMATCH
#include "fastmatch.h"
+#endif
#include "grep.h"
static int linesqueued;
@@ -317,10 +319,12 @@ procline(struct str *l, int nottext)
for (i = 0; i < patterns; i++) {
pmatch.rm_so = st;
pmatch.rm_eo = l->len;
+#ifndef WITHOUT_FASTMATCH
if (fg_pattern[i].pattern)
r = fastexec(&fg_pattern[i],
l->dat, 1, &pmatch, leflags);
else
+#endif
r = regexec(&r_pattern[i], l->dat, 1,
&pmatch, leflags);
r = (r == 0) ? 0 : REG_NOMATCH;
@@ -332,7 +336,11 @@ procline(struct str *l, int nottext)
(size_t)pmatch.rm_eo != l->len)
r = REG_NOMATCH;
/* Check for whole word match */
+#ifndef WITHOUT_FASTMATCH
if (r == 0 && (wflag || fg_pattern[i].word)) {
+#else
+ if (r == 0 && wflag) {
+#endif
wchar_t wbegin, wend;
wbegin = wend = L' ';
OpenPOWER on IntegriCloud