Commit 408e057870c8680a50963b08f9f7efaa151a74ec

Authored by Linus Torvalds

Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

* 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
  scripts/coccinelle: improve the coverage of some semantic patches
  coccinelle: semantic patches related to devm_ functions (part 2)
  coccinelle: semantic patches related to devm_ functions (part 1)
  coccinelle.txt: update documentation to include M= option
  coccicheck: add M= option to control which dir is processed
  ctags: remove struct forward declarations
  scripts/tags.sh: Add Page flag function magic

Showing 16 changed files Inline Diff

Documentation/coccinelle.txt
1 Copyright 2010 Nicolas Palix <npalix@diku.dk> 1 Copyright 2010 Nicolas Palix <npalix@diku.dk>
2 Copyright 2010 Julia Lawall <julia@diku.dk> 2 Copyright 2010 Julia Lawall <julia@diku.dk>
3 Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr> 3 Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
4 4
5 5
6 Getting Coccinelle 6 Getting Coccinelle
7 ~~~~~~~~~~~~~~~~~~~~ 7 ~~~~~~~~~~~~~~~~~~~~
8 8
9 The semantic patches included in the kernel use the 'virtual rule' 9 The semantic patches included in the kernel use the 'virtual rule'
10 feature which was introduced in Coccinelle version 0.1.11. 10 feature which was introduced in Coccinelle version 0.1.11.
11 11
12 Coccinelle (>=0.2.0) is available through the package manager 12 Coccinelle (>=0.2.0) is available through the package manager
13 of many distributions, e.g. : 13 of many distributions, e.g. :
14 14
15 - Debian (>=squeeze) 15 - Debian (>=squeeze)
16 - Fedora (>=13) 16 - Fedora (>=13)
17 - Ubuntu (>=10.04 Lucid Lynx) 17 - Ubuntu (>=10.04 Lucid Lynx)
18 - OpenSUSE 18 - OpenSUSE
19 - Arch Linux 19 - Arch Linux
20 - NetBSD 20 - NetBSD
21 - FreeBSD 21 - FreeBSD
22 22
23 23
24 You can get the latest version released from the Coccinelle homepage at 24 You can get the latest version released from the Coccinelle homepage at
25 http://coccinelle.lip6.fr/ 25 http://coccinelle.lip6.fr/
26 26
27 Information and tips about Coccinelle are also provided on the wiki 27 Information and tips about Coccinelle are also provided on the wiki
28 pages at http://cocci.ekstranet.diku.dk/wiki/doku.php 28 pages at http://cocci.ekstranet.diku.dk/wiki/doku.php
29 29
30 Once you have it, run the following command: 30 Once you have it, run the following command:
31 31
32 ./configure 32 ./configure
33 make 33 make
34 34
35 as a regular user, and install it with 35 as a regular user, and install it with
36 36
37 sudo make install 37 sudo make install
38 38
39 The semantic patches in the kernel will work best with Coccinelle version 39 The semantic patches in the kernel will work best with Coccinelle version
40 0.2.4 or later. Using earlier versions may incur some parse errors in the 40 0.2.4 or later. Using earlier versions may incur some parse errors in the
41 semantic patch code, but any results that are obtained should still be 41 semantic patch code, but any results that are obtained should still be
42 correct. 42 correct.
43 43
44 Using Coccinelle on the Linux kernel 44 Using Coccinelle on the Linux kernel
45 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 45 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 46
47 A Coccinelle-specific target is defined in the top level 47 A Coccinelle-specific target is defined in the top level
48 Makefile. This target is named 'coccicheck' and calls the 'coccicheck' 48 Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
49 front-end in the 'scripts' directory. 49 front-end in the 'scripts' directory.
50 50
51 Four modes are defined: patch, report, context, and org. The mode to 51 Four modes are defined: patch, report, context, and org. The mode to
52 use is specified by setting the MODE variable with 'MODE=<mode>'. 52 use is specified by setting the MODE variable with 'MODE=<mode>'.
53 53
54 'patch' proposes a fix, when possible. 54 'patch' proposes a fix, when possible.
55 55
56 'report' generates a list in the following format: 56 'report' generates a list in the following format:
57 file:line:column-column: message 57 file:line:column-column: message
58 58
59 'context' highlights lines of interest and their context in a 59 'context' highlights lines of interest and their context in a
60 diff-like style.Lines of interest are indicated with '-'. 60 diff-like style.Lines of interest are indicated with '-'.
61 61
62 'org' generates a report in the Org mode format of Emacs. 62 'org' generates a report in the Org mode format of Emacs.
63 63
64 Note that not all semantic patches implement all modes. For easy use 64 Note that not all semantic patches implement all modes. For easy use
65 of Coccinelle, the default mode is "chain" which tries the previous 65 of Coccinelle, the default mode is "chain" which tries the previous
66 modes in the order above until one succeeds. 66 modes in the order above until one succeeds.
67 67
68 To make a report for every semantic patch, run the following command: 68 To make a report for every semantic patch, run the following command:
69 69
70 make coccicheck MODE=report 70 make coccicheck MODE=report
71 71
72 NB: The 'report' mode is the default one. 72 NB: The 'report' mode is the default one.
73 73
74 To produce patches, run: 74 To produce patches, run:
75 75
76 make coccicheck MODE=patch 76 make coccicheck MODE=patch
77 77
78 78
79 The coccicheck target applies every semantic patch available in the 79 The coccicheck target applies every semantic patch available in the
80 sub-directories of 'scripts/coccinelle' to the entire Linux kernel. 80 sub-directories of 'scripts/coccinelle' to the entire Linux kernel.
81 81
82 For each semantic patch, a commit message is proposed. It gives a 82 For each semantic patch, a commit message is proposed. It gives a
83 description of the problem being checked by the semantic patch, and 83 description of the problem being checked by the semantic patch, and
84 includes a reference to Coccinelle. 84 includes a reference to Coccinelle.
85 85
86 As any static code analyzer, Coccinelle produces false 86 As any static code analyzer, Coccinelle produces false
87 positives. Thus, reports must be carefully checked, and patches 87 positives. Thus, reports must be carefully checked, and patches
88 reviewed. 88 reviewed.
89 89
90 90
91 Using Coccinelle with a single semantic patch 91 Using Coccinelle with a single semantic patch
92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93 93
94 The optional make variable COCCI can be used to check a single 94 The optional make variable COCCI can be used to check a single
95 semantic patch. In that case, the variable must be initialized with 95 semantic patch. In that case, the variable must be initialized with
96 the name of the semantic patch to apply. 96 the name of the semantic patch to apply.
97 97
98 For instance: 98 For instance:
99 99
100 make coccicheck COCCI=<my_SP.cocci> MODE=patch 100 make coccicheck COCCI=<my_SP.cocci> MODE=patch
101 or 101 or
102 make coccicheck COCCI=<my_SP.cocci> MODE=report 102 make coccicheck COCCI=<my_SP.cocci> MODE=report
103 103
104 104
105 Using Coccinelle on (modified) files 105 Controlling Which Files are Processed by Coccinelle
106 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 106 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107 By default the entire kernel source tree is checked.
107 108
109 To apply Coccinelle to a specific directory, M= can be used.
110 For example, to check drivers/net/wireless/ one may write:
111
112 make coccicheck M=drivers/net/wireless/
113
108 To apply Coccinelle on a file basis, instead of a directory basis, the 114 To apply Coccinelle on a file basis, instead of a directory basis, the
109 following command may be used: 115 following command may be used:
110 116
111 make C=1 CHECK="scripts/coccicheck" 117 make C=1 CHECK="scripts/coccicheck"
112 118
113 To check only newly edited code, use the value 2 for the C flag, i.e. 119 To check only newly edited code, use the value 2 for the C flag, i.e.
114 120
115 make C=2 CHECK="scripts/coccicheck" 121 make C=2 CHECK="scripts/coccicheck"
116 122
117 This runs every semantic patch in scripts/coccinelle by default. The 123 This runs every semantic patch in scripts/coccinelle by default. The
118 COCCI variable may additionally be used to only apply a single 124 COCCI variable may additionally be used to only apply a single
119 semantic patch as shown in the previous section. 125 semantic patch as shown in the previous section.
120 126
121 The "chain" mode is the default. You can select another one with the 127 The "chain" mode is the default. You can select another one with the
122 MODE variable explained above. 128 MODE variable explained above.
123 129
124 In this mode, there is no information about semantic patches 130 In this mode, there is no information about semantic patches
125 displayed, and no commit message proposed. 131 displayed, and no commit message proposed.
126 132
127 133
128 Proposing new semantic patches 134 Proposing new semantic patches
129 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130 136
131 New semantic patches can be proposed and submitted by kernel 137 New semantic patches can be proposed and submitted by kernel
132 developers. For sake of clarity, they should be organized in the 138 developers. For sake of clarity, they should be organized in the
133 sub-directories of 'scripts/coccinelle/'. 139 sub-directories of 'scripts/coccinelle/'.
134 140
135 141
136 Detailed description of the 'report' mode 142 Detailed description of the 'report' mode
137 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 143 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138 144
139 'report' generates a list in the following format: 145 'report' generates a list in the following format:
140 file:line:column-column: message 146 file:line:column-column: message
141 147
142 Example: 148 Example:
143 149
144 Running 150 Running
145 151
146 make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci 152 make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci
147 153
148 will execute the following part of the SmPL script. 154 will execute the following part of the SmPL script.
149 155
150 <smpl> 156 <smpl>
151 @r depends on !context && !patch && (org || report)@ 157 @r depends on !context && !patch && (org || report)@
152 expression x; 158 expression x;
153 position p; 159 position p;
154 @@ 160 @@
155 161
156 ERR_PTR@p(PTR_ERR(x)) 162 ERR_PTR@p(PTR_ERR(x))
157 163
158 @script:python depends on report@ 164 @script:python depends on report@
159 p << r.p; 165 p << r.p;
160 x << r.x; 166 x << r.x;
161 @@ 167 @@
162 168
163 msg="ERR_CAST can be used with %s" % (x) 169 msg="ERR_CAST can be used with %s" % (x)
164 coccilib.report.print_report(p[0], msg) 170 coccilib.report.print_report(p[0], msg)
165 </smpl> 171 </smpl>
166 172
167 This SmPL excerpt generates entries on the standard output, as 173 This SmPL excerpt generates entries on the standard output, as
168 illustrated below: 174 illustrated below:
169 175
170 /home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg 176 /home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
171 /home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth 177 /home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
172 /home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg 178 /home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
173 179
174 180
175 Detailed description of the 'patch' mode 181 Detailed description of the 'patch' mode
176 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177 183
178 When the 'patch' mode is available, it proposes a fix for each problem 184 When the 'patch' mode is available, it proposes a fix for each problem
179 identified. 185 identified.
180 186
181 Example: 187 Example:
182 188
183 Running 189 Running
184 make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci 190 make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci
185 191
186 will execute the following part of the SmPL script. 192 will execute the following part of the SmPL script.
187 193
188 <smpl> 194 <smpl>
189 @ depends on !context && patch && !org && !report @ 195 @ depends on !context && patch && !org && !report @
190 expression x; 196 expression x;
191 @@ 197 @@
192 198
193 - ERR_PTR(PTR_ERR(x)) 199 - ERR_PTR(PTR_ERR(x))
194 + ERR_CAST(x) 200 + ERR_CAST(x)
195 </smpl> 201 </smpl>
196 202
197 This SmPL excerpt generates patch hunks on the standard output, as 203 This SmPL excerpt generates patch hunks on the standard output, as
198 illustrated below: 204 illustrated below:
199 205
200 diff -u -p a/crypto/ctr.c b/crypto/ctr.c 206 diff -u -p a/crypto/ctr.c b/crypto/ctr.c
201 --- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200 207 --- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
202 +++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200 208 +++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
203 @@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct 209 @@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
204 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER, 210 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
205 CRYPTO_ALG_TYPE_MASK); 211 CRYPTO_ALG_TYPE_MASK);
206 if (IS_ERR(alg)) 212 if (IS_ERR(alg))
207 - return ERR_PTR(PTR_ERR(alg)); 213 - return ERR_PTR(PTR_ERR(alg));
208 + return ERR_CAST(alg); 214 + return ERR_CAST(alg);
209 215
210 /* Block size must be >= 4 bytes. */ 216 /* Block size must be >= 4 bytes. */
211 err = -EINVAL; 217 err = -EINVAL;
212 218
213 Detailed description of the 'context' mode 219 Detailed description of the 'context' mode
214 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215 221
216 'context' highlights lines of interest and their context 222 'context' highlights lines of interest and their context
217 in a diff-like style. 223 in a diff-like style.
218 224
219 NOTE: The diff-like output generated is NOT an applicable patch. The 225 NOTE: The diff-like output generated is NOT an applicable patch. The
220 intent of the 'context' mode is to highlight the important lines 226 intent of the 'context' mode is to highlight the important lines
221 (annotated with minus, '-') and gives some surrounding context 227 (annotated with minus, '-') and gives some surrounding context
222 lines around. This output can be used with the diff mode of 228 lines around. This output can be used with the diff mode of
223 Emacs to review the code. 229 Emacs to review the code.
224 230
225 Example: 231 Example:
226 232
227 Running 233 Running
228 make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci 234 make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci
229 235
230 will execute the following part of the SmPL script. 236 will execute the following part of the SmPL script.
231 237
232 <smpl> 238 <smpl>
233 @ depends on context && !patch && !org && !report@ 239 @ depends on context && !patch && !org && !report@
234 expression x; 240 expression x;
235 @@ 241 @@
236 242
237 * ERR_PTR(PTR_ERR(x)) 243 * ERR_PTR(PTR_ERR(x))
238 </smpl> 244 </smpl>
239 245
240 This SmPL excerpt generates diff hunks on the standard output, as 246 This SmPL excerpt generates diff hunks on the standard output, as
241 illustrated below: 247 illustrated below:
242 248
243 diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing 249 diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
244 --- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200 250 --- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
245 +++ /tmp/nothing 251 +++ /tmp/nothing
246 @@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct 252 @@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
247 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER, 253 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
248 CRYPTO_ALG_TYPE_MASK); 254 CRYPTO_ALG_TYPE_MASK);
249 if (IS_ERR(alg)) 255 if (IS_ERR(alg))
250 - return ERR_PTR(PTR_ERR(alg)); 256 - return ERR_PTR(PTR_ERR(alg));
251 257
252 /* Block size must be >= 4 bytes. */ 258 /* Block size must be >= 4 bytes. */
253 err = -EINVAL; 259 err = -EINVAL;
254 260
255 Detailed description of the 'org' mode 261 Detailed description of the 'org' mode
256 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
257 263
258 'org' generates a report in the Org mode format of Emacs. 264 'org' generates a report in the Org mode format of Emacs.
259 265
260 Example: 266 Example:
261 267
262 Running 268 Running
263 make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci 269 make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci
264 270
265 will execute the following part of the SmPL script. 271 will execute the following part of the SmPL script.
266 272
267 <smpl> 273 <smpl>
268 @r depends on !context && !patch && (org || report)@ 274 @r depends on !context && !patch && (org || report)@
269 expression x; 275 expression x;
270 position p; 276 position p;
271 @@ 277 @@
272 278
273 ERR_PTR@p(PTR_ERR(x)) 279 ERR_PTR@p(PTR_ERR(x))
274 280
275 @script:python depends on org@ 281 @script:python depends on org@
276 p << r.p; 282 p << r.p;
277 x << r.x; 283 x << r.x;
278 @@ 284 @@
279 285
280 msg="ERR_CAST can be used with %s" % (x) 286 msg="ERR_CAST can be used with %s" % (x)
281 msg_safe=msg.replace("[","@(").replace("]",")") 287 msg_safe=msg.replace("[","@(").replace("]",")")
282 coccilib.org.print_todo(p[0], msg_safe) 288 coccilib.org.print_todo(p[0], msg_safe)
283 </smpl> 289 </smpl>
284 290
285 This SmPL excerpt generates Org entries on the standard output, as 291 This SmPL excerpt generates Org entries on the standard output, as
286 illustrated below: 292 illustrated below:
287 293
288 * TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]] 294 * TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
289 * TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]] 295 * TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
290 * TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]] 296 * TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
291 297
1 #!/bin/sh 1 #!/bin/sh
2 2
3 SPATCH="`which ${SPATCH:=spatch}`" 3 SPATCH="`which ${SPATCH:=spatch}`"
4 4
5 if [ "$C" = "1" -o "$C" = "2" ]; then 5 if [ "$C" = "1" -o "$C" = "2" ]; then
6 ONLINE=1 6 ONLINE=1
7 7
8 # This requires Coccinelle >= 0.2.3 8 # This requires Coccinelle >= 0.2.3
9 # FLAGS="-ignore_unknown_options -very_quiet" 9 # FLAGS="-ignore_unknown_options -very_quiet"
10 # OPTIONS=$* 10 # OPTIONS=$*
11 11
12 # Workaround for Coccinelle < 0.2.3 12 if [ "$KBUILD_EXTMOD" = "" ] ; then
13 FLAGS="-I $srctree/include -very_quiet" 13 # Workaround for Coccinelle < 0.2.3
14 shift $(( $# - 1 )) 14 FLAGS="-I $srctree/include -very_quiet"
15 OPTIONS=$1 15 shift $(( $# - 1 ))
16 OPTIONS=$1
17 else
18 echo M= is not currently supported when C=1 or C=2
19 exit 1
20 fi
16 else 21 else
17 ONLINE=0 22 ONLINE=0
18 FLAGS="-very_quiet" 23 FLAGS="-very_quiet"
19 OPTIONS="-dir $srctree" 24 if [ "$KBUILD_EXTMOD" = "" ] ; then
25 OPTIONS="-dir $srctree"
26 else
27 OPTIONS="-dir $KBUILD_EXTMOD -patch $srctree -I $srctree/include -I $KBUILD_EXTMOD/include"
28 fi
20 fi 29 fi
21 30
22 if [ ! -x "$SPATCH" ]; then 31 if [ ! -x "$SPATCH" ]; then
23 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/' 32 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
24 exit 1 33 exit 1
25 fi 34 fi
26 35
27 if [ "$MODE" = "" ] ; then 36 if [ "$MODE" = "" ] ; then
28 if [ "$ONLINE" = "0" ] ; then 37 if [ "$ONLINE" = "0" ] ; then
29 echo 'You have not explicitly specified the mode to use. Using default "chain" mode.' 38 echo 'You have not explicitly specified the mode to use. Using default "chain" mode.'
30 echo 'All available modes will be tried (in that order): patch, report, context, org' 39 echo 'All available modes will be tried (in that order): patch, report, context, org'
31 echo 'You can specify the mode with "make coccicheck MODE=<mode>"' 40 echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
32 fi 41 fi
33 MODE="chain" 42 MODE="chain"
34 elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then 43 elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
35 FLAGS="$FLAGS -no_show_diff" 44 FLAGS="$FLAGS -no_show_diff"
36 fi 45 fi
37 46
38 if [ "$ONLINE" = "0" ] ; then 47 if [ "$ONLINE" = "0" ] ; then
39 echo '' 48 echo ''
40 echo 'Please check for false positives in the output before submitting a patch.' 49 echo 'Please check for false positives in the output before submitting a patch.'
41 echo 'When using "patch" mode, carefully review the patch before submitting it.' 50 echo 'When using "patch" mode, carefully review the patch before submitting it.'
42 echo '' 51 echo ''
43 fi 52 fi
44 53
45 coccinelle () { 54 coccinelle () {
46 COCCI="$1" 55 COCCI="$1"
47 56
48 OPT=`grep "Option" $COCCI | cut -d':' -f2` 57 OPT=`grep "Option" $COCCI | cut -d':' -f2`
49 58
50 # The option '-parse_cocci' can be used to syntactically check the SmPL files. 59 # The option '-parse_cocci' can be used to syntactically check the SmPL files.
51 # 60 #
52 # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null 61 # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
53 62
54 if [ "$ONLINE" = "0" ] ; then 63 if [ "$ONLINE" = "0" ] ; then
55 64
56 FILE=`echo $COCCI | sed "s|$srctree/||"` 65 FILE=`echo $COCCI | sed "s|$srctree/||"`
57 66
58 echo "Processing `basename $COCCI`" 67 echo "Processing `basename $COCCI`"
59 echo "with option(s) \"$OPT\"" 68 echo "with option(s) \"$OPT\""
60 echo '' 69 echo ''
61 echo 'Message example to submit a patch:' 70 echo 'Message example to submit a patch:'
62 71
63 sed -ne 's|^///||p' $COCCI 72 sed -ne 's|^///||p' $COCCI
64 73
65 if [ "$MODE" = "patch" ] ; then 74 if [ "$MODE" = "patch" ] ; then
66 echo ' The semantic patch that makes this change is available' 75 echo ' The semantic patch that makes this change is available'
67 elif [ "$MODE" = "report" ] ; then 76 elif [ "$MODE" = "report" ] ; then
68 echo ' The semantic patch that makes this report is available' 77 echo ' The semantic patch that makes this report is available'
69 elif [ "$MODE" = "context" ] ; then 78 elif [ "$MODE" = "context" ] ; then
70 echo ' The semantic patch that spots this code is available' 79 echo ' The semantic patch that spots this code is available'
71 elif [ "$MODE" = "org" ] ; then 80 elif [ "$MODE" = "org" ] ; then
72 echo ' The semantic patch that makes this Org report is available' 81 echo ' The semantic patch that makes this Org report is available'
73 else 82 else
74 echo ' The semantic patch that makes this output is available' 83 echo ' The semantic patch that makes this output is available'
75 fi 84 fi
76 echo " in $FILE." 85 echo " in $FILE."
77 echo '' 86 echo ''
78 echo ' More information about semantic patching is available at' 87 echo ' More information about semantic patching is available at'
79 echo ' http://coccinelle.lip6.fr/' 88 echo ' http://coccinelle.lip6.fr/'
80 echo '' 89 echo ''
81 90
82 if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then 91 if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
83 echo 'Semantic patch information:' 92 echo 'Semantic patch information:'
84 sed -ne 's|^//#||p' $COCCI 93 sed -ne 's|^//#||p' $COCCI
85 echo '' 94 echo ''
86 fi 95 fi
87 fi 96 fi
88 97
89 if [ "$MODE" = "chain" ] ; then 98 if [ "$MODE" = "chain" ] ; then
90 $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ 99 $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
91 $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \ 100 $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
92 $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ 101 $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
93 $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1 102 $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
94 else 103 else
95 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 104 $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
96 fi 105 fi
97 106
98 } 107 }
99 108
100 if [ "$COCCI" = "" ] ; then 109 if [ "$COCCI" = "" ] ; then
101 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do 110 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
102 coccinelle $f 111 coccinelle $f
103 done 112 done
104 else 113 else
105 coccinelle $COCCI 114 coccinelle $COCCI
106 fi 115 fi
107 116
scripts/coccinelle/api/devm_request_and_ioremap.cocci
File was created 1 /// Reimplement a call to devm_request_mem_region followed by a call to ioremap
2 /// or ioremap_nocache by a call to devm_request_and_ioremap.
3 /// Devm_request_and_ioremap was introduced in
4 /// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0. It makes the code much more
5 /// concise.
6 ///
7 ///
8 // Confidence: High
9 // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2.
10 // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2.
11 // URL: http://coccinelle.lip6.fr/
12 // Comments:
13 // Options: -no_includes -include_headers
14
15 virtual patch
16 virtual org
17 virtual report
18 virtual context
19
20 @nm@
21 expression myname;
22 identifier i;
23 @@
24
25 struct platform_driver i = { .driver = { .name = myname } };
26
27 @depends on patch@
28 expression dev,res,size;
29 @@
30
31 -if (!devm_request_mem_region(dev, res->start, size,
32 - \(res->name\|dev_name(dev)\))) {
33 - ...
34 - return ...;
35 -}
36 ... when != res->start
37 (
38 -devm_ioremap(dev,res->start,size)
39 +devm_request_and_ioremap(dev,res)
40 |
41 -devm_ioremap_nocache(dev,res->start,size)
42 +devm_request_and_ioremap(dev,res)
43 )
44 ... when any
45 when != res->start
46
47 // this rule is separate from the previous one, because a single file can
48 // have multiple values of myname
49 @depends on patch@
50 expression dev,res,size;
51 expression nm.myname;
52 @@
53
54 -if (!devm_request_mem_region(dev, res->start, size,myname)) {
55 - ...
56 - return ...;
57 -}
58 ... when != res->start
59 (
60 -devm_ioremap(dev,res->start,size)
61 +devm_request_and_ioremap(dev,res)
62 |
63 -devm_ioremap_nocache(dev,res->start,size)
64 +devm_request_and_ioremap(dev,res)
65 )
66 ... when any
67 when != res->start
68
69
70 @pb depends on org || report || context@
71 expression dev,res,size;
72 expression nm.myname;
73 position p1,p2;
74 @@
75
76 *if
77 (!devm_request_mem_region@p1(dev, res->start, size,
78 \(res->name\|dev_name(dev)\|myname\))) {
79 ...
80 return ...;
81 }
82 ... when != res->start
83 (
84 *devm_ioremap@p2(dev,res->start,size)
85 |
86 *devm_ioremap_nocache@p2(dev,res->start,size)
87 )
88 ... when any
89 when != res->start
90
91 @script:python depends on org@
92 p1 << pb.p1;
93 p2 << pb.p2;
94 @@
95
96 cocci.print_main("INFO: replace by devm_request_and_ioremap",p1)
97 cocci.print_secs("",p2)
98
99 @script:python depends on report@
100 p1 << pb.p1;
101 p2 << pb.p2;
102 @@
103
104 msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line)
105 coccilib.report.print_report(p1[0],msg)
106
scripts/coccinelle/api/kstrdup.cocci
1 /// Use kstrdup rather than duplicating its implementation 1 /// Use kstrdup rather than duplicating its implementation
2 /// 2 ///
3 // Confidence: High 3 // Confidence: High
4 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 4 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
5 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
6 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 6 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 // URL: http://coccinelle.lip6.fr/ 7 // URL: http://coccinelle.lip6.fr/
8 // Comments: 8 // Comments:
9 // Options: -no_includes -include_headers 9 // Options: -no_includes -include_headers
10 10
11 virtual patch 11 virtual patch
12 virtual context
13 virtual org
14 virtual report
12 15
13 @@ 16 @depends on patch@
14 expression from,to; 17 expression from,to;
15 expression flag,E1,E2; 18 expression flag,E1,E2;
16 statement S; 19 statement S;
17 @@ 20 @@
18 21
19 - to = kmalloc(strlen(from) + 1,flag); 22 - to = kmalloc(strlen(from) + 1,flag);
20 + to = kstrdup(from, flag); 23 + to = kstrdup(from, flag);
21 ... when != \(from = E1 \| to = E1 \) 24 ... when != \(from = E1 \| to = E1 \)
22 if (to==NULL || ...) S 25 if (to==NULL || ...) S
23 ... when != \(from = E2 \| to = E2 \) 26 ... when != \(from = E2 \| to = E2 \)
24 - strcpy(to, from); 27 - strcpy(to, from);
25 28
26 @@ 29 @depends on patch@
27 expression x,from,to; 30 expression x,from,to;
28 expression flag,E1,E2,E3; 31 expression flag,E1,E2,E3;
29 statement S; 32 statement S;
30 @@ 33 @@
31 34
32 - x = strlen(from) + 1; 35 - x = strlen(from) + 1;
33 ... when != \( x = E1 \| from = E1 \) 36 ... when != \( x = E1 \| from = E1 \)
34 - to = \(kmalloc\|kzalloc\)(x,flag); 37 - to = \(kmalloc\|kzalloc\)(x,flag);
35 + to = kstrdup(from, flag); 38 + to = kstrdup(from, flag);
36 ... when != \(x = E2 \| from = E2 \| to = E2 \) 39 ... when != \(x = E2 \| from = E2 \| to = E2 \)
37 if (to==NULL || ...) S 40 if (to==NULL || ...) S
38 ... when != \(x = E3 \| from = E3 \| to = E3 \) 41 ... when != \(x = E3 \| from = E3 \| to = E3 \)
39 - memcpy(to, from, x); 42 - memcpy(to, from, x);
43
44 // ---------------------------------------------------------------------
45
46 @r1 depends on !patch exists@
47 expression from,to;
48 expression flag,E1,E2;
49 statement S;
50 position p1,p2;
51 @@
52
53 * to = kmalloc@p1(strlen(from) + 1,flag);
54 ... when != \(from = E1 \| to = E1 \)
55 if (to==NULL || ...) S
56 ... when != \(from = E2 \| to = E2 \)
57 * strcpy@p2(to, from);
58
59 @r2 depends on !patch exists@
60 expression x,from,to;
61 expression flag,E1,E2,E3;
62 statement S;
63 position p1,p2;
64 @@
65
66 * x = strlen(from) + 1;
67 ... when != \( x = E1 \| from = E1 \)
68 * to = \(kmalloc@p1\|kzalloc@p2\)(x,flag);
69 ... when != \(x = E2 \| from = E2 \| to = E2 \)
70 if (to==NULL || ...) S
71 ... when != \(x = E3 \| from = E3 \| to = E3 \)
72 * memcpy@p2(to, from, x);
73
74 @script:python depends on org@
75 p1 << r1.p1;
76 p2 << r1.p2;
77 @@
78
79 cocci.print_main("WARNING opportunity for kstrdep",p1)
80 cocci.print_secs("strcpy",p2)
81
82 @script:python depends on org@
83 p1 << r2.p1;
84 p2 << r2.p2;
85 @@
86
87 cocci.print_main("WARNING opportunity for kstrdep",p1)
88 cocci.print_secs("memcpy",p2)
89
90 @script:python depends on report@
91 p1 << r1.p1;
92 p2 << r1.p2;
93 @@
94
95 msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line)
96 coccilib.report.print_report(p1[0], msg)
97
98 @script:python depends on report@
99 p1 << r2.p1;
100 p2 << r2.p2;
101 @@
102
103 msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line)
104 coccilib.report.print_report(p1[0], msg)
40 105
scripts/coccinelle/api/memdup.cocci
1 /// Use kmemdup rather than duplicating its implementation 1 /// Use kmemdup rather than duplicating its implementation
2 /// 2 ///
3 // Confidence: High 3 // Confidence: High
4 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 4 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
5 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
6 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 6 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 // URL: http://coccinelle.lip6.fr/ 7 // URL: http://coccinelle.lip6.fr/
8 // Comments: 8 // Comments:
9 // Options: -no_includes -include_headers 9 // Options: -no_includes -include_headers
10 10
11 virtual patch 11 virtual patch
12 virtual context
13 virtual org
14 virtual report
12 15
13 @r1@ 16 @r1@
14 expression from,to; 17 expression from,to;
15 expression flag; 18 expression flag;
16 position p; 19 position p;
17 @@ 20 @@
18 21
19 to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); 22 to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
20 23
21 @r2@ 24 @r2@
22 expression x,from,to; 25 expression x,from,to;
23 expression flag,E1; 26 expression flag,E1;
24 position p; 27 position p;
25 @@ 28 @@
26 29
27 x = strlen(from) + 1; 30 x = strlen(from) + 1;
28 ... when != \( x = E1 \| from = E1 \) 31 ... when != \( x = E1 \| from = E1 \)
29 to = \(kmalloc@p\|kzalloc@p\)(x,flag); 32 to = \(kmalloc@p\|kzalloc@p\)(x,flag);
30 33
31 @@ 34 @depends on patch@
32 expression from,to,size,flag; 35 expression from,to,size,flag;
33 position p != {r1.p,r2.p}; 36 position p != {r1.p,r2.p};
34 statement S; 37 statement S;
35 @@ 38 @@
36 39
37 - to = \(kmalloc@p\|kzalloc@p\)(size,flag); 40 - to = \(kmalloc@p\|kzalloc@p\)(size,flag);
38 + to = kmemdup(from,size,flag); 41 + to = kmemdup(from,size,flag);
39 if (to==NULL || ...) S 42 if (to==NULL || ...) S
40 - memcpy(to, from, size); 43 - memcpy(to, from, size);
44
45 @r depends on !patch@
46 expression from,to,size,flag;
47 position p != {r1.p,r2.p};
48 statement S;
49 @@
50
51 * to = \(kmalloc@p\|kzalloc@p\)(size,flag);
52 to = kmemdup(from,size,flag);
53 if (to==NULL || ...) S
54 * memcpy(to, from, size);
55
56 @script:python depends on org@
57 p << r.p;
58 @@
59
60 coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
61
62 @script:python depends on report@
63 p << r.p;
64 @@
65
66 coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
41 67
scripts/coccinelle/api/memdup_user.cocci
1 /// Use kmemdup_user rather than duplicating its implementation 1 /// Use memdup_user rather than duplicating its implementation
2 /// This is a little bit restricted to reduce false positives 2 /// This is a little bit restricted to reduce false positives
3 /// 3 ///
4 // Confidence: High 4 // Confidence: High
5 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
6 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 6 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
7 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 7 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
8 // URL: http://coccinelle.lip6.fr/ 8 // URL: http://coccinelle.lip6.fr/
9 // Comments: 9 // Comments:
10 // Options: -no_includes -include_headers 10 // Options: -no_includes -include_headers
11 11
12 virtual patch 12 virtual patch
13 virtual context
14 virtual org
15 virtual report
13 16
14 @@ 17 @depends on patch@
15 expression from,to,size,flag; 18 expression from,to,size,flag;
16 position p;
17 identifier l1,l2; 19 identifier l1,l2;
18 @@ 20 @@
19 21
20 - to = \(kmalloc@p\|kzalloc@p\)(size,flag); 22 - to = \(kmalloc\|kzalloc\)(size,flag);
21 + to = memdup_user(from,size); 23 + to = memdup_user(from,size);
22 if ( 24 if (
23 - to==NULL 25 - to==NULL
24 + IS_ERR(to) 26 + IS_ERR(to)
25 || ...) { 27 || ...) {
26 <+... when != goto l1; 28 <+... when != goto l1;
27 - -ENOMEM 29 - -ENOMEM
28 + PTR_ERR(to) 30 + PTR_ERR(to)
29 ...+> 31 ...+>
30 } 32 }
31 - if (copy_from_user(to, from, size) != 0) { 33 - if (copy_from_user(to, from, size) != 0) {
32 - <+... when != goto l2; 34 - <+... when != goto l2;
33 - -EFAULT 35 - -EFAULT
34 - ...+> 36 - ...+>
35 - } 37 - }
38
39 @r depends on !patch@
40 expression from,to,size,flag;
41 position p;
42 statement S1,S2;
43 @@
44
45 * to = \(kmalloc@p\|kzalloc@p\)(size,flag);
46 if (to==NULL || ...) S1
47 if (copy_from_user(to, from, size) != 0)
48 S2
49
50 @script:python depends on org@
51 p << r.p;
52 @@
53
54 coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user")
55
56 @script:python depends on report@
57 p << r.p;
58 @@
59
60 coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user")
scripts/coccinelle/free/devm_free.cocci
File was created 1 /// Find uses of standard freeing functons on values allocated using devm_
2 /// functions. Values allocated using the devm_functions are freed when
3 /// the device is detached, and thus the use of the standard freeing
4 /// function would cause a double free.
5 /// See Documentation/driver-model/devres.txt for more information.
6 ///
7 /// A difficulty of detecting this problem is that the standard freeing
8 /// function might be called from a different function than the one
9 /// containing the allocation function. It is thus necessary to make the
10 /// connection between the allocation function and the freeing function.
11 /// Here this is done using the specific argument text, which is prone to
12 /// false positives. There is no rule for the request_region and
13 /// request_mem_region variants because this heuristic seems to be a bit
14 /// less reliable in these cases.
15 ///
16 // Confidence: Moderate
17 // Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2.
18 // Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2.
19 // URL: http://coccinelle.lip6.fr/
20 // Comments:
21 // Options: -no_includes -include_headers
22
23 virtual org
24 virtual report
25 virtual context
26
27 @r depends on context || org || report@
28 expression x;
29 @@
30
31 (
32 x = devm_kzalloc(...)
33 |
34 x = devm_request_irq(...)
35 |
36 x = devm_ioremap(...)
37 |
38 x = devm_ioremap_nocache(...)
39 |
40 x = devm_ioport_map(...)
41 )
42
43 @pb@
44 expression r.x;
45 position p;
46 @@
47
48 (
49 * kfree@p(x)
50 |
51 * free_irq@p(x)
52 |
53 * iounmap@p(x)
54 |
55 * ioport_unmap@p(x)
56 )
57
58 @script:python depends on org@
59 p << pb.p;
60 @@
61
62 msg="WARNING: invalid free of devm_ allocated data"
63 coccilib.org.print_todo(p[0], msg)
64
65 @script:python depends on report@
66 p << pb.p;
67 @@
68
69 msg="WARNING: invalid free of devm_ allocated data"
70 coccilib.report.print_report(p[0], msg)
71
72
scripts/coccinelle/free/kfree.cocci
1 /// Find a use after free. 1 /// Find a use after free.
2 //# Values of variables may imply that some 2 //# Values of variables may imply that some
3 //# execution paths are not possible, resulting in false positives. 3 //# execution paths are not possible, resulting in false positives.
4 //# Another source of false positives are macros such as 4 //# Another source of false positives are macros such as
5 //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument 5 //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
6 /// 6 ///
7 // Confidence: Moderate 7 // Confidence: Moderate
8 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 8 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
9 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 9 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
10 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 10 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
11 // URL: http://coccinelle.lip6.fr/ 11 // URL: http://coccinelle.lip6.fr/
12 // Comments: 12 // Comments:
13 // Options: -no_includes -include_headers 13 // Options: -no_includes -include_headers
14 14
15 virtual org 15 virtual org
16 virtual report 16 virtual report
17 17
18 @free@ 18 @free@
19 expression E; 19 expression E;
20 position p1; 20 position p1;
21 @@ 21 @@
22 22
23 kfree@p1(E) 23 kfree@p1(E)
24 24
25 @print expression@ 25 @print expression@
26 constant char *c; 26 constant char [] c;
27 expression free.E,E2; 27 expression free.E,E2;
28 type T; 28 type T;
29 position p; 29 position p;
30 identifier f; 30 identifier f;
31 @@ 31 @@
32 32
33 ( 33 (
34 f(...,c,...,(T)E@p,...) 34 f(...,c,...,(T)E@p,...)
35 | 35 |
36 E@p == E2 36 E@p == E2
37 | 37 |
38 E@p != E2 38 E@p != E2
39 | 39 |
40 E2 == E@p
41 |
42 E2 != E@p
43 |
40 !E@p 44 !E@p
41 | 45 |
42 E@p || ... 46 E@p || ...
43 ) 47 )
44 48
45 @sz@ 49 @sz@
46 expression free.E; 50 expression free.E;
47 position p; 51 position p;
48 @@ 52 @@
49 53
50 sizeof(<+...E@p...+>) 54 sizeof(<+...E@p...+>)
51 55
52 @loop exists@ 56 @loop exists@
53 expression E; 57 expression E;
54 identifier l; 58 identifier l;
55 position ok; 59 position ok;
56 @@ 60 @@
57 61
58 while (1) { ... 62 while (1) { ...
59 kfree@ok(E) 63 kfree@ok(E)
60 ... when != break; 64 ... when != break;
61 when != goto l; 65 when != goto l;
62 when forall 66 when forall
63 } 67 }
64 68
65 @r exists@ 69 @r exists@
66 expression free.E, subE<=free.E, E2; 70 expression free.E, subE<=free.E, E2;
67 expression E1; 71 expression E1;
68 iterator iter; 72 iterator iter;
69 statement S; 73 statement S;
70 position free.p1!=loop.ok,p2!={print.p,sz.p}; 74 position free.p1!=loop.ok,p2!={print.p,sz.p};
71 @@ 75 @@
72 76
73 kfree@p1(E,...) 77 kfree@p1(E,...)
74 ... 78 ...
75 ( 79 (
76 iter(...,subE,...) S // no use 80 iter(...,subE,...) S // no use
77 | 81 |
78 list_remove_head(E1,subE,...) 82 list_remove_head(E1,subE,...)
79 | 83 |
80 subE = E2 84 subE = E2
81 | 85 |
82 subE++ 86 subE++
83 | 87 |
84 ++subE 88 ++subE
85 | 89 |
86 --subE 90 --subE
87 | 91 |
88 subE-- 92 subE--
89 | 93 |
90 &subE 94 &subE
91 | 95 |
92 BUG(...) 96 BUG(...)
93 | 97 |
94 BUG_ON(...) 98 BUG_ON(...)
95 | 99 |
96 return_VALUE(...) 100 return_VALUE(...)
97 | 101 |
98 return_ACPI_STATUS(...) 102 return_ACPI_STATUS(...)
99 | 103 |
100 E@p2 // bad use 104 E@p2 // bad use
101 ) 105 )
102 106
103 @script:python depends on org@ 107 @script:python depends on org@
104 p1 << free.p1; 108 p1 << free.p1;
105 p2 << r.p2; 109 p2 << r.p2;
106 @@ 110 @@
107 111
108 cocci.print_main("kfree",p1) 112 cocci.print_main("kfree",p1)
109 cocci.print_secs("ref",p2) 113 cocci.print_secs("ref",p2)
110 114
111 @script:python depends on report@ 115 @script:python depends on report@
112 p1 << free.p1; 116 p1 << free.p1;
113 p2 << r.p2; 117 p2 << r.p2;
114 @@ 118 @@
115 119
116 msg = "reference preceded by free on line %s" % (p1[0].line) 120 msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
117 coccilib.report.print_report(p2[0],msg) 121 coccilib.report.print_report(p2[0],msg)
118 122
scripts/coccinelle/iterators/fen.cocci
1 /// These iterators only exit normally when the loop cursor is NULL, so there 1 /// These iterators only exit normally when the loop cursor is NULL, so there
2 /// is no point to call of_node_put on the final value. 2 /// is no point to call of_node_put on the final value.
3 /// 3 ///
4 // Confidence: High 4 // Confidence: High
5 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
6 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 6 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
7 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 7 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
8 // URL: http://coccinelle.lip6.fr/ 8 // URL: http://coccinelle.lip6.fr/
9 // Comments: 9 // Comments:
10 // Options: -no_includes -include_headers 10 // Options: -no_includes -include_headers
11 11
12 virtual patch 12 virtual patch
13 virtual context
14 virtual org
15 virtual report
13 16
14 @@ 17 @depends on patch@
15 iterator name for_each_node_by_name; 18 iterator name for_each_node_by_name;
16 expression np,E; 19 expression np,E;
17 identifier l; 20 identifier l;
18 @@ 21 @@
19 22
20 for_each_node_by_name(np,...) { 23 for_each_node_by_name(np,...) {
21 ... when != break; 24 ... when != break;
22 when != goto l; 25 when != goto l;
23 } 26 }
24 ... when != np = E 27 ... when != np = E
25 - of_node_put(np); 28 - of_node_put(np);
26 29
27 @@ 30 @depends on patch@
28 iterator name for_each_node_by_type; 31 iterator name for_each_node_by_type;
29 expression np,E; 32 expression np,E;
30 identifier l; 33 identifier l;
31 @@ 34 @@
32 35
33 for_each_node_by_type(np,...) { 36 for_each_node_by_type(np,...) {
34 ... when != break; 37 ... when != break;
35 when != goto l; 38 when != goto l;
36 } 39 }
37 ... when != np = E 40 ... when != np = E
38 - of_node_put(np); 41 - of_node_put(np);
39 42
40 @@ 43 @depends on patch@
41 iterator name for_each_compatible_node; 44 iterator name for_each_compatible_node;
42 expression np,E; 45 expression np,E;
43 identifier l; 46 identifier l;
44 @@ 47 @@
45 48
46 for_each_compatible_node(np,...) { 49 for_each_compatible_node(np,...) {
47 ... when != break; 50 ... when != break;
48 when != goto l; 51 when != goto l;
49 } 52 }
50 ... when != np = E 53 ... when != np = E
51 - of_node_put(np); 54 - of_node_put(np);
52 55
53 @@ 56 @depends on patch@
54 iterator name for_each_matching_node; 57 iterator name for_each_matching_node;
55 expression np,E; 58 expression np,E;
56 identifier l; 59 identifier l;
57 @@ 60 @@
58 61
59 for_each_matching_node(np,...) { 62 for_each_matching_node(np,...) {
60 ... when != break; 63 ... when != break;
61 when != goto l; 64 when != goto l;
62 } 65 }
63 ... when != np = E 66 ... when != np = E
64 - of_node_put(np); 67 - of_node_put(np);
68
69 // ----------------------------------------------------------------------
70
71 @r depends on !patch forall@
72 //iterator name for_each_node_by_name;
73 //iterator name for_each_node_by_type;
74 //iterator name for_each_compatible_node;
75 //iterator name for_each_matching_node;
76 expression np,E;
77 identifier l;
78 position p1,p2;
79 @@
80
81 (
82 *for_each_node_by_name@p1(np,...)
83 {
84 ... when != break;
85 when != goto l;
86 }
87 |
88 *for_each_node_by_type@p1(np,...)
89 {
90 ... when != break;
91 when != goto l;
92 }
93 |
94 *for_each_compatible_node@p1(np,...)
95 {
96 ... when != break;
97 when != goto l;
98 }
99 |
100 *for_each_matching_node@p1(np,...)
101 {
102 ... when != break;
103 when != goto l;
104 }
105 )
106 ... when != np = E
107 * of_node_put@p2(np);
108
109 @script:python depends on org@
110 p1 << r.p1;
111 p2 << r.p2;
112 @@
113
114 cocci.print_main("unneeded of_node_put",p2)
115 cocci.print_secs("iterator",p1)
116
117 @script:python depends on report@
118 p1 << r.p1;
119 p2 << r.p2;
120 @@
121
122 msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line)
123 coccilib.report.print_report(p2[0], msg)
65 124
scripts/coccinelle/iterators/itnull.cocci
1 /// Many iterators have the property that the first argument is always bound 1 /// Many iterators have the property that the first argument is always bound
2 /// to a real list element, never NULL. False positives arise for some 2 /// to a real list element, never NULL.
3 /// iterators that do not have this property, or in cases when the loop 3 //# False positives arise for some iterators that do not have this property,
4 /// cursor is reassigned. The latter should only happen when the matched 4 //# or in cases when the loop cursor is reassigned. The latter should only
5 /// code is on the way to a loop exit (break, goto, or return). 5 //# happen when the matched code is on the way to a loop exit (break, goto,
6 //# or return).
6 /// 7 ///
7 // Confidence: Moderate 8 // Confidence: Moderate
8 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 9 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
9 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 10 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
10 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 11 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
11 // URL: http://coccinelle.lip6.fr/ 12 // URL: http://coccinelle.lip6.fr/
12 // Comments: 13 // Comments:
13 // Options: -no_includes -include_headers 14 // Options: -no_includes -include_headers
14 15
15 virtual patch 16 virtual patch
17 virtual context
18 virtual org
19 virtual report
16 20
17 @@ 21 @depends on patch@
18 iterator I; 22 iterator I;
19 expression x,E,E1,E2; 23 expression x,E,E1,E2;
20 statement S,S1,S2; 24 statement S,S1,S2;
21 @@ 25 @@
22 26
23 I(x,...) { <... 27 I(x,...) { <...
24 ( 28 (
25 - if (x == NULL && ...) S 29 - if (x == NULL && ...) S
26 | 30 |
27 - if (x != NULL || ...) 31 - if (x != NULL || ...)
28 S 32 S
29 | 33 |
30 - (x == NULL) || 34 - (x == NULL) ||
31 E 35 E
32 | 36 |
33 - (x != NULL) && 37 - (x != NULL) &&
34 E 38 E
35 | 39 |
36 - (x == NULL && ...) ? E1 : 40 - (x == NULL && ...) ? E1 :
37 E2 41 E2
38 | 42 |
39 - (x != NULL || ...) ? 43 - (x != NULL || ...) ?
40 E1 44 E1
41 - : E2 45 - : E2
42 | 46 |
43 - if (x == NULL && ...) S1 else 47 - if (x == NULL && ...) S1 else
44 S2 48 S2
45 | 49 |
46 - if (x != NULL || ...) 50 - if (x != NULL || ...)
47 S1 51 S1
48 - else S2 52 - else S2
49 | 53 |
50 + BAD( 54 + BAD(
51 x == NULL 55 x == NULL
52 + ) 56 + )
53 | 57 |
54 + BAD( 58 + BAD(
55 x != NULL 59 x != NULL
56 + ) 60 + )
57 ) 61 )
58 ...> } 62 ...> }
63
64 @r depends on !patch exists@
65 iterator I;
66 expression x,E;
67 position p1,p2;
68 @@
69
70 *I@p1(x,...)
71 { ... when != x = E
72 (
73 * x@p2 == NULL
74 |
75 * x@p2 != NULL
76 )
77 ... when any
78 }
79
80 @script:python depends on org@
81 p1 << r.p1;
82 p2 << r.p2;
83 @@
84
85 cocci.print_main("iterator-bound variable",p1)
86 cocci.print_secs("useless NULL test",p2)
87
88 @script:python depends on report@
89 p1 << r.p1;
90 p2 << r.p2;
91 @@
92
93 msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
94 coccilib.report.print_report(p2[0], msg)
95
scripts/coccinelle/locks/call_kern.cocci
1 /// Find functions that refer to GFP_KERNEL but are called with locks held. 1 /// Find functions that refer to GFP_KERNEL but are called with locks held.
2 /// The proposed change of converting the GFP_KERNEL is not necessarily the 2 //# The proposed change of converting the GFP_KERNEL is not necessarily the
3 /// correct one. It may be desired to unlock the lock, or to not call the 3 //# correct one. It may be desired to unlock the lock, or to not call the
4 /// function under the lock in the first place. 4 //# function under the lock in the first place.
5 /// 5 ///
6 // Confidence: Moderate 6 // Confidence: Moderate
7 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 7 // Copyright: (C) 2012 Nicolas Palix. GPLv2.
8 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 8 // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
9 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 9 // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
10 // URL: http://coccinelle.lip6.fr/ 10 // URL: http://coccinelle.lip6.fr/
11 // Comments: 11 // Comments:
12 // Options: -no_includes -include_headers 12 // Options: -no_includes -include_headers
13 13
14 virtual patch 14 virtual patch
15 virtual context
16 virtual org
17 virtual report
15 18
16 @gfp exists@ 19 @gfp exists@
17 identifier fn; 20 identifier fn;
18 position p; 21 position p;
19 @@ 22 @@
20 23
21 fn(...) { 24 fn(...) {
22 ... when != read_unlock_irq(...) 25 ... when != read_unlock_irq(...)
23 when != write_unlock_irq(...) 26 when != write_unlock_irq(...)
24 when != read_unlock_irqrestore(...) 27 when != read_unlock_irqrestore(...)
25 when != write_unlock_irqrestore(...) 28 when != write_unlock_irqrestore(...)
26 when != spin_unlock(...) 29 when != spin_unlock(...)
27 when != spin_unlock_irq(...) 30 when != spin_unlock_irq(...)
28 when != spin_unlock_irqrestore(...) 31 when != spin_unlock_irqrestore(...)
29 when != local_irq_enable(...) 32 when != local_irq_enable(...)
30 when any 33 when any
31 GFP_KERNEL@p 34 GFP_KERNEL@p
32 ... when any 35 ... when any
33 } 36 }
34 37
35 @locked@ 38 @locked exists@
36 identifier gfp.fn; 39 identifier gfp.fn;
40 position p1,p2;
37 @@ 41 @@
38 42
39 ( 43 (
40 read_lock_irq 44 read_lock_irq@p1
41 | 45 |
42 write_lock_irq 46 write_lock_irq@p1
43 | 47 |
44 read_lock_irqsave 48 read_lock_irqsave@p1
45 | 49 |
46 write_lock_irqsave 50 write_lock_irqsave@p1
47 | 51 |
48 spin_lock 52 spin_lock@p1
49 | 53 |
50 spin_trylock 54 spin_trylock@p1
51 | 55 |
52 spin_lock_irq 56 spin_lock_irq@p1
53 | 57 |
54 spin_lock_irqsave 58 spin_lock_irqsave@p1
55 | 59 |
56 local_irq_disable 60 local_irq_disable@p1
57 ) 61 )
58 (...) 62 (...)
59 ... when != read_unlock_irq(...) 63 ... when != read_unlock_irq(...)
60 when != write_unlock_irq(...) 64 when != write_unlock_irq(...)
61 when != read_unlock_irqrestore(...) 65 when != read_unlock_irqrestore(...)
62 when != write_unlock_irqrestore(...) 66 when != write_unlock_irqrestore(...)
63 when != spin_unlock(...) 67 when != spin_unlock(...)
64 when != spin_unlock_irq(...) 68 when != spin_unlock_irq(...)
65 when != spin_unlock_irqrestore(...) 69 when != spin_unlock_irqrestore(...)
66 when != local_irq_enable(...) 70 when != local_irq_enable(...)
67 fn(...) 71 fn@p2(...)
68 72
69 @depends on locked@ 73 @depends on locked && patch@
70 position gfp.p; 74 position gfp.p;
71 @@ 75 @@
72 76
73 - GFP_KERNEL@p 77 - GFP_KERNEL@p
74 + GFP_ATOMIC 78 + GFP_ATOMIC
79
80 @depends on locked && !patch@
81 position gfp.p;
82 @@
83
84 * GFP_KERNEL@p
85
86 @script:python depends on !patch && org@
87 p << gfp.p;
88 fn << gfp.fn;
89 p1 << locked.p1;
90 p2 << locked.p2;
91 @@
92
93 cocci.print_main("lock",p1)
94 cocci.print_secs("call",p2)
95 cocci.print_secs("GFP_KERNEL",p)
96
97 @script:python depends on !patch && report@
98 p << gfp.p;
99 fn << gfp.fn;
100 p1 << locked.p1;
101 p2 << locked.p2;
102 @@
103
104 msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
105 coccilib.report.print_report(p[0], msg)
75 106
scripts/coccinelle/locks/flags.cocci
1 /// Find nested lock+irqsave functions that use the same flags variables 1 /// Find nested lock+irqsave functions that use the same flags variables
2 /// 2 ///
3 // Confidence: High 3 // Confidence: High
4 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 4 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
5 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
6 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 6 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 // URL: http://coccinelle.lip6.fr/ 7 // URL: http://coccinelle.lip6.fr/
8 // Comments: 8 // Comments:
9 // Options: -no_includes -include_headers 9 // Options: -no_includes -include_headers
10 10
11 virtual context 11 virtual context
12 virtual org 12 virtual org
13 virtual report 13 virtual report
14 14
15 @r@ 15 @r exists@
16 expression lock1,lock2,flags; 16 expression lock1,lock2,flags;
17 position p1,p2; 17 position p1,p2;
18 @@ 18 @@
19 19
20 ( 20 (
21 spin_lock_irqsave@p1(lock1,flags) 21 spin_lock_irqsave@p1(lock1,flags)
22 | 22 |
23 read_lock_irqsave@p1(lock1,flags) 23 read_lock_irqsave@p1(lock1,flags)
24 | 24 |
25 write_lock_irqsave@p1(lock1,flags) 25 write_lock_irqsave@p1(lock1,flags)
26 ) 26 )
27 ... when != flags 27 ... when != flags
28 ( 28 (
29 spin_lock_irqsave(lock1,flags) 29 spin_lock_irqsave(lock1,flags)
30 | 30 |
31 read_lock_irqsave(lock1,flags) 31 read_lock_irqsave(lock1,flags)
32 | 32 |
33 write_lock_irqsave(lock1,flags) 33 write_lock_irqsave(lock1,flags)
34 | 34 |
35 spin_lock_irqsave@p2(lock2,flags) 35 spin_lock_irqsave@p2(lock2,flags)
36 | 36 |
37 read_lock_irqsave@p2(lock2,flags) 37 read_lock_irqsave@p2(lock2,flags)
38 | 38 |
39 write_lock_irqsave@p2(lock2,flags) 39 write_lock_irqsave@p2(lock2,flags)
40 ) 40 )
41 41
42 @d@ 42 @d exists@
43 expression f <= r.flags; 43 expression f <= r.flags;
44 expression lock1,lock2,flags; 44 expression lock1,lock2,flags;
45 position r.p1, r.p2; 45 position r.p1, r.p2;
46 @@ 46 @@
47 47
48 ( 48 (
49 *spin_lock_irqsave@p1(lock1,flags) 49 *spin_lock_irqsave@p1(lock1,flags)
50 | 50 |
51 *read_lock_irqsave@p1(lock1,flags) 51 *read_lock_irqsave@p1(lock1,flags)
52 | 52 |
53 *write_lock_irqsave@p1(lock1,flags) 53 *write_lock_irqsave@p1(lock1,flags)
54 ) 54 )
55 ... when != f 55 ... when != f
56 ( 56 (
57 *spin_lock_irqsave@p2(lock2,flags) 57 *spin_lock_irqsave@p2(lock2,flags)
58 | 58 |
59 *read_lock_irqsave@p2(lock2,flags) 59 *read_lock_irqsave@p2(lock2,flags)
60 | 60 |
61 *write_lock_irqsave@p2(lock2,flags) 61 *write_lock_irqsave@p2(lock2,flags)
62 ) 62 )
63 63
64 // ---------------------------------------------------------------------- 64 // ----------------------------------------------------------------------
65 65
66 @script:python depends on d && org@ 66 @script:python depends on d && org@
67 p1 << r.p1; 67 p1 << r.p1;
68 p2 << r.p2; 68 p2 << r.p2;
69 @@ 69 @@
70 70
71 cocci.print_main("original lock",p1) 71 cocci.print_main("original lock",p1)
72 cocci.print_secs("nested lock+irqsave that reuses flags",p2) 72 cocci.print_secs("nested lock+irqsave that reuses flags",p2)
73 73
74 @script:python depends on d && report@ 74 @script:python depends on d && report@
75 p1 << r.p1; 75 p1 << r.p1;
76 p2 << r.p2; 76 p2 << r.p2;
77 @@ 77 @@
78 78
79 msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) 79 msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
80 coccilib.report.print_report(p2[0], msg) 80 coccilib.report.print_report(p2[0], msg)
81 81
scripts/coccinelle/locks/mini_lock.cocci
1 /// Find missing unlocks. This semantic match considers the specific case 1 /// Find missing unlocks. This semantic match considers the specific case
2 /// where the unlock is missing from an if branch, and there is a lock 2 /// where the unlock is missing from an if branch, and there is a lock
3 /// before the if and an unlock after the if. False positives are due to 3 /// before the if and an unlock after the if. False positives are due to
4 /// cases where the if branch represents a case where the function is 4 /// cases where the if branch represents a case where the function is
5 /// supposed to exit with the lock held, or where there is some preceding 5 /// supposed to exit with the lock held, or where there is some preceding
6 /// function call that releases the lock. 6 /// function call that releases the lock.
7 /// 7 ///
8 // Confidence: Moderate 8 // Confidence: Moderate
9 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 9 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
10 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 10 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
11 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 11 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
12 // URL: http://coccinelle.lip6.fr/ 12 // URL: http://coccinelle.lip6.fr/
13 // Comments: 13 // Comments:
14 // Options: -no_includes -include_headers 14 // Options: -no_includes -include_headers
15 15
16 virtual context
16 virtual org 17 virtual org
17 virtual report 18 virtual report
18 19
19 @prelocked@ 20 @prelocked@
20 position p1,p; 21 position p1,p;
21 expression E1; 22 expression E1;
22 @@ 23 @@
23 24
24 ( 25 (
25 mutex_lock@p1 26 mutex_lock@p1
26 | 27 |
27 mutex_trylock@p1 28 mutex_trylock@p1
28 | 29 |
29 spin_lock@p1 30 spin_lock@p1
30 | 31 |
31 spin_trylock@p1 32 spin_trylock@p1
32 | 33 |
33 read_lock@p1 34 read_lock@p1
34 | 35 |
35 read_trylock@p1 36 read_trylock@p1
36 | 37 |
37 write_lock@p1 38 write_lock@p1
38 | 39 |
39 write_trylock@p1 40 write_trylock@p1
40 | 41 |
41 read_lock_irq@p1 42 read_lock_irq@p1
42 | 43 |
43 write_lock_irq@p1 44 write_lock_irq@p1
44 | 45 |
45 read_lock_irqsave@p1 46 read_lock_irqsave@p1
46 | 47 |
47 write_lock_irqsave@p1 48 write_lock_irqsave@p1
48 | 49 |
49 spin_lock_irq@p1 50 spin_lock_irq@p1
50 | 51 |
51 spin_lock_irqsave@p1 52 spin_lock_irqsave@p1
52 ) (E1@p,...); 53 ) (E1@p,...);
53 54
54 @looped@ 55 @looped@
55 position r; 56 position r;
56 @@ 57 @@
57 58
58 for(...;...;...) { <+... return@r ...; ...+> } 59 for(...;...;...) { <+... return@r ...; ...+> }
59 60
60 @err@ 61 @err exists@
61 expression E1; 62 expression E1;
62 position prelocked.p; 63 position prelocked.p;
63 position up != prelocked.p1; 64 position up != prelocked.p1;
64 position r!=looped.r; 65 position r!=looped.r;
65 identifier lock,unlock; 66 identifier lock,unlock;
66 @@ 67 @@
67 68
68 lock(E1@p,...); 69 *lock(E1@p,...);
69 <+... when != E1 70 <+... when != E1
70 if (...) { 71 if (...) {
71 ... when != E1 72 ... when != E1
72 return@r ...; 73 * return@r ...;
73 } 74 }
74 ...+> 75 ...+>
75 unlock@up(E1,...); 76 *unlock@up(E1,...);
76 77
77 @script:python depends on org@ 78 @script:python depends on org@
78 p << prelocked.p1; 79 p << prelocked.p1;
79 lock << err.lock; 80 lock << err.lock;
80 unlock << err.unlock; 81 unlock << err.unlock;
81 p2 << err.r; 82 p2 << err.r;
82 @@ 83 @@
83 84
84 cocci.print_main(lock,p) 85 cocci.print_main(lock,p)
85 cocci.print_secs(unlock,p2) 86 cocci.print_secs(unlock,p2)
86 87
87 @script:python depends on report@ 88 @script:python depends on report@
88 p << prelocked.p1; 89 p << prelocked.p1;
89 lock << err.lock; 90 lock << err.lock;
90 unlock << err.unlock; 91 unlock << err.unlock;
91 p2 << err.r; 92 p2 << err.r;
92 @@ 93 @@
93 94
94 msg = "preceding lock on line %s" % (p[0].line) 95 msg = "preceding lock on line %s" % (p[0].line)
95 coccilib.report.print_report(p2[0],msg) 96 coccilib.report.print_report(p2[0],msg)
96 97
scripts/coccinelle/misc/doubleinit.cocci
1 /// Find duplicate field initializations. This has a high rate of false 1 /// Find duplicate field initializations. This has a high rate of false
2 /// positives due to #ifdefs, which Coccinelle is not aware of in a structure 2 /// positives due to #ifdefs, which Coccinelle is not aware of in a structure
3 /// initialization. 3 /// initialization.
4 /// 4 ///
5 // Confidence: Low 5 // Confidence: Low
6 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 6 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
7 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 7 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
8 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 8 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
9 // URL: http://coccinelle.lip6.fr/ 9 // URL: http://coccinelle.lip6.fr/
10 // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise 10 // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
11 // Options: -no_includes -include_headers 11 // Options: -no_includes -include_headers
12 12
13 virtual org 13 virtual org
14 virtual report 14 virtual report
15 15
16 @r@ 16 @r@
17 identifier I, s, fld; 17 identifier I, s, fld;
18 position p0,p; 18 position p0,p;
19 expression E; 19 expression E;
20 @@ 20 @@
21 21
22 struct I s =@p0 { ..., .fld@p = E, ...}; 22 struct I s =@p0 { ..., .fld@p = E, ...};
23 23
24 @s@ 24 @s@
25 identifier I, s, r.fld; 25 identifier I, s, r.fld;
26 position r.p0,p; 26 position r.p0,p;
27 expression E; 27 expression E;
28 @@ 28 @@
29 29
30 struct I s =@p0 { ..., .fld@p = E, ...}; 30 struct I s =@p0 { ..., .fld@p = E, ...};
31 31
32 @script:python depends on org@ 32 @script:python depends on org@
33 p0 << r.p0; 33 p0 << r.p0;
34 fld << r.fld; 34 fld << r.fld;
35 ps << s.p; 35 ps << s.p;
36 pr << r.p; 36 pr << r.p;
37 @@ 37 @@
38 38
39 if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): 39 if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
40 cocci.print_main(fld,p0) 40 cocci.print_main(fld,p0)
41 cocci.print_secs("s",ps) 41 cocci.print_secs("s",ps)
42 cocci.print_secs("r",pr) 42 cocci.print_secs("r",pr)
43 43
44 @script:python depends on report@ 44 @script:python depends on report@
45 p0 << r.p0; 45 p0 << r.p0;
46 fld << r.fld; 46 fld << r.fld;
47 ps << s.p; 47 ps << s.p;
48 pr << r.p; 48 pr << r.p;
49 @@ 49 @@
50 50
51 if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): 51 if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
52 msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) 52 msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
53 coccilib.report.print_report(p0[0],msg) 53 coccilib.report.print_report(p0[0],msg)
54 54
scripts/coccinelle/null/eno.cocci
1 /// The various basic memory allocation functions don't return ERR_PTR 1 /// The various basic memory allocation functions don't return ERR_PTR
2 /// 2 ///
3 // Confidence: High 3 // Confidence: High
4 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 4 // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
5 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 5 // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
6 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 6 // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 // URL: http://coccinelle.lip6.fr/ 7 // URL: http://coccinelle.lip6.fr/
8 // Comments: 8 // Comments:
9 // Options: -no_includes -include_headers 9 // Options: -no_includes -include_headers
10 10
11 virtual patch 11 virtual patch
12 virtual context
13 virtual org
14 virtual report
12 15
13 @@ 16 @depends on patch@
14 expression x,E; 17 expression x,E;
15 @@ 18 @@
16 19
17 x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) 20 x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
18 ... when != x = E 21 ... when != x = E
19 - IS_ERR(x) 22 - IS_ERR(x)
20 + !x 23 + !x
24
25 @r depends on !patch exists@
26 expression x,E;
27 position p1,p2;
28 @@
29
30 *x = \(kmalloc@p1\|kzalloc@p1\|kcalloc@p1\|kmem_cache_alloc@p1\|kmem_cache_zalloc@p1\|kmem_cache_alloc_node@p1\|kmalloc_node@p1\|kzalloc_node@p1\)(...)
31 ... when != x = E
32 * IS_ERR@p2(x)
33
34 @script:python depends on org@
35 p1 << r.p1;
36 p2 << r.p2;
37 @@
38
39 cocci.print_main("alloc call",p1)
40 cocci.print_secs("IS_ERR that should be NULL tests",p2)
41
42 @script:python depends on report@
43 p1 << r.p1;
44 p2 << r.p2;
45 @@
46
47 msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line)
48 coccilib.report.print_report(p2[0], msg)
21 49
1 #!/bin/sh 1 #!/bin/sh
2 # Generate tags or cscope files 2 # Generate tags or cscope files
3 # Usage tags.sh <mode> 3 # Usage tags.sh <mode>
4 # 4 #
5 # mode may be any of: tags, TAGS, cscope 5 # mode may be any of: tags, TAGS, cscope
6 # 6 #
7 # Uses the following environment variables: 7 # Uses the following environment variables:
8 # ARCH, SUBARCH, SRCARCH, srctree, src, obj 8 # ARCH, SUBARCH, SRCARCH, srctree, src, obj
9 9
10 if [ "$KBUILD_VERBOSE" = "1" ]; then 10 if [ "$KBUILD_VERBOSE" = "1" ]; then
11 set -x 11 set -x
12 fi 12 fi
13 13
14 # This is a duplicate of RCS_FIND_IGNORE without escaped '()' 14 # This is a duplicate of RCS_FIND_IGNORE without escaped '()'
15 ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \ 15 ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
16 -name CVS -o -name .pc -o -name .hg -o \ 16 -name CVS -o -name .pc -o -name .hg -o \
17 -name .git ) \ 17 -name .git ) \
18 -prune -o" 18 -prune -o"
19 19
20 # Do not use full path if we do not use O=.. builds 20 # Do not use full path if we do not use O=.. builds
21 # Use make O=. {tags|cscope} 21 # Use make O=. {tags|cscope}
22 # to force full paths for a non-O= build 22 # to force full paths for a non-O= build
23 if [ "${KBUILD_SRC}" = "" ]; then 23 if [ "${KBUILD_SRC}" = "" ]; then
24 tree= 24 tree=
25 else 25 else
26 tree=${srctree}/ 26 tree=${srctree}/
27 fi 27 fi
28 28
29 # Find all available archs 29 # Find all available archs
30 find_all_archs() 30 find_all_archs()
31 { 31 {
32 ALLSOURCE_ARCHS="" 32 ALLSOURCE_ARCHS=""
33 for arch in `ls ${tree}arch`; do 33 for arch in `ls ${tree}arch`; do
34 ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/} 34 ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
35 done 35 done
36 } 36 }
37 37
38 # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH 38 # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
39 if [ "${ALLSOURCE_ARCHS}" = "" ]; then 39 if [ "${ALLSOURCE_ARCHS}" = "" ]; then
40 ALLSOURCE_ARCHS=${SRCARCH} 40 ALLSOURCE_ARCHS=${SRCARCH}
41 elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then 41 elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
42 find_all_archs 42 find_all_archs
43 fi 43 fi
44 44
45 # find sources in arch/$ARCH 45 # find sources in arch/$ARCH
46 find_arch_sources() 46 find_arch_sources()
47 { 47 {
48 for i in $archincludedir; do 48 for i in $archincludedir; do
49 prune="$prune -wholename $i -prune -o" 49 prune="$prune -wholename $i -prune -o"
50 done 50 done
51 find ${tree}arch/$1 $ignore $prune -name "$2" -print; 51 find ${tree}arch/$1 $ignore $prune -name "$2" -print;
52 } 52 }
53 53
54 # find sources in arch/$1/include 54 # find sources in arch/$1/include
55 find_arch_include_sources() 55 find_arch_include_sources()
56 { 56 {
57 include=$(find ${tree}arch/$1/ -name include -type d); 57 include=$(find ${tree}arch/$1/ -name include -type d);
58 if [ -n "$include" ]; then 58 if [ -n "$include" ]; then
59 archincludedir="$archincludedir $include" 59 archincludedir="$archincludedir $include"
60 find $include $ignore -name "$2" -print; 60 find $include $ignore -name "$2" -print;
61 fi 61 fi
62 } 62 }
63 63
64 # find sources in include/ 64 # find sources in include/
65 find_include_sources() 65 find_include_sources()
66 { 66 {
67 find ${tree}include $ignore -name config -prune -o -name "$1" -print; 67 find ${tree}include $ignore -name config -prune -o -name "$1" -print;
68 } 68 }
69 69
70 # find sources in rest of tree 70 # find sources in rest of tree
71 # we could benefit from a list of dirs to search in here 71 # we could benefit from a list of dirs to search in here
72 find_other_sources() 72 find_other_sources()
73 { 73 {
74 find ${tree}* $ignore \ 74 find ${tree}* $ignore \
75 \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ 75 \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
76 -name "$1" -print; 76 -name "$1" -print;
77 } 77 }
78 78
79 find_sources() 79 find_sources()
80 { 80 {
81 find_arch_sources $1 "$2" 81 find_arch_sources $1 "$2"
82 } 82 }
83 83
84 all_sources() 84 all_sources()
85 { 85 {
86 find_arch_include_sources ${SRCARCH} '*.[chS]' 86 find_arch_include_sources ${SRCARCH} '*.[chS]'
87 if [ ! -z "$archinclude" ]; then 87 if [ ! -z "$archinclude" ]; then
88 find_arch_include_sources $archinclude '*.[chS]' 88 find_arch_include_sources $archinclude '*.[chS]'
89 fi 89 fi
90 find_include_sources '*.[chS]' 90 find_include_sources '*.[chS]'
91 for arch in $ALLSOURCE_ARCHS 91 for arch in $ALLSOURCE_ARCHS
92 do 92 do
93 find_sources $arch '*.[chS]' 93 find_sources $arch '*.[chS]'
94 done 94 done
95 find_other_sources '*.[chS]' 95 find_other_sources '*.[chS]'
96 } 96 }
97 97
98 all_kconfigs() 98 all_kconfigs()
99 { 99 {
100 for arch in $ALLSOURCE_ARCHS; do 100 for arch in $ALLSOURCE_ARCHS; do
101 find_sources $arch 'Kconfig*' 101 find_sources $arch 'Kconfig*'
102 done 102 done
103 find_other_sources 'Kconfig*' 103 find_other_sources 'Kconfig*'
104 } 104 }
105 105
106 all_defconfigs() 106 all_defconfigs()
107 { 107 {
108 find_sources $ALLSOURCE_ARCHS "defconfig" 108 find_sources $ALLSOURCE_ARCHS "defconfig"
109 } 109 }
110 110
111 docscope() 111 docscope()
112 { 112 {
113 (echo \-k; echo \-q; all_sources) > cscope.files 113 (echo \-k; echo \-q; all_sources) > cscope.files
114 cscope -b -f cscope.out 114 cscope -b -f cscope.out
115 } 115 }
116 116
117 dogtags() 117 dogtags()
118 { 118 {
119 all_sources | gtags -f - 119 all_sources | gtags -f -
120 } 120 }
121 121
122 exuberant() 122 exuberant()
123 { 123 {
124 all_sources | xargs $1 -a \ 124 all_sources | xargs $1 -a \
125 -I __initdata,__exitdata,__acquires,__releases \ 125 -I __initdata,__exitdata,__acquires,__releases \
126 -I __read_mostly,____cacheline_aligned \ 126 -I __read_mostly,____cacheline_aligned \
127 -I ____cacheline_aligned_in_smp \ 127 -I ____cacheline_aligned_in_smp \
128 -I ____cacheline_internodealigned_in_smp \ 128 -I ____cacheline_internodealigned_in_smp \
129 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ 129 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
130 -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ 130 -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
131 --extra=+f --c-kinds=+px \ 131 --extra=+f --c-kinds=+px \
132 --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ 132 --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \
133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ 133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ 134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
135 --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' 135 --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \
136 --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \
137 --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
138 --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
139 --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
140 --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
141 --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
142 --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
143 --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
144 --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
145 --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
146 --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
147 --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
148 --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
149 --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
150 --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
151 --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
152 --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
153 --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
154 --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
155 --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
156 --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/'
136 157
137 all_kconfigs | xargs $1 -a \ 158 all_kconfigs | xargs $1 -a \
138 --langdef=kconfig --language-force=kconfig \ 159 --langdef=kconfig --language-force=kconfig \
139 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/' 160 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'
140 161
141 all_kconfigs | xargs $1 -a \ 162 all_kconfigs | xargs $1 -a \
142 --langdef=kconfig --language-force=kconfig \ 163 --langdef=kconfig --language-force=kconfig \
143 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/' 164 --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/'
144 165
145 all_defconfigs | xargs -r $1 -a \ 166 all_defconfigs | xargs -r $1 -a \
146 --langdef=dotconfig --language-force=dotconfig \ 167 --langdef=dotconfig --language-force=dotconfig \
147 --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' 168 --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
148 169
170 # Remove structure forward declarations.
171 LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' tags
149 } 172 }
150 173
151 emacs() 174 emacs()
152 { 175 {
153 all_sources | xargs $1 -a \ 176 all_sources | xargs $1 -a \
154 --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \ 177 --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \
155 --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ 178 --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
156 --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ 179 --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
157 --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' 180 --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \
181 --regex='/PAGEFLAG\(([^,)]*).*/Page\1/' \
182 --regex='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
183 --regex='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
184 --regex='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
185 --regex='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
186 --regex='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
187 --regex='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
188 --regex='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
189 --regex='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
190 --regex='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
191 --regex='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
192 --regex='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
193 --regex='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
194 --regex='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
195 --regex='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
196 --regex='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
197 --regex='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
198 --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
199 --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
200 --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
201 --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/'
158 202
159 all_kconfigs | xargs $1 -a \ 203 all_kconfigs | xargs $1 -a \
160 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' 204 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
161 205
162 all_kconfigs | xargs $1 -a \ 206 all_kconfigs | xargs $1 -a \
163 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/' 207 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/'
164 208
165 all_defconfigs | xargs -r $1 -a \ 209 all_defconfigs | xargs -r $1 -a \
166 --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/' 210 --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'
167 } 211 }
168 212
169 xtags() 213 xtags()
170 { 214 {
171 if $1 --version 2>&1 | grep -iq exuberant; then 215 if $1 --version 2>&1 | grep -iq exuberant; then
172 exuberant $1 216 exuberant $1
173 elif $1 --version 2>&1 | grep -iq emacs; then 217 elif $1 --version 2>&1 | grep -iq emacs; then
174 emacs $1 218 emacs $1
175 else 219 else
176 all_sources | xargs $1 -a 220 all_sources | xargs $1 -a
177 fi 221 fi
178 } 222 }
179 223
180 224
181 # Support um (which uses SUBARCH) 225 # Support um (which uses SUBARCH)
182 if [ "${ARCH}" = "um" ]; then 226 if [ "${ARCH}" = "um" ]; then
183 if [ "$SUBARCH" = "i386" ]; then 227 if [ "$SUBARCH" = "i386" ]; then
184 archinclude=x86 228 archinclude=x86
185 elif [ "$SUBARCH" = "x86_64" ]; then 229 elif [ "$SUBARCH" = "x86_64" ]; then
186 archinclude=x86 230 archinclude=x86
187 else 231 else
188 archinclude=${SUBARCH} 232 archinclude=${SUBARCH}
189 fi 233 fi
190 fi 234 fi
191 235
192 case "$1" in 236 case "$1" in
193 "cscope") 237 "cscope")
194 docscope 238 docscope
195 ;; 239 ;;
196 240
197 "gtags") 241 "gtags")
198 dogtags 242 dogtags
199 ;; 243 ;;
200 244
201 "tags") 245 "tags")
202 rm -f tags 246 rm -f tags
203 xtags ctags 247 xtags ctags
204 ;; 248 ;;
205 249
206 "TAGS") 250 "TAGS")
207 rm -f TAGS 251 rm -f TAGS
208 xtags etags 252 xtags etags
209 ;; 253 ;;
210 esac 254 esac
211 255