Commit | Line | Data |
---|---|---|
34e49164 C |
1 | From 12o3l@tiscali.nl Fri Apr 18 18:13:39 2008 |
2 | Date: Fri, 18 Apr 2008 18:15:06 +0200 | |
3 | From: Roel Kluin <12o3l@tiscali.nl> | |
4 | To: kernel-janitors@vger.kernel.org, kernelnewbies-bounce@nl.linux.org | |
5 | Subject: script to find incorrect tests on unsigneds | |
6 | ||
7 | A bash script to find incorrect tests on unsigned values. for instance: | |
8 | ||
9 | unsigned int i; | |
10 | ... | |
11 | i = neg_ret_function(); | |
12 | ... | |
13 | if (i < 0) ... | |
14 | ||
15 | #!/bin/bash | |
16 | # (c) roel kluin 2008 GPL v2 | |
17 | # | |
18 | # TODO: make this working also for | |
19 | # ... $unsigned_var == $signed_var ... | |
20 | # ... $unsigned_var == \(-POSITIVE_DEF\|NEGATIVE_DEF\) ... | |
21 | # ... ( $unsigned_var [+*/%^&~-]?= ... ) < 0 ... | |
22 | ||
23 | # a number | |
24 | int="[0-9]" | |
25 | hex="[a-f0-9]" | |
26 | hEx="[A-Fa-f0-9]" | |
27 | HEX="[A-F0-9]" | |
28 | upp="[A-Z]" | |
29 | up_="[A-Z_]" | |
30 | low="[a-z0-9]" | |
31 | lo_="[a-z0-9_]" | |
32 | alp="[A-Za-z]" | |
33 | al_="[A-Za-z_]" | |
34 | ALN="[A-Z0-9]" | |
35 | AN_="[A-Z0-9_]" | |
36 | aln="[A-Za-z0-9]" | |
37 | an_="[A-Za-z0-9_]" | |
38 | # to match something like 1ul, floats or hexes as well: | |
39 | D="$int*\.\?$int\+x\?$hex*[uUlL]\{0,3\}[fF]\?" | |
40 | ||
41 | # more strict and catches it (costs one backreference for (git-)grep) | |
42 | d="\($int\+[uUlLfF]\?\|$int\+[uU]\?[lL][lL]\?\|0x$hex\+\|0x$HEX\+\|$i\+[lL][lL][uU]\|$i*\.$i\+[fF]\?\)" | |
43 | ||
44 | # capital: can be used to catch a definition or config option | |
45 | K="$UP_\+$AN_*"; | |
46 | ||
47 | # can be used for a variable/function name: | |
48 | V="$an_\+$an_*" | |
49 | ||
50 | # works the same as above, but also for members and arrays: one backreference | |
51 | # is more strict | |
52 | W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*" | |
53 | # catches it at once (less strict) | |
54 | w="\($V\|${V}\[$s$an_*${s}\]\|$V\.\|$V->\)\+" | |
55 | ||
56 | # seperators: | |
57 | s="[[:space:]]*"; | |
58 | S="[[:space:]]\+" | |
59 | ||
60 | # useful to delimit a variable name: | |
61 | Q="[^[:alnum:]_]" | |
62 | ||
63 | # match the end of the line, including comments: one backreference (but at eol) | |
64 | cendl="$s\(\/[\*\/].*\)\?$" | |
65 | ||
66 | # match something that is not comment, string or character: 2 backreferences | |
67 | ccode="\([^\/\"']*\|\/[^\*\/]\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\+\/\|'[^']*'\|\"[^\"]*\"\)*" | |
68 | ||
69 | # resp function open and end (only works when indentation is correct. | |
70 | fo="^[\{]$cendl" | |
71 | fe="^[\}]$cendl" | |
72 | se="^[\}];$cendl" | |
73 | ||
74 | # to match nested parentheses | |
75 | nps="[^()]*" | |
76 | nstdps="\(($nps\(($nps\(($nps\(($nps\(($nps)$nps\)*)$nps\)*)$nps\)*)$nps\)*)$nps\)*" | |
77 | ||
78 | ||
79 | # first determine unsigned typedefs | |
80 | arr="\(\[[^\]]*\]$s\)*" | |
81 | attr="__attribute__$s(([^;]*))" | |
82 | utype="${s}typedef${S}unsigned$S\($V$S\)*" | |
83 | uns="unsigned$( | |
84 | git-grep "^$utype\($V$s$arr\|$attr$S$V$s$arr\|$V$s$arr$S$attr\)$s;$cendl" | sed -n "s/^[^.]*\.[hc]:$utype\(\($V\)$s$arr\|$attr$S\($V\)$s$arr\|\($V\)$s$arr$S$attr\)$s;$cendl/\\\\|\3\5\7/p" | sort | uniq | tr -d "\n")" | |
85 | ||
86 | # define left and right operators | |
87 | # to decrease the number backrefences, these are assigned in loops | |
88 | opl= | |
89 | for op in "[;,|^?:(]" "[\!+*/%&|~^-]=" ">>=" "<<=" "\[" "&&" "$an_$s&"; do | |
90 | opl="$opl$op\|$op$s++\|$op$s--\|" | |
91 | done | |
92 | opl="\(${opl%|})" | |
93 | opr= | |
94 | for op in "[;,&|^?:)]" "[\!+*/%&|~^<>-]=" ">>=" "<<=" ">[^>]" "<[^<]" "\]"; do | |
95 | opr="$opr$op\|$op$s++\|$op$s--\|" | |
96 | done | |
97 | opr="\(${opr%|})" | |
98 | ||
99 | # string catches invalid comparison | |
100 | q1="$opl$s\($w$s\(>=${s}0\|<${s}0\|[><\!=]=$s-$s$D\|[<>]$s-$s$D\)\|\(0$s>\|0$s<=\|-$s$D${s}[><\!=]=\|-$s$D${s}[<>]\)$s$w\)$s$opr" | |
101 | ||
102 | start=0 | |
103 | end=$(echo $uns | tr -cd "|" | wc -c) | |
104 | ||
105 | # main function | |
106 | while [ $start -lt $end ]; do | |
107 | # we match 30 typedefs at a time | |
108 | tuns="$(echo $uns | cut -d "\\" -f$start-$(($start+29)))" | |
109 | ||
110 | # catch candidate files | |
111 | for f in $(git-grep -l "^\(${ccode}[,;]$s\)\?\($tuns\)$S" | grep "[^.]*\.[ch]" | xargs grep -l "$q1"); do | |
112 | for n in $(sed -n "/^.*$q1/=" $f); do # lines | |
113 | for v in $(sed -n "${n}s/^.*$q1.*$/\3\6/p" $f); do | |
114 | # n2 = wine there | |
115 | head -n$n $f | tac | sed -n "/^[{]/q; /^\(.*$Q\)\?\($tuns\)$S\($V$S\)*$v$Q.*$/=" | while read n2; | |
116 | do | |
117 | echo "# --- invalid test on unsigned variable '$v' --- #" | |
118 | echo "vi $f +$n2 # unsigned declaration" | |
119 | echo "vi $f +$n # invalid test" | |
120 | done | |
121 | done | |
122 | done | |
123 | done | |
124 | start=$(($start+30)) | |
125 | done | less | |
126 | -- | |
127 | To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in | |
128 | the body of a message to majordomo@vger.kernel.org | |
129 | More majordomo info at http://vger.kernel.org/majordomo-info.html |