On Thu, Aug 31, 2017 at 04:09:30PM +0200, Julia Lawall wrote:
> The problem is in the rule shortcut_replace.  You have:
> 
> [...]
> 
> There are three case (1, 2, and 3).  Normally a disjunction like this
> matches from top to bottom, ie if the first case matches the ohers are not
> considered.  Here however the patterns don' all start matching at the same
> node.  The first two do, ie at an {, but the third does not.  So the third
> will match over top of what was matched by the previous ones.  So there
> will b multiple matches, and Coccinelle would prefer to do nothing rather
> than to do something inconsistent.
> 
> As far as I can see, there is no real difference between the cases.  It
> could probably be easier to just put the third case, and then have some
> other rules to clean up any kinds of {} that occur.

Yes, that has worked quite well actually. It has caused one problem,
though, splitting it up has made coccinelle strip curly brackets all
over the place, which is a bit problematic in places like this:

if (...) {
    /* comment */
    Debug( ... );
}

turning it into something very hard to read, especially if there is an
else branch:

if (...)
    /* comment */
    Debug( ... );

So far, nothing I've tried has helped limiting this, those include:
- pinning it on "+Debug@p3" which coccinelle rejects.
- using the below, probably because of your observation above
(
 if (...) {
     Debug(...);
 }
|
-{
 Debug(...);
-}
)
- the above but splitting that in two rules and a remembered location

The current patch I'm using is:
-----8<------
@initialize:python@
@@

#regex from 
https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
import re
fmtstring = '''\
(                                  # start of capture group 1
%                                  # literal "%"
(?:                                # first option
(?:[-+0 #]{0,5})                   # optional flags
(?:\d+|\*)?                        # width
(?:\.(?:\d+|\*))?                  # precision
(?:h|l|ll|w|I|I32|I64)?            # size
[cCdiouxXeEfgGaAnpsSZ]             # type
) |                                # OR
%%)                                # literal "%%"
'''

regex = re.compile(fmtstring, re.X)

def parse_format(f):
    return tuple((m.span(), m.group()) for m in
        regex.finditer(f))

def insert_at_pos(fmt, s, pos):
    formats = parse_format(fmt)
    span, format = formats[pos]
    acc = fmt[:span[0]]
    if s.startswith('"'):
        acc += s[1:]
    else:
        acc += '" '
        acc += s
    if acc.endswith('"'):
        acc = acc[:-1] + fmt[span[1]:]
    else:
        acc += ' "'
        acc += fmt[span[1]:]
    return acc

// covered by others but processing that can take hours on some files
@shortcut@
identifier buf;
expression E, L;
expression list args_before, args, args_after;
expression format1, format2;
position p1, p2;
@@

snprintf@p1( buf, E, format1, args );
Debug@p2( L, format2, args_before, buf, args_after );

@script:python shortcut_process@
format1 << shortcut.format1;
format2 << shortcut.format2;
args_before << shortcut.args_before;
merged;
@@

pos = len(args_before.elements)
coccinelle.merged = insert_at_pos(format2, format1, pos)

@shortcut_replace@
position shortcut.p1, shortcut.p2;
identifier shortcut_process.merged;

identifier buf;
expression E, L;
expression list args_before, args, args_after;
expression format1, format2;
@@

-snprintf@p1( buf, E, format1, args );
-Debug@p2( L, format2, args_before, buf, args_after );
+Debug( L, merged, args_before, args, args_after );

@@
type T;
initializer I;
@@
{
-\( T buf = I; \| T buf; \)
 Debug( ... );
}

@@
@@
-{
 Debug( ... );
-}

@useless_if@
expression L;
@@

-if ( LogTest( L ) ) {
 Debug( L, ... );
-}
-----8<------

> I think that it should also be possible to define a metavariable
> 
> initializer i;
> 
> And then replace
> 
> T buf = {...}; \| T buf = I;
> 
> by T buf = i;

That does work, thanks.

-- 
Ondřej Kuzník
Senior Software Engineer
Symas Corporation                       http://www.symas.com
Packaged, certified, and supported LDAP solutions powered by OpenLDAP
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

Reply via email to