tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

ctrl-reply.cocci (1961B)


      1 // Script to edit control_*.c for refactored control reply output functions
      2 
      3 @ initialize:python @
      4 @@
      5 import re
      6 from coccilib.report import *
      7 
      8 # reply strings "NNN-foo", "NNN+foo", "NNN foo", etc.
      9 r = re.compile(r'^"(\d+)([ +-])(.*)\\r\\n"$')
     10 
     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"
     20 
     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
     31 
     32     code, sep, s1 = m.groups()
     33 
     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
     39 
     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
     46 
     47 @ match @
     48 identifier f;
     49 position p;
     50 expression E;
     51 constant s;
     52 @@
     53 (
     54  connection_printf_to_buf@f@p(E, s, ...)
     55 |
     56  connection_write_str_to_buf@f@p(s, E)
     57 )
     58 
     59 @ script:python sc1 @
     60 s << match.s;
     61 p << match.p;
     62 f << match.f;
     63 id;
     64 body;
     65 code;
     66 @@
     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)))
     73 
     74 @ replace @
     75 constant match.s;
     76 expression match.E;
     77 identifier match.f;
     78 identifier sc1.body, sc1.id, sc1.code;
     79 @@
     80 (
     81 -connection_write_str_to_buf@f(s, E)
     82 +id(E, code, body)
     83 |
     84 -connection_printf_to_buf@f(E, s
     85 +id(E, code, body
     86  , ...)
     87 )