mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
88 lines
1.9 KiB
Plaintext
88 lines
1.9 KiB
Plaintext
|
// Script to edit control_*.c for refactored control reply output functions
|
||
|
|
||
|
@ initialize:python @
|
||
|
@@
|
||
|
import re
|
||
|
from coccilib.report import *
|
||
|
|
||
|
# reply strings "NNN-foo", "NNN+foo", "NNN foo", etc.
|
||
|
r = re.compile(r'^"(\d+)([ +-])(.*)\\r\\n"$')
|
||
|
|
||
|
# Generate name of function to call based on which separator character
|
||
|
# comes between the numeric code and the text
|
||
|
def idname(sep, base):
|
||
|
if sep == '+':
|
||
|
return base + "datareply"
|
||
|
elif sep == '-':
|
||
|
return base + "midreply"
|
||
|
else:
|
||
|
return base + "endreply"
|
||
|
|
||
|
# Generate the actual replacements used by the rules
|
||
|
def gen(s, base, p):
|
||
|
pos = p[0]
|
||
|
print_report(pos, "%s %s" % (base, s))
|
||
|
m = r.match(s)
|
||
|
if m is None:
|
||
|
# String not correct format, so fail match
|
||
|
cocci.include_match(False)
|
||
|
print_report(pos, "BAD STRING %s" % s)
|
||
|
return
|
||
|
|
||
|
code, sep, s1 = m.groups()
|
||
|
|
||
|
if r'\r\n' in s1:
|
||
|
# Extra CRLF in string, so fail match
|
||
|
cocci.include_match(False)
|
||
|
print_report(pos, "extra CRLF in string %s" % s)
|
||
|
return
|
||
|
|
||
|
coccinelle.code = code
|
||
|
# Need a string that is a single C token, because Coccinelle only allows
|
||
|
# "identifiers" to be output from Python scripts?
|
||
|
coccinelle.body = '"%s"' % s1
|
||
|
coccinelle.id = idname(sep, base)
|
||
|
return
|
||
|
|
||
|
@ match @
|
||
|
identifier f;
|
||
|
position p;
|
||
|
expression E;
|
||
|
constant s;
|
||
|
@@
|
||
|
(
|
||
|
connection_printf_to_buf@f@p(E, s, ...)
|
||
|
|
|
||
|
connection_write_str_to_buf@f@p(s, E)
|
||
|
)
|
||
|
|
||
|
@ script:python sc1 @
|
||
|
s << match.s;
|
||
|
p << match.p;
|
||
|
f << match.f;
|
||
|
id;
|
||
|
body;
|
||
|
code;
|
||
|
@@
|
||
|
if f == 'connection_printf_to_buf':
|
||
|
gen(s, 'control_printf_', p)
|
||
|
elif f == 'connection_write_str_to_buf':
|
||
|
gen(s, 'control_write_', p)
|
||
|
else:
|
||
|
raise(ValueError("%s: %s" % (f, s)))
|
||
|
|
||
|
@ replace @
|
||
|
constant match.s;
|
||
|
expression match.E;
|
||
|
identifier match.f;
|
||
|
identifier sc1.body, sc1.id, sc1.code;
|
||
|
@@
|
||
|
(
|
||
|
-connection_write_str_to_buf@f(s, E)
|
||
|
+id(E, code, body)
|
||
|
|
|
||
|
-connection_printf_to_buf@f(E, s
|
||
|
+id(E, code, body
|
||
|
, ...)
|
||
|
)
|