cocci.inria.fr archive mirror
 help / color / mirror / Atom feed
From: Timur Tabi <timur@kernel.org>
To: Timur Tabi <timur@kernel.org>
Cc: cocci <cocci@systeme.lip6.fr>
Subject: Re: [Cocci] Can the current function name be passed to a Python snippet?
Date: Wed, 5 Dec 2018 12:32:05 -0600	[thread overview]
Message-ID: <CAOZdJXXYi=iwXuP07L2r29NmJLBUk2dyx_xU=GEz0M5xDcpd3w@mail.gmail.com> (raw)
In-Reply-To: <CAOZdJXX+0cVy0zC7xVgf2EE-YrP+qU_6QWJA_uhhiCqhbgAD7A@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 402 bytes --]

Another thing that I don't understand is why do I need to have two
rules for every Python script?  I've attached my .cocci file.  Each
Python script is in between a pair of //---- comments.  They all have
the same format:

1. One rule to specify the pattern to match
2. A Python script
3. Another rule to specify how to process the output of the Python script

Can't I combine 1) and 3) into one rule?

[-- Attachment #2: nv_printf.cocci --]
[-- Type: application/octet-stream, Size: 4989 bytes --]

/*
 * Coccinelle file to replace DBG_PRINTF() calls with NV_PRINTF() 
 *
 * To work around an odd behavior of Coccinelle, we temporarily change
 * the DBG_PRINTx statements into NV_PRINT2, and do all our work on that
 * macro name.  Only at the very end do we change NV_PRINT2 to NV_PRINTF.
 * We do this so that Coccinelle won't touch existing NV_PRINTF statements.
 *
 * Python rules come in three parts:
 *  1. A rule to determine if the Python code should be run
 *  2. The Python code itself, inside a rule
 *  3. A final rule that applies the output of the Python script
 */

// Remove the double-parentheses in DBG_PRINTF statements
@rule0@
@@
DBG_PRINTF(
-(
...
-)
 );

// Replace DBG_PRINTF with NV_PRINTF2
@rule1 depends on rule0@
expression x;
expression list y;
@@
-DBG_PRINTF(x, y);
+NV_PRINTF2(y);

// Replace DBG_PRINT_STRING with NV_PRINTF2
@rule2@
expression list x;
@@
-DBG_PRINT_STRING(x);
+NV_PRINTF2(x);

// Replace DBG_PRINT_STRING_VALUE with NV_PRINTF2
@rule3@
expression x;
expression list y;
@@
-DBG_PRINT_STRING_VALUE(x, y);
+NV_PRINTF2(x, "%s 0x%x\n", y);

// Replace DBG_PRINT_STRING_PTR with NV_PRINTF2
@rule4@
expression x;
expression list y;
@@
-DBG_PRINT_STRING_PTR(x, y);
+NV_PRINTF2(x, "%s %p\n", y);

// Replace DBG_PRINT_STRING_VAL64 with NV_PRINTF2
@rule5@
expression x;
expression list y;
@@
-DBG_PRINT_STRING_VAL64(x, y);
+NV_PRINTF2(x, "%s 0x%llx\n", y);

// Collect all the previous rules as a dependecy, so that the rules below
// can depend only on "rules" instead of "rule1 || rule2 || ..."
@rules depends on rule1 || rule2 || rule3 || rule4 || rule5@
@@
NV_PRINTF2

// Replace the DBG_xxx or DEBUGLEVEL_xxx with LEVEL_xxx
@depends on rules@
@@
NV_PRINTF2(...,
-\(DBG_LEVEL_INFO \| DEBUGLEVEL_TRACEINFO \| DBG_LEVEL_SETUPINFO \| DEBUGLEVEL_SETUPINFO\)
+LEVEL_INFO
, ...);

@depends on rules@
@@
NV_PRINTF2(...,
-\(DBG_LEVEL_USERERRORS \| DEBUGLEVEL_USERERRORS\)
+LEVEL_NOTICE
, ...);

@depends on rules@
@@
NV_PRINTF2(...,
-\(DBG_LEVEL_WARNINGS \| DEBUGLEVEL_WARNINGS\)
+LEVEL_WARNING
, ...);

@depends on rules@
@@
NV_PRINTF2(...,
-\(DBG_LEVEL_ERRORS \| DEBUGLEVEL_ERRORS\)
+LEVEL_ERROR
, ...);

// -------------------------------

// Use Python to clean up the string literals.
// Comments are still C-style though
@r depends on rules@
expression x;
constant char[] c;
position p1, p2;
@@
NV_PRINTF2(x, c, ...)

@script:python s@
c << r.c;
c2;
p1 << r.p1;
p2 << r.p2;
@@
import re

print 'p1=', p1
print 'p2=', p2
// Convert a malformed multi-line string literal into one line
// Coccinelle sometimes takes care of this for us, but sometimes it doesn't
c = re.sub(r'\\\n[ ]*', '', c, re.DOTALL)

// Combine "xxx" "yyy" into "xxxyyy"
while True:
    m = re.match(r'(.*)"([^"]+)" "(.*)', c)
    if not m:
	break
    c = '%s"%s%s' % (m.group(1), m.group(2), m.group(3))

// Finally, remove the "NXXX: " prefix
c = re.sub(r'"N[\-A-Z]+[\: ]*', '"', c, 1)
coccinelle.c2 = c

@depends on rules@
expression x;
constant char[] r.c;
identifier s.c2;
@@
NV_PRINTF2(x,
-c
+c2
,...)

// -------------------------------

// Look for NV_PRINTF2 calls that have __FUNCTION__ or __func__ as the first parameter
@r2 depends on rules@
constant char[] c;
expression x;
symbol __func__;
@@
NV_PRINTF2(x, c, __FUNCTION__, ...)

// Get rid of __FUNCTION__ at the beginning of the string
@script:python s2@
c << r2.c;
c2;
@@
import re
coccinelle.c2 = re.sub('%s[: ]*', '', c, 1)

@depends on rules@
expression x;
constant char[] r2.c;
identifier s2.c2;
@@
NV_PRINTF2(x,
-c, __FUNCTION__
+c2
,...);

// -------------------------------

// Look for NV_PRINTF2 calls that have __FUNCTION__ or __func__ as the last parameter
@r3 depends on rules@
constant char[] c;
expression x;
symbol __func__;
@@
NV_PRINTF2(x, c, ..., __FUNCTION__)

// Get rid of __FUNCTION__ at the end of the string
@script:python s3@
c << r3.c;
c2;
@@
import re
print 'Start'
// Find the last [: ]*%s, and remove it
pos = [i.span() for i in re.finditer('[: ]*%s', c)][-1]
coccinelle.c2 = c[:pos[0]] + c[pos[1]:]
print 'End'

@depends on rules@
expression x;
constant char[] r3.c;
identifier s3.c2;
@@
NV_PRINTF2(x,
-c
+c2
,...);

// -------------------------------

// Look for NV_PRINTF2 calls that have the function name in the string
@r4 depends on rules@
identifier func;
expression x;
constant char[] c;
@@
func(...) {
<+...
NV_PRINTF2(x, c, ...)
...+>
}

// Get rid of the function name at the beginning of the string
@script:python s4@
c << r4.c;
c2;
f << r4.func;
@@
import re
coccinelle.c2 = re.sub('"%s[: ]*' % f, '"', c, 1)

@depends on rules@
expression x;
constant char[] r4.c;
identifier s4.c2;
@@
NV_PRINTF2(x,
-c
+c2
,...);

// -------------------------------

// Remove any unnecessary braces
//@depends on rules@
//expression list x;
//@@
//-{
//NV_PRINTF2(x);
//-}

// Finally, change NV_PRINT2 to NV_PRINTF.  This has the side-effect of
// also compressing all the parameters into as few lines as possible.
@depends on rules@
expression list x;
@@
-NV_PRINTF2(x)
+NV_PRINTF(x)

[-- Attachment #3: Type: text/plain, Size: 136 bytes --]

_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

  reply	other threads:[~2018-12-05 18:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-15 20:58 [Cocci] Can the current function name be passed to a Python snippet? Timur Tabi
2018-11-15 21:29 ` Julia Lawall
2018-12-04 20:17   ` Timur Tabi
2018-12-04 20:25     ` Julia Lawall
2018-12-04 22:02       ` Timur Tabi
2018-12-04 22:19         ` Timur Tabi
2018-12-05  6:35           ` Julia Lawall
2018-12-05 17:49             ` Timur Tabi
2018-12-05 19:33               ` Julia Lawall
2018-12-05  6:34         ` Julia Lawall
2018-12-05 17:57           ` Timur Tabi
2018-12-05 18:32             ` Timur Tabi [this message]
2018-12-05 19:45               ` Julia Lawall
2018-12-05 19:11             ` Timur Tabi
2018-12-05 23:27               ` Timur Tabi
2018-12-06  6:33                 ` Julia Lawall
2018-12-05 19:32             ` Julia Lawall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOZdJXXYi=iwXuP07L2r29NmJLBUk2dyx_xU=GEz0M5xDcpd3w@mail.gmail.com' \
    --to=timur@kernel.org \
    --cc=cocci@systeme.lip6.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).