Merge branch 'maint-0.4.6'
[tor.git] / scripts / coccinelle / ctrl-reply.cocci
blobd6e9aeedd700e4878d7a74c14f44aa054ad354e2
1 // Script to edit control_*.c for refactored control reply output functions
3 @ initialize:python @
4 @@
5 import re
6 from coccilib.report import *
8 # reply strings "NNN-foo", "NNN+foo", "NNN foo", etc.
9 r = re.compile(r'^"(\d+)([ +-])(.*)\\r\\n"$')
11 # Generate name of function to call based on which separator character
12 # comes between the numeric code and the text
13 def idname(sep, base):
14     if sep == '+':
15         return base + "datareply"
16     elif sep == '-':
17         return base + "midreply"
18     else:
19         return base + "endreply"
21 # Generate the actual replacements used by the rules
22 def gen(s, base, p):
23     pos = p[0]
24     print_report(pos, "%s %s" % (base, s))
25     m = r.match(s)
26     if m is None:
27         # String not correct format, so fail match
28         cocci.include_match(False)
29         print_report(pos, "BAD STRING %s" % s)
30         return
32     code, sep, s1 = m.groups()
34     if r'\r\n' in s1:
35         # Extra CRLF in string, so fail match
36         cocci.include_match(False)
37         print_report(pos, "extra CRLF in string %s" % s)
38         return
40     coccinelle.code = code
41     # Need a string that is a single C token, because Coccinelle only allows
42     # "identifiers" to be output from Python scripts?
43     coccinelle.body = '"%s"' % s1
44     coccinelle.id = idname(sep, base)
45     return
47 @ match @
48 identifier f;
49 position p;
50 expression E;
51 constant s;
54  connection_printf_to_buf@f@p(E, s, ...)
56  connection_write_str_to_buf@f@p(s, E)
59 @ script:python sc1 @
60 s << match.s;
61 p << match.p;
62 f << match.f;
63 id;
64 body;
65 code;
67 if f == 'connection_printf_to_buf':
68     gen(s, 'control_printf_', p)
69 elif f == 'connection_write_str_to_buf':
70     gen(s, 'control_write_', p)
71 else:
72     raise(ValueError("%s: %s" % (f, s)))
74 @ replace @
75 constant match.s;
76 expression match.E;
77 identifier match.f;
78 identifier sc1.body, sc1.id, sc1.code;
81 -connection_write_str_to_buf@f(s, E)
82 +id(E, code, body)
84 -connection_printf_to_buf@f(E, s
85 +id(E, code, body
86  , ...)