ctrl-reply.cocci 1.9 KB

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