⇤ ← Revision 1 as of 2009-12-28 14:55:45
3736
Comment: description of how to use cvars tools
|
3748
typos
|
Deletions are marked like this. | Additions are marked like this. |
Line 88: | Line 88: |
The first of the `path/to/filename.c-301-' is transformed into a vi command, the remainder are removed. Also any comments are removed before pattern matching. newlines are extended. For each match that git grep piped to sed If an exclusion pattern matches or if before the first pattern matched an end-of-function- or end-of-match-pattern occurred, i.e. respectively "^}" and "^--", nothing is displayed. |
The first of the `path/to/filename.c-301-' is transformed into a vi command, the remainder are removed. Also any comments are removed before pattern matching. newlines are extended. For each match that git grep piped to sed (parsed) matches are displayed if: * The last pattern matched and * no exclusion pattern matched * no end-of-function occurred, i.e. "\^}" * no end-of-match-pattern occurred, i.e. "\^--" |
You have to source [wiki:roelkluin/cvars cvars] to use these tools and run these commands in your git Linux kernel directory.
gg
gg does something like
git grep -n -E [other_options] "$(bli2 "$1")"
bli2
bli2() parses a string and transforms it into a more complex extended regexp, which it simply echoes.
To understand how it parses things try these:
bli2 "@V" bli2 "@d" bli2 " " bli2 " "
Note that @V will catch the identifier of a simple local variable, @d will catch a number (even if it's a hex or 1ull), spaces are squeezed and parsed to match optional spaces.
bli2 pattern |
echoed (description) |
echoed literal |
number of backrefs |
any space |
optional space |
no backref |
|
\! |
exclamation mark (because bash otherwise bangs) |
! |
no backref |
@S |
obligatory space |
no backref |
|
@V |
identifier |
[[:alpha:]_]+[[:alnum:]_]* |
no backref |
@K |
identifier in only uppercases |
[[:upper:]_]+[[:upper:][:digit:]_]* |
no backref |
@Q |
a non-alnumeric |
[^[:alnum:]_] |
no backref |
@Q2 |
a non-alnumeric or extension to the left of a variable |
[^[:alnum:]_>.] |
no backref |
@w |
(pointer) member, array |
see `bli2 "@w"' |
one backref |
@d |
any number |
see `bli2 "@d"' |
one backref |
\(...\) |
up to 2 nested parentheses |
see `bli2 "\(...\)"' |
two backrefs |
\{...\} |
up to 2 nested curly brackets |
see `bli2 "\{...\}"' |
two backrefs |
\[...\] |
up to 2 nested square brackets |
see `bli2 "\[...\]"' |
two backrefs |
\(-..\) |
characters optionally followed by up to 2 nested parentheses |
see `bli2 "\(...\)"' |
three backrefs |
\{-..\} |
characters optionally followed by up to 2 curly brackets |
see `bli2 "\{...\}"' |
three backrefs |
\{.8.\} |
up to 8 curly brackets |
see `bli2 "\(...\)"' |
eight backrefs |
gres
I wrote this to do a multiline (git-)grep
lets say we want to search for an erroneous pattern like this:
for (i = 0; i < n; i++) {} ... if (i > n) ...
We can match this with:
gres -B1 -A40 "@V < @d ;" "for \( (@V) = @d ; \1 < (@d) ; \1 \+\+ \) \{.8.\}@n if \( \1 > \3 \)"
For me - I currently have kernel version 2.6.33-rc2 - this results after a few seconds in:
-- ---[ vi drivers/mmc/host/s3cmci.c +1209 ]--- /* Set clock */ for (mci_psc = 0; mci_psc < 255; mci_psc++) { host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); if (host->real_rate <= ios->clock) break; } if (mci_psc > 255) mci_psc = 255; host->prescaler = mci_psc; writel(host->prescaler, host->base + S3C2410_SDIPRE); /* If requested clock is 0, real_rate will be 0, too */ if (ios->clock == 0) host->real_rate = 0;
So how does it work? gres does something in the order of:
git grep -E -n -other_opts "$(bli2 "$1")" -- '*.c' '*.h' | sed -n -r "$(ecsed2 "${@:2})"
The -B1' and -A40' are passed to git-grep, bli2() parses the first pattern and subsequent patterns are passed to ecsed2().
ecsed2
ecsed2() parses the `git grep' output and prints only the ones of which the last passed pattern matches, prior patterns (if any) are excluded.
More in detail:
gg -B1 -A40 "@V < @d ;"
The first of the `path/to/filename.c-301-' is transformed into a vi command, the remainder are removed. Also any comments are removed before pattern matching. newlines are extended. For each match that git grep piped to sed (parsed) matches are displayed if:
- The last pattern matched and
- no exclusion pattern matched
- no end-of-function occurred, i.e. "\^}"
- no end-of-match-pattern occurred, i.e. "\^--"