aboutsummaryrefslogtreecommitdiff
path: root/scripts/coccinelle/ctrl-reply.cocci
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/coccinelle/ctrl-reply.cocci')
-rw-r--r--scripts/coccinelle/ctrl-reply.cocci87
1 files changed, 87 insertions, 0 deletions
diff --git a/scripts/coccinelle/ctrl-reply.cocci b/scripts/coccinelle/ctrl-reply.cocci
new file mode 100644
index 0000000000..d6e9aeedd7
--- /dev/null
+++ b/scripts/coccinelle/ctrl-reply.cocci
@@ -0,0 +1,87 @@
+// 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
+ , ...)
+)