KernelNewbies:

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]")", I'm too lazy for that.
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: replaces spaces with bracket expressions to match
# optional/obligatory spaces for usage with egrep.
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"
# fixme: a regexp like [ *]+ fails since this becomes [[[:space:]]**]+
l="$(echo "$l" | sed -r "s/@branch/\(\\\\\{\.\.\.\\\\\}\|\[\^\{\};\]\*;\)/g")"  # 3 backrefs
l="$(echo "$l" | sed -r "s/@in_branch/\(\\\\\{\\\\\{-\.\.\\\\\}\)\?/g")"                # 5 backrefs
l="$(echo "$l" | sed -r "s/@branch8/\(\\\\\{\.8\.\\\\\}\|\[\^\{\};\]\*;\)/g")"  # 9 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//\\\(-..\\\)/[^()|&;]*(\(...\)[^()|&;]*)*}"                              # 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/$sp*}"
l="${l//@n/([^\n]*\n)*}"
l="${l//@S/$sp+}"
l="${l//\\$em/$em}"
l="${l//@w/($V|\.|->|\[$sp*[^][]+$sp*\]|\($sp*[^)(]*$sp*\))+}"
l="$(echo "$l" | sed -r "s/\\\\\{-\.\.\\\\\}/\[^\}\{\]*\(\\\\\{...\\\\\}\[^\}\{\]*\)*/g")" # 2 backrefs
l="$(echo "$l" | sed -r "s/\\\\\{\.\.\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g")" # 2 backrefs
l="$(echo "$l" | sed -r "s/\\\\\{\.8\.\\\\\}/\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*(\\\\\{\[^\}\{\]*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}\[^\}\{\]*)*\\\\\}/g")" # 2 backrefs
 echo "$l" | sed -r "
:a
s/($an_)$sp+($an_)/\1$sp+\2/g
s/(\[\[:space:\]\]\*)*$sp+/$sp*/g
$!{
 N
 ba
}
"
}

# echo a sed script to catch from multiline grep $n (where n=$#) and filter out $1 up to  ${n-1}.
# 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 app not prt;
local sp="[[:space:]]";         # space
local Sp="[     ]"
local ns="[^[:space:]]";        # no space
local bol="$ns*[:-][0-9]+[:-]"  # begin of line
local func="$(bli2 "$V\(...\)$Sp")"
while [ $# -ne 1 ]; do
 if [ -n "$1" ]; then
  [ "${1:0:6}" = "--sed=" ] && not="${1:6}" ||
  [ "${1:0:6}" = "--PrE=" ] && app="${1:6}" ||
  [ "${1:0:6}" = "--PrT=" ] && prt="${1:6}" || not="$not
/$(bli2 "$app$1")/d"
 fi
 shift
done
echo "
/^--/b
s/^($ns*)[:-]([0-9]+)[:-]/---[ vi \1 +\2 ]---\n/
:loop
s/^$bol//
/^(--$|\}$s|[^\n]*$func\n\{)/!{
 /\/\//s/$Sp\/\/.*$//g
 H
 \$!{
  n
  b loop
 }
}
x
/$(bli2 "$app$1")/!d
/\/\*/s/$Sp*\/\*+([^*]*|\*[^\/])*\*+\/$Sp/ /g
$not
p
$prt
d"
}

# gres does something like
# git grep -E -n [-opts] "$(bli2 "$1")" -- '*.c' '*.h' | sed -n -r "$(ecsed2 "${@:2})"
gres()
{
 local opts gq sq eopts prt file;
 while [ $# -ne 0 ]; do
  [ "${1:0:1}" != "-" ] && break;
  [ "${1:0:6}" = "--PrE=" ] && gq="${1:6}" ||
  [ "${1:0:6}" = "--PrT=" ] && prt="$1" ||
  [ "${1:0:6}" = "--FiL=" ] && file="${1:6}" ||
  [ "${1:0:6}" = "--sed=" ] && eopts="$1" || opts="${opts:+$opts }$1";
  shift;
 done
 if [ -n "$file" ]; then
  sq="$(ecsed2 "$prt" "$eopts" "$@")"
  sed -n -r "$sq" "$file"
 elif [ -z "$gq" ]; then
  gq="$(bli2 "$1")";
  sq="$(ecsed2 "$prt" "$eopts" "${@:2}")"
 else
  gq="$(bli2 "$gq")"
  sq="$(ecsed2 "$prt" "$eopts" "--PrE=$gq" "$@")";
 fi
 git grep -E -n $opts "$gq" -- '*.c' '*.h' | sed -n -r "$sq"
}

To use, save, e.g. as ~/bin/cvars.sh and:

source ~/bin/cvars.sh

For examples see examples on [wiki:roelkluin my page]

KernelNewbies: roelkluin/cvars (last edited 2010-01-20 01:03:06 by d133062)