
function uno_check() {
  if (select("malloc", [FCALL]))    // unmarked symbols of type function call
  {
    if (select("", [DEF]))    // unmarked symbols DEFined in those stmnts
    {
      if (match(1, [DEF]))  // are there matching symbols with mark 1?
        error("malloc follows malloc");
      else {
        mark(1);    // mark 1
      }
    } else
      error("result of malloc unused");
  }
  else if (select("free", [FCALL]))
  {
    if (select("", [USE]))
    {
      if (match(1/*, [DEF]*/)) { // unlike uno we do not do a DFS, just statement iteration
        unmark();   // remove mark
      }
      else {
        error("free without malloc");
      }
    } else
      error("no argument to free");
  }
}

function path_end(state) {
  if (marked(1))
  {
    /*if (known_zero())
      no_error();
    else*/
      error("malloc without free");
  } // print("finished")
}
/*
void
uno_check(void)
{ // warning, named args to select() are currently not supported 

  if (select("malloc", FCALL))    // unmarked symbols of type function call
  { if (select("", DEF))    // unmarked symbols DEFined in those stmnts
    { if (match(1, DEF))  // are there matching symbols with mark 1?
        error("malloc follows malloc");
      else
        mark(1);    // mark 1
    } else
      error("result of malloc unused");
  } else

  if (select("free", FCALL))
  { if (select("", USE))
    { if (match(1, DEF))
        unmark();   // remove mark
      else
        error("free without malloc");
    } else
      error("no argument to free");
  }

  if (path_ends())
  { if (marked(1, ANY))
    { if (known_zero())
        no_error();
      else
        error("malloc without free");
  } }
}

*/
