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 12virtual report 13 14@initialize:ocaml@ 15@@ 16 17let print_report p msg = 18 let p = List.hd p in 19 Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg 20 21@str depends on report@ 22type t; 23identifier i,i1,i2; 24expression e1,e2; 25@@ 26 27t i[] = { 28 ..., 29 [e1] = BQ27XXX_DATA(i1,...), 30 ..., 31 [e2] = BQ27XXX_DATA(i2,...), 32 ..., 33}; 34 35@script:ocaml tocheck@ 36i1 << str.i1; 37i2 << str.i2; 38i1regs; i2regs; 39i1dmregs; i2dmregs; 40i1props; i2props; 41@@ 42 43if not(i1 = i2) 44then 45 begin 46 i1regs := make_ident (i1 ^ "_regs"); 47 i2regs := make_ident (i2 ^ "_regs"); 48 i1dmregs := make_ident (i1 ^ "_dm_regs"); 49 i2dmregs := make_ident (i2 ^ "_dm_regs"); 50 i1props := make_ident (i1 ^ "_props"); 51 i2props := make_ident (i2 ^ "_props") 52 end 53 54(* ---------------------------------------------------------------- *) 55 56@getregs1@ 57typedef u8; 58identifier tocheck.i1regs; 59initializer list i1regs_vals; 60position p1; 61@@ 62 63u8 i1regs@p1[...] = { i1regs_vals, }; 64 65@getregs2@ 66identifier tocheck.i2regs; 67initializer list i2regs_vals; 68position p2; 69@@ 70 71u8 i2regs@p2[...] = { i2regs_vals, }; 72 73@script:ocaml@ 74(_,i1regs_vals) << getregs1.i1regs_vals; 75(_,i2regs_vals) << getregs2.i2regs_vals; 76i1regs << tocheck.i1regs; 77i2regs << tocheck.i2regs; 78p1 << getregs1.p1; 79p2 << getregs2.p2; 80@@ 81 82if i1regs < i2regs && 83 List.sort compare i1regs_vals = List.sort compare i2regs_vals 84then 85 let msg = 86 Printf.sprintf 87 "WARNING %s and %s (line %d) are identical\n" 88 i1regs i2regs (List.hd p2).line in 89 print_report p1 msg 90 91(* ---------------------------------------------------------------- *) 92 93@getdmregs1@ 94identifier tocheck.i1dmregs; 95initializer list i1dmregs_vals; 96position p1; 97@@ 98 99struct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, }; 100 101@getdmregs2@ 102identifier tocheck.i2dmregs; 103initializer list i2dmregs_vals; 104position p2; 105@@ 106 107struct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, }; 108 109@script:ocaml@ 110(_,i1dmregs_vals) << getdmregs1.i1dmregs_vals; 111(_,i2dmregs_vals) << getdmregs2.i2dmregs_vals; 112i1dmregs << tocheck.i1dmregs; 113i2dmregs << tocheck.i2dmregs; 114p1 << getdmregs1.p1; 115p2 << getdmregs2.p2; 116@@ 117 118if i1dmregs < i2dmregs && 119 List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals 120then 121 let msg = 122 Printf.sprintf 123 "WARNING %s and %s (line %d) are identical\n" 124 i1dmregs i2dmregs (List.hd p2).line in 125 print_report p1 msg 126 127(* ---------------------------------------------------------------- *) 128 129@getprops1@ 130identifier tocheck.i1props; 131initializer list[n1] i1props_vals; 132position p1; 133@@ 134 135enum power_supply_property i1props@p1[] = { i1props_vals, }; 136 137@getprops2@ 138identifier tocheck.i2props; 139initializer list[n2] i2props_vals; 140position p2; 141@@ 142 143enum power_supply_property i2props@p2[] = { i2props_vals, }; 144 145@script:ocaml@ 146(_,i1props_vals) << getprops1.i1props_vals; 147(_,i2props_vals) << getprops2.i2props_vals; 148i1props << tocheck.i1props; 149i2props << tocheck.i2props; 150p1 << getprops1.p1; 151p2 << getprops2.p2; 152@@ 153 154if i1props < i2props && 155 List.sort compare i1props_vals = List.sort compare i2props_vals 156then 157 let msg = 158 Printf.sprintf 159 "WARNING %s and %s (line %d) are identical\n" 160 i1props i2props (List.hd p2).line in 161 print_report p1 msg 162