Merge branch 'rs/color-grep'
* rs/color-grep: grep: prefer builtin over external one when coloring results grep: cast printf %.*s "precision" argument explicitly to int grep: add support for coloring with external greps grep: color patterns in output grep: add pmatch and eflags arguments to match_one_pattern() grep: remove grep_opt argument from match_expr_eval() grep: micro-optimize hit collection for AND nodes
This commit is contained in:
@ -553,6 +553,25 @@ color.diff.<slot>::
|
|||||||
whitespace errors). The values of these variables may be specified as
|
whitespace errors). The values of these variables may be specified as
|
||||||
in color.branch.<slot>.
|
in color.branch.<slot>.
|
||||||
|
|
||||||
|
color.grep::
|
||||||
|
When set to `always`, always highlight matches. When `false` (or
|
||||||
|
`never`), never. When set to `true` or `auto`, use color only
|
||||||
|
when the output is written to the terminal. Defaults to `false`.
|
||||||
|
|
||||||
|
color.grep.external::
|
||||||
|
The string value of this variable is passed to an external 'grep'
|
||||||
|
command as a command line option if match highlighting is turned
|
||||||
|
on. If set to an empty string, no option is passed at all,
|
||||||
|
turning off coloring for external 'grep' calls; this is the default.
|
||||||
|
For GNU grep, set it to `--color=always` to highlight matches even
|
||||||
|
when a pager is used.
|
||||||
|
|
||||||
|
color.grep.match::
|
||||||
|
Use customized color for matches. The value of this variable
|
||||||
|
may be specified as in color.branch.<slot>. It is passed using
|
||||||
|
the environment variables 'GREP_COLOR' and 'GREP_COLORS' when
|
||||||
|
calling an external 'grep'.
|
||||||
|
|
||||||
color.interactive::
|
color.interactive::
|
||||||
When set to `always`, always use colors for interactive prompts
|
When set to `always`, always use colors for interactive prompts
|
||||||
and displays (such as those used by "git-add --interactive").
|
and displays (such as those used by "git-add --interactive").
|
||||||
|
@ -17,6 +17,7 @@ SYNOPSIS
|
|||||||
[-l | --files-with-matches] [-L | --files-without-match]
|
[-l | --files-with-matches] [-L | --files-without-match]
|
||||||
[-z | --null]
|
[-z | --null]
|
||||||
[-c | --count] [--all-match]
|
[-c | --count] [--all-match]
|
||||||
|
[--color | --no-color]
|
||||||
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
||||||
[-f <file>] [-e] <pattern>
|
[-f <file>] [-e] <pattern>
|
||||||
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
|
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
|
||||||
@ -105,6 +106,13 @@ OPTIONS
|
|||||||
Instead of showing every matched line, show the number of
|
Instead of showing every matched line, show the number of
|
||||||
lines that match.
|
lines that match.
|
||||||
|
|
||||||
|
--color::
|
||||||
|
Show colored matches.
|
||||||
|
|
||||||
|
--no-color::
|
||||||
|
Turn off match highlighting, even when the configuration file
|
||||||
|
gives the default to color output.
|
||||||
|
|
||||||
-[ABC] <context>::
|
-[ABC] <context>::
|
||||||
Show `context` trailing (`A` -- after), or leading (`B`
|
Show `context` trailing (`A` -- after), or leading (`B`
|
||||||
-- before), or both (`C` -- context) lines, and place a
|
-- before), or both (`C` -- context) lines, and place a
|
||||||
|
@ -22,6 +22,28 @@
|
|||||||
|
|
||||||
static int builtin_grep;
|
static int builtin_grep;
|
||||||
|
|
||||||
|
static int grep_config(const char *var, const char *value, void *cb)
|
||||||
|
{
|
||||||
|
struct grep_opt *opt = cb;
|
||||||
|
|
||||||
|
if (!strcmp(var, "grep.color") || !strcmp(var, "color.grep")) {
|
||||||
|
opt->color = git_config_colorbool(var, value, -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(var, "grep.color.external") ||
|
||||||
|
!strcmp(var, "color.grep.external")) {
|
||||||
|
return git_config_string(&(opt->color_external), var, value);
|
||||||
|
}
|
||||||
|
if (!strcmp(var, "grep.color.match") ||
|
||||||
|
!strcmp(var, "color.grep.match")) {
|
||||||
|
if (!value)
|
||||||
|
return config_error_nonbool(var);
|
||||||
|
color_parse(value, var, opt->color_match);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return git_color_default_config(var, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* git grep pathspecs are somewhat different from diff-tree pathspecs;
|
* git grep pathspecs are somewhat different from diff-tree pathspecs;
|
||||||
* pathname wildcards are allowed.
|
* pathname wildcards are allowed.
|
||||||
@ -269,6 +291,21 @@ static int flush_grep(struct grep_opt *opt,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void grep_add_color(struct strbuf *sb, const char *escape_seq)
|
||||||
|
{
|
||||||
|
size_t orig_len = sb->len;
|
||||||
|
|
||||||
|
while (*escape_seq) {
|
||||||
|
if (*escape_seq == 'm')
|
||||||
|
strbuf_addch(sb, ';');
|
||||||
|
else if (*escape_seq != '\033' && *escape_seq != '[')
|
||||||
|
strbuf_addch(sb, *escape_seq);
|
||||||
|
escape_seq++;
|
||||||
|
}
|
||||||
|
if (sb->len > orig_len && sb->buf[sb->len - 1] == ';')
|
||||||
|
strbuf_setlen(sb, sb->len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
||||||
{
|
{
|
||||||
int i, nr, argc, hit, len, status;
|
int i, nr, argc, hit, len, status;
|
||||||
@ -339,6 +376,23 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
|||||||
push_arg("-e");
|
push_arg("-e");
|
||||||
push_arg(p->pattern);
|
push_arg(p->pattern);
|
||||||
}
|
}
|
||||||
|
if (opt->color) {
|
||||||
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
|
||||||
|
grep_add_color(&sb, opt->color_match);
|
||||||
|
setenv("GREP_COLOR", sb.buf, 1);
|
||||||
|
|
||||||
|
strbuf_reset(&sb);
|
||||||
|
strbuf_addstr(&sb, "mt=");
|
||||||
|
grep_add_color(&sb, opt->color_match);
|
||||||
|
strbuf_addstr(&sb, ":sl=:cx=:fn=:ln=:bn=:se=");
|
||||||
|
setenv("GREP_COLORS", sb.buf, 1);
|
||||||
|
|
||||||
|
strbuf_release(&sb);
|
||||||
|
|
||||||
|
if (opt->color_external && strlen(opt->color_external) > 0)
|
||||||
|
push_arg(opt->color_external);
|
||||||
|
}
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
argc = nr;
|
argc = nr;
|
||||||
@ -536,6 +590,12 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
opt.pattern_tail = &opt.pattern_list;
|
opt.pattern_tail = &opt.pattern_list;
|
||||||
opt.regflags = REG_NEWLINE;
|
opt.regflags = REG_NEWLINE;
|
||||||
|
|
||||||
|
strcpy(opt.color_match, GIT_COLOR_RED GIT_COLOR_BOLD);
|
||||||
|
opt.color = -1;
|
||||||
|
git_config(grep_config, &opt);
|
||||||
|
if (opt.color == -1)
|
||||||
|
opt.color = git_use_color_default;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no -- then the paths must exist in the working
|
* If there is no -- then the paths must exist in the working
|
||||||
* tree. If there is no explicit pattern specified with -e or
|
* tree. If there is no explicit pattern specified with -e or
|
||||||
@ -732,6 +792,14 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
opt.relative = 0;
|
opt.relative = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("--color", arg)) {
|
||||||
|
opt.color = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp("--no-color", arg)) {
|
||||||
|
opt.color = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("--", arg)) {
|
if (!strcmp("--", arg)) {
|
||||||
/* later processing wants to have this at argv[1] */
|
/* later processing wants to have this at argv[1] */
|
||||||
argv--;
|
argv--;
|
||||||
@ -757,6 +825,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.color && !opt.color_external)
|
||||||
|
builtin_grep = 1;
|
||||||
if (!opt.pattern_list)
|
if (!opt.pattern_list)
|
||||||
die("no pattern given.");
|
die("no pattern given.");
|
||||||
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
||||||
|
145
grep.c
145
grep.c
@ -39,6 +39,8 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
p->word_regexp = opt->word_regexp;
|
||||||
|
|
||||||
if (opt->fixed || is_fixed(p->pattern))
|
if (opt->fixed || is_fixed(p->pattern))
|
||||||
p->fixed = 1;
|
p->fixed = 1;
|
||||||
if (opt->regflags & REG_ICASE)
|
if (opt->regflags & REG_ICASE)
|
||||||
@ -251,18 +253,6 @@ static int word_char(char ch)
|
|||||||
return isalnum(ch) || ch == '_';
|
return isalnum(ch) || ch == '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_line(struct grep_opt *opt, const char *bol, const char *eol,
|
|
||||||
const char *name, unsigned lno, char sign)
|
|
||||||
{
|
|
||||||
if (opt->null_following_name)
|
|
||||||
sign = '\0';
|
|
||||||
if (opt->pathname)
|
|
||||||
printf("%s%c", name, sign);
|
|
||||||
if (opt->linenum)
|
|
||||||
printf("%d%c", lno, sign);
|
|
||||||
printf("%.*s\n", (int)(eol-bol), bol);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_name(struct grep_opt *opt, const char *name)
|
static void show_name(struct grep_opt *opt, const char *name)
|
||||||
{
|
{
|
||||||
printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
|
printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
|
||||||
@ -306,11 +296,12 @@ static struct {
|
|||||||
{ "committer ", 10 },
|
{ "committer ", 10 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
|
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||||
|
enum grep_context ctx,
|
||||||
|
regmatch_t *pmatch, int eflags)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
int saved_ch = 0;
|
int saved_ch = 0;
|
||||||
regmatch_t pmatch[10];
|
|
||||||
|
|
||||||
if ((p->token != GREP_PATTERN) &&
|
if ((p->token != GREP_PATTERN) &&
|
||||||
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
|
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
|
||||||
@ -329,16 +320,12 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
|
|||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (!p->fixed) {
|
if (p->fixed)
|
||||||
regex_t *exp = &p->regexp;
|
|
||||||
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
|
|
||||||
pmatch, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hit = !fixmatch(p->pattern, bol, pmatch);
|
hit = !fixmatch(p->pattern, bol, pmatch);
|
||||||
}
|
else
|
||||||
|
hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
|
||||||
|
|
||||||
if (hit && opt->word_regexp) {
|
if (hit && p->word_regexp) {
|
||||||
if ((pmatch[0].rm_so < 0) ||
|
if ((pmatch[0].rm_so < 0) ||
|
||||||
(eol - bol) <= pmatch[0].rm_so ||
|
(eol - bol) <= pmatch[0].rm_so ||
|
||||||
(pmatch[0].rm_eo < 0) ||
|
(pmatch[0].rm_eo < 0) ||
|
||||||
@ -378,39 +365,33 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_expr_eval(struct grep_opt *o,
|
static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
|
||||||
struct grep_expr *x,
|
enum grep_context ctx, int collect_hits)
|
||||||
char *bol, char *eol,
|
|
||||||
enum grep_context ctx,
|
|
||||||
int collect_hits)
|
|
||||||
{
|
{
|
||||||
int h = 0;
|
int h = 0;
|
||||||
|
regmatch_t match;
|
||||||
|
|
||||||
switch (x->node) {
|
switch (x->node) {
|
||||||
case GREP_NODE_ATOM:
|
case GREP_NODE_ATOM:
|
||||||
h = match_one_pattern(o, x->u.atom, bol, eol, ctx);
|
h = match_one_pattern(x->u.atom, bol, eol, ctx, &match, 0);
|
||||||
break;
|
break;
|
||||||
case GREP_NODE_NOT:
|
case GREP_NODE_NOT:
|
||||||
h = !match_expr_eval(o, x->u.unary, bol, eol, ctx, 0);
|
h = !match_expr_eval(x->u.unary, bol, eol, ctx, 0);
|
||||||
break;
|
break;
|
||||||
case GREP_NODE_AND:
|
case GREP_NODE_AND:
|
||||||
if (!collect_hits)
|
if (!match_expr_eval(x->u.binary.left, bol, eol, ctx, 0))
|
||||||
return (match_expr_eval(o, x->u.binary.left,
|
return 0;
|
||||||
bol, eol, ctx, 0) &&
|
h = match_expr_eval(x->u.binary.right, bol, eol, ctx, 0);
|
||||||
match_expr_eval(o, x->u.binary.right,
|
|
||||||
bol, eol, ctx, 0));
|
|
||||||
h = match_expr_eval(o, x->u.binary.left, bol, eol, ctx, 0);
|
|
||||||
h &= match_expr_eval(o, x->u.binary.right, bol, eol, ctx, 0);
|
|
||||||
break;
|
break;
|
||||||
case GREP_NODE_OR:
|
case GREP_NODE_OR:
|
||||||
if (!collect_hits)
|
if (!collect_hits)
|
||||||
return (match_expr_eval(o, x->u.binary.left,
|
return (match_expr_eval(x->u.binary.left,
|
||||||
bol, eol, ctx, 0) ||
|
bol, eol, ctx, 0) ||
|
||||||
match_expr_eval(o, x->u.binary.right,
|
match_expr_eval(x->u.binary.right,
|
||||||
bol, eol, ctx, 0));
|
bol, eol, ctx, 0));
|
||||||
h = match_expr_eval(o, x->u.binary.left, bol, eol, ctx, 0);
|
h = match_expr_eval(x->u.binary.left, bol, eol, ctx, 0);
|
||||||
x->u.binary.left->hit |= h;
|
x->u.binary.left->hit |= h;
|
||||||
h |= match_expr_eval(o, x->u.binary.right, bol, eol, ctx, 1);
|
h |= match_expr_eval(x->u.binary.right, bol, eol, ctx, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die("Unexpected node type (internal error) %d", x->node);
|
die("Unexpected node type (internal error) %d", x->node);
|
||||||
@ -424,24 +405,104 @@ static int match_expr(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
enum grep_context ctx, int collect_hits)
|
enum grep_context ctx, int collect_hits)
|
||||||
{
|
{
|
||||||
struct grep_expr *x = opt->pattern_expression;
|
struct grep_expr *x = opt->pattern_expression;
|
||||||
return match_expr_eval(opt, x, bol, eol, ctx, collect_hits);
|
return match_expr_eval(x, bol, eol, ctx, collect_hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_line(struct grep_opt *opt, char *bol, char *eol,
|
static int match_line(struct grep_opt *opt, char *bol, char *eol,
|
||||||
enum grep_context ctx, int collect_hits)
|
enum grep_context ctx, int collect_hits)
|
||||||
{
|
{
|
||||||
struct grep_pat *p;
|
struct grep_pat *p;
|
||||||
|
regmatch_t match;
|
||||||
|
|
||||||
if (opt->extended)
|
if (opt->extended)
|
||||||
return match_expr(opt, bol, eol, ctx, collect_hits);
|
return match_expr(opt, bol, eol, ctx, collect_hits);
|
||||||
|
|
||||||
/* we do not call with collect_hits without being extended */
|
/* we do not call with collect_hits without being extended */
|
||||||
for (p = opt->pattern_list; p; p = p->next) {
|
for (p = opt->pattern_list; p; p = p->next) {
|
||||||
if (match_one_pattern(opt, p, bol, eol, ctx))
|
if (match_one_pattern(p, bol, eol, ctx, &match, 0))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int match_next_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||||
|
enum grep_context ctx,
|
||||||
|
regmatch_t *pmatch, int eflags)
|
||||||
|
{
|
||||||
|
regmatch_t match;
|
||||||
|
|
||||||
|
if (!match_one_pattern(p, bol, eol, ctx, &match, eflags))
|
||||||
|
return 0;
|
||||||
|
if (match.rm_so < 0 || match.rm_eo < 0)
|
||||||
|
return 0;
|
||||||
|
if (pmatch->rm_so >= 0 && pmatch->rm_eo >= 0) {
|
||||||
|
if (match.rm_so > pmatch->rm_so)
|
||||||
|
return 1;
|
||||||
|
if (match.rm_so == pmatch->rm_so && match.rm_eo < pmatch->rm_eo)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pmatch->rm_so = match.rm_so;
|
||||||
|
pmatch->rm_eo = match.rm_eo;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int next_match(struct grep_opt *opt, char *bol, char *eol,
|
||||||
|
enum grep_context ctx, regmatch_t *pmatch, int eflags)
|
||||||
|
{
|
||||||
|
struct grep_pat *p;
|
||||||
|
int hit = 0;
|
||||||
|
|
||||||
|
pmatch->rm_so = pmatch->rm_eo = -1;
|
||||||
|
if (bol < eol) {
|
||||||
|
for (p = opt->pattern_list; p; p = p->next) {
|
||||||
|
switch (p->token) {
|
||||||
|
case GREP_PATTERN: /* atom */
|
||||||
|
case GREP_PATTERN_HEAD:
|
||||||
|
case GREP_PATTERN_BODY:
|
||||||
|
hit |= match_next_pattern(p, bol, eol, ctx,
|
||||||
|
pmatch, eflags);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
||||||
|
const char *name, unsigned lno, char sign)
|
||||||
|
{
|
||||||
|
int rest = eol - bol;
|
||||||
|
|
||||||
|
if (opt->null_following_name)
|
||||||
|
sign = '\0';
|
||||||
|
if (opt->pathname)
|
||||||
|
printf("%s%c", name, sign);
|
||||||
|
if (opt->linenum)
|
||||||
|
printf("%d%c", lno, sign);
|
||||||
|
if (opt->color) {
|
||||||
|
regmatch_t match;
|
||||||
|
enum grep_context ctx = GREP_CONTEXT_BODY;
|
||||||
|
int ch = *eol;
|
||||||
|
int eflags = 0;
|
||||||
|
|
||||||
|
*eol = '\0';
|
||||||
|
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
|
||||||
|
printf("%.*s%s%.*s%s",
|
||||||
|
(int)match.rm_so, bol,
|
||||||
|
opt->color_match,
|
||||||
|
(int)(match.rm_eo - match.rm_so), bol + match.rm_so,
|
||||||
|
GIT_COLOR_RESET);
|
||||||
|
bol += match.rm_eo;
|
||||||
|
rest -= match.rm_eo;
|
||||||
|
eflags = REG_NOTBOL;
|
||||||
|
}
|
||||||
|
*eol = ch;
|
||||||
|
}
|
||||||
|
printf("%.*s\n", rest, bol);
|
||||||
|
}
|
||||||
|
|
||||||
static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
static int grep_buffer_1(struct grep_opt *opt, const char *name,
|
||||||
char *buf, unsigned long size, int collect_hits)
|
char *buf, unsigned long size, int collect_hits)
|
||||||
{
|
{
|
||||||
|
5
grep.h
5
grep.h
@ -1,5 +1,6 @@
|
|||||||
#ifndef GREP_H
|
#ifndef GREP_H
|
||||||
#define GREP_H
|
#define GREP_H
|
||||||
|
#include "color.h"
|
||||||
|
|
||||||
enum grep_pat_token {
|
enum grep_pat_token {
|
||||||
GREP_PATTERN,
|
GREP_PATTERN,
|
||||||
@ -31,6 +32,7 @@ struct grep_pat {
|
|||||||
enum grep_header_field field;
|
enum grep_header_field field;
|
||||||
regex_t regexp;
|
regex_t regexp;
|
||||||
unsigned fixed:1;
|
unsigned fixed:1;
|
||||||
|
unsigned word_regexp:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum grep_expr_node {
|
enum grep_expr_node {
|
||||||
@ -76,6 +78,9 @@ struct grep_opt {
|
|||||||
unsigned relative:1;
|
unsigned relative:1;
|
||||||
unsigned pathname:1;
|
unsigned pathname:1;
|
||||||
unsigned null_following_name:1;
|
unsigned null_following_name:1;
|
||||||
|
int color;
|
||||||
|
char color_match[COLOR_MAXLEN];
|
||||||
|
const char *color_external;
|
||||||
int regflags;
|
int regflags;
|
||||||
unsigned pre_context;
|
unsigned pre_context;
|
||||||
unsigned post_context;
|
unsigned post_context;
|
||||||
|
Reference in New Issue
Block a user