check_bq27xxx_data.cocci 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /// Detect BQ27XXX_DATA structures with identical registers, dm registers or
  2. /// properties.
  3. //# Doesn't unfold macros used in register or property fields.
  4. //# Requires OCaml scripting
  5. ///
  6. // Confidence: High
  7. // Copyright: (C) 2017 Julia Lawall, Inria/LIP6, GPLv2.
  8. // URL: http://coccinelle.lip6.fr/
  9. // Requires: 1.0.7
  10. // Keywords: BQ27XXX_DATA
  11. virtual report
  12. @initialize:ocaml@
  13. @@
  14. let print_report p msg =
  15. let p = List.hd p in
  16. Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg
  17. @str depends on report@
  18. type t;
  19. identifier i,i1,i2;
  20. expression e1,e2;
  21. @@
  22. t i[] = {
  23. ...,
  24. [e1] = BQ27XXX_DATA(i1,...),
  25. ...,
  26. [e2] = BQ27XXX_DATA(i2,...),
  27. ...,
  28. };
  29. @script:ocaml tocheck@
  30. i1 << str.i1;
  31. i2 << str.i2;
  32. i1regs; i2regs;
  33. i1dmregs; i2dmregs;
  34. i1props; i2props;
  35. @@
  36. if not(i1 = i2)
  37. then
  38. begin
  39. i1regs := make_ident (i1 ^ "_regs");
  40. i2regs := make_ident (i2 ^ "_regs");
  41. i1dmregs := make_ident (i1 ^ "_dm_regs");
  42. i2dmregs := make_ident (i2 ^ "_dm_regs");
  43. i1props := make_ident (i1 ^ "_props");
  44. i2props := make_ident (i2 ^ "_props")
  45. end
  46. (* ---------------------------------------------------------------- *)
  47. @getregs1@
  48. typedef u8;
  49. identifier tocheck.i1regs;
  50. initializer list i1regs_vals;
  51. position p1;
  52. @@
  53. u8 i1regs@p1[...] = { i1regs_vals, };
  54. @getregs2@
  55. identifier tocheck.i2regs;
  56. initializer list i2regs_vals;
  57. position p2;
  58. @@
  59. u8 i2regs@p2[...] = { i2regs_vals, };
  60. @script:ocaml@
  61. (_,i1regs_vals) << getregs1.i1regs_vals;
  62. (_,i2regs_vals) << getregs2.i2regs_vals;
  63. i1regs << tocheck.i1regs;
  64. i2regs << tocheck.i2regs;
  65. p1 << getregs1.p1;
  66. p2 << getregs2.p2;
  67. @@
  68. if i1regs < i2regs &&
  69. List.sort compare i1regs_vals = List.sort compare i2regs_vals
  70. then
  71. let msg =
  72. Printf.sprintf
  73. "WARNING %s and %s (line %d) are identical\n"
  74. i1regs i2regs (List.hd p2).line in
  75. print_report p1 msg
  76. (* ---------------------------------------------------------------- *)
  77. @getdmregs1@
  78. identifier tocheck.i1dmregs;
  79. initializer list i1dmregs_vals;
  80. position p1;
  81. @@
  82. struct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, };
  83. @getdmregs2@
  84. identifier tocheck.i2dmregs;
  85. initializer list i2dmregs_vals;
  86. position p2;
  87. @@
  88. struct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, };
  89. @script:ocaml@
  90. (_,i1dmregs_vals) << getdmregs1.i1dmregs_vals;
  91. (_,i2dmregs_vals) << getdmregs2.i2dmregs_vals;
  92. i1dmregs << tocheck.i1dmregs;
  93. i2dmregs << tocheck.i2dmregs;
  94. p1 << getdmregs1.p1;
  95. p2 << getdmregs2.p2;
  96. @@
  97. if i1dmregs < i2dmregs &&
  98. List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals
  99. then
  100. let msg =
  101. Printf.sprintf
  102. "WARNING %s and %s (line %d) are identical\n"
  103. i1dmregs i2dmregs (List.hd p2).line in
  104. print_report p1 msg
  105. (* ---------------------------------------------------------------- *)
  106. @getprops1@
  107. identifier tocheck.i1props;
  108. initializer list[n1] i1props_vals;
  109. position p1;
  110. @@
  111. enum power_supply_property i1props@p1[] = { i1props_vals, };
  112. @getprops2@
  113. identifier tocheck.i2props;
  114. initializer list[n2] i2props_vals;
  115. position p2;
  116. @@
  117. enum power_supply_property i2props@p2[] = { i2props_vals, };
  118. @script:ocaml@
  119. (_,i1props_vals) << getprops1.i1props_vals;
  120. (_,i2props_vals) << getprops2.i2props_vals;
  121. i1props << tocheck.i1props;
  122. i2props << tocheck.i2props;
  123. p1 << getprops1.p1;
  124. p2 << getprops2.p2;
  125. @@
  126. if i1props < i2props &&
  127. List.sort compare i1props_vals = List.sort compare i2props_vals
  128. then
  129. let msg =
  130. Printf.sprintf
  131. "WARNING %s and %s (line %d) are identical\n"
  132. i1props i2props (List.hd p2).line in
  133. print_report p1 msg