Git fork
at reftables-rust 266 lines 6.8 kB view raw
1#ifndef GREP_H 2#define GREP_H 3#include "color.h" 4#ifdef USE_LIBPCRE2 5#define PCRE2_CODE_UNIT_WIDTH 8 6#include <pcre2.h> 7#if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 36) || PCRE2_MAJOR >= 11 8#define GIT_PCRE2_VERSION_10_36_OR_HIGHER 9#endif 10#if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 35) || PCRE2_MAJOR >= 11 11#define GIT_PCRE2_VERSION_10_35_OR_HIGHER 12#endif 13#if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 34) || PCRE2_MAJOR >= 11 14#define GIT_PCRE2_VERSION_10_34_OR_HIGHER 15#endif 16#else 17typedef int pcre2_code; 18typedef int pcre2_match_data; 19typedef int pcre2_compile_context; 20typedef int pcre2_general_context; 21#endif 22#ifndef PCRE2_MATCH_INVALID_UTF 23/* PCRE2_MATCH_* dummy also with !USE_LIBPCRE2, for test-pcre2-config.c */ 24#define PCRE2_MATCH_INVALID_UTF 0 25#endif 26#include "thread-utils.h" 27#include "userdiff.h" 28 29struct repository; 30 31enum grep_pat_token { 32 GREP_PATTERN, 33 GREP_PATTERN_HEAD, 34 GREP_PATTERN_BODY, 35 GREP_AND, 36 GREP_OPEN_PAREN, 37 GREP_CLOSE_PAREN, 38 GREP_NOT, 39 GREP_OR 40}; 41 42enum grep_context { 43 GREP_CONTEXT_HEAD, 44 GREP_CONTEXT_BODY 45}; 46 47enum grep_header_field { 48 GREP_HEADER_FIELD_MIN = 0, 49 GREP_HEADER_AUTHOR = GREP_HEADER_FIELD_MIN, 50 GREP_HEADER_COMMITTER, 51 GREP_HEADER_REFLOG, 52 53 /* Must be at the end of the enum */ 54 GREP_HEADER_FIELD_MAX 55}; 56 57enum grep_color { 58 GREP_COLOR_CONTEXT, 59 GREP_COLOR_FILENAME, 60 GREP_COLOR_FUNCTION, 61 GREP_COLOR_LINENO, 62 GREP_COLOR_COLUMNNO, 63 GREP_COLOR_MATCH_CONTEXT, 64 GREP_COLOR_MATCH_SELECTED, 65 GREP_COLOR_SELECTED, 66 GREP_COLOR_SEP, 67 NR_GREP_COLORS 68}; 69 70struct grep_pat { 71 struct grep_pat *next; 72 const char *origin; 73 int no; 74 enum grep_pat_token token; 75 char *pattern; 76 size_t patternlen; 77 enum grep_header_field field; 78 regex_t regexp; 79 pcre2_code *pcre2_pattern; 80 pcre2_match_data *pcre2_match_data; 81 pcre2_compile_context *pcre2_compile_context; 82 pcre2_general_context *pcre2_general_context; 83 const uint8_t *pcre2_tables; 84 uint32_t pcre2_jit_on; 85 unsigned fixed:1; 86 unsigned is_fixed:1; 87 unsigned ignore_case:1; 88 unsigned word_regexp:1; 89}; 90 91enum grep_expr_node { 92 GREP_NODE_ATOM, 93 GREP_NODE_NOT, 94 GREP_NODE_AND, 95 GREP_NODE_TRUE, 96 GREP_NODE_OR 97}; 98 99enum grep_pattern_type { 100 GREP_PATTERN_TYPE_UNSPECIFIED = 0, 101 GREP_PATTERN_TYPE_BRE, 102 GREP_PATTERN_TYPE_ERE, 103 GREP_PATTERN_TYPE_FIXED, 104 GREP_PATTERN_TYPE_PCRE 105}; 106 107struct grep_expr { 108 enum grep_expr_node node; 109 unsigned hit; 110 union { 111 struct grep_pat *atom; 112 struct grep_expr *unary; 113 struct { 114 struct grep_expr *left; 115 struct grep_expr *right; 116 } binary; 117 } u; 118}; 119 120struct grep_opt { 121 struct grep_pat *pattern_list; 122 struct grep_pat **pattern_tail; 123 struct grep_pat *header_list; 124 struct grep_pat **header_tail; 125 struct grep_expr *pattern_expression; 126 127 /* 128 * NEEDSWORK: See if we can remove this field, because the repository 129 * should probably be per-source. That is, grep.c functions using this 130 * field should probably start using "repo" in "struct grep_source" 131 * instead. 132 * 133 * This is potentially the cause of at least one bug - "git grep" 134 * using the textconv attributes from the superproject on the 135 * submodules. See the failing "git grep --textconv" tests in 136 * t7814-grep-recurse-submodules.sh for more information. 137 */ 138 struct repository *repo; 139 140 int linenum; 141 int columnnum; 142 int invert; 143 int ignore_case; 144 int status_only; 145 int name_only; 146 int unmatch_name_only; 147 int count; 148 int word_regexp; 149 int all_match; 150 int no_body_match; 151 int body_hit; 152#define GREP_BINARY_DEFAULT 0 153#define GREP_BINARY_NOMATCH 1 154#define GREP_BINARY_TEXT 2 155 int binary; 156 int allow_textconv; 157 int use_reflog_filter; 158 int relative; 159 int pathname; 160 int null_following_name; 161 int only_matching; 162 enum git_colorbool color; 163 int max_depth; 164 int funcname; 165 int funcbody; 166 int extended_regexp_option; 167 enum grep_pattern_type pattern_type_option; 168 int ignore_locale; 169 char colors[NR_GREP_COLORS][COLOR_MAXLEN]; 170 unsigned pre_context; 171 unsigned post_context; 172 unsigned last_shown; 173 int show_hunk_mark; 174 int file_break; 175 int heading; 176 int max_count; 177 void *priv; 178 179 void (*output)(struct grep_opt *opt, const void *data, size_t size); 180 void *output_priv; 181}; 182 183#define GREP_OPT_INIT { \ 184 .relative = 1, \ 185 .pathname = 1, \ 186 .max_depth = -1, \ 187 .max_count = -1, \ 188 .pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED, \ 189 .colors = { \ 190 [GREP_COLOR_CONTEXT] = "", \ 191 [GREP_COLOR_FILENAME] = GIT_COLOR_MAGENTA, \ 192 [GREP_COLOR_FUNCTION] = "", \ 193 [GREP_COLOR_LINENO] = GIT_COLOR_GREEN, \ 194 [GREP_COLOR_COLUMNNO] = GIT_COLOR_GREEN, \ 195 [GREP_COLOR_MATCH_CONTEXT] = GIT_COLOR_BOLD_RED, \ 196 [GREP_COLOR_MATCH_SELECTED] = GIT_COLOR_BOLD_RED, \ 197 [GREP_COLOR_SELECTED] = "", \ 198 [GREP_COLOR_SEP] = GIT_COLOR_CYAN, \ 199 }, \ 200 .only_matching = 0, \ 201 .color = GIT_COLOR_UNKNOWN, \ 202 .output = std_output, \ 203} 204 205struct config_context; 206int grep_config(const char *var, const char *value, 207 const struct config_context *ctx, void *data); 208void grep_init(struct grep_opt *, struct repository *repo); 209 210void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t); 211void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t); 212void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *); 213void compile_grep_patterns(struct grep_opt *opt); 214void free_grep_patterns(struct grep_opt *opt); 215int grep_buffer(struct grep_opt *opt, const char *buf, unsigned long size); 216 217/* The field parameter is only used to filter header patterns 218 * (where appropriate). If filtering isn't desirable 219 * GREP_HEADER_FIELD_MAX should be supplied. 220 */ 221int grep_next_match(struct grep_opt *opt, 222 const char *bol, const char *eol, 223 enum grep_context ctx, regmatch_t *pmatch, 224 enum grep_header_field field, int eflags); 225 226struct grep_source { 227 char *name; 228 229 enum grep_source_type { 230 GREP_SOURCE_OID, 231 GREP_SOURCE_FILE, 232 GREP_SOURCE_BUF, 233 } type; 234 void *identifier; 235 struct repository *repo; /* if GREP_SOURCE_OID */ 236 237 const char *buf; 238 unsigned long size; 239 240 char *path; /* for attribute lookups */ 241 struct userdiff_driver *driver; 242}; 243 244void grep_source_init_file(struct grep_source *gs, const char *name, 245 const char *path); 246void grep_source_init_oid(struct grep_source *gs, const char *name, 247 const char *path, const struct object_id *oid, 248 struct repository *repo); 249void grep_source_clear_data(struct grep_source *gs); 250void grep_source_clear(struct grep_source *gs); 251void grep_source_load_driver(struct grep_source *gs, 252 struct index_state *istate); 253 254 255int grep_source(struct grep_opt *opt, struct grep_source *gs); 256 257struct grep_opt *grep_opt_dup(const struct grep_opt *opt); 258 259/* 260 * Mutex used around access to the attributes machinery if 261 * opt->use_threads. Must be initialized/destroyed by callers! 262 */ 263extern int grep_use_locks; 264extern pthread_mutex_t grep_attr_mutex; 265 266#endif