// category 1 should only have a NULL test

@def0@ // save the file name, run with -no_includes
expression x;
@@

x = FN(...)

// -----------------------------------------------------------------------

@protected using "../likely.iso", "../if.iso" disable and_comm, or_comm @
identifier fld;
position p,p1;
statement S;
expression def0.x,E,E1,E2;
iterator I;
@@

(
if (@p1(x != NULL)&&...) { <... x@p->fld ...> } else S
|
 ((x != NULL)&&...) ?@p1 <+... x@p->fld ...+> : E
|
 ((x != NULL)&&...) ?@p1 E1 : E2
|
 I(x,...) { <... x@p->fld ...> }
)

@andprotected using "../likely.iso", "../iftwo.iso" @
identifier fld;
position p,protected.p1;
statement S1,S2;
expression def0.x,E1,E2;
@@ // pb with associativity of && ||, so can't say X&&<+...E...+>

(
 if (@p1<+...x@p->fld...+>) S1 else S2
|
 (<+...x@p->fld...+>) ?@p1 E1 : E2
)

@opprotected using "../likely.iso"@
identifier fld;
position p;
expression def0.x;
@@

(
 sizeof(<+... x@p->fld ...+>)
|
 BUG_ON(<+... x@p->fld ...+>)
|
 (x != NULL)&&<+...x@p->fld...+>
|
 (x == NULL)||<+...x@p->fld...+>
)

@call using "../if.iso" @
position p1;
statement S1,S2;
expression def0.x,E1,E2;
@@

(
if (<+... x = FN(...) ...+>) S1 else S2
|
 (<+...x = FN(...)...+>) ? E1 : E2
|
x@p1 = FN(...)
)

@unprotected using "../likely.iso", "../if.iso" disable and_comm, or_comm exists@
identifier fld, fld1, l;
position p != {protected.p,andprotected.p,opprotected.p};
position call.p1;
statement S;
expression def0.x,E,E1;
@@

 x@p1 = FN(...)
  ... when != x = E
      when != &x
      when != x->fld1
(
  BUG_ON((x == NULL)||...);
|
  if ((x == NULL)||...) {
  ... when forall
  \(return ...; \| goto l; \| break; \| continue; \| panic(...); \| BUG(...);\)
  } else S
|
  if ((x == NULL)||...) {
    ... when any,forall
    \(x = E1\|&x\)
    ... when any,forall
  } else S
|
  while ((x == NULL)||...) S
|
  x@p->fld
)

@ script:python @
p << unprotected.p; // position of ref
p1 << call.p1; // position of call
fld << unprotected.fld; // identifier
@@

print "* TODO [[view:%s::face=ovl-face1::linb=%s::colb=%s::cole=%s][%s::%s]]" % (p1[0].file,p1[0].line,p1[0].column,p1[0].column_end,p1[0].file,p1[0].line)
print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][ref to field %s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,fld)
print "call to FN, ref to %s" % fld