162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/// Detect BQ27XXX_DATA structures with identical registers, dm registers or
362306a36Sopenharmony_ci/// properties.
462306a36Sopenharmony_ci//# Doesn't unfold macros used in register or property fields.
562306a36Sopenharmony_ci//# Requires OCaml scripting
662306a36Sopenharmony_ci///
762306a36Sopenharmony_ci// Confidence: High
862306a36Sopenharmony_ci// Copyright: (C) 2017 Julia Lawall, Inria/LIP6,
962306a36Sopenharmony_ci// URL: https://coccinelle.gitlabpages.inria.fr/website
1062306a36Sopenharmony_ci// Requires: 1.0.7
1162306a36Sopenharmony_ci// Keywords: BQ27XXX_DATA
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_civirtual report
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci@initialize:ocaml@
1662306a36Sopenharmony_ci@@
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cilet print_report p msg =
1962306a36Sopenharmony_ci  let p = List.hd p in
2062306a36Sopenharmony_ci  Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci@str depends on report@
2362306a36Sopenharmony_citype t;
2462306a36Sopenharmony_ciidentifier i,i1,i2;
2562306a36Sopenharmony_ciexpression e1,e2;
2662306a36Sopenharmony_ci@@
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cit i[] = {
2962306a36Sopenharmony_ci  ...,
3062306a36Sopenharmony_ci  [e1] = BQ27XXX_DATA(i1,...),
3162306a36Sopenharmony_ci  ...,
3262306a36Sopenharmony_ci  [e2] = BQ27XXX_DATA(i2,...),
3362306a36Sopenharmony_ci  ...,
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci@script:ocaml tocheck@
3762306a36Sopenharmony_cii1 << str.i1;
3862306a36Sopenharmony_cii2 << str.i2;
3962306a36Sopenharmony_cii1regs; i2regs;
4062306a36Sopenharmony_cii1dmregs; i2dmregs;
4162306a36Sopenharmony_cii1props; i2props;
4262306a36Sopenharmony_ci@@
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciif not(i1 = i2)
4562306a36Sopenharmony_cithen
4662306a36Sopenharmony_ci  begin
4762306a36Sopenharmony_ci    i1regs := make_ident (i1 ^ "_regs");
4862306a36Sopenharmony_ci    i2regs := make_ident (i2 ^ "_regs");
4962306a36Sopenharmony_ci    i1dmregs := make_ident (i1 ^ "_dm_regs");
5062306a36Sopenharmony_ci    i2dmregs := make_ident (i2 ^ "_dm_regs");
5162306a36Sopenharmony_ci    i1props := make_ident (i1 ^ "_props");
5262306a36Sopenharmony_ci    i2props := make_ident (i2 ^ "_props")
5362306a36Sopenharmony_ci  end
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci(* ---------------------------------------------------------------- *)
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci@getregs1@
5862306a36Sopenharmony_citypedef u8;
5962306a36Sopenharmony_ciidentifier tocheck.i1regs;
6062306a36Sopenharmony_ciinitializer list i1regs_vals;
6162306a36Sopenharmony_ciposition p1;
6262306a36Sopenharmony_ci@@
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciu8 i1regs@p1[...] = { i1regs_vals, };
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci@getregs2@
6762306a36Sopenharmony_ciidentifier tocheck.i2regs;
6862306a36Sopenharmony_ciinitializer list i2regs_vals;
6962306a36Sopenharmony_ciposition p2;
7062306a36Sopenharmony_ci@@
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciu8 i2regs@p2[...] = { i2regs_vals, };
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci@script:ocaml@
7562306a36Sopenharmony_ci(_,i1regs_vals) << getregs1.i1regs_vals;
7662306a36Sopenharmony_ci(_,i2regs_vals) << getregs2.i2regs_vals;
7762306a36Sopenharmony_cii1regs << tocheck.i1regs;
7862306a36Sopenharmony_cii2regs << tocheck.i2regs;
7962306a36Sopenharmony_cip1 << getregs1.p1;
8062306a36Sopenharmony_cip2 << getregs2.p2;
8162306a36Sopenharmony_ci@@
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciif i1regs < i2regs &&
8462306a36Sopenharmony_ci   List.sort compare i1regs_vals = List.sort compare i2regs_vals
8562306a36Sopenharmony_cithen
8662306a36Sopenharmony_ci  let msg =
8762306a36Sopenharmony_ci    Printf.sprintf
8862306a36Sopenharmony_ci      "WARNING %s and %s (line %d) are identical\n"
8962306a36Sopenharmony_ci      i1regs i2regs (List.hd p2).line in
9062306a36Sopenharmony_ci  print_report p1 msg
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci(* ---------------------------------------------------------------- *)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci@getdmregs1@
9562306a36Sopenharmony_ciidentifier tocheck.i1dmregs;
9662306a36Sopenharmony_ciinitializer list i1dmregs_vals;
9762306a36Sopenharmony_ciposition p1;
9862306a36Sopenharmony_ci@@
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistruct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, };
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci@getdmregs2@
10362306a36Sopenharmony_ciidentifier tocheck.i2dmregs;
10462306a36Sopenharmony_ciinitializer list i2dmregs_vals;
10562306a36Sopenharmony_ciposition p2;
10662306a36Sopenharmony_ci@@
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistruct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, };
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci@script:ocaml@
11162306a36Sopenharmony_ci(_,i1dmregs_vals) << getdmregs1.i1dmregs_vals;
11262306a36Sopenharmony_ci(_,i2dmregs_vals) << getdmregs2.i2dmregs_vals;
11362306a36Sopenharmony_cii1dmregs << tocheck.i1dmregs;
11462306a36Sopenharmony_cii2dmregs << tocheck.i2dmregs;
11562306a36Sopenharmony_cip1 << getdmregs1.p1;
11662306a36Sopenharmony_cip2 << getdmregs2.p2;
11762306a36Sopenharmony_ci@@
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciif i1dmregs < i2dmregs &&
12062306a36Sopenharmony_ci   List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals
12162306a36Sopenharmony_cithen
12262306a36Sopenharmony_ci  let msg =
12362306a36Sopenharmony_ci    Printf.sprintf
12462306a36Sopenharmony_ci      "WARNING %s and %s (line %d) are identical\n"
12562306a36Sopenharmony_ci      i1dmregs i2dmregs (List.hd p2).line in
12662306a36Sopenharmony_ci  print_report p1 msg
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci(* ---------------------------------------------------------------- *)
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci@getprops1@
13162306a36Sopenharmony_ciidentifier tocheck.i1props;
13262306a36Sopenharmony_ciinitializer list[n1] i1props_vals;
13362306a36Sopenharmony_ciposition p1;
13462306a36Sopenharmony_ci@@
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cienum power_supply_property i1props@p1[] = { i1props_vals, };
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci@getprops2@
13962306a36Sopenharmony_ciidentifier tocheck.i2props;
14062306a36Sopenharmony_ciinitializer list[n2] i2props_vals;
14162306a36Sopenharmony_ciposition p2;
14262306a36Sopenharmony_ci@@
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cienum power_supply_property i2props@p2[] = { i2props_vals, };
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci@script:ocaml@
14762306a36Sopenharmony_ci(_,i1props_vals) << getprops1.i1props_vals;
14862306a36Sopenharmony_ci(_,i2props_vals) << getprops2.i2props_vals;
14962306a36Sopenharmony_cii1props << tocheck.i1props;
15062306a36Sopenharmony_cii2props << tocheck.i2props;
15162306a36Sopenharmony_cip1 << getprops1.p1;
15262306a36Sopenharmony_cip2 << getprops2.p2;
15362306a36Sopenharmony_ci@@
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ciif i1props < i2props &&
15662306a36Sopenharmony_ci   List.sort compare i1props_vals = List.sort compare i2props_vals
15762306a36Sopenharmony_cithen
15862306a36Sopenharmony_ci  let msg =
15962306a36Sopenharmony_ci    Printf.sprintf
16062306a36Sopenharmony_ci      "WARNING %s and %s (line %d) are identical\n"
16162306a36Sopenharmony_ci      i1props i2props (List.hd p2).line in
16262306a36Sopenharmony_ci  print_report p1 msg
163