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