Size: 3048
Comment:
|
← Revision 19 as of 2017-12-30 01:30:28 ⇥
Size: 6487
Comment: converted to 1.6 markup
|
Deletions are marked like this. | Additions are marked like this. |
Line 5: | Line 5: |
# (c) [kernelnewbies.org/roelkluin Roel Kluin], 2009, GPL v2. | # (c) Roel Kluin, 2009, GPL v2. |
Line 8: | Line 8: |
# blank_it: replaces spaces with bracket expressions to match # optional/obligatory spaces for usage with egrep. |
# does git grep -n -E [options] "$(bli2 "[query]")". gg() { local opts; local q; local opts while [ $# -ne 0 ]; do [ "${1:0:2}" = "--" ] && break; if [ "${1:0:1}" = "-" ]; then opts="${opts:+$opts }${q:+$q }$1"; q="" else q="$1" fi shift; done git grep -n -E $opts "$(bli2 "$q")" $@ } # blank_it: creates extended regular expressions |
Line 19: | Line 35: |
local ns="[^[:space:]]" | |
Line 23: | Line 40: |
l="${l//@V/$V}" # variable/function/struct name l="${l//@Q2/[^[:alnum:]_>.]}" # 1 char left of variable/function/struct name l="${l//@Q/[^[:alnum:]_]}" # 1 char right of variable/function/struct name l="${l//@d/($int+[uUlLfF]?|$int+[uU]?[lL][lL]?|0x$hex+|$int+[lL][lL][uU]|$int*\.$int+[fF]?)}" # a number l="${l//@K/$up_+$AN_*}" # an definition or macro name (uppercase) l="${l//@s/$sp*}" # optional space l="${l//@S/$sp+}" # obligatory space l="${l//\\$em/$em}" # Because bash bangs otherwise l="${l//@w/($V|\.|->|\[$sp*[^][]+$sp*\]|\($sp*[^)(]*$sp*\))+}" # a variable/array/member/unnested function or macro l="${l//\\\(...\\\)/\([^()]*(\([^()]*(\([^()]*\)[^()]*)*\)[^()]*)*\)}" # nested parentheses, 2 backrefs l="$(echo "$l" | sed -r "s/\\\\\{\.\.\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g")" # nested curly brackets, 2 backrefs |
l="${l//@&...@/(&+\(-..\))*}" # 4 backrefs l="${l//@|...@/(\|+\(-..\))*}" # 4 backrefs l="${l//@&...&@/&+@...&@}" # 4 backrefs l="${l//@|...|@/\|+@...|@}" # 4 backrefs l="${l//@...&@/(\(-..\)&+)*}" # 4 backrefs l="${l//@...|@/(\(-..\)\|+)*}" # 4 backrefs l="${l//@&|...@/([&|]+\(-..\))*}" # 4 backrefs l="${l//@&|...&|@/[&|]+@...&|@}" # 4 backrefs l="${l//@...&|@/(\(-..\)[&|]+)*}" # 4 backrefs l="${l//\\\(-8.\\\)/[^()|&;]*(\(.8.\)[^()|&;]*)*}" # 9 backrefs l="${l//\\\(-..\\\)/[^()|&;]*(\(...\)[^()|&;]*)*}" # 3 backrefs l="${l//\\\(...\\\)/\([^();]*(\([^();]*(\([^();]*\)[^();]*)*\)[^();]*)*\)}" # 2 backrefs l="${l//\\\(.8.\\\)/\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*\)[^();]*)*\)[^();]*)*\)[^();]*)*\)[^();]*)\)[^();]*)*\)[^();]*)*\)[^();]*)*\)[^();]*)*\)}" # 8 backrefs l="${l//\\\[...\\\]/\[[^][]*(\[[^][]*(\[[^][]*\][^][]*)*\][^][]*)*\]}" # 2 backrefs l="${l//@V/$V}" l="${l//@Q2/[^[:alnum:]_>.]}" l="${l//@Q1/[^[:alnum:]_.-]}" l="${l//@Q/[^[:alnum:]_]}" l="${l//@d/($int+[uUlLfF]?|$int+[uU]?[lL][lL]?|0x$hex+|$int+[lL][lL][uU]|$int*\.$int+[fF]?)}" l="${l//@K/$up_+$AN_*}" l="${l//@s/ }" l="${l//@n/([^\n]*\n)*}" l="${l//@S/$sp+}" l="${l//\\$em/$em}" l="${l//\\t/$(echo -e "\t")}" l="${l//@w/($V| \. | -> |\[ [^][]* \]|\( [^)(]* \))+}" # warning: @dstring is impossible because of previous parsing of @d |
Line 36: | Line 69: |
s/@branch/\(\\\\\{\.\.\.\\\\\}\|\[\^\{\};\]\*;\)/g # 2 backrefs s/@in_branches/\(\\\\\{\\\\\{-\.\.\\\\\}\)+/g # 4 backrefs s/@in_branch/\(\\\\\{\\\\\{-\.\.\\\\\}\)\?/g # 4 backrefs s/@branch8/\(\\\\\{\.8\.\\\\\}\|\[\^\{\};\]\*;\)/g # 9 backrefs s/\\\\\{-\.\.\\\\\}/\[^\}\{\]*\(\\\\\{...\\\\\}\[^\}\{\]*\)*/g # 3 backrefs s/\\\\\{-8\.\\\\\}/\[^\}\{\]*\(\\\\\{.8.\\\\\}\[^\}\{\]*\)*/g # 9 backrefs s/\\\\\{\.\.\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g # 2 backrefs s/\\\\\{\.8\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g # 8 backrefs |
|
Line 37: | Line 79: |
s/(\[\[:space:\]\]\*)*$sp+/$sp*/g | s/((^|[^\\\\])\[\^?([^][[:space:]]*|\[:[^][]+:\])*)($sp+)/\1@\4@/g s/([^@[:space:]]|^)$sp+/\1$sp*/g s/@($sp+)@/\1/g |
Line 45: | Line 89: |
# echo a sed script to catch from multiline grep $n (where n=$#) and filter out $1 up to ${n-1}. | # echoes a sed script to filter multiline grep -n -H to display only # the ones with particular patterns. The last eregex determines what # is displayed, unless one of the eregexes before the last - if any - # match. # |
Line 48: | Line 96: |
ecsed() | ecsed2() |
Line 50: | Line 98: |
local app; if [ "${1:0:6}" = "--PrE=" ]; then app="${1:6}"; shift; fi local sp="[[:space:]]"; # space local ns="[^[:space:]]"; # no space local bol="$ns*[:-][0-9]+[:-]" # begin of line local not; while [ -n "$2" ]; do not="$not/$(bli2 "$app$1")/b;" shift; |
local match= exclude print catchrefs l; local op_sp="[ $(echo -e "\t")]*" while [ $# -ne 1 ]; do if [ -n "$1" ]; then if [ "${1:0:6}" = "--sed=" ]; then exclude="${1:6}"; elif [ "${1:0:11}" = "--backrefs=" ]; then catchrefs="${1:11}"; elif [ "${1:0:10}" = "--prepend=" ]; then match="${1:10}"; else #echo "excluded:^[^\n]*\n.*$match$1" 1>&2 exclude="$exclude /$(bli2 "^[^\n]*\n.*$match$1")/b" # the first line is the vi file +line printing fi fi shift |
Line 62: | Line 116: |
echo ":start /(--|$bol}$s)$/!{ N b start |
match="$match$1" [ -z "$catchrefs" ] && catchrefs="$(echo "$match" | grep -o -E "\\\\[1-9]" | sort | uniq)" for l in $catchrefs; do print="${print:+$print, }${l:1:1}: $l" done match="$(bli2 "^[^\n]*\n.*$match")" print="${print:+h;s/$match.*$/----[ backrefs: $print ]----/p;x;} s/^([^[:space:]]+)[:-]([1-9][0-9]*).(.*)$/---[ vi \1 +\2 ]---\3/p" echo " /^--$/b s/^([^[:space:]]+[:-][1-9][0-9]*.)/\1\n/ :loop H \$!{ n /^--$/!{ s/^[^[:space:]]+[:-][1-9][0-9]*.// /^\}/!b loop /^\{/{ x s/$(bli2 "^([^\n]*\n)(.*@Q2)?(@V\(.8.\) \n\{[^\n]*)")$/\1\3/ x } } |
Line 67: | Line 141: |
s/$sp*\/\*+([^*]*|\*[^\/])*\*+\// /g # remove C style comment s/(\/\/[^\n]*)?\n$bol/\n/g # remove C99 comment $not s/^($ns*)[:-]([0-9]+)[:-]/---[ vi \1 +\2 ]---\n/ s/\n--$// /$(bli2 "$app$1")/p" |
x s/^[^\n]*\n// /$match/!b /(\*\/|\/[\/*])/{ s/($op_sp\/\*+|^([^\n]*\n))([^\/]*|\/*[^*\/])*\*+\//\2/g /\/[\/*]/ s/$op_sp\/(\/[^\n]*((\n|$))|\*+([^*]*|\**[^*\/])*$)/\3/g } /$match/!b $exclude " |
Line 75: | Line 154: |
Line 76: | Line 156: |
# git grep -E -n [-opts] "[parsed $1]" | sed -n -r "[parsed ${@:2}]" | # git grep -E -n [-opts] "$(bli2 "$1")" -- '*.c' '*.h' | sed -n -r "$(ecsed2 "${@:2})" |
Line 79: | Line 159: |
local opts; local o; local append; local gq; local sq; | local opts gq sq eopts fil tim; |
Line 81: | Line 161: |
[ "${1:0:1}" != "-" ] && break; [ "${1:0:6}" != "--PrE=" ] && opts="$opts $1" || gq="${1:6}"; |
if [ "${1:0:1}" != "-" ]; then break; fi if [ "${1:0:6}" = "--time" ]; then tim="time"; elif [ "${1:0:10}" = "--prepend=" ]; then gq="${1:10}"; elif [ "${1:0:6}" = "--FiL=" ]; then fil="${1:6}"; elif [ "${1:0:11}" = "--backrefs=" ]; then eopts="${eopts:+$eopts }$1"; elif [ "${1:0:6}" = "--sed=" ]; then eopts="${eopts:+$eopts }$1"; else opts="${opts:+$opts }$1"; fi |
Line 85: | Line 179: |
if [ -n "$fil" ]; then sq="$(ecsed2 "$prt" $eopts "$@")" $tim sed -n -r "$sq" "$fil" elif [ -z "$(echo "$opts" | grep -o "[-][ACB][1-9]")" ]; then echo "gres without --FiL=... requires an -[ABC]n Context argument, otherwise use grep" return; fi |
|
Line 87: | Line 188: |
shift; sq="$(ecsed2 "$@")" |
sq="$(ecsed2 "$prt" $eopts "${@:2}")" |
Line 91: | Line 191: |
sq="$(ecsed2 "--PrE=$gq" "$@")"; | sq="$(ecsed2 "$prt" $eopts "--PrE=$gq" "$@")"; |
Line 93: | Line 193: |
git grep -E -n $opts "$gq" | sed -n -r "$sq" | $tim git grep -E -n $opts "$gq" -- '*.c' '*.h' 2>&1 | sed -n -r "$sq" |
Line 97: | Line 197: |
To use, save, e.g. as ~/bin/cvars.sh and: {{{ source ~/bin/cvars.sh }}} |
To use, save, e.g. as ~/bin/cvars.sh, and source it. For examples see examples on [[roelkluin|my page]] |
The script below can be used for static code analysis. It requires git, sed and grep
# (c) Roel Kluin, 2009, GPL v2. #!/bin/bash # does git grep -n -E [options] "$(bli2 "[query]")". gg() { local opts; local q; local opts while [ $# -ne 0 ]; do [ "${1:0:2}" = "--" ] && break; if [ "${1:0:1}" = "-" ]; then opts="${opts:+$opts }${q:+$q }$1"; q="" else q="$1" fi shift; done git grep -n -E $opts "$(bli2 "$q")" $@ } # blank_it: creates extended regular expressions bli2() { local int="[[:digit:]]" local hex="[[:xdigit:]]" local up_="[[:upper:]_]" local al_="[[:alpha:]_]" local AN_="[[:upper:][:digit:]_]" local an_="[[:alnum:]_]" local sp="[[:space:]]" local ns="[^[:space:]]" local V="$al_+$an_*" local em='!' local l="$1" l="${l//@&...@/(&+\(-..\))*}" # 4 backrefs l="${l//@|...@/(\|+\(-..\))*}" # 4 backrefs l="${l//@&...&@/&+@...&@}" # 4 backrefs l="${l//@|...|@/\|+@...|@}" # 4 backrefs l="${l//@...&@/(\(-..\)&+)*}" # 4 backrefs l="${l//@...|@/(\(-..\)\|+)*}" # 4 backrefs l="${l//@&|...@/([&|]+\(-..\))*}" # 4 backrefs l="${l//@&|...&|@/[&|]+@...&|@}" # 4 backrefs l="${l//@...&|@/(\(-..\)[&|]+)*}" # 4 backrefs l="${l//\\\(-8.\\\)/[^()|&;]*(\(.8.\)[^()|&;]*)*}" # 9 backrefs l="${l//\\\(-..\\\)/[^()|&;]*(\(...\)[^()|&;]*)*}" # 3 backrefs l="${l//\\\(...\\\)/\([^();]*(\([^();]*(\([^();]*\)[^();]*)*\)[^();]*)*\)}" # 2 backrefs l="${l//\\\(.8.\\\)/\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*(\([^();]*\)[^();]*)*\)[^();]*)*\)[^();]*)*\)[^();]*)\)[^();]*)*\)[^();]*)*\)[^();]*)*\)[^();]*)*\)}" # 8 backrefs l="${l//\\\[...\\\]/\[[^][]*(\[[^][]*(\[[^][]*\][^][]*)*\][^][]*)*\]}" # 2 backrefs l="${l//@V/$V}" l="${l//@Q2/[^[:alnum:]_>.]}" l="${l//@Q1/[^[:alnum:]_.-]}" l="${l//@Q/[^[:alnum:]_]}" l="${l//@d/($int+[uUlLfF]?|$int+[uU]?[lL][lL]?|0x$hex+|$int+[lL][lL][uU]|$int*\.$int+[fF]?)}" l="${l//@K/$up_+$AN_*}" l="${l//@s/ }" l="${l//@n/([^\n]*\n)*}" l="${l//@S/$sp+}" l="${l//\\$em/$em}" l="${l//\\t/$(echo -e "\t")}" l="${l//@w/($V| \. | -> |\[ [^][]* \]|\( [^)(]* \))+}" # warning: @dstring is impossible because of previous parsing of @d echo "$l" | sed -r " :a s/@branch/\(\\\\\{\.\.\.\\\\\}\|\[\^\{\};\]\*;\)/g # 2 backrefs s/@in_branches/\(\\\\\{\\\\\{-\.\.\\\\\}\)+/g # 4 backrefs s/@in_branch/\(\\\\\{\\\\\{-\.\.\\\\\}\)\?/g # 4 backrefs s/@branch8/\(\\\\\{\.8\.\\\\\}\|\[\^\{\};\]\*;\)/g # 9 backrefs s/\\\\\{-\.\.\\\\\}/\[^\}\{\]*\(\\\\\{...\\\\\}\[^\}\{\]*\)*/g # 3 backrefs s/\\\\\{-8\.\\\\\}/\[^\}\{\]*\(\\\\\{.8.\\\\\}\[^\}\{\]*\)*/g # 9 backrefs s/\\\\\{\.\.\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g # 2 backrefs s/\\\\\{\.8\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g # 8 backrefs s/($an_)$sp+($an_)/\1$sp+\2/g s/((^|[^\\\\])\[\^?([^][[:space:]]*|\[:[^][]+:\])*)($sp+)/\1@\4@/g s/([^@[:space:]]|^)$sp+/\1$sp*/g s/@($sp+)@/\1/g $!{ N ba } " } # echoes a sed script to filter multiline grep -n -H to display only # the ones with particular patterns. The last eregex determines what # is displayed, unless one of the eregexes before the last - if any - # match. # # e.g. grep -E -n -H -B1 -A10 "foo" ~/file | sed -n -r "$(ecsed2 "foo.*bar" "foo")" # searches for lines with `foo', not followed by `bar' ecsed2() { local match= exclude print catchrefs l; local op_sp="[ $(echo -e "\t")]*" while [ $# -ne 1 ]; do if [ -n "$1" ]; then if [ "${1:0:6}" = "--sed=" ]; then exclude="${1:6}"; elif [ "${1:0:11}" = "--backrefs=" ]; then catchrefs="${1:11}"; elif [ "${1:0:10}" = "--prepend=" ]; then match="${1:10}"; else #echo "excluded:^[^\n]*\n.*$match$1" 1>&2 exclude="$exclude /$(bli2 "^[^\n]*\n.*$match$1")/b" # the first line is the vi file +line printing fi fi shift done match="$match$1" [ -z "$catchrefs" ] && catchrefs="$(echo "$match" | grep -o -E "\\\\[1-9]" | sort | uniq)" for l in $catchrefs; do print="${print:+$print, }${l:1:1}: $l" done match="$(bli2 "^[^\n]*\n.*$match")" print="${print:+h;s/$match.*$/----[ backrefs: $print ]----/p;x;} s/^([^[:space:]]+)[:-]([1-9][0-9]*).(.*)$/---[ vi \1 +\2 ]---\3/p" echo " /^--$/b s/^([^[:space:]]+[:-][1-9][0-9]*.)/\1\n/ :loop H \$!{ n /^--$/!{ s/^[^[:space:]]+[:-][1-9][0-9]*.// /^\}/!b loop /^\{/{ x s/$(bli2 "^([^\n]*\n)(.*@Q2)?(@V\(.8.\) \n\{[^\n]*)")$/\1\3/ x } } } x s/^[^\n]*\n// /$match/!b /(\*\/|\/[\/*])/{ s/($op_sp\/\*+|^([^\n]*\n))([^\/]*|\/*[^*\/])*\*+\//\2/g /\/[\/*]/ s/$op_sp\/(\/[^\n]*((\n|$))|\*+([^*]*|\**[^*\/])*$)/\3/g } /$match/!b $exclude $print " } # gres does something like # git grep -E -n [-opts] "$(bli2 "$1")" -- '*.c' '*.h' | sed -n -r "$(ecsed2 "${@:2})" gres() { local opts gq sq eopts fil tim; while [ $# -ne 0 ]; do if [ "${1:0:1}" != "-" ]; then break; fi if [ "${1:0:6}" = "--time" ]; then tim="time"; elif [ "${1:0:10}" = "--prepend=" ]; then gq="${1:10}"; elif [ "${1:0:6}" = "--FiL=" ]; then fil="${1:6}"; elif [ "${1:0:11}" = "--backrefs=" ]; then eopts="${eopts:+$eopts }$1"; elif [ "${1:0:6}" = "--sed=" ]; then eopts="${eopts:+$eopts }$1"; else opts="${opts:+$opts }$1"; fi shift; done if [ -n "$fil" ]; then sq="$(ecsed2 "$prt" $eopts "$@")" $tim sed -n -r "$sq" "$fil" elif [ -z "$(echo "$opts" | grep -o "[-][ACB][1-9]")" ]; then echo "gres without --FiL=... requires an -[ABC]n Context argument, otherwise use grep" return; fi if [ -z "$gq" ]; then gq="$(bli2 "$1")"; sq="$(ecsed2 "$prt" $eopts "${@:2}")" else gq="$(bli2 "$gq")" sq="$(ecsed2 "$prt" $eopts "--PrE=$gq" "$@")"; fi $tim git grep -E -n $opts "$gq" -- '*.c' '*.h' 2>&1 | sed -n -r "$sq" }
To use, save, e.g. as ~/bin/cvars.sh, and source it.
For examples see examples on my page