| 
  
   Size: 3957 
  
  Comment:  
 | 
  
   Size: 8030 
  
  Comment:  
 | 
| Deletions are marked like this. | Additions are marked like this. | 
| Line 3: | Line 3: | 
| == Your Name == Roel Kluin  | 
== Roel Kluin == | 
| Line 12: | Line 11: | 
some scripts for configuring a kernel: To translate a module name (as listed in modprobe -l or modinfo -n ''module'') into a kernel .config option: {{{ #!/bin/bash mod="${1%.ko}"; dir="${1%/*}"; sed -e :a -e '/\\$/N; s/\\\n//; ta' "${dir#*/kernel/}/Makefile" | \ sed -n "s/^obj-\$(CONFIG_\([A-Z0-9_]*\))\W*+=\W*"${mod##*/}"\.o$/\1/p"; }}} a sed script to check ioremap/iounmap balancing (can be adapted for others)  | 
all code is (c) Roel kluin, 2007 GNU GPL V.2. ==Examples== These may require the variables in the script 'vars' below, and should be called in a git tree. I simply paste them into my console (bash). some of Match Unlikely(x) ?= y {{{ git-grep -n "\(un\)\?likely$s([^()]*\(([^()]*)[^()]*\)*)$s.=" }}} These can be replaced with strchr {{{ E="\([^\"\\]\|\\[\\tnr\?'\"0bafv]\|\\[0-7]\{1,3\}\|\\[a-f0-9]\{1,2\}\|\\[A-F0-9]\{1,2\}\)" git-grep -n "strstr$s($s$W$s,$s\"$E\"$s)" }}} Show module initializing functions, not using {{{__init}}} or similarly exit {{{ git-grep -n "\(void\|int\)$s[[:alnum:]_]*module_[ei][xn]it(void)" | grep -v "__[ie][xn]it" }}} Matches if(function) BUG() {{{ q="${s}if$s(\($ccode$Q\)\?$L$s($ccode)$s$ccode$s)" git-grep -n -B1 "^\($q\)\?${s}BUG($s)$s;$cendl" | grep "$q$cendl" | grep -v "\(sizeof\|unlikely\|likely\)($ccode)" | less }}} A sed script to audit ioremap/iounmap balancing (can be adapted for others)  | 
| Line 45: | Line 63: | 
| scripts below may use these variables: {{{ # a number D="[0-9]\+" # we could also use this, to match something like 1ul, floats or hexes as well: # but the parentheses will cost one backreference for (git-)grep d="\([0-9]\+[uUlLfF]\?\|[0-9]\+[uU]\?[lL][lL]\?\|0x[a-f0-9]\+\|0x[A-F0-9]\+\|[0-9]\+[lL][lL][uU]\|[0-9]*\.[0-9]\+[fF]\?\)" # can be used for a variable/function name: V="[A-Za-z_]\+[A-Za-z0-9_]*" # capital: a config option/definition K="[A-Z]\+[A-Z0-9_]*"; # works the same as above, but also for members and arrays: one backreference W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*" # seperators: s="[[:space:]]*"; S="[[:space:]]\+" # useful to delimit a variable name: Q="[^[:alnum:]_]" # match the end of the line, including comments: one backreference (but at eol) cendl="$s\(\/[\*\/].*\)\?$" # match something that is not comment, string or character: 2 backreferences ccode="\([^\/\"']*\|\/[^\*\/]\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\/\|'[^']*'\|\"[^\"]*\"\)*" # resp function open and end (only works when indentation is correct. fo="^[\{]$cendl" fe="^[\}]$cendl" }}}  | 
|
| Line 94: | Line 75: | 
| show module initializing functions, not using {{{__init}}} or similarly exit {{{ git-grep -n "\(void\|int\)$s[[:alnum:]_]*module_[ei][xn]it(void)" | grep -v "__[ie][xn]it" }}} these can be replaced with strchr {{{ E="\([^\"\\]\|\\[\\tnr\?'\"0bafv]\|\\[0-7]\{1,3\}\|\\[a-f0-9]\{1,2\}\)" git-grep -n "strstr$s($s$W$s,$s\"$E\"$s)" }}} matches if(function) BUG() {{{  | 
matches a comparison as the last argument of a function. This may be correct but it is sometimes a misplaced check (and should be placed after the parenthesis instead). Use getcalls and/or getfunc to determine whether a boolean as the last argument is correct. {{{ h="\(([^()]*)\)\+"; git-grep -n -A9 ",[^);,]*=" | sed -n "s/^\([^\.]*\.[chsS]-[0-9]*-\|\([^\.]*\.[chsS]:[0-9]*:\)$s\)\(.*\)$/\2\3/p" | tr "\n" "@" | grep -o "@[^@]*$W$s(\(\([^,()]*\|$h\)*,\)\+\([^,()]*\|$h\)*[^\"]=${s}[^\",()]*)${s}[)&|]" | tr "@\t" " " | tr -s " " | less }}} Find values used as a boolean instead of the more common bitwise {{{ f1="\($W${s}[&|]\|[0-9]\+${s}[&|]\|)${s}[&|]\)" # adds 2 h="\(([^()]*\(([^()]*\(([^()]*)[^()]*\)*[^()]*)[^()]*\)*)\)\?" git-grep "\($f1$s$V$s$h$s\(&&\|||\|)\|?\)\|\(&&\|||\|(\)$s$V$s$h${s}[&|]$s\([0-9]*\($W\|[^0]\)[0-9]*\)\)" | sed -n "s/^.*\($f1$s\($V\)$s\(([^()]*)\)\?$s\(&&\|||\|)\)\|\(&&\|||\|(\)$s\($V\)$s\(([^()]*)\)\?${s}[&|]$s\([0-9]*\($W\|[^0]\)[0-9]*\)\).*$/\4\8/p" | while read n; do echo "$n"; done | sort | uniq -c | sort -rn | while read n a; do b=$(git-grep -n "\(\(\(if\|while\)$s(\|&&\|||\|\!\)$s$a$s\(&&\|||\|\|)?\|(\)\|\(&&\|||\|(\)$s$a$s\(&&\|||\|(\|?\)\)" | grep -v "Kconfig") [ -z "$b" ] && continue; c=`echo "$b" | wc -l` let d=$(($n/$c)) echo "----[ a=\"$a\" # used $n times as bitwise, $c times as boolean, div $d ]----" [ $c -gt 20 ] && continue; [ $d -lt 5 ] && continue; echo "$b" done | less }}} ==scripts== I called it vars, it contains some useful functions for kernel hacking. usage: "source path/to/vars" N.B. do not source this in the shell where you will compile the kernel ($Q is used in Makefiles as well, which will give problems) {{{ #!/bin/bash # (c) Roel kluin, 2008 GNU GPL V.2 # a number D="[0-9]\+" # we could also use this, to match something like 1ul, floats or hexes as well: # but the parentheses will cost one backreference for (git-)grep d="\([0-9]\+[uUlLfF]\?\|[0-9]\+[uU]\?[lL][lL]\?\|0x[a-f0-9]\+\|0x[A-F0-9]\+\|[0-9]\+[lL][lL][uU]\|[0-9]*\.[0-9]\+[fF]\?\)" # can be used for a variable/function name: V="[A-Za-z_]\+[A-Za-z0-9_]*" # capital: a config option/definition K="[A-Z]\+[A-Z0-9_]*"; # works the same as above, but also for members and arrays: one backreference W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*" # seperators: s="[[:space:]]*"; S="[[:space:]]\+" # useful to delimit a variable name: Q="[^[:alnum:]_]" # match the end of the line, including comments: one backreference (but at eol)  | 
| Line 108: | Line 142: | 
# match something that is not comment, string or character: 2 backreferences  | 
|
| Line 109: | Line 145: | 
| q="${s}if$s(\($ccode$Q\)\?$L$s($ccode)$s$ccode$s)" git-grep -n -B1 "^\($q\)\?${s}BUG($s)$s;$cendl" | grep "$q$cendl" | grep -v "\(sizeof\|unlikely\|likely\)($ccode)" | less  | 
# resp function open and end (only works when indentation is correct. fo="^[\{]$cendl" fe="^[\}]$cendl" alias gg="git-grep -n" # Usage: v /path/to/sourcefile.c:1 # (as pasted from git-grep -n) v() { [ -n "$1" ] && vi ${1%[:-]*} +${1##*[:-]} } # works similar to git-grep -n "$query" | tr ":" " " # except that :'s in the line are preserved ggrep2fnl() { git-grep -n "$1" | while read fnl; do f="$(echo "$fnl"| cut -d":" -f1)"; e="$(echo "$f" | rev | cut --complement -c3- | rev)"; [ "$e" != ".h" -a "$e" != ".c" ] && continue; echo "$f $(echo "$fnl"| cut -d":" -f2) $(echo "$fnl"| cut -d":" -f3-)"; done } #print function declaration at file "$1", line "$2" getfuncat() { head -n$2 "$1" | tac | sed -n "p; /^\(${V}[*&[:space:]]\+\)*$V$s(${ccode}[^;]$cendl/q" | tac #sed -n "/^\(${V}[*&[:space:]]\+\)*$V$s(${ccode}[^;]$cendl/,$(($2 - 1))p" "$1" | sed "{$2,/^[\}]$cendl/p}" } #print function declaration(s) getfunc() { q="^\(${V}[*&[:space:]]\+\)*$1$s(${ccode}[^;]$cendl"; ggrep2fnl "$q" | while read f n l; do [ -z "`echo $l | grep "{$cendl"`" -a \ -n "`sed -n "$n,/{$cendl/{/;/p}" "$f"`" ] && continue echo "//---[ vi $f +$n ]---" [ -n "`echo $l | grep "^$s$1"`" ] && let "n--" sed -n "$n,/$fe/p" "$f" done } # helper to print definition(s) / macro(s) _getdef() { ggrep2fnl "$2" | while read f n l; do echo "---[ vi $f +$n ]---" 1>&2 if [ -z `echo $l | grep "\\$cendl"` ]; then echo $l else sed -n "/$2/,/[^\\]$cendl/p" "$f" fi done } #print definition(s) / macro(s) getdef() { _getdef "$1" "^$s#${s}define$S$1\(([^()]*)\)\?$S" } #print only macro(s) getmac() { _getdef "$1" "^$s#${s}define$S$1([^()]*)$S" } #print function declaration(s) / definition(s) / macro(s) getfod() { getfunc $1; getdef $1; } #print macro(s) or function declaration(s) getfom() { getfunc $1; getmac $1; } # echoes "function name" at file "$1" line "$2" det_func() { q="^\(${V}[*&[:space:]]\+\)*\($V\)$s(${ccode}[^;]$cendl" head "$1" -n"$2" | tac | sed -n "/$q/{s/$q/\2/p;q}" } getcalls() { git-grep -n "\(^\|^$ccode$Q\)$1$s(\($ccode\()$s;\|[^)]\|)$ccode)$ccode\)\)\?$cendl" } }}} To translate a module name (as listed in modprobe -l or modinfo -n ''module'') into a kernel .config option: {{{ #!/bin/bash mod="${1%.ko}"; dir="${1%/*}"; sed -e :a -e '/\\$/N; s/\\\n//; ta' "${dir#*/kernel/}/Makefile" | \ sed -n "s/^obj-\$(CONFIG_\([A-Z0-9_]*\))\W*+=\W*"${mod##*/}"\.o$/\1/p";  | 
Roel Kluin
Email: MailTo(12o3l AT SPAMFREE tiscali DOT nl) ...
all code is (c) Roel kluin, 2007 GNU GPL V.2.
==Examples==
These may require the variables in the script 'vars' below, and should be called in a git tree. I simply paste them into my console (bash).
some of
Match Unlikely(x) ?= y
git-grep -n "\(un\)\?likely$s([^()]*\(([^()]*)[^()]*\)*)$s.="
These can be replaced with strchr
E="\([^\"\\]\|\\[\\tnr\?'\"0bafv]\|\\[0-7]\{1,3\}\|\\[a-f0-9]\{1,2\}\|\\[A-F0-9]\{1,2\}\)"
git-grep -n "strstr$s($s$W$s,$s\"$E\"$s)"Show module initializing functions, not using __init or similarly exit
git-grep -n "\(void\|int\)$s[[:alnum:]_]*module_[ei][xn]it(void)" | grep -v "__[ie][xn]it"
Matches if(function) BUG()
q="${s}if$s(\($ccode$Q\)\?$L$s($ccode)$s$ccode$s)"
git-grep -n -B1 "^\($q\)\?${s}BUG($s)$s;$cendl" | grep "$q$cendl" |
grep -v "\(sizeof\|unlikely\|likely\)($ccode)" | lessA sed script to audit ioremap/iounmap balancing (can be adapted for others)
git-grep -l '[^[:alnum:]]ioremap' | while read g; do
echo "--------------------------[ $g ]--------------------------"
sed -n "/[^[:alnum:]]ioremap.*(\(.*\))/,/^[}{]$/{
s/\(.*return.*\)/\1\t\t-------return/
tp
s/\(.*goto.*\)/\1\t\t------goto/
tp
s/\(.*iounmap.*\)/\1\t\t<----/
tp
s/\(.*ioremap.*\)/\1\t\t---->/
Tp
=
:p
p
}" $g
done | lessMake sure no-one is freeing skbs with kfree instead of kfree_skb
for f in $(git-grep -l "struct${s}sk_buff"); do
sed -n "s/^.*struct${S}sk_buff${s}\*${s}\(${V}\)$Q.*$/\1/p" $f | sort | uniq | while read n; do
sed -n "/struct${s}sk_buff${s}\*${s}${n}/,/^[{}].*$/{ /kfree(${s}${n}${s})/= }" $f | while read q; do
echo -e "kfreeing sk_buff $n at line $q in $f\n$q";
sed -n "/struct${s}sk_buff${s}\*${s}${n}/,/^[{}].*$/p" $f;
done
done
done 2>&1 | lessmatches a comparison as the last argument of a function. This may be correct but it is sometimes a misplaced check (and should be placed after the parenthesis instead). Use getcalls and/or getfunc to determine whether a boolean as the last argument is correct.
h="\(([^()]*)\)\+"; 
git-grep -n -A9 ",[^);,]*="  | 
sed -n "s/^\([^\.]*\.[chsS]-[0-9]*-\|\([^\.]*\.[chsS]:[0-9]*:\)$s\)\(.*\)$/\2\3/p" |
tr "\n" "@" |
grep -o "@[^@]*$W$s(\(\([^,()]*\|$h\)*,\)\+\([^,()]*\|$h\)*[^\"]=${s}[^\",()]*)${s}[)&|]" |
tr "@\t" " " | tr -s " " | lessFind values used as a boolean instead of the more common bitwise
f1="\($W${s}[&|]\|[0-9]\+${s}[&|]\|)${s}[&|]\)" # adds 2
h="\(([^()]*\(([^()]*\(([^()]*)[^()]*\)*[^()]*)[^()]*\)*)\)\?"
git-grep "\($f1$s$V$s$h$s\(&&\|||\|)\|?\)\|\(&&\|||\|(\)$s$V$s$h${s}[&|]$s\([0-9]*\($W\|[^0]\)[0-9]*\)\)" | 
sed -n "s/^.*\($f1$s\($V\)$s\(([^()]*)\)\?$s\(&&\|||\|)\)\|\(&&\|||\|(\)$s\($V\)$s\(([^()]*)\)\?${s}[&|]$s\([0-9]*\($W\|[^0]\)[0-9]*\)\).*$/\4\8/p" |
while read n; do
echo "$n"; 
done | 
sort | uniq -c | sort -rn | while read n a; do
b=$(git-grep -n "\(\(\(if\|while\)$s(\|&&\|||\|\!\)$s$a$s\(&&\|||\|\|)?\|(\)\|\(&&\|||\|(\)$s$a$s\(&&\|||\|(\|?\)\)" |
grep -v "Kconfig")
[ -z "$b" ] && continue;
c=`echo "$b" | wc -l`
let d=$(($n/$c))
echo "----[ a=\"$a\" # used $n times as bitwise, $c times as boolean, div $d ]----"
[ $c -gt 20 ] && continue; [ $d -lt 5 ] && continue;
echo "$b"
done | less==scripts==
I called it vars, it contains some useful functions for kernel hacking. usage: "source path/to/vars" N.B. do not source this in the shell where you will compile the kernel ($Q is used in Makefiles as well, which will give problems)
# (c) Roel kluin, 2008 GNU GPL V.2
# a number
D="[0-9]\+"
# we could also use this, to match something like 1ul, floats or hexes as well:
# but the parentheses will cost one backreference for (git-)grep
d="\([0-9]\+[uUlLfF]\?\|[0-9]\+[uU]\?[lL][lL]\?\|0x[a-f0-9]\+\|0x[A-F0-9]\+\|[0-9]\+[lL][lL][uU]\|[0-9]*\.[0-9]\+[fF]\?\)"
# can be used for a variable/function name:
V="[A-Za-z_]\+[A-Za-z0-9_]*"
# capital: a config option/definition
K="[A-Z]\+[A-Z0-9_]*";
# works the same as above, but also for members and arrays: one backreference
W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*"
# seperators:
s="[[:space:]]*";
S="[[:space:]]\+"
# useful to delimit a variable name:
Q="[^[:alnum:]_]"
# match the end of the line, including comments: one backreference (but at eol)
cendl="$s\(\/[\*\/].*\)\?$"
# match something that is not comment, string or character: 2 backreferences
ccode="\([^\/\"']*\|\/[^\*\/]\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\/\|'[^']*'\|\"[^\"]*\"\)*"
# resp function open and end (only works when indentation is correct.
fo="^[\{]$cendl"
fe="^[\}]$cendl"
alias gg="git-grep -n"
# Usage: v /path/to/sourcefile.c:1
# (as pasted from git-grep -n)
v()
{
  [ -n "$1" ] && vi ${1%[:-]*} +${1##*[:-]}
}
# works similar to git-grep -n "$query" | tr ":" " "
# except that :'s in the line are preserved
ggrep2fnl()
{
  git-grep -n "$1" | while read fnl; do
    f="$(echo "$fnl"| cut -d":" -f1)";
    e="$(echo "$f" | rev | cut --complement -c3- | rev)";
    [ "$e" != ".h" -a "$e" != ".c" ] && continue;
    echo "$f $(echo "$fnl"| cut -d":" -f2) $(echo "$fnl"| cut -d":" -f3-)";
  done
}
#print function declaration at file "$1", line "$2"
getfuncat()
{
  head -n$2 "$1" | tac | sed -n "p; /^\(${V}[*&[:space:]]\+\)*$V$s(${ccode}[^;]$cendl/q" | tac
  #sed -n "/^\(${V}[*&[:space:]]\+\)*$V$s(${ccode}[^;]$cendl/,$(($2 - 1))p" "$1" | sed "{$2,/^[\}]$cendl/p}"
}
#print function declaration(s)
getfunc()
{
  q="^\(${V}[*&[:space:]]\+\)*$1$s(${ccode}[^;]$cendl";
  ggrep2fnl "$q" | while read f n l; do
    [ -z "`echo $l | grep "{$cendl"`" -a \
         -n "`sed -n "$n,/{$cendl/{/;/p}" "$f"`" ] &&
      continue
    echo "//---[ vi $f +$n ]---"
    [ -n "`echo $l | grep "^$s$1"`" ] && 
      let "n--"
    sed -n "$n,/$fe/p" "$f"
  done
}
# helper to print definition(s) / macro(s)
_getdef()
{
  ggrep2fnl "$2" | while read f n l; do
    echo "---[ vi $f +$n ]---" 1>&2
    if [ -z `echo $l | grep "\\$cendl"` ]; then
      echo $l
    else
      sed -n "/$2/,/[^\\]$cendl/p" "$f"
    fi
  done
}
#print definition(s) / macro(s)
getdef()
{
  _getdef "$1" "^$s#${s}define$S$1\(([^()]*)\)\?$S"
}
#print only macro(s)
getmac()
{
  _getdef "$1" "^$s#${s}define$S$1([^()]*)$S"
}
#print function declaration(s) / definition(s) / macro(s)
getfod()
{
  getfunc $1;
  getdef $1;
}
#print macro(s) or function declaration(s)
getfom()
{
  getfunc $1;
  getmac $1;
}
# echoes "function name" at file "$1" line "$2"
det_func()
{
  q="^\(${V}[*&[:space:]]\+\)*\($V\)$s(${ccode}[^;]$cendl"
  head "$1" -n"$2" | tac | sed -n "/$q/{s/$q/\2/p;q}"
}
getcalls()
{
 git-grep -n "\(^\|^$ccode$Q\)$1$s(\($ccode\()$s;\|[^)]\|)$ccode)$ccode\)\)\?$cendl"
}To translate a module name (as listed in modprobe -l or modinfo -n module) into a kernel .config option:
mod="${1%.ko}";
dir="${1%/*}";
sed -e :a -e '/\\$/N; s/\\\n//; ta' "${dir#*/kernel/}/Makefile" | \
sed -n "s/^obj-\$(CONFIG_\([A-Z0-9_]*\))\W*+=\W*"${mod##*/}"\.o$/\1/p";Based on Linus' script to get the email address of a maintainer, I wrote this script to get the address of a list rather than a maintainers address for mailing.
git log --since="1 year ago"  "$@" | sed -n "s/^    .[-a-z]*by: \(.*\) <.*$/\1/p" |
sort | uniq | sort -n -r | while read name; do
        sed -n "/^P:[ \t]*.*$name/,/^$/{
                s/^L:[ \t]*\(.*\)$/\1/p
        }" ./MAINTAINERS
done | sort | uniq -c | sort -n -r | while read nr list; do
        tot=`grep -c "^L:\W*.*$list.*" ./MAINTAINERS`
        echo "`expr $nr / \( $tot + 1 \)` $nr $tot $list"
done | sort -r | cut -d " " -f2- | while read nr tot list; do
        echo -e "$nr/$tot Acks were commited by maintainers of list $list"
done