mirror of
https://github.com/git/git.git
synced 2026-01-11 21:33:13 +09:00
Amend my change earlier in this series ("grep: add support for the
PCRE v1 JIT API", 2017-04-11) to un-break the build on PCRE v1
versions later than 8.31 compiled without --enable-jit.
As explained in that change and a later compatibility change in this
series ("grep: un-break building with PCRE < 8.32", 2017-05-10) the
pcre_jit_exec() function is a faster path to execute the JIT.
Unfortunately there's no compatibility stub for that function compiled
into the library if pcre_config(PCRE_CONFIG_JIT, &ret) would return 0,
and no macro that can be used to check for it, so the only portable
option to support builds without --enable-jit is via a new
NO_LIBPCRE1_JIT=UnfortunatelyYes Makefile option[1].
Another option would be to make the JIT opt-in via
USE_LIBPCRE1_JIT=YesPlease, after all it's not a default option of
PCRE v1.
I think it makes more sense to make it opt-out since even though it's
not a default option, most packagers of PCRE seem to turn it on by
default, with the notable exception of the MinGW package.
Make the MinGW platform work by default by changing the build defaults
to turn on NO_LIBPCRE1_JIT=UnfortunatelyYes. It is the only platform
that turns on USE_LIBPCRE=YesPlease by default, see commit
df5218b4c3 ("config.mak.uname: support MSys2", 2016-01-13) for that
change.
1. "How do I support pcre1 JIT on all
versions?" (https://lists.exim.org/lurker/thread/20170601.103148.10253788.en.html)
2. https://github.com/Alexpux/MINGW-packages/blob/master/mingw-w64-pcre/PKGBUILD
(referenced from "Re: PCRE v2 compile error, was Re: What's cooking
in git.git (May 2017, #01; Mon, 1)";
<alpine.DEB.2.20.1705021756530.3480@virtualbox>)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
231 lines
5.1 KiB
C
231 lines
5.1 KiB
C
#ifndef GREP_H
|
|
#define GREP_H
|
|
#include "color.h"
|
|
#ifdef USE_LIBPCRE1
|
|
#include <pcre.h>
|
|
#ifdef PCRE_CONFIG_JIT
|
|
#if PCRE_MAJOR >= 8 && PCRE_MINOR >= 32
|
|
#ifndef NO_LIBPCRE1_JIT
|
|
#define GIT_PCRE1_USE_JIT
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifndef PCRE_STUDY_JIT_COMPILE
|
|
#define PCRE_STUDY_JIT_COMPILE 0
|
|
#endif
|
|
#if PCRE_MAJOR <= 8 && PCRE_MINOR < 20
|
|
typedef int pcre_jit_stack;
|
|
#endif
|
|
#else
|
|
typedef int pcre;
|
|
typedef int pcre_extra;
|
|
typedef int pcre_jit_stack;
|
|
#endif
|
|
#include "kwset.h"
|
|
#include "thread-utils.h"
|
|
#include "userdiff.h"
|
|
|
|
enum grep_pat_token {
|
|
GREP_PATTERN,
|
|
GREP_PATTERN_HEAD,
|
|
GREP_PATTERN_BODY,
|
|
GREP_AND,
|
|
GREP_OPEN_PAREN,
|
|
GREP_CLOSE_PAREN,
|
|
GREP_NOT,
|
|
GREP_OR
|
|
};
|
|
|
|
enum grep_context {
|
|
GREP_CONTEXT_HEAD,
|
|
GREP_CONTEXT_BODY
|
|
};
|
|
|
|
enum grep_header_field {
|
|
GREP_HEADER_FIELD_MIN = 0,
|
|
GREP_HEADER_AUTHOR = GREP_HEADER_FIELD_MIN,
|
|
GREP_HEADER_COMMITTER,
|
|
GREP_HEADER_REFLOG,
|
|
|
|
/* Must be at the end of the enum */
|
|
GREP_HEADER_FIELD_MAX
|
|
};
|
|
|
|
struct grep_pat {
|
|
struct grep_pat *next;
|
|
const char *origin;
|
|
int no;
|
|
enum grep_pat_token token;
|
|
char *pattern;
|
|
size_t patternlen;
|
|
enum grep_header_field field;
|
|
regex_t regexp;
|
|
pcre *pcre1_regexp;
|
|
pcre_extra *pcre1_extra_info;
|
|
pcre_jit_stack *pcre1_jit_stack;
|
|
const unsigned char *pcre1_tables;
|
|
int pcre1_jit_on;
|
|
kwset_t kws;
|
|
unsigned fixed:1;
|
|
unsigned ignore_case:1;
|
|
unsigned word_regexp:1;
|
|
};
|
|
|
|
enum grep_expr_node {
|
|
GREP_NODE_ATOM,
|
|
GREP_NODE_NOT,
|
|
GREP_NODE_AND,
|
|
GREP_NODE_TRUE,
|
|
GREP_NODE_OR
|
|
};
|
|
|
|
enum grep_pattern_type {
|
|
GREP_PATTERN_TYPE_UNSPECIFIED = 0,
|
|
GREP_PATTERN_TYPE_BRE,
|
|
GREP_PATTERN_TYPE_ERE,
|
|
GREP_PATTERN_TYPE_FIXED,
|
|
GREP_PATTERN_TYPE_PCRE
|
|
};
|
|
|
|
struct grep_expr {
|
|
enum grep_expr_node node;
|
|
unsigned hit;
|
|
union {
|
|
struct grep_pat *atom;
|
|
struct grep_expr *unary;
|
|
struct {
|
|
struct grep_expr *left;
|
|
struct grep_expr *right;
|
|
} binary;
|
|
} u;
|
|
};
|
|
|
|
struct grep_opt {
|
|
struct grep_pat *pattern_list;
|
|
struct grep_pat **pattern_tail;
|
|
struct grep_pat *header_list;
|
|
struct grep_pat **header_tail;
|
|
struct grep_expr *pattern_expression;
|
|
const char *prefix;
|
|
int prefix_length;
|
|
regex_t regexp;
|
|
int linenum;
|
|
int invert;
|
|
int ignore_case;
|
|
int status_only;
|
|
int name_only;
|
|
int unmatch_name_only;
|
|
int count;
|
|
int word_regexp;
|
|
int fixed;
|
|
int all_match;
|
|
int debug;
|
|
#define GREP_BINARY_DEFAULT 0
|
|
#define GREP_BINARY_NOMATCH 1
|
|
#define GREP_BINARY_TEXT 2
|
|
int binary;
|
|
int allow_textconv;
|
|
int extended;
|
|
int use_reflog_filter;
|
|
int pcre1;
|
|
int relative;
|
|
int pathname;
|
|
int null_following_name;
|
|
int color;
|
|
int max_depth;
|
|
int funcname;
|
|
int funcbody;
|
|
int extended_regexp_option;
|
|
int pattern_type_option;
|
|
char color_context[COLOR_MAXLEN];
|
|
char color_filename[COLOR_MAXLEN];
|
|
char color_function[COLOR_MAXLEN];
|
|
char color_lineno[COLOR_MAXLEN];
|
|
char color_match_context[COLOR_MAXLEN];
|
|
char color_match_selected[COLOR_MAXLEN];
|
|
char color_selected[COLOR_MAXLEN];
|
|
char color_sep[COLOR_MAXLEN];
|
|
int regflags;
|
|
unsigned pre_context;
|
|
unsigned post_context;
|
|
unsigned last_shown;
|
|
int show_hunk_mark;
|
|
int file_break;
|
|
int heading;
|
|
void *priv;
|
|
|
|
void (*output)(struct grep_opt *opt, const void *data, size_t size);
|
|
void *output_priv;
|
|
};
|
|
|
|
extern void init_grep_defaults(void);
|
|
extern int grep_config(const char *var, const char *value, void *);
|
|
extern void grep_init(struct grep_opt *, const char *prefix);
|
|
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
|
|
|
|
extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
|
|
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
|
extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
|
|
extern void compile_grep_patterns(struct grep_opt *opt);
|
|
extern void free_grep_patterns(struct grep_opt *opt);
|
|
extern int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size);
|
|
|
|
struct grep_source {
|
|
char *name;
|
|
|
|
enum grep_source_type {
|
|
GREP_SOURCE_SHA1,
|
|
GREP_SOURCE_FILE,
|
|
GREP_SOURCE_BUF,
|
|
GREP_SOURCE_SUBMODULE,
|
|
} type;
|
|
void *identifier;
|
|
|
|
char *buf;
|
|
unsigned long size;
|
|
|
|
char *path; /* for attribute lookups */
|
|
struct userdiff_driver *driver;
|
|
};
|
|
|
|
void grep_source_init(struct grep_source *gs, enum grep_source_type type,
|
|
const char *name, const char *path,
|
|
const void *identifier);
|
|
void grep_source_clear_data(struct grep_source *gs);
|
|
void grep_source_clear(struct grep_source *gs);
|
|
void grep_source_load_driver(struct grep_source *gs);
|
|
|
|
|
|
int grep_source(struct grep_opt *opt, struct grep_source *gs);
|
|
|
|
extern struct grep_opt *grep_opt_dup(const struct grep_opt *opt);
|
|
extern int grep_threads_ok(const struct grep_opt *opt);
|
|
|
|
#ifndef NO_PTHREADS
|
|
/*
|
|
* Mutex used around access to the attributes machinery if
|
|
* opt->use_threads. Must be initialized/destroyed by callers!
|
|
*/
|
|
extern int grep_use_locks;
|
|
extern pthread_mutex_t grep_attr_mutex;
|
|
extern pthread_mutex_t grep_read_mutex;
|
|
|
|
static inline void grep_read_lock(void)
|
|
{
|
|
if (grep_use_locks)
|
|
pthread_mutex_lock(&grep_read_mutex);
|
|
}
|
|
|
|
static inline void grep_read_unlock(void)
|
|
{
|
|
if (grep_use_locks)
|
|
pthread_mutex_unlock(&grep_read_mutex);
|
|
}
|
|
|
|
#else
|
|
#define grep_read_lock()
|
|
#define grep_read_unlock()
|
|
#endif
|
|
|
|
#endif
|