Size: 8434
Comment: use raw read to catch backslashes in macros and test string in _getdef
|
Size: 12625
Comment: update email and add a link to my updated personal page.
|
Deletions are marked like this. | Additions are marked like this. |
Line 5: | Line 5: |
Email: [[MailTo(12o3l AT SPAMFREE tiscali DOT nl)]] | Email: [[MailTo(roel.kluin@gmail.com)]] |
Line 11: | Line 11: |
""This is my old page, see [[roelkluin]] for updated scripts and snippets."" |
|
Line 24: | Line 26: |
E="\([^\"\\]\|\\[\\tnr\?'\"0bafv]\|\\[0-7]\{1,3\}\|\\[a-f0-9]\{1,2\}\|\\[A-F0-9]\{1,2\}\)" | E="\([^\"\\\\]\|\\\\[\\\\tnr\?'\"0bafv]\|\\\\[0-7]\{1,3\}\|\\\\[a-f0-9]\{1,2\}\|\\\\[A-F0-9]\{1,2\}\)" |
Line 30: | Line 32: |
git-grep -n "\(void\|int\)$s[[:alnum:]_]*module_[ei][xn]it(void)" | grep -v "__[ie][xn]it" | git-grep -n "\(void\|int\)${s}[[:alnum:]_]*module_[ei][xn]it(void)" | grep -v "__[ie][xn]it" |
Line 103: | Line 105: |
catch tests below 0 on unsigned {{{ # define what to search for left_operator="\([;,|^?:(]\|[\!+*/%&|~^-]=\|>>=\|<<=\|\[\|&&\|$an_$s&\)" right_operator="\([;,&|^?:)]\|[\!+*/%&|~^<>-]=\|>>=\|<<=\|>[^>]\|<[^<]\|\]\)" variable="$s\(\(++\|--\)$w\|$w\(++\|--\)\|$w\)$s" comparison="\(\(>=\|<\)${s}0\|\([><\!=]=\|[<>]\)$s-$s$D\)$s" query="$left_operator$variable$comparison$right_operator" arr="\(\[[^\]]*\]$s\)*" attr="__attribute__$s(([^;]*))" # for each unsigned typedefs for ut in "unsigned" "unsigned long" $( git-grep "^${s}typedef${S}unsigned$S\($V$S\)*\($V$s$arr\|$attr$S$V$s$arr\|$V$s$arr$S$attr\)$s;$cendl" | sed -n "s/^[^.]*\.[hc]:${s}typedef${S}unsigned$S\($V$S\)*\(\($V\)$s$arr\|$attr$S\($V\)$s$arr\|\($V\)$s$arr$S$attr\)$s;$cendl/\3\5\7/p" | sort | uniq); do # create the spatch cat > ../spatches/negative_unsigned.cocci << EOF @@ constant C; $ut i; @@ ( * i < 0 | * i < -C | * i > -C | * i <= -C | * i >= -C ) EOF # find for f in $(git-grep -l "\(^\|$Q\)$ut\($Q\|$\)" | grep "[^.]*\.[ch]" | xargs grep -l "$query"); do spatch -quiet -all_includes -I ./include -sp_file ../spatches/negative_unsigned $f; done done > ../spatch.log }}} to display the results of the previous patch as 'vi file +line' commands: {{{ sed -n "s/^\(.\)\(-- \([^[:space:]]*\)[[:space:]]\|@ -\([0-9]*\),\|\).*$/\1 \3\4/p" ../spatch.log| while read a b; do if [ "$a" = "-" ]; then if [ -f "$b" ]; then f="$b" elif [ -z "$b" ]; then echo "vi $f +$i"; i=$(($i+1)); fi elif [ "$a" = "@" ]; then i=$b; else i=$(($i+1)); fi done }}} |
|
Line 114: | Line 178: |
# Usage: v /path/to/sourcefile.c:1 | # Usage: v /path/to/sourcefile.c[:- ]linenr or |
Line 118: | Line 182: |
[ -n "$1" ] && vi ${1%[:-]*} +${1##*[:-]} } # a number export 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 export 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]\?\)" |
f="$1" [ $# -eq 2 ] && l=$2 if [ ! -f "$f" ]; then l=${f##*[:-]}; f="${f%[:-]*}"; fi [ -f "$f" -a $l -gt 0 ] && vi "$f" +"$l"; } export int="[0-9]" export hex="[a-f0-9]" export hEx="[A-Fa-f0-9]" export HEX="[A-F0-9]" export upp="[A-Z]" export up_="[A-Z_]" export low="[a-z0-9]" export lo_="[a-z0-9_]" export alp="[A-Za-z]" export al_="[A-Za-z_]" export ALN="[A-Z0-9]" export AN_="[A-Z0-9_]" export aln="[A-Za-z0-9]" export an_="[A-Za-z0-9_]" # to match something like 1ul, floats or hexes as well: export D="$int*\.\?$int\+x\?$hex*[uUlL]\{0,3\}[fF]\?" # more strict and catches it (costs one backreference for (git-)grep) export d="\($int\+[uUlLfF]\?\|$int\+[uU]\?[lL][lL]\?\|0x$hex\+\|0x$HEX\+\|$i\+[lL][lL][uU]\|$i*\.$i\+[fF]\?\)" # capital: can be used to catch a definition or config option export K="$UP_\+$AN_*"; |
Line 129: | Line 215: |
export V="[A-Za-z_]\+[A-Za-z0-9_]*" # capital: a config option/definition export K="[A-Z]\+[A-Z0-9_]*"; |
export V="$al_\+$an_*" |
Line 135: | Line 218: |
# is more strict | |
Line 136: | Line 220: |
# catches it at once (less strict) export w="\($V\|${V}\[$s$an_*${s}\]\|$V\.\|$V->\)\+" |
|
Line 145: | Line 231: |
export cendl="$s\(\/[\*\/].*\)\?$" | export cendl="$s\(\/[*\/].*\)\?$" |
Line 148: | Line 234: |
export ccode="\([^\/\"']*\|\/[^\*\/]\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\+\/\|'[^']*'\|\"[^\"]*\"\)*" | export ccode="\([^\/\"']*\|\/[^*\/]\|\/\*\([^*]*\|\**[^*\/]\)*\*\+\/\|'[^']*'\|\"[^\"]*\"\)*" |
Line 153: | Line 239: |
# to match nested parentheses export nps="[^()]*" export nstdps="\(($nps\(($nps\(($nps\(($nps\(($nps)$nps\)*)$nps\)*)$nps\)*)$nps\)*)$nps\)*" |
|
Line 175: | Line 265: |
Z="@[:space:]" a="[^()]*" nested_parentheses="\(($a\(($a\(($a\(($a\(($a)$a\)*)$a\)*)$a\)*)$a\)*)$a\)*" func="\(${V}[$Z]\+\)*${V}[*$Z]\+$V$s($a$nested_parentheses)" eol="[$Z]*\([$Z]\|\/\/[^@]*@\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\+\/\)*@{" |
Z="[@[:space:]]" func="\($V$Z\+\)*${V}[*@[:space:]]\+$V$s($nps$nstdps)" eol="$Z*\($Z\|\/\/[^@]*@\|\/\*\([^*]*\|\**[^\/*]\)*\*\+\/\)*@{" |
Line 201: | Line 289: |
# helper to print definition(s) / macro(s) _getdef() { ggrep2fnl "$2" | while read -r 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) |
getstruct() { q="^$s\($V$S\)*struct\(${S}__$V\($s($nps$nstdps)\)\?\)*$S$1\(${S}__$V\($s($nps$nstdps)\)\?\)*${s}[{]\?$cendl"; ggrep2fnl "$q" | while read -r 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,/$se/p" "$f" done } |
Line 217: | Line 305: |
_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; |
del="[[:space:](]" sed_print=":a; /\\\\\\\\$/{N;ba}; p}" while getopts dmho Options; do case $Options in h) echo "getdef [options] DEFINITION_NAME(s) print definition(s) / macro(s) options -d print only definitions -m print only macros -o print as a single line (squeezes spaces)" return ;; d) del="[[:space:]]" ;; m) del="(" ;; o) sed_print=":a; /\\\\\\\\$/{N;ba}; s/\(\/\(\/.*\|\*\([^*]*\|\**[^\/]\)*\*\/$s\)\?\(\\\\\\\\\n\|$\)\|$S\)\+/ /g; s/^$S//g; p}" ;; esac done while [ $OPTIND -gt 1 ]; do shift; OPTIND=$(($OPTIND-1)); done def="^$s#${s}define$S$1$del" for f in $(git-grep -l -I "$def"); do sed -n "/$def/,/[^\\\\]$/{/$def/=; $sed_print" "$f" | sed "/^[0-9]*$/s/^\([0-9]*\)$/\/\/---[ vi ${f//\//\\/} +\1 ]---/" done } # rparse [source.c]: prints contents with comments removed and extended lines joined. rparse() { sed " :a s:\($S$S\|$s\n$s\): : ta /^$ccode\?\/\*/{ /^$ccode\?\/\*\([^*]*\|\**[^\/*]\)*\**$/N s:^$ccode\?\/\*\([^*]*\|\**[^\/*]\)*\*\+\/$ccode\?:\1 \4: ba } /^$ccode\?\/\//s:^$ccode\?\/\/.*$:\1: s: $:: s:^ :: /\\\\$s$/{ N s:$s\\\\$s\n$s: : ba } /^\([^#].*[^;{}]\)\?$/{ N ba } " "$1" |
Line 250: | Line 375: |
} # get filename in git-diff with match $1 (matches from start of line) # in after (default, $2 == "+") or before ($2 == "-") changes were made gdfwm() { dil="+"; [ $# -eq 2 ] && dil="$2"; echo "$dil" git-diff | grep "^\($dil\{3\}\|$dil$1$\)" | grep -B1 "^${dil}[^$dil]" | sed -n "s/^$dil\{3\} [^\/]*\/\([^\n]*\)$/\1/p"; } # get filename and line in git-diff with match $1 (matches from start to end of line) gdflwm() { git-diff | sed -n "s/^\(.\)\(++ [^\/]*\/\(.*\)\|@ -[0-9]*,[0-9]* +\([0-9]*\),.*\|\($1\)\|.*\)$/\1 \3\4\5/p" | while read a b; do if [ "$a" = "+" ]; then if [ -f "$b" ]; then f="$b" elif [ -n "$b" ]; then echo "$f $i"; i=$(($i+1)); fi elif [ "$a" = "@" ]; then i=$b; elif [ "$a" != "-" ]; then i=$(($i+1)) fi done |
Roel Kluin
Email: MailTo(roel.kluin@gmail.com) ...
""This is my old page, see roelkluin for updated scripts and snippets.""
all code is (c) Roel kluin, 2007 GNU GPL V.2.
Examples
These may require the script 'vars' below sourced, and should be called in a git tree. I simply paste them into my console (bash).
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):
git-grep -l '[^[:alnum:]]ioremap' | while read -r 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 | less
Make 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 -r n; do sed -n "/struct${s}sk_buff${s}\*${s}${n}/,/^[{}].*$/{ /kfree(${s}${n}${s})/= }" $f | while read -r 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 | less
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 usage:
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 -r n; do echo "$n"; done | sort | uniq -c | sort -rn | while read -r 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
catch tests below 0 on unsigned
# define what to search for left_operator="\([;,|^?:(]\|[\!+*/%&|~^-]=\|>>=\|<<=\|\[\|&&\|$an_$s&\)" right_operator="\([;,&|^?:)]\|[\!+*/%&|~^<>-]=\|>>=\|<<=\|>[^>]\|<[^<]\|\]\)" variable="$s\(\(++\|--\)$w\|$w\(++\|--\)\|$w\)$s" comparison="\(\(>=\|<\)${s}0\|\([><\!=]=\|[<>]\)$s-$s$D\)$s" query="$left_operator$variable$comparison$right_operator" arr="\(\[[^\]]*\]$s\)*" attr="__attribute__$s(([^;]*))" # for each unsigned typedefs for ut in "unsigned" "unsigned long" $( git-grep "^${s}typedef${S}unsigned$S\($V$S\)*\($V$s$arr\|$attr$S$V$s$arr\|$V$s$arr$S$attr\)$s;$cendl" | sed -n "s/^[^.]*\.[hc]:${s}typedef${S}unsigned$S\($V$S\)*\(\($V\)$s$arr\|$attr$S\($V\)$s$arr\|\($V\)$s$arr$S$attr\)$s;$cendl/\3\5\7/p" | sort | uniq); do # create the spatch cat > ../spatches/negative_unsigned.cocci << EOF @@ constant C; $ut i; @@ ( * i < 0 | * i < -C | * i > -C | * i <= -C | * i >= -C ) EOF # find for f in $(git-grep -l "\(^\|$Q\)$ut\($Q\|$\)" | grep "[^.]*\.[ch]" | xargs grep -l "$query"); do spatch -quiet -all_includes -I ./include -sp_file ../spatches/negative_unsigned $f; done done > ../spatch.log
to display the results of the previous patch as 'vi file +line' commands:
sed -n "s/^\(.\)\(-- \([^[:space:]]*\)[[:space:]]\|@ -\([0-9]*\),\|\).*$/\1 \3\4/p" ../spatch.log| while read a b; do if [ "$a" = "-" ]; then if [ -f "$b" ]; then f="$b" elif [ -z "$b" ]; then echo "vi $f +$i"; i=$(($i+1)); fi elif [ "$a" = "@" ]; then i=$b; else i=$(($i+1)); fi done
Scripts
I called it vars, it contains some functions for kernel hacking. usage: "source path/to/vars" N.B. do not source this in a shell that you plan to use to compile a kernel ($Q is used in Makefiles as well, which will give some problems)
# (c) Roel kluin, 2008 GNU GPL V.2 alias gg="git-grep -n" # Usage: v /path/to/sourcefile.c[:- ]linenr or # (as pasted from git-grep -n) v() { f="$1" [ $# -eq 2 ] && l=$2 if [ ! -f "$f" ]; then l=${f##*[:-]}; f="${f%[:-]*}"; fi [ -f "$f" -a $l -gt 0 ] && vi "$f" +"$l"; } export int="[0-9]" export hex="[a-f0-9]" export hEx="[A-Fa-f0-9]" export HEX="[A-F0-9]" export upp="[A-Z]" export up_="[A-Z_]" export low="[a-z0-9]" export lo_="[a-z0-9_]" export alp="[A-Za-z]" export al_="[A-Za-z_]" export ALN="[A-Z0-9]" export AN_="[A-Z0-9_]" export aln="[A-Za-z0-9]" export an_="[A-Za-z0-9_]" # to match something like 1ul, floats or hexes as well: export D="$int*\.\?$int\+x\?$hex*[uUlL]\{0,3\}[fF]\?" # more strict and catches it (costs one backreference for (git-)grep) export d="\($int\+[uUlLfF]\?\|$int\+[uU]\?[lL][lL]\?\|0x$hex\+\|0x$HEX\+\|$i\+[lL][lL][uU]\|$i*\.$i\+[fF]\?\)" # capital: can be used to catch a definition or config option export K="$UP_\+$AN_*"; # can be used for a variable/function name: export V="$al_\+$an_*" # works the same as above, but also for members and arrays: one backreference # is more strict export W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*" # catches it at once (less strict) export w="\($V\|${V}\[$s$an_*${s}\]\|$V\.\|$V->\)\+" # seperators: export s="[[:space:]]*"; export S="[[:space:]]\+" # useful to delimit a variable name: export Q="[^[:alnum:]_]" # match the end of the line, including comments: one backreference (but at eol) export cendl="$s\(\/[*\/].*\)\?$" # match something that is not comment, string or character: 2 backreferences export ccode="\([^\/\"']*\|\/[^*\/]\|\/\*\([^*]*\|\**[^*\/]\)*\*\+\/\|'[^']*'\|\"[^\"]*\"\)*" # resp function open and end (only works when indentation is correct. export fo="^[\{]$cendl" export fe="^[\}]$cendl" # to match nested parentheses export nps="[^()]*" export nstdps="\(($nps\(($nps\(($nps\(($nps\(($nps)$nps\)*)$nps\)*)$nps\)*)$nps\)*)$nps\)*" # works similar to git-grep -n "$query" | tr ":" " " # except that :'s in the line are preserved ggrep2fnl() { git-grep -n "$1" | while read -r 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" # also works for /path/to/filename.c:nr getfuncat() { [ $# -ne 1 ] && return 1; f="${1%[:-]*}" [ ! -f "$f" ] && return 2; l="${1##*[:-]}" Z="[@[:space:]]" func="\($V$Z\+\)*${V}[*@[:space:]]\+$V$s($nps$nstdps)" eol="$Z*\($Z\|\/\/[^@]*@\|\/\*\([^*]*\|\**[^\/*]\)*\*\+\/\)*@{" head -n$l "$f" | tr "\n" "@" | sed -n "s/.*@\($func\)$eol.*/\1@/p" | tail -n1 | tr "@" "\n" } #print function declaration(s) getfunc() { q="^\(${V}[*&[:space:]]\+\)*$1$s(${ccode}[^;]$cendl"; ggrep2fnl "$q" | while read -r 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 } getstruct() { q="^$s\($V$S\)*struct\(${S}__$V\($s($nps$nstdps)\)\?\)*$S$1\(${S}__$V\($s($nps$nstdps)\)\?\)*${s}[{]\?$cendl"; ggrep2fnl "$q" | while read -r 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,/$se/p" "$f" done } getdef() { del="[[:space:](]" sed_print=":a; /\\\\\\\\$/{N;ba}; p}" while getopts dmho Options; do case $Options in h) echo "getdef [options] DEFINITION_NAME(s) print definition(s) / macro(s) options -d print only definitions -m print only macros -o print as a single line (squeezes spaces)" return ;; d) del="[[:space:]]" ;; m) del="(" ;; o) sed_print=":a; /\\\\\\\\$/{N;ba}; s/\(\/\(\/.*\|\*\([^*]*\|\**[^\/]\)*\*\/$s\)\?\(\\\\\\\\\n\|$\)\|$S\)\+/ /g; s/^$S//g; p}" ;; esac done while [ $OPTIND -gt 1 ]; do shift; OPTIND=$(($OPTIND-1)); done def="^$s#${s}define$S$1$del" for f in $(git-grep -l -I "$def"); do sed -n "/$def/,/[^\\\\]$/{/$def/=; $sed_print" "$f" | sed "/^[0-9]*$/s/^\([0-9]*\)$/\/\/---[ vi ${f//\//\\/} +\1 ]---/" done } # rparse [source.c]: prints contents with comments removed and extended lines joined. rparse() { sed " :a s:\($S$S\|$s\n$s\): : ta /^$ccode\?\/\*/{ /^$ccode\?\/\*\([^*]*\|\**[^\/*]\)*\**$/N s:^$ccode\?\/\*\([^*]*\|\**[^\/*]\)*\*\+\/$ccode\?:\1 \4: ba } /^$ccode\?\/\//s:^$ccode\?\/\/.*$:\1: s: $:: s:^ :: /\\\\$s$/{ N s:$s\\\\$s\n$s: : ba } /^\([^#].*[^;{}]\)\?$/{ N ba } " "$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" } # get filename in git-diff with match $1 (matches from start of line) # in after (default, $2 == "+") or before ($2 == "-") changes were made gdfwm() { dil="+"; [ $# -eq 2 ] && dil="$2"; echo "$dil" git-diff | grep "^\($dil\{3\}\|$dil$1$\)" | grep -B1 "^${dil}[^$dil]" | sed -n "s/^$dil\{3\} [^\/]*\/\([^\n]*\)$/\1/p"; } # get filename and line in git-diff with match $1 (matches from start to end of line) gdflwm() { git-diff | sed -n "s/^\(.\)\(++ [^\/]*\/\(.*\)\|@ -[0-9]*,[0-9]* +\([0-9]*\),.*\|\($1\)\|.*\)$/\1 \3\4\5/p" | while read a b; do if [ "$a" = "+" ]; then if [ -f "$b" ]; then f="$b" elif [ -n "$b" ]; then echo "$f $i"; i=$(($i+1)); fi elif [ "$a" = "@" ]; then i=$b; elif [ "$a" != "-" ]; then i=$(($i+1)) fi done }
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 -r name; do sed -n "/^P:[ \t]*.*$name/,/^$/{ s/^L:[ \t]*\(.*\)$/\1/p }" ./MAINTAINERS done | sort | uniq -c | sort -n -r | while read -r 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 -r nr tot list; do echo -e "$nr/$tot Acks were commited by maintainers of list $list" done