<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "conf.hh"
#include "dparse.h"
#include "helper.hh"
#include "history.hh"
#include <cstring>

#ifndef DROI
#include <glib.h>
#else

#endif

class EndHook;
#include "endhook.hh"
extern "C" {
  extern D_ParserTables parser_tables_conf;
}

extern Conf* conf_obj;
#define RETURN_ERROR_VOID(s) {                  \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    return;                                     \
  }

#define RETURN_ERROR_VERDICT(s) {               \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    exit_status=-1;                             \
    return Verdict::ERROR;                      \
  }

void Conf::load(std::string& name,std::string& content)
{
  D_Parser *p = new_D_Parser(&parser_tables_conf, 512);
  p->loc.pathname = name.c_str();
  char *s;

  Conf* tmp=conf_obj;
  log.push("conf_load");
  log.debug("Conf::load %s",name.c_str());
  conf_obj=this;

  s=readfile(name.c_str());

  if (s==NULL) {
    status=false;
    errormsg=std::string("Can't read configuration file \"")+name+"\"";
    log.pop();
    free_D_Parser(p);
    return;
  }

  std::string ss(s);
  ss=ss+"\n"+content;
  if ((name!="" && s==NULL))
    RETURN_ERROR_VOID("Loading \"" + name + "\" failed.");

  if (ss=="")
    RETURN_ERROR_VOID("Empty configuration");

  bool ret=dparse(p,(char*)ss.c_str(),std::strlen(ss.c_str()));

  ret=p->syntax_errors==0 && ret;

  if (!ret)
    RETURN_ERROR_VOID("Parsing \"" + name + "\" failed.");

  free(s);

  free_D_Parser(p);

  conf_obj=tmp;

  if ((heuristic=new_heuristic(log,heuristic_name)) == NULL)
    RETURN_ERROR_VOID("Creating heuristic \"" + heuristic_name + "\" failed.");

  if (heuristic->status==false)
    RETURN_ERROR_VOID("Error in heuristic \"" + heuristic_name + "\":" +
                      heuristic->errormsg);

  if ((model=new_model(log, model_name)) == NULL) {
    RETURN_ERROR_VOID("Creating model \"" +
                      filetype(model_name)
                      + "\" failed.");
  }

  coverage = new_coverage(log,coverage_name);

  if (coverage == NULL)
    RETURN_ERROR_VOID("Creating coverage \"" + coverage_name + "\" failed.");

  if (!coverage->status)
    RETURN_ERROR_VOID("Error in coverage \"" + coverage_name + "\": " + coverage->errormsg);

  if (!model->status || !model->init() || !model->reset())
    RETURN_ERROR_VOID("Error in model: " + model->stringify());

  heuristic->set_coverage(coverage);

  heuristic->set_model(model);

  coverage->set_model(model);

  adapter = new_adapter(log, adapter_name);

  if (adapter == NULL)
    RETURN_ERROR_VOID("Creating adapter \"" + adapter_name + "\" failed.");

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  adapter->set_tags(&model->getSPNames());

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  // Parse adapter-tags filter (if any)
  for(unsigned i=0;i<disable_tags.size();i++) {
    std::vector<std::string>& tags=model->getSPNames();
    std::vector<std::string> f;
    commalist(disable_tags[i],f);
    std::vector<int> tmp;
    find(tags,f,tmp);
    for(unsigned i=0;i<tags.size();i++) {
      if (std::find(tmp.begin(),tmp.end(),i)==tmp.end()) {
	disabled_tags[i]=true;
      }
    }

  }

  // Free some memory.
  disable_tags.clear();

  /* handle history */
  for(unsigned i=0;i<history.size();i++) {
    History* h=new_history(log,*history[i]);

    if (h) {
      h->set_coverage(coverage,model);
      if (!h->status) {
        RETURN_ERROR_VOID(h->errormsg);
      }
    } else {
      RETURN_ERROR_VOID("Creating history \""+ *history[i] + "\" failed.");
    }
  }

  adapter->set_actions(&model->getActionNames());

  if (!coverage->status)
    RETURN_ERROR_VOID("Coverage error: " + coverage->stringify());

  if (!adapter->status)
    RETURN_ERROR_VOID("Adapter error: " + adapter->stringify());

  log.pop();
}

void Conf::disable_tagchecking(std::string& s) {
  disable_tags.push_back(s);
}

#include <sstream>

std::string Conf::stringify() {
  std::ostringstream t(std::ios::out | std::ios::binary);

  if (!status) {
    return errormsg;
  }

  t << "model = \"" << removehash(model_name) << capsulate(model->stringify()) << std::endl;
  t << "heuristic = \"" << heuristic_name << "\"" << std::endl;
  t << "coverage = \"" <<  coverage_name << "\"" << std::endl;
  t << "adapter = \"" << adapter_name
    << capsulate(adapter->stringify()) << std::endl;

  // end conditions
  for(size_t i=0;i<end_conditions.size();i++) {
    t << end_conditions[i]->stringify() << std::endl;
  }

  // exit-hooks
  stringify_hooks(t,pass_hooks ,"on_pass"  );
  stringify_hooks(t,fail_hooks ,"on_fail"  );
  stringify_hooks(t,inc_hooks  ,"on_inconc");
  stringify_hooks(t,error_hooks,"on_error" );

  return t.str();
}

Verdict::Verdict Conf::execute(bool interactive) {

  Policy policy;
  log.push("conf_execute");

  if (!status) {
    errormsg = "cannot start executing test due to earlier errors: " + errormsg;
    return Verdict::ERROR;
  }

  if (!adapter->init())
    RETURN_ERROR_VERDICT("Initialising adapter failed: " + adapter->stringify());

  // Validate and finish existing end_conditions
  {
    bool end_by_tagverify = false;
    bool end_by_coverage = false;
    for (unsigned int i = 0; i < end_conditions.size(); i++) {
      End_condition* e = end_conditions[i];
      if (e->status == false)
        RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
      if (e->counter == End_condition::ACTION) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getActionNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::STATETAG) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getSPNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::TAGVERIFY) {
        end_by_tagverify = true;
	((End_condition_tagverify*) e)
	  ->evaluate_filter(model->getSPNames());
      }
      if (e->counter == End_condition::COVERAGE) {
        end_by_coverage = true;
      }
      if (e->counter == End_condition::DURATION) {
        end_time = e->param_time;
      }
    }
    // Add default end conditions (if coverage is reached, test is passed)
    if (!end_by_coverage) {
      end_conditions.push_back(new End_condition_coverage(Verdict::PASS, "1.0"));
    }
    if (!end_by_tagverify && !disable_tagverify) {
      end_conditions.push_back(new End_condition_tagverify(Verdict::FAIL, ""));
    }
  }

  Test_engine engine(*heuristic,*adapter,log,policy,end_conditions,disabled_tags);

  if (interactive) {
    engine.interactive();
  } else {
    Verdict::Verdict v = engine.run(end_time,disable_tagverify);

    if (!heuristic->status) {
      fprintf(stderr,"heuristic error: %s\n",heuristic->errormsg.c_str());
    }

    if (!model->status) {
      fprintf(stderr,"model error: %s\n",model->errormsg.c_str());
    }

    if (!adapter->status) {
      fprintf(stderr,"adapter error: %s\n",adapter->errormsg.c_str());
    }

    if (!coverage->status) {
      fprintf(stderr,"coverage error: %s\n",coverage->errormsg.c_str());
    }
    handle_hooks(v);
  }
  log.pop();
  status = true;
  errormsg = engine.verdict_msg() + ": " + engine.reason_msg();

  if (adapter->status) {
    adapter->adapter_exit(engine.verdict(),engine.reason_msg());
  }

  return engine.verdict();
}

void Conf::handle_hooks(Verdict::Verdict v)
{
  std::list<EndHook*>* hooklist=NULL;

  switch (v) {
  case Verdict::FAIL: {
    hooklist=&fail_hooks;
    break;
  }
  case Verdict::PASS: {
    hooklist=&pass_hooks;
    break;
  }
  case Verdict::INCONCLUSIVE: {
    hooklist=&inc_hooks;
    break;
  }
  case Verdict::ERROR: {
    hooklist=&error_hooks;
    break;
  }
  case Verdict::NOTIFY: {
    abort();
    break;
  }
  default: {
    // unknown verdict?
  }
  }
  if (hooklist)
    for_each(hooklist->begin(),hooklist->end(),hook_runner);
}

void Conf::set_observe_sleep(std::string &s)
{
  Adapter::sleeptime=atoi(s.c_str());
}

void Conf::add_end_condition(Verdict::Verdict v,std::string& s)

{
  End_condition *ec = new_end_condition(v,s);

  if (ec==NULL) {
    status=false;
    errormsg=errormsg+"Creating end condition \""+s+"\" failed.\n";
  } else {
    add_end_condition(ec);
  }
}

void hook_delete(EndHook* e);

Conf::~Conf() {
  for (unsigned int i = 0; i < end_conditions.size(); i++)
    delete end_conditions[i];
  log.pop();
  if (heuristic)
    delete heuristic;

  if (adapter)
    delete adapter;

  if (model)
    delete model;

  if (coverage)
    delete coverage;

  adapter=NULL;
  heuristic=NULL;
  model=NULL;
  coverage=NULL;

  for(unsigned i=0;i<history.size();i++) {
    if (history[i]) {
      delete history[i];
    }
  }

  for_each(pass_hooks.begin(),pass_hooks.end(),hook_delete);
  for_each(fail_hooks.begin(),fail_hooks.end(),hook_delete);
  for_each(inc_hooks.begin(),inc_hooks.end(),hook_delete);
  for_each(error_hooks.begin(),error_hooks.end(),hook_delete);

}
<commit_msg>Don't run fail verdict default hook if it's not the only one<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "conf.hh"
#include "dparse.h"
#include "helper.hh"
#include "history.hh"
#include <cstring>

#ifndef DROI
#include <glib.h>
#else

#endif

class EndHook;
#include "endhook.hh"
extern "C" {
  extern D_ParserTables parser_tables_conf;
}

extern Conf* conf_obj;
#define RETURN_ERROR_VOID(s) {                  \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    return;                                     \
  }

#define RETURN_ERROR_VERDICT(s) {               \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    exit_status=-1;                             \
    return Verdict::ERROR;                      \
  }

void Conf::load(std::string& name,std::string& content)
{
  D_Parser *p = new_D_Parser(&parser_tables_conf, 512);
  p->loc.pathname = name.c_str();
  char *s;

  Conf* tmp=conf_obj;
  log.push("conf_load");
  log.debug("Conf::load %s",name.c_str());
  conf_obj=this;

  s=readfile(name.c_str());

  if (s==NULL) {
    status=false;
    errormsg=std::string("Can't read configuration file \"")+name+"\"";
    log.pop();
    free_D_Parser(p);
    return;
  }

  std::string ss(s);
  ss=ss+"\n"+content;
  if ((name!="" && s==NULL))
    RETURN_ERROR_VOID("Loading \"" + name + "\" failed.");

  if (ss=="")
    RETURN_ERROR_VOID("Empty configuration");

  bool ret=dparse(p,(char*)ss.c_str(),std::strlen(ss.c_str()));

  ret=p->syntax_errors==0 && ret;

  if (!ret)
    RETURN_ERROR_VOID("Parsing \"" + name + "\" failed.");

  free(s);

  free_D_Parser(p);

  conf_obj=tmp;

  if ((heuristic=new_heuristic(log,heuristic_name)) == NULL)
    RETURN_ERROR_VOID("Creating heuristic \"" + heuristic_name + "\" failed.");

  if (heuristic->status==false)
    RETURN_ERROR_VOID("Error in heuristic \"" + heuristic_name + "\":" +
                      heuristic->errormsg);

  if ((model=new_model(log, model_name)) == NULL) {
    RETURN_ERROR_VOID("Creating model \"" +
                      filetype(model_name)
                      + "\" failed.");
  }

  coverage = new_coverage(log,coverage_name);

  if (coverage == NULL)
    RETURN_ERROR_VOID("Creating coverage \"" + coverage_name + "\" failed.");

  if (!coverage->status)
    RETURN_ERROR_VOID("Error in coverage \"" + coverage_name + "\": " + coverage->errormsg);

  if (!model->status || !model->init() || !model->reset())
    RETURN_ERROR_VOID("Error in model: " + model->stringify());

  heuristic->set_coverage(coverage);

  heuristic->set_model(model);

  coverage->set_model(model);

  adapter = new_adapter(log, adapter_name);

  if (adapter == NULL)
    RETURN_ERROR_VOID("Creating adapter \"" + adapter_name + "\" failed.");

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  adapter->set_tags(&model->getSPNames());

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  // Parse adapter-tags filter (if any)
  for(unsigned i=0;i<disable_tags.size();i++) {
    std::vector<std::string>& tags=model->getSPNames();
    std::vector<std::string> f;
    commalist(disable_tags[i],f);
    std::vector<int> tmp;
    find(tags,f,tmp);
    for(unsigned i=0;i<tags.size();i++) {
      if (std::find(tmp.begin(),tmp.end(),i)==tmp.end()) {
	disabled_tags[i]=true;
      }
    }

  }

  // Free some memory.
  disable_tags.clear();

  /* handle history */
  for(unsigned i=0;i<history.size();i++) {
    History* h=new_history(log,*history[i]);

    if (h) {
      h->set_coverage(coverage,model);
      if (!h->status) {
        RETURN_ERROR_VOID(h->errormsg);
      }
    } else {
      RETURN_ERROR_VOID("Creating history \""+ *history[i] + "\" failed.");
    }
  }

  adapter->set_actions(&model->getActionNames());

  if (!coverage->status)
    RETURN_ERROR_VOID("Coverage error: " + coverage->stringify());

  if (!adapter->status)
    RETURN_ERROR_VOID("Adapter error: " + adapter->stringify());

  log.pop();
}

void Conf::disable_tagchecking(std::string& s) {
  disable_tags.push_back(s);
}

#include <sstream>

std::string Conf::stringify() {
  std::ostringstream t(std::ios::out | std::ios::binary);

  if (!status) {
    return errormsg;
  }

  t << "model = \"" << removehash(model_name) << capsulate(model->stringify()) << std::endl;
  t << "heuristic = \"" << heuristic_name << "\"" << std::endl;
  t << "coverage = \"" <<  coverage_name << "\"" << std::endl;
  t << "adapter = \"" << adapter_name
    << capsulate(adapter->stringify()) << std::endl;

  // end conditions
  for(size_t i=0;i<end_conditions.size();i++) {
    t << end_conditions[i]->stringify() << std::endl;
  }

  // exit-hooks
  stringify_hooks(t,pass_hooks ,"on_pass"  );
  stringify_hooks(t,fail_hooks ,"on_fail"  );
  stringify_hooks(t,inc_hooks  ,"on_inconc");
  stringify_hooks(t,error_hooks,"on_error" );

  return t.str();
}

Verdict::Verdict Conf::execute(bool interactive) {

  Policy policy;
  log.push("conf_execute");

  if (!status) {
    errormsg = "cannot start executing test due to earlier errors: " + errormsg;
    return Verdict::ERROR;
  }

  if (!adapter->init())
    RETURN_ERROR_VERDICT("Initialising adapter failed: " + adapter->stringify());

  // Validate and finish existing end_conditions
  {
    bool end_by_tagverify = false;
    bool end_by_coverage = false;
    for (unsigned int i = 0; i < end_conditions.size(); i++) {
      End_condition* e = end_conditions[i];
      if (e->status == false)
        RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
      if (e->counter == End_condition::ACTION) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getActionNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::STATETAG) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getSPNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::TAGVERIFY) {
        end_by_tagverify = true;
	((End_condition_tagverify*) e)
	  ->evaluate_filter(model->getSPNames());
      }
      if (e->counter == End_condition::COVERAGE) {
        end_by_coverage = true;
      }
      if (e->counter == End_condition::DURATION) {
        end_time = e->param_time;
      }
    }
    // Add default end conditions (if coverage is reached, test is passed)
    if (!end_by_coverage) {
      end_conditions.push_back(new End_condition_coverage(Verdict::PASS, "1.0"));
    }
    if (!end_by_tagverify && !disable_tagverify) {
      end_conditions.push_back(new End_condition_tagverify(Verdict::FAIL, ""));
    }
  }

  Test_engine engine(*heuristic,*adapter,log,policy,end_conditions,disabled_tags);

  if (interactive) {
    engine.interactive();
  } else {
    Verdict::Verdict v = engine.run(end_time,disable_tagverify);

    if (!heuristic->status) {
      fprintf(stderr,"heuristic error: %s\n",heuristic->errormsg.c_str());
    }

    if (!model->status) {
      fprintf(stderr,"model error: %s\n",model->errormsg.c_str());
    }

    if (!adapter->status) {
      fprintf(stderr,"adapter error: %s\n",adapter->errormsg.c_str());
    }

    if (!coverage->status) {
      fprintf(stderr,"coverage error: %s\n",coverage->errormsg.c_str());
    }
    handle_hooks(v);
  }
  log.pop();
  status = true;
  errormsg = engine.verdict_msg() + ": " + engine.reason_msg();

  if (adapter->status) {
    adapter->adapter_exit(engine.verdict(),engine.reason_msg());
  }

  return engine.verdict();
}

void Conf::handle_hooks(Verdict::Verdict v)
{
  std::list<EndHook*>* hooklist=NULL;

  switch (v) {
  case Verdict::FAIL: {
    hooklist=&fail_hooks;
    break;
  }
  case Verdict::PASS: {
    hooklist=&pass_hooks;
    break;
  }
  case Verdict::INCONCLUSIVE: {
    hooklist=&inc_hooks;
    break;
  }
  case Verdict::ERROR: {
    hooklist=&error_hooks;
    break;
  }
  case Verdict::NOTIFY: {
    abort();
    break;
  }
  default: {
    // unknown verdict?
  }
  }
  if (hooklist) {
    std::list<EndHook*>::iterator b,e;
    b=hooklist->begin();
    e=hooklist->end();
    if (v==Verdict::FAIL && b++ != e) {
      for_each(b++,e,hook_runner);
    } else {
      for_each(b,e,hook_runner);
    }
  }
}

void Conf::set_observe_sleep(std::string &s)
{
  Adapter::sleeptime=atoi(s.c_str());
}

void Conf::add_end_condition(Verdict::Verdict v,std::string& s)

{
  End_condition *ec = new_end_condition(v,s);

  if (ec==NULL) {
    status=false;
    errormsg=errormsg+"Creating end condition \""+s+"\" failed.\n";
  } else {
    add_end_condition(ec);
  }
}

void hook_delete(EndHook* e);

Conf::~Conf() {
  for (unsigned int i = 0; i < end_conditions.size(); i++)
    delete end_conditions[i];
  log.pop();
  if (heuristic)
    delete heuristic;

  if (adapter)
    delete adapter;

  if (model)
    delete model;

  if (coverage)
    delete coverage;

  adapter=NULL;
  heuristic=NULL;
  model=NULL;
  coverage=NULL;

  for(unsigned i=0;i<history.size();i++) {
    if (history[i]) {
      delete history[i];
    }
  }

  for_each(pass_hooks.begin(),pass_hooks.end(),hook_delete);
  for_each(fail_hooks.begin(),fail_hooks.end(),hook_delete);
  for_each(inc_hooks.begin(),inc_hooks.end(),hook_delete);
  for_each(error_hooks.begin(),error_hooks.end(),hook_delete);

}
<|endoftext|>


<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "conf.hh"
#include "dparse.h"
#include "helper.hh"
#include "history.hh"
#include "coverage_of.hh"
#include <cstring>

#ifndef DROI
#include <glib.h>
#else

#endif

class EndHook;
#include "endhook.hh"
extern "C" {
  extern D_ParserTables parser_tables_conf;
}

extern Conf* conf_obj;
#define RETURN_ERROR_VOID(i,s) {		\
    log.pop();                                  \
    status=false;                               \
    if (i>0) {                                  \
      errormsg=name+":"+to_string(i)+" " + s;	\
    } else {					\
      errormsg=s;				\
    }						\
    return;                                     \
  }

#define RETURN_ERROR_VERDICT(s) {               \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    exit_status=-1;                             \
    return Verdict::W_ERROR;                      \
  }

Conf::Conf(Log& l, bool debug_enabled)
  :log(l), exit_status(0), exit_interactive(false),
   heuristic_name("random"), coverage_name("perm"),
   adapter_name("dummy"), model_lineno(-1), heuristic_lineno(-1),
   coverage_lineno(-1),adapter_lineno(-1),
   end_time(-1),
   on_error("exit(1)"), on_fail("interactive"),
   on_pass("exit(0)"), on_inconc("exit(1)"),
   heuristic(NULL), model(NULL),
   adapter(NULL),coverage(NULL),
   disable_tagverify(false)
{
  // Reserve first slot for THE coverage
  set_model_callbacks.push_back(NULL);
  log.ref();
  log.push("fmbt_log");
  log.set_debug(debug_enabled);

  End_condition *ec = new End_status_error(this,Verdict::W_ERROR,"");
  add_end_condition(ec);

  set_on_error("exit(4)");
  set_on_fail("interactive");
  set_on_pass("exit(0)");
  set_on_inconc("exit(1)");
}

void Conf::load(std::string& name,std::string& content)
{
  D_Parser *p = new_D_Parser(&parser_tables_conf, 512);
  p->loc.pathname = name.c_str();
  char *s;

  Conf* tmp=conf_obj;
  log.push("conf_load");
  log.debug("Conf::load %s",name.c_str());
  conf_obj=this;

  s=readfile(name.c_str());

  if (s==NULL) {
    status=false;
    errormsg=std::string("Can't read configuration file \"")+name+"\"";
    log.pop();
    free_D_Parser(p);
    return;
  }

  gchar* t1=g_path_get_dirname(name.c_str());
  std::string dirname(t1);
  g_free(t1);

  if (dirname!=".") {
    g_setenv("AAL_INCLUDE_PREFIX",dirname.c_str(),TRUE);
  }

  std::string ss(s);
  free(s);
  ss=ss+"\n"+content;
  if ((name!="" && s==NULL))
    RETURN_ERROR_VOID(-1,"Loading \"" + name + "\" failed.");

  if (ss=="")
    RETURN_ERROR_VOID(-1,"Empty configuration");

  bool ret=dparse(p,(char*)ss.c_str(),std::strlen(ss.c_str()));

  ret=p->syntax_errors==0 && ret;

  free_D_Parser(p);

  if (!ret) {
    RETURN_ERROR_VOID(-1,"Parsing \"" + name + "\" failed.");
  }

  conf_obj=tmp;

  if ((heuristic=new_heuristic(log,heuristic_name)) == NULL)
    RETURN_ERROR_VOID(heuristic_lineno,"Creating heuristic \"" +
		      heuristic_name + "\" failed.");

  heuristic->lineno = heuristic_lineno;

  if (heuristic->status==false)
    RETURN_ERROR_VOID(heuristic_lineno,"Error in heuristic \"" +
		      heuristic_name + "\":" +
                      heuristic->errormsg);

  if ((model=new_model(log, model_name)) == NULL) {
    RETURN_ERROR_VOID(model_lineno,"Creating model \"" +
                      filetype(model_name)
                      + "\" failed.");
  }

  coverage = new_coverage(log,coverage_name);

  if (coverage == NULL)
    RETURN_ERROR_VOID(coverage_lineno,
		      "Creating coverage \"" +
		      coverage_name + "\" failed.");

  coverage->lineno=coverage_lineno;

  if (!coverage->status)
    RETURN_ERROR_VOID(coverage->lineno,
		      "Error in coverage \"" +
		      coverage_name + "\": " + coverage->errormsg);

  if (!model->status || !model->init() || !model->reset())
    RETURN_ERROR_VOID(model->lineno,"Error in model: " + model->stringify());

  heuristic->set_coverage(coverage);

  heuristic->set_model(model);

  set_model_callbacks[0]=coverage;

  for(std::vector<Coverage*>::iterator i=set_model_callbacks.begin();i!=set_model_callbacks.end();i++) {
    (*i)->set_model(model);
    if (!((*i)->status)) {
      RETURN_ERROR_VOID((*i)->lineno,"Coverage error: " + (*i)->stringify());
    }
  }

  adapter = new_adapter(log, adapter_name);

  if (adapter == NULL)
    RETURN_ERROR_VOID(adapter_lineno,
		      "Creating adapter \"" + adapter_name + "\" failed.");

  adapter->lineno = adapter_lineno;

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  adapter->set_tags(&model->getSPNames());

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  // Handle post set_model calls.

  // Parse adapter-tags filter (if any)
  for(unsigned i=0;i<disable_tags.size();i++) {
    std::vector<std::string>& tags=model->getSPNames();
    std::vector<std::string> f;
    commalist(disable_tags[i],f);
    std::vector<int> tmp;
    find(tags,f,tmp);
    for(unsigned i=0;i<tags.size();i++) {
      if (std::find(tmp.begin(),tmp.end(),i)==tmp.end()) {
	disabled_tags[i]=true;
      }
    }

  }

  // Free some memory.
  disable_tags.clear();

  /* handle history */
  for(unsigned i=0;i<history.size();i++) {
    History* h=new_history(log,* (history[i].first));
    Coverage_of cof(log,set_model_callbacks);

    if (h) {
      h->lineno=history[i].second;
      h->set_coverage(&cof,model);
      if (!h->status) {
	errormsg=h->errormsg;
	delete h;
	RETURN_ERROR_VOID(h->lineno,errormsg);
      }
      delete h;
    } else {
      RETURN_ERROR_VOID(history[i].second,"Creating history \""+ *(history[i].first) + "\" failed.");
    }
  }

  adapter->set_actions(&model->getActionNames());

  if (!adapter->status)
    RETURN_ERROR_VOID(adapter->lineno,"Adapter error: " + adapter->stringify());

  log.pop();
}

void Conf::disable_tagchecking(std::string& s) {
  disable_tags.push_back(s);
}

#include <sstream>

std::string Conf::stringify() {
  std::ostringstream t(std::ios::out | std::ios::binary);

  if (!status) {
    return errormsg;
  }

  t << "model = \"" << removehash(model_name) << capsulate(model->stringify()) << std::endl;
  t << "heuristic = \"" << heuristic_name << "\"" << std::endl;
  t << "coverage = \"" <<  coverage_name << "\"" << std::endl;
  t << "adapter = \"" << adapter_name
    << capsulate(adapter->stringify()) << std::endl;

  // end conditions
  for(size_t i=0;i<end_conditions.size();i++) {
    t << end_conditions[i]->stringify() << std::endl;
  }

  // exit-hooks
  stringify_hooks(t,pass_hooks ,"on_pass"  );
  stringify_hooks(t,fail_hooks ,"on_fail"  );
  stringify_hooks(t,inc_hooks  ,"on_inconc");
  stringify_hooks(t,error_hooks,"on_error" );

  return t.str();
}

Verdict::Verdict Conf::execute(bool interactive) {

  Policy policy;
  log.push("conf_execute");

  if (!status) {
    errormsg = "cannot start executing test due to earlier errors: " + errormsg;
    return Verdict::W_ERROR;
  }

  if (!adapter->init())
    RETURN_ERROR_VERDICT("Initialising adapter failed: " + adapter->stringify());

  // Validate and finish existing end_conditions
  {
    bool end_by_tagverify = false;
    bool end_by_coverage = false;
    for (unsigned int i = 0; i < end_conditions.size(); i++) {
      End_condition* e = end_conditions[i];
      if (e->status == false)
        RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
      if (e->counter == End_condition::ACTION) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getActionNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::STATETAG) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getSPNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::TAGVERIFY) {
        end_by_tagverify = true;
	((End_condition_tagverify*) e)
	  ->evaluate_filter(model->getSPNames());
      }
      if ((e->verdict==Verdict::PASS) &&
	  (e->counter == End_condition::COVERAGE)) {
        end_by_coverage = true;
      }
      if (e->counter == End_condition::DURATION) {
	end_time = e->param_time;
      }
    }
    // Add default end conditions (if coverage is reached, test is passed)
    if (!end_by_coverage) {
      end_conditions.push_back(new End_condition_coverage(this,Verdict::PASS, "1.0"));
    }
    if (!end_by_tagverify && !disable_tagverify) {
      end_conditions.push_back(new End_condition_tagverify(this,Verdict::FAIL, ""));
    }
  }

  Test_engine engine(*heuristic,*adapter,log,policy,end_conditions,disabled_tags);

  if (interactive) {
    engine.interactive();
  } else {
    Verdict::Verdict v = engine.run(end_time,disable_tagverify);

    if (!heuristic->status) {
      fprintf(stderr,"heuristic error: %s\n",heuristic->errormsg.c_str());
    }

    if (!model->status) {
      fprintf(stderr,"model error: %s\n",model->errormsg.c_str());
    }

    if (!adapter->status) {
      fprintf(stderr,"adapter error: %s\n",adapter->errormsg.c_str());
    }

    if (!coverage->status) {
      fprintf(stderr,"coverage error: %s\n",coverage->errormsg.c_str());
    }
    handle_hooks(v);
  }
  log.pop();
  status = true;
  errormsg = engine.verdict_msg() + ": " + engine.reason_msg();

  if (adapter->status) {
    adapter->adapter_exit(engine.verdict(),engine.reason_msg());
  }

  return engine.verdict();
}

void Conf::handle_hooks(Verdict::Verdict v)
{
  std::list<EndHook*>* hooklist=NULL;

  switch (v) {
  case Verdict::FAIL: {
    hooklist=&fail_hooks;
    break;
  }
  case Verdict::PASS: {
    hooklist=&pass_hooks;
    break;
  }
  case Verdict::INCONCLUSIVE: {
    hooklist=&inc_hooks;
    break;
  }
  case Verdict::W_ERROR: {
    hooklist=&error_hooks;
    break;
  }
  case Verdict::NOTIFY: {
    abort();
    break;
  }
  default: {
    // unknown verdict?
  }
  }
  if (hooklist) {
    std::list<EndHook*>::iterator b,e;
    b=hooklist->begin();
    e=hooklist->end();
    if (v==Verdict::FAIL && b++ != e) {
      for_each(b++,e,hook_runner);
    } else {
      for_each(b,e,hook_runner);
    }
  }
}

void Conf::set_observe_sleep(std::string &s)
{
  Adapter::sleeptime=atoi(s.c_str());
}

void Conf::add_end_condition(Verdict::Verdict v,std::string& s,int line)
{
  End_condition *ec = new_end_condition(v,s,this);

  if (ec==NULL) {
    status=false;
    errormsg=errormsg+"Creating end condition \""+s+"\" failed.\n";
  } else {
    ec->lineno=line;
    add_end_condition(ec);
  }
}

void Conf::set_on_error(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  error_hooks.push_back(e);
}

void Conf::set_on_fail(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  fail_hooks.push_back(e);
}

void Conf::set_on_pass(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  pass_hooks.push_back(e);
}

void Conf::set_on_inconc(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  inc_hooks.push_back(e);
}

void Conf::set_model(Coverage* _c)
{
  set_model_callbacks.push_back(_c);
}

void hook_delete(EndHook* e);

Conf::~Conf() {
  for (unsigned int i = 0; i < end_conditions.size(); i++)
    delete end_conditions[i];
  log.pop();
  if (heuristic)
    delete heuristic;

  if (adapter)
    delete adapter;

  if (model)
    delete model;

  if (coverage)
    delete coverage;

  adapter=NULL;
  heuristic=NULL;
  model=NULL;
  coverage=NULL;

  for(unsigned i=0;i<history.size();i++) {
    if (history[i].first) {
      delete history[i].first;
    }
  }

  for_each(pass_hooks.begin(),pass_hooks.end(),hook_delete);
  for_each(fail_hooks.begin(),fail_hooks.end(),hook_delete);
  for_each(inc_hooks.begin(),inc_hooks.end(),hook_delete);
  for_each(error_hooks.begin(),error_hooks.end(),hook_delete);
  log.unref();
}
<commit_msg>fmbt log: log test configuration filename<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#include "conf.hh"
#include "dparse.h"
#include "helper.hh"
#include "history.hh"
#include "coverage_of.hh"
#include <cstring>

#ifndef DROI
#include <glib.h>
#else

#endif

class EndHook;
#include "endhook.hh"
extern "C" {
  extern D_ParserTables parser_tables_conf;
}

extern Conf* conf_obj;
#define RETURN_ERROR_VOID(i,s) {		\
    log.pop();                                  \
    status=false;                               \
    if (i>0) {                                  \
      errormsg=name+":"+to_string(i)+" " + s;	\
    } else {					\
      errormsg=s;				\
    }						\
    return;                                     \
  }

#define RETURN_ERROR_VERDICT(s) {               \
    log.pop();                                  \
    status=false;                               \
    errormsg=s;                                 \
    exit_status=-1;                             \
    return Verdict::W_ERROR;                      \
  }

Conf::Conf(Log& l, bool debug_enabled)
  :log(l), exit_status(0), exit_interactive(false),
   heuristic_name("random"), coverage_name("perm"),
   adapter_name("dummy"), model_lineno(-1), heuristic_lineno(-1),
   coverage_lineno(-1),adapter_lineno(-1),
   end_time(-1),
   on_error("exit(1)"), on_fail("interactive"),
   on_pass("exit(0)"), on_inconc("exit(1)"),
   heuristic(NULL), model(NULL),
   adapter(NULL),coverage(NULL),
   disable_tagverify(false)
{
  // Reserve first slot for THE coverage
  set_model_callbacks.push_back(NULL);
  log.ref();
  log.push("fmbt_log");
  log.set_debug(debug_enabled);

  End_condition *ec = new End_status_error(this,Verdict::W_ERROR,"");
  add_end_condition(ec);

  set_on_error("exit(4)");
  set_on_fail("interactive");
  set_on_pass("exit(0)");
  set_on_inconc("exit(1)");
}

void Conf::load(std::string& name,std::string& content)
{
  D_Parser *p = new_D_Parser(&parser_tables_conf, 512);
  p->loc.pathname = name.c_str();
  char *s;

  Conf* tmp=conf_obj;
  log.push("conf_load");
  {
      std::string escaped_fname = name;
      escape_string(escaped_fname);
      log.print("<conf_file name=\"%s\"/>\n", escaped_fname.c_str());
  }
  log.debug("Conf::load %s",name.c_str());
  conf_obj=this;

  s=readfile(name.c_str());

  if (s==NULL) {
    status=false;
    errormsg=std::string("Can't read configuration file \"")+name+"\"";
    log.pop();
    free_D_Parser(p);
    return;
  }

  gchar* t1=g_path_get_dirname(name.c_str());
  std::string dirname(t1);
  g_free(t1);

  if (dirname!=".") {
    g_setenv("AAL_INCLUDE_PREFIX",dirname.c_str(),TRUE);
  }

  std::string ss(s);
  free(s);
  ss=ss+"\n"+content;
  if ((name!="" && s==NULL))
    RETURN_ERROR_VOID(-1,"Loading \"" + name + "\" failed.");

  if (ss=="")
    RETURN_ERROR_VOID(-1,"Empty configuration");

  bool ret=dparse(p,(char*)ss.c_str(),std::strlen(ss.c_str()));

  ret=p->syntax_errors==0 && ret;

  free_D_Parser(p);

  if (!ret) {
    RETURN_ERROR_VOID(-1,"Parsing \"" + name + "\" failed.");
  }

  conf_obj=tmp;

  if ((heuristic=new_heuristic(log,heuristic_name)) == NULL)
    RETURN_ERROR_VOID(heuristic_lineno,"Creating heuristic \"" +
		      heuristic_name + "\" failed.");

  heuristic->lineno = heuristic_lineno;

  if (heuristic->status==false)
    RETURN_ERROR_VOID(heuristic_lineno,"Error in heuristic \"" +
		      heuristic_name + "\":" +
                      heuristic->errormsg);

  if ((model=new_model(log, model_name)) == NULL) {
    RETURN_ERROR_VOID(model_lineno,"Creating model \"" +
                      filetype(model_name)
                      + "\" failed.");
  }

  coverage = new_coverage(log,coverage_name);

  if (coverage == NULL)
    RETURN_ERROR_VOID(coverage_lineno,
		      "Creating coverage \"" +
		      coverage_name + "\" failed.");

  coverage->lineno=coverage_lineno;

  if (!coverage->status)
    RETURN_ERROR_VOID(coverage->lineno,
		      "Error in coverage \"" +
		      coverage_name + "\": " + coverage->errormsg);

  if (!model->status || !model->init() || !model->reset())
    RETURN_ERROR_VOID(model->lineno,"Error in model: " + model->stringify());

  heuristic->set_coverage(coverage);

  heuristic->set_model(model);

  set_model_callbacks[0]=coverage;

  for(std::vector<Coverage*>::iterator i=set_model_callbacks.begin();i!=set_model_callbacks.end();i++) {
    (*i)->set_model(model);
    if (!((*i)->status)) {
      RETURN_ERROR_VOID((*i)->lineno,"Coverage error: " + (*i)->stringify());
    }
  }

  adapter = new_adapter(log, adapter_name);

  if (adapter == NULL)
    RETURN_ERROR_VOID(adapter_lineno,
		      "Creating adapter \"" + adapter_name + "\" failed.");

  adapter->lineno = adapter_lineno;

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  adapter->set_tags(&model->getSPNames());

  if (!adapter->status) {
    status=false;
    errormsg=adapter->errormsg;
    return;
  }

  // Handle post set_model calls.

  // Parse adapter-tags filter (if any)
  for(unsigned i=0;i<disable_tags.size();i++) {
    std::vector<std::string>& tags=model->getSPNames();
    std::vector<std::string> f;
    commalist(disable_tags[i],f);
    std::vector<int> tmp;
    find(tags,f,tmp);
    for(unsigned i=0;i<tags.size();i++) {
      if (std::find(tmp.begin(),tmp.end(),i)==tmp.end()) {
	disabled_tags[i]=true;
      }
    }

  }

  // Free some memory.
  disable_tags.clear();

  /* handle history */
  for(unsigned i=0;i<history.size();i++) {
    History* h=new_history(log,* (history[i].first));
    Coverage_of cof(log,set_model_callbacks);

    if (h) {
      h->lineno=history[i].second;
      h->set_coverage(&cof,model);
      if (!h->status) {
	errormsg=h->errormsg;
	delete h;
	RETURN_ERROR_VOID(h->lineno,errormsg);
      }
      delete h;
    } else {
      RETURN_ERROR_VOID(history[i].second,"Creating history \""+ *(history[i].first) + "\" failed.");
    }
  }

  adapter->set_actions(&model->getActionNames());

  if (!adapter->status)
    RETURN_ERROR_VOID(adapter->lineno,"Adapter error: " + adapter->stringify());

  log.pop();
}

void Conf::disable_tagchecking(std::string& s) {
  disable_tags.push_back(s);
}

#include <sstream>

std::string Conf::stringify() {
  std::ostringstream t(std::ios::out | std::ios::binary);

  if (!status) {
    return errormsg;
  }

  t << "model = \"" << removehash(model_name) << capsulate(model->stringify()) << std::endl;
  t << "heuristic = \"" << heuristic_name << "\"" << std::endl;
  t << "coverage = \"" <<  coverage_name << "\"" << std::endl;
  t << "adapter = \"" << adapter_name
    << capsulate(adapter->stringify()) << std::endl;

  // end conditions
  for(size_t i=0;i<end_conditions.size();i++) {
    t << end_conditions[i]->stringify() << std::endl;
  }

  // exit-hooks
  stringify_hooks(t,pass_hooks ,"on_pass"  );
  stringify_hooks(t,fail_hooks ,"on_fail"  );
  stringify_hooks(t,inc_hooks  ,"on_inconc");
  stringify_hooks(t,error_hooks,"on_error" );

  return t.str();
}

Verdict::Verdict Conf::execute(bool interactive) {

  Policy policy;
  log.push("conf_execute");

  if (!status) {
    errormsg = "cannot start executing test due to earlier errors: " + errormsg;
    return Verdict::W_ERROR;
  }

  if (!adapter->init())
    RETURN_ERROR_VERDICT("Initialising adapter failed: " + adapter->stringify());

  // Validate and finish existing end_conditions
  {
    bool end_by_tagverify = false;
    bool end_by_coverage = false;
    for (unsigned int i = 0; i < end_conditions.size(); i++) {
      End_condition* e = end_conditions[i];
      if (e->status == false)
        RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
      if (e->counter == End_condition::ACTION) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getActionNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::STATETAG) {
        // avoid string comparisons, fetch the index of the tag
        e->param_long = find(model->getSPNames(), (e->param),-1);
        if (e->param_long==-1) {
          RETURN_ERROR_VERDICT("Error in end condition: " + e->stringify());
        }
      }
      if (e->counter == End_condition::TAGVERIFY) {
        end_by_tagverify = true;
	((End_condition_tagverify*) e)
	  ->evaluate_filter(model->getSPNames());
      }
      if ((e->verdict==Verdict::PASS) &&
	  (e->counter == End_condition::COVERAGE)) {
        end_by_coverage = true;
      }
      if (e->counter == End_condition::DURATION) {
	end_time = e->param_time;
      }
    }
    // Add default end conditions (if coverage is reached, test is passed)
    if (!end_by_coverage) {
      end_conditions.push_back(new End_condition_coverage(this,Verdict::PASS, "1.0"));
    }
    if (!end_by_tagverify && !disable_tagverify) {
      end_conditions.push_back(new End_condition_tagverify(this,Verdict::FAIL, ""));
    }
  }

  Test_engine engine(*heuristic,*adapter,log,policy,end_conditions,disabled_tags);

  if (interactive) {
    engine.interactive();
  } else {
    Verdict::Verdict v = engine.run(end_time,disable_tagverify);

    if (!heuristic->status) {
      fprintf(stderr,"heuristic error: %s\n",heuristic->errormsg.c_str());
    }

    if (!model->status) {
      fprintf(stderr,"model error: %s\n",model->errormsg.c_str());
    }

    if (!adapter->status) {
      fprintf(stderr,"adapter error: %s\n",adapter->errormsg.c_str());
    }

    if (!coverage->status) {
      fprintf(stderr,"coverage error: %s\n",coverage->errormsg.c_str());
    }
    handle_hooks(v);
  }
  log.pop();
  status = true;
  errormsg = engine.verdict_msg() + ": " + engine.reason_msg();

  if (adapter->status) {
    adapter->adapter_exit(engine.verdict(),engine.reason_msg());
  }

  return engine.verdict();
}

void Conf::handle_hooks(Verdict::Verdict v)
{
  std::list<EndHook*>* hooklist=NULL;

  switch (v) {
  case Verdict::FAIL: {
    hooklist=&fail_hooks;
    break;
  }
  case Verdict::PASS: {
    hooklist=&pass_hooks;
    break;
  }
  case Verdict::INCONCLUSIVE: {
    hooklist=&inc_hooks;
    break;
  }
  case Verdict::W_ERROR: {
    hooklist=&error_hooks;
    break;
  }
  case Verdict::NOTIFY: {
    abort();
    break;
  }
  default: {
    // unknown verdict?
  }
  }
  if (hooklist) {
    std::list<EndHook*>::iterator b,e;
    b=hooklist->begin();
    e=hooklist->end();
    if (v==Verdict::FAIL && b++ != e) {
      for_each(b++,e,hook_runner);
    } else {
      for_each(b,e,hook_runner);
    }
  }
}

void Conf::set_observe_sleep(std::string &s)
{
  Adapter::sleeptime=atoi(s.c_str());
}

void Conf::add_end_condition(Verdict::Verdict v,std::string& s,int line)
{
  End_condition *ec = new_end_condition(v,s,this);

  if (ec==NULL) {
    status=false;
    errormsg=errormsg+"Creating end condition \""+s+"\" failed.\n";
  } else {
    ec->lineno=line;
    add_end_condition(ec);
  }
}

void Conf::set_on_error(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  error_hooks.push_back(e);
}

void Conf::set_on_fail(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  fail_hooks.push_back(e);
}

void Conf::set_on_pass(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  pass_hooks.push_back(e);
}

void Conf::set_on_inconc(const std::string &s,int line) {
  EndHook* e=new_endhook(this,s,line);
  inc_hooks.push_back(e);
}

void Conf::set_model(Coverage* _c)
{
  set_model_callbacks.push_back(_c);
}

void hook_delete(EndHook* e);

Conf::~Conf() {
  for (unsigned int i = 0; i < end_conditions.size(); i++)
    delete end_conditions[i];
  log.pop();
  if (heuristic)
    delete heuristic;

  if (adapter)
    delete adapter;

  if (model)
    delete model;

  if (coverage)
    delete coverage;

  adapter=NULL;
  heuristic=NULL;
  model=NULL;
  coverage=NULL;

  for(unsigned i=0;i<history.size();i++) {
    if (history[i].first) {
      delete history[i].first;
    }
  }

  for_each(pass_hooks.begin(),pass_hooks.end(),hook_delete);
  for_each(fail_hooks.begin(),fail_hooks.end(),hook_delete);
  for_each(inc_hooks.begin(),inc_hooks.end(),hook_delete);
  for_each(error_hooks.begin(),error_hooks.end(),hook_delete);
  log.unref();
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_NVE_NEWTONIAN_INTEGRATOR
#define MJOLNIR_NVE_NEWTONIAN_INTEGRATOR
#include <mjolnir/core/System.hpp>
#include <mjolnir/core/SystemMotionRemover.hpp>

namespace mjolnir
{

template<typename traitsT>
class VelocityVerletStepper
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::boundary_type   boundary_type;
    typedef typename traits_type::real_type       real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    typedef System<traitsT>     system_type;
    typedef ForceField<traitsT> forcefield_type;

  public:

    VelocityVerletStepper(const real_type dt) noexcept
        : dt_(dt), halfdt_(dt / 2)
    {}
    ~VelocityVerletStepper() = default;

    void initialize(system_type& sys, forcefield_type& ff);

    real_type step(const real_type time, system_type& sys, forcefield_type& ff);

    real_type delta_t() const noexcept {return dt_;}
    void  set_delta_t(const real_type dt) noexcept
    {
        dt_ = dt; halfdt_ = dt / 2;
    }

    void update(const system_type& sys) const noexcept {/* do nothing */}

  private:
    real_type dt_;      //!< dt
    real_type halfdt_;  //!< dt/2
};

template<typename traitsT>
void VelocityVerletStepper<traitsT>::initialize(
        system_type& system, forcefield_type& ff)
{
    this->update(system);

    for(std::size_t i=0; i<system.size(); ++i)
    {
        system[i].force = coordinate_type(real_type(0.0), real_type(0.0), real_type(0.0));
    }
    system.largest_displacement() = 0;
    ff.calc_force(system);
    return;
}

template<typename traitsT>
typename VelocityVerletStepper<traitsT>::real_type
VelocityVerletStepper<traitsT>::step(
        const real_type time, system_type& system, forcefield_type& ff)
{
    real_type largest_disp2(0);
    for(std::size_t i=0; i<system.size(); ++i)
    {
        auto pv = system[i]; // particle_view that points i-th particle.

        pv.velocity += (halfdt_ * pv.rmass) * pv.force;

        const auto disp = dt_ * pv.velocity;

        pv.position = system.adjust_position(pv.position + disp);
        pv.force    = coordinate_type(real_type(0.0), real_type(0.0), real_type(0.0));

        largest_disp2 = std::max(largest_disp2, length_sq(disp));
    }
    system.largest_displacement() = std::sqrt(largest_disp2);

    // calc f(t+dt)
    ff.calc_force(system);

    // calc v(t+dt)
    for(std::size_t i=0; i<system.size(); ++i)
    {
        auto pv = system[i];
        pv.velocity += (halfdt_ * pv.rmass) * pv.force;
    }
    return time + dt_;
}

} // mjolnir
#endif /* MJOLNIR_VELOCITY_VERLET_INTEGRATOR */
<commit_msg>add missing include file<commit_after>#ifndef MJOLNIR_NVE_NEWTONIAN_INTEGRATOR
#define MJOLNIR_NVE_NEWTONIAN_INTEGRATOR
#include <mjolnir/core/System.hpp>
#include <mjolnir/core/ForceField.hpp>

namespace mjolnir
{

template<typename traitsT>
class VelocityVerletStepper
{
  public:
    typedef traitsT traits_type;
    typedef typename traits_type::boundary_type   boundary_type;
    typedef typename traits_type::real_type       real_type;
    typedef typename traits_type::coordinate_type coordinate_type;
    typedef System<traitsT>     system_type;
    typedef ForceField<traitsT> forcefield_type;

  public:

    VelocityVerletStepper(const real_type dt) noexcept
        : dt_(dt), halfdt_(dt / 2)
    {}
    ~VelocityVerletStepper() = default;

    void initialize(system_type& sys, forcefield_type& ff);

    real_type step(const real_type time, system_type& sys, forcefield_type& ff);

    real_type delta_t() const noexcept {return dt_;}
    void  set_delta_t(const real_type dt) noexcept
    {
        dt_ = dt; halfdt_ = dt / 2;
    }

    void update(const system_type& sys) const noexcept {/* do nothing */}

  private:
    real_type dt_;      //!< dt
    real_type halfdt_;  //!< dt/2
};

template<typename traitsT>
void VelocityVerletStepper<traitsT>::initialize(
        system_type& system, forcefield_type& ff)
{
    this->update(system);

    for(std::size_t i=0; i<system.size(); ++i)
    {
        system[i].force = coordinate_type(real_type(0.0), real_type(0.0), real_type(0.0));
    }
    system.largest_displacement() = 0;
    ff.calc_force(system);
    return;
}

template<typename traitsT>
typename VelocityVerletStepper<traitsT>::real_type
VelocityVerletStepper<traitsT>::step(
        const real_type time, system_type& system, forcefield_type& ff)
{
    real_type largest_disp2(0);
    for(std::size_t i=0; i<system.size(); ++i)
    {
        auto pv = system[i]; // particle_view that points i-th particle.

        pv.velocity += (halfdt_ * pv.rmass) * pv.force;

        const auto disp = dt_ * pv.velocity;

        pv.position = system.adjust_position(pv.position + disp);
        pv.force    = coordinate_type(real_type(0.0), real_type(0.0), real_type(0.0));

        largest_disp2 = std::max(largest_disp2, length_sq(disp));
    }
    system.largest_displacement() = std::sqrt(largest_disp2);

    // calc f(t+dt)
    ff.calc_force(system);

    // calc v(t+dt)
    for(std::size_t i=0; i<system.size(); ++i)
    {
        auto pv = system[i];
        pv.velocity += (halfdt_ * pv.rmass) * pv.force;
    }
    return time + dt_;
}

} // mjolnir
#endif /* MJOLNIR_VELOCITY_VERLET_INTEGRATOR */
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "media/video/capture/fake_video_capture_device.h"
#include "media/video/capture/video_capture_device.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_MACOSX)
// The camera is 'locked' by the application once started on Mac OS X, not when
// allocated as for Windows and Linux, and this test case will fail.
#define MAYBE_AllocateSameCameraTwice DISABLED_AllocateSameCameraTwice
#else
#define MAYBE_AllocateSameCameraTwice AllocateSameCameraTwice
#endif

#if defined(OS_MACOSX)
// Mac/QTKit will always give you the size you ask for and this case will fail.
#define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
#else
#define MAYBE_AllocateBadSize AllocateBadSize
#endif

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::AtLeast;

namespace media {

class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
 public:
  MOCK_METHOD0(OnErr, void());
  MOCK_METHOD3(OnFrameInfo, void(int width, int height, int frame_rate));

  explicit MockFrameObserver(base::WaitableEvent* wait_event)
     : wait_event_(wait_event) {}

  virtual void OnError() OVERRIDE {
    OnErr();
  }

  virtual void OnFrameInfo(
      const VideoCaptureDevice::Capability& info) OVERRIDE {
    OnFrameInfo(info.width, info.height, info.frame_rate);
  }

  virtual void OnIncomingCapturedFrame(const uint8* data, int length,
                                       base::Time timestamp) OVERRIDE {
    wait_event_->Signal();
  }

 private:
  base::WaitableEvent* wait_event_;
};

class VideoCaptureDeviceTest : public testing::Test {
 public:
  VideoCaptureDeviceTest(): wait_event_(false, false) { }

  void PostQuitTask() {
    loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
    loop_->Run();
  }

 protected:
  virtual void SetUp() {
    frame_observer_.reset(new MockFrameObserver(&wait_event_));
    loop_.reset(new MessageLoopForUI());
  }

  virtual void TearDown() {
  }

  base::WaitableEvent wait_event_;
  scoped_ptr<MockFrameObserver> frame_observer_;
  VideoCaptureDevice::Names names_;
  scoped_ptr<MessageLoop> loop_;
};

TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) {
  VideoCaptureDevice::Name device_name;
  device_name.device_name = "jibberish";
  device_name.unique_id = "jibberish";
  VideoCaptureDevice* device = VideoCaptureDevice::Create(device_name);
  EXPECT_TRUE(device == NULL);
}

TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }

  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_FALSE(device.get() == NULL);

  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(640, 480, 30, frame_observer_.get());
  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, Capture720p) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }

  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_FALSE(device.get() == NULL);

  // Get info about the new resolution.
  // We don't care about the resulting resolution or frame rate as it might
  // be different from one machine to the next.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(_, _, _))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(1280, 720, 30, frame_observer_.get());
  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateSameCameraTwice) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device1(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device1.get() != NULL);

  scoped_ptr<VideoCaptureDevice> device2(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device2.get() != NULL);

  // 1. Get info about the new resolution on the first allocated camera
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30));

  device1->Allocate(640, 480, 30, frame_observer_.get());

  // 2. Error when trying to allocate the same camera again.
  EXPECT_CALL(*frame_observer_, OnErr());
  device2->Allocate(640, 480, 30, frame_observer_.get());

  device1->DeAllocate();
  device2->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  // get info about the new resolution
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480 , _))
      .Times(AtLeast(1));

  device->Allocate(637, 472, 35, frame_observer_.get());
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);
  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);
  // get info about the new resolution
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, _));

  EXPECT_CALL(*frame_observer_, OnFrameInfo(320, 240, _));

  device->Allocate(640, 480, 30, frame_observer_.get());
  device->Start();
  // Nothing shall happen.
  device->Allocate(1280, 1024, 30, frame_observer_.get());
  device->DeAllocate();
  // Allocate new size 320, 240
  device->Allocate(320, 240, 30, frame_observer_.get());

  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);
  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30));

  device->Allocate(640, 480, 30, frame_observer_.get());

  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, TestFakeCapture) {
  VideoCaptureDevice::Names names;

  FakeVideoCaptureDevice::GetDeviceNames(&names);

  ASSERT_GT(static_cast<int>(names.size()), 0);

  scoped_ptr<VideoCaptureDevice> device(
      FakeVideoCaptureDevice::Create(names.front()));
  ASSERT_TRUE(device.get() != NULL);

  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(640, 480, 30, frame_observer_.get());

  device->Start();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

};  // namespace media
<commit_msg>Remove flaky unit test VideoCaptureTest::AllocateSameCameraTwice AllocateSameCameraTwice tested to open the same camera twice. However, this is can not happen in Chrome since the VideoCaptureManager ensure this. Further more, this have never worked on Mac and reasently have started to fail on Linux due to changes in the V4L2 driver behaviour.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "media/video/capture/fake_video_capture_device.h"
#include "media/video/capture/video_capture_device.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_MACOSX)
// Mac/QTKit will always give you the size you ask for and this case will fail.
#define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
#else
#define MAYBE_AllocateBadSize AllocateBadSize
#endif

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::AtLeast;

namespace media {

class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
 public:
  MOCK_METHOD0(OnErr, void());
  MOCK_METHOD3(OnFrameInfo, void(int width, int height, int frame_rate));

  explicit MockFrameObserver(base::WaitableEvent* wait_event)
     : wait_event_(wait_event) {}

  virtual void OnError() OVERRIDE {
    OnErr();
  }

  virtual void OnFrameInfo(
      const VideoCaptureDevice::Capability& info) OVERRIDE {
    OnFrameInfo(info.width, info.height, info.frame_rate);
  }

  virtual void OnIncomingCapturedFrame(const uint8* data, int length,
                                       base::Time timestamp) OVERRIDE {
    wait_event_->Signal();
  }

 private:
  base::WaitableEvent* wait_event_;
};

class VideoCaptureDeviceTest : public testing::Test {
 public:
  VideoCaptureDeviceTest(): wait_event_(false, false) { }

  void PostQuitTask() {
    loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
    loop_->Run();
  }

 protected:
  virtual void SetUp() {
    frame_observer_.reset(new MockFrameObserver(&wait_event_));
    loop_.reset(new MessageLoopForUI());
  }

  virtual void TearDown() {
  }

  base::WaitableEvent wait_event_;
  scoped_ptr<MockFrameObserver> frame_observer_;
  VideoCaptureDevice::Names names_;
  scoped_ptr<MessageLoop> loop_;
};

TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) {
  VideoCaptureDevice::Name device_name;
  device_name.device_name = "jibberish";
  device_name.unique_id = "jibberish";
  VideoCaptureDevice* device = VideoCaptureDevice::Create(device_name);
  EXPECT_TRUE(device == NULL);
}

TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }

  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_FALSE(device.get() == NULL);

  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(640, 480, 30, frame_observer_.get());
  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, Capture720p) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }

  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_FALSE(device.get() == NULL);

  // Get info about the new resolution.
  // We don't care about the resulting resolution or frame rate as it might
  // be different from one machine to the next.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(_, _, _))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(1280, 720, 30, frame_observer_.get());
  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  // get info about the new resolution
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480 , _))
      .Times(AtLeast(1));

  device->Allocate(637, 472, 35, frame_observer_.get());
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);
  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);
  // get info about the new resolution
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, _));

  EXPECT_CALL(*frame_observer_, OnFrameInfo(320, 240, _));

  device->Allocate(640, 480, 30, frame_observer_.get());
  device->Start();
  // Nothing shall happen.
  device->Allocate(1280, 1024, 30, frame_observer_.get());
  device->DeAllocate();
  // Allocate new size 320, 240
  device->Allocate(320, 240, 30, frame_observer_.get());

  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
  VideoCaptureDevice::GetDeviceNames(&names_);
  if (!names_.size()) {
    LOG(WARNING) << "No camera available. Exiting test.";
    return;
  }
  scoped_ptr<VideoCaptureDevice> device(
      VideoCaptureDevice::Create(names_.front()));
  ASSERT_TRUE(device.get() != NULL);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);
  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30));

  device->Allocate(640, 480, 30, frame_observer_.get());

  device->Start();
  // Get captured video frames.
  PostQuitTask();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->DeAllocate();
}

TEST_F(VideoCaptureDeviceTest, TestFakeCapture) {
  VideoCaptureDevice::Names names;

  FakeVideoCaptureDevice::GetDeviceNames(&names);

  ASSERT_GT(static_cast<int>(names.size()), 0);

  scoped_ptr<VideoCaptureDevice> device(
      FakeVideoCaptureDevice::Create(names.front()));
  ASSERT_TRUE(device.get() != NULL);

  // Get info about the new resolution.
  EXPECT_CALL(*frame_observer_, OnFrameInfo(640, 480, 30))
      .Times(1);

  EXPECT_CALL(*frame_observer_, OnErr())
      .Times(0);

  device->Allocate(640, 480, 30, frame_observer_.get());

  device->Start();
  EXPECT_TRUE(wait_event_.TimedWait(base::TimeDelta::FromMilliseconds(
      TestTimeouts::action_max_timeout_ms())));
  device->Stop();
  device->DeAllocate();
}

};  // namespace media
<|endoftext|>


<commit_before>// Time:  O(n^2)
// Space: O(n^2)

struct MaxHW {
    int h, w;
};

class Solution {
public:
    int maximalSquare(vector<vector<char>>& A) {
        if (A.empty()) {
            return 0;
        }

        // DP table stores (h, w) for each (i, j).
        vector<vector<MaxHW>> table(A.size(), vector<MaxHW>(A.front().size()));
        for (int i = A.size() - 1; i >= 0; --i) {
            for (int j = A[i].size() - 1; j >= 0; --j) {
                // Find the largest h such that (i, j) to (i + h - 1, j) are feasible.
                // Find the largest w such that (i, j) to (i, j + w - 1) are feasible.
                table[i][j] = A[i][j] == '1'
                                  ? MaxHW{i + 1 < A.size() ? table[i + 1][j].h + 1 : 1,
                                          j + 1 < A[i].size() ? table[i][j + 1].w + 1 : 1}
                                  : MaxHW{0, 0};
            }
        }

        // A table stores the length of largest square for each (i, j).
        vector<vector<int>> s(A.size(), vector<int>(A.front().size(), 0));
        int max_square_area = 0;
        for (int i = A.size() - 1; i >= 0; --i) {
            for (int j = A[i].size() - 1; j >= 0; --j) {
                int side = min(table[i][j].h, table[i][j].w);
                if (A[i][j]) {
                    // Get the length of largest square with bottom-left corner (i, j).
                    if (i + 1 < A.size() && j + 1 < A[i + 1].size()) {
                        side = min(s[i + 1][j + 1] + 1, side);
                    }
                    s[i][j] = side;
                    max_square_area = max(max_square_area, side * side);
                }
            }
        }
        return max_square_area;
    }
};
<commit_msg>Update maximal-square.cpp<commit_after>// Time:  O(n^2)
// Space: O(n)

// DP with rolling window.
class Solution {
public:
    int maximalSquare(vector<vector<char>>& A) {
        if (A.empty()) {
            return 0;
        }
        const int m = A.size(), n = A[0].size();
        vector<vector<int>> size(2, vector<int>(n, 0));
        int max_size = 0;

        for (int j = 0; j < n; ++j) {
            size[0][j] = A[0][j] - '0';
            max_size = max(max_size, size[0][j]);
        }
        for (int i = 1; i < m; ++i) {
            size[i % 2][0] = A[i][0] - '0';
            for (int j = 1; j < n; ++j) {
                if (A[i][j] == '1') {
                    size[i % 2][j] = min(size[i % 2][j - 1],
                                         min(size[(i - 1) % 2][j],
                                             size[(i - 1) % 2][j - 1])) + 1;
                    max_size = max(max_size, size[i % 2][j]);
                } else {
                    size[i % 2][j] = 0;
                }
            }
        }
        return max_size * max_size;
    }
};

// Time:  O(n^2)
// Space: O(n^2)
// DP.
class Solution2 {
public:
    int maximalSquare(vector<vector<char>>& A) {
        if (A.empty()) {
            return 0;
        }
        const int m = A.size(), n = A[0].size();
        vector<vector<int>> size(m, vector<int>(n, 0));
        int max_size = 0;

        for (int j = 0; j < n; ++j) {
            size[0][j] = A[0][j] - '0';
            max_size = max(max_size, size[0][j]);
        }
        for (int i = 1; i < m; ++i) {
            size[i][0] = A[i][0] - '0';
            for (int j = 1; j < n; ++j) {
                if (A[i][j] == '1') {
                    size[i][j] = min(size[i][j - 1],
                                    min(size[i - 1][j],
                                        size[i - 1][j - 1])) + 1;
                    max_size = max(max_size, size[i][j]);
                } else {
                    size[i][j] = 0;
                }
            }
        }
        return max_size * max_size;
    }
};

// Time:  O(n^2)
// Space: O(n^2)
// DP.
class Solution3 {
public:
    struct MaxHW {
        int h, w;
    };

    int maximalSquare(vector<vector<char>>& A) {
        if (A.empty()) {
            return 0;
        }

        // DP table stores (h, w) for each (i, j).
        vector<vector<MaxHW>> table(A.size(), vector<MaxHW>(A.front().size()));
        for (int i = A.size() - 1; i >= 0; --i) {
            for (int j = A[i].size() - 1; j >= 0; --j) {
                // Find the largest h such that (i, j) to (i + h - 1, j) are feasible.
                // Find the largest w such that (i, j) to (i, j + w - 1) are feasible.
                table[i][j] = A[i][j] == '1'
                                  ? MaxHW{i + 1 < A.size() ? table[i + 1][j].h + 1 : 1,
                                          j + 1 < A[i].size() ? table[i][j + 1].w + 1 : 1}
                                  : MaxHW{0, 0};
            }
        }

        // A table stores the length of largest square for each (i, j).
        vector<vector<int>> s(A.size(), vector<int>(A.front().size(), 0));
        int max_square_area = 0;
        for (int i = A.size() - 1; i >= 0; --i) {
            for (int j = A[i].size() - 1; j >= 0; --j) {
                int side = min(table[i][j].h, table[i][j].w);
                if (A[i][j]) {
                    // Get the length of largest square with bottom-left corner (i, j).
                    if (i + 1 < A.size() && j + 1 < A[i + 1].size()) {
                        side = min(s[i + 1][j + 1] + 1, side);
                    }
                    s[i][j] = side;
                    max_square_area = max(max_square_area, side * side);
                }
            }
        }
        return max_square_area;
    }
};
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/compiler/Dialect/HAL/Target/LLVM/AOT/LLVMAOTTarget.h"

#include <cstdlib>

#include "iree/compiler/Dialect/HAL/Target/LLVM/AOT/LinkerTool.h"
#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMBaseTarget.h"
#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h"
#include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h"
#include "iree/compiler/Utils/FlatbufferUtils.h"
#include "iree/schemas/dylib_executable_def_builder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetSelect.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Target/LLVMIR.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

class LLVMAOTTargetBackend final : public LLVMBaseTargetBackend {
 public:
  explicit LLVMAOTTargetBackend(LLVMTargetOptions options)
      : LLVMBaseTargetBackend(options) {}

  // NOTE: we could vary these based on the options, such as by arch/etc.
  std::string name() const override { return "llvm_aot"; }
  std::string filter_pattern() const override { return "dylib*"; }

  LogicalResult serializeExecutable(IREE::HAL::ExecutableTargetOp targetOp,
                                    OpBuilder &executableBuilder) override {
    // Perform the translation in a separate context to avoid any
    // multi-threading issues.
    llvm::LLVMContext context;

    // We name our files after the executable name so that they are easy to
    // track both during compilation (logs/artifacts/etc), as outputs (final
    // intermediate code/binary files), and at runtime (loaded
    // libraries/symbols/etc).
    auto libraryName =
        targetOp.getParentOfType<IREE::HAL::ExecutableOp>().getName().str();

    // TODO(#3737): don't add functions we don't want to serialize to the
    // module. Right now workgroup count calculation functions end up in here
    // as std.func ops and not just the llvm.func ops we expect.
    auto illegalFuncOps =
        llvm::to_vector<4>(targetOp.getInnerModule().getOps<FuncOp>());
    for (auto funcOp : illegalFuncOps) {
      funcOp.erase();
    }

    llvm::Triple targetTriple(options_.targetTriple);
    targetOp.getInnerModule().setAttr(
        LLVM::LLVMDialect::getTargetTripleAttrName(),
        executableBuilder.getStringAttr(targetTriple.str()));

    // At this moment we are leaving MLIR LLVM dialect land translating module
    // into target independent LLVMIR.
    auto llvmModule =
        mlir::translateModuleToLLVMIR(targetOp.getInnerModule(), context);
    if (!llvmModule) {
      return targetOp.emitError() << "failed to translate the MLIR LLVM "
                                     "dialect to the native llvm::Module";
    }

    // Try to grab a linker tool based on the options (and target environment).
    auto linkerTool = LinkerTool::getForTarget(targetTriple, options_);
    if (!linkerTool) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to find a target linker for the given target triple '"
             << options_.targetTriple << "'";
    }

    // Configure the module with any code generation options required later by
    // linking (such as initializer functions).
    auto entryPointNames = llvm::to_vector<8>(
        llvm::map_range(targetOp.getBlock().getOps<ExecutableEntryPointOp>(),
                        [&](auto op) { return op.getName(); }));
    if (failed(
            linkerTool->configureModule(llvmModule.get(), entryPointNames))) {
      return targetOp.emitError()
             << "failed to configure LLVM module for target linker";
    }

    // LLVM opt passes that perform code generation optimizations/transformation
    // similar to what a frontend would do before passing to linking.
    auto targetMachine = createTargetMachine(options_);
    if (!targetMachine) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to create target machine for target triple '"
             << options_.targetTriple << "'";
    }
    llvmModule->setDataLayout(targetMachine->createDataLayout());
    llvmModule->setTargetTriple(targetMachine->getTargetTriple().str());
    if (failed(
            runLLVMIRPasses(options_, targetMachine.get(), llvmModule.get()))) {
      return targetOp.emitError()
             << "failed to run LLVM-IR opt passes for IREE::HAL::ExecutableOp "
                "targeting '"
             << options_.targetTriple << "'";
    }

    // Emit object files.
    SmallVector<Artifact, 4> objectFiles;
    {
      // NOTE: today we just use a single object file, however if we wanted to
      // scale code generation and linking we'd want to generate one per
      // function (or something like that).
      std::string objectData;
      if (failed(runEmitObjFilePasses(targetMachine.get(), llvmModule.get(),
                                      &objectData))) {
        return targetOp.emitError()
               << "failed to compile LLVM-IR module to an object file";
      }
      auto objectFile = Artifact::createTemporary(libraryName, "obj");
      auto &os = objectFile.outputFile->os();
      os << objectData;
      os.flush();
      os.close();
      objectFiles.push_back(std::move(objectFile));
    }

    // Link the generated object files into a dylib.
    auto linkArtifactsOr =
        linkerTool->linkDynamicLibrary(libraryName, objectFiles);
    if (!linkArtifactsOr.hasValue()) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to link executable and generate target dylib using "
                "linker toolchain "
             << linkerTool->getToolPath();
    }
    auto &linkArtifacts = linkArtifactsOr.getValue();
    if (options_.keepLinkerArtifacts) {
      mlir::emitRemark(targetOp.getLoc())
          << "Linker artifacts for " << targetOp.getName() << " preserved:\n"
          << "    " << linkArtifacts.libraryFile.path;
      linkArtifacts.keepAllFiles();
    }

    // Embed debug symbols at the end of the flatbuffer by adding first in the
    // bottoms-up builder.
    FlatbufferBuilder builder;
    flatbuffers_uint8_vec_ref_t debugDatabaseRef = 0;
    flatbuffers_string_ref_t debugDatabaseFilenameRef = 0;
    if (options_.debugSymbols && linkArtifacts.debugFile.outputFile) {
      debugDatabaseRef = builder.streamUint8Vec([&](raw_ostream &stream) {
        return linkArtifacts.debugFile.readInto(stream);
      });
      debugDatabaseFilenameRef = builder.createString(
          llvm::sys::path::filename(linkArtifacts.debugFile.path));
    }

    // Embed entire dynamic library output.
    flatbuffers_uint8_vec_ref_t libraryEmbeddedRef =
        builder.streamUint8Vec([&](raw_ostream &stream) {
          return linkArtifacts.libraryFile.readInto(stream);
        });
    if (!libraryEmbeddedRef) {
      return targetOp.emitError() << "failed to read back dylib temp file at "
                                  << linkArtifacts.libraryFile.path;
    }

    // Entry point names up from.
    // TODO(#3580): these won't be needed in the executable_library world.
    auto entryPointsRef = builder.createStringVec(llvm::map_range(
        targetOp.getBlock().getOps<ExecutableEntryPointOp>(),
        [&](ExecutableEntryPointOp op) { return op.getName(); }));

    iree_DyLibExecutableDef_start_as_root(builder);
    iree_DyLibExecutableDef_entry_points_add(builder, entryPointsRef);
    iree_DyLibExecutableDef_library_embedded_add(builder, libraryEmbeddedRef);
    iree_DyLibExecutableDef_debug_database_filename_add(
        builder, debugDatabaseFilenameRef);
    iree_DyLibExecutableDef_debug_database_embedded_add(builder,
                                                        debugDatabaseRef);
    iree_DyLibExecutableDef_end_as_root(builder);

    // Add the binary data to the target executable.
    executableBuilder.create<IREE::HAL::ExecutableBinaryOp>(
        targetOp.getLoc(),
        static_cast<uint32_t>(IREE::HAL::ExecutableFormat::DyLib),
        builder.getBufferAttr(executableBuilder.getContext()));
    return success();
  }
};

void registerLLVMAOTTargetBackends(
    std::function<LLVMTargetOptions()> queryOptions) {
  getLLVMTargetOptionsFromFlags();
  static TargetBackendRegistration registration("dylib-llvm-aot", [=]() {
#define INIT_LLVM_TARGET(TargetName)        \
  LLVMInitialize##TargetName##Target();     \
  LLVMInitialize##TargetName##TargetMC();   \
  LLVMInitialize##TargetName##TargetInfo(); \
  LLVMInitialize##TargetName##AsmPrinter(); \
  LLVMInitialize##TargetName##AsmParser();
    INIT_LLVM_TARGET(X86)
    INIT_LLVM_TARGET(ARM)
    INIT_LLVM_TARGET(AArch64)
    return std::make_unique<LLVMAOTTargetBackend>(queryOptions());
  });
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<commit_msg>Overriding the default MLIR -> LLVM module name.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iree/compiler/Dialect/HAL/Target/LLVM/AOT/LLVMAOTTarget.h"

#include <cstdlib>

#include "iree/compiler/Dialect/HAL/Target/LLVM/AOT/LinkerTool.h"
#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMBaseTarget.h"
#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h"
#include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h"
#include "iree/compiler/Utils/FlatbufferUtils.h"
#include "iree/schemas/dylib_executable_def_builder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetSelect.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Target/LLVMIR.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

class LLVMAOTTargetBackend final : public LLVMBaseTargetBackend {
 public:
  explicit LLVMAOTTargetBackend(LLVMTargetOptions options)
      : LLVMBaseTargetBackend(options) {}

  // NOTE: we could vary these based on the options, such as by arch/etc.
  std::string name() const override { return "llvm_aot"; }
  std::string filter_pattern() const override { return "dylib*"; }

  LogicalResult serializeExecutable(IREE::HAL::ExecutableTargetOp targetOp,
                                    OpBuilder &executableBuilder) override {
    // Perform the translation in a separate context to avoid any
    // multi-threading issues.
    llvm::LLVMContext context;

    // We name our files after the executable name so that they are easy to
    // track both during compilation (logs/artifacts/etc), as outputs (final
    // intermediate code/binary files), and at runtime (loaded
    // libraries/symbols/etc).
    auto libraryName =
        targetOp.getParentOfType<IREE::HAL::ExecutableOp>().getName().str();

    // TODO(#3737): don't add functions we don't want to serialize to the
    // module. Right now workgroup count calculation functions end up in here
    // as std.func ops and not just the llvm.func ops we expect.
    auto illegalFuncOps =
        llvm::to_vector<4>(targetOp.getInnerModule().getOps<FuncOp>());
    for (auto funcOp : illegalFuncOps) {
      funcOp.erase();
    }

    llvm::Triple targetTriple(options_.targetTriple);
    targetOp.getInnerModule().setAttr(
        LLVM::LLVMDialect::getTargetTripleAttrName(),
        executableBuilder.getStringAttr(targetTriple.str()));

    // At this moment we are leaving MLIR LLVM dialect land translating module
    // into target independent LLVMIR.
    auto llvmModule = mlir::translateModuleToLLVMIR(targetOp.getInnerModule(),
                                                    context, libraryName);
    if (!llvmModule) {
      return targetOp.emitError() << "failed to translate the MLIR LLVM "
                                     "dialect to the native llvm::Module";
    }

    // Try to grab a linker tool based on the options (and target environment).
    auto linkerTool = LinkerTool::getForTarget(targetTriple, options_);
    if (!linkerTool) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to find a target linker for the given target triple '"
             << options_.targetTriple << "'";
    }

    // Configure the module with any code generation options required later by
    // linking (such as initializer functions).
    auto entryPointNames = llvm::to_vector<8>(
        llvm::map_range(targetOp.getBlock().getOps<ExecutableEntryPointOp>(),
                        [&](auto op) { return op.getName(); }));
    if (failed(
            linkerTool->configureModule(llvmModule.get(), entryPointNames))) {
      return targetOp.emitError()
             << "failed to configure LLVM module for target linker";
    }

    // LLVM opt passes that perform code generation optimizations/transformation
    // similar to what a frontend would do before passing to linking.
    auto targetMachine = createTargetMachine(options_);
    if (!targetMachine) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to create target machine for target triple '"
             << options_.targetTriple << "'";
    }
    llvmModule->setDataLayout(targetMachine->createDataLayout());
    llvmModule->setTargetTriple(targetMachine->getTargetTriple().str());
    if (failed(
            runLLVMIRPasses(options_, targetMachine.get(), llvmModule.get()))) {
      return targetOp.emitError()
             << "failed to run LLVM-IR opt passes for IREE::HAL::ExecutableOp "
                "targeting '"
             << options_.targetTriple << "'";
    }

    // Emit object files.
    SmallVector<Artifact, 4> objectFiles;
    {
      // NOTE: today we just use a single object file, however if we wanted to
      // scale code generation and linking we'd want to generate one per
      // function (or something like that).
      std::string objectData;
      if (failed(runEmitObjFilePasses(targetMachine.get(), llvmModule.get(),
                                      &objectData))) {
        return targetOp.emitError()
               << "failed to compile LLVM-IR module to an object file";
      }
      auto objectFile = Artifact::createTemporary(libraryName, "obj");
      auto &os = objectFile.outputFile->os();
      os << objectData;
      os.flush();
      os.close();
      objectFiles.push_back(std::move(objectFile));
    }

    // Link the generated object files into a dylib.
    auto linkArtifactsOr =
        linkerTool->linkDynamicLibrary(libraryName, objectFiles);
    if (!linkArtifactsOr.hasValue()) {
      return mlir::emitError(targetOp.getLoc())
             << "failed to link executable and generate target dylib using "
                "linker toolchain "
             << linkerTool->getToolPath();
    }
    auto &linkArtifacts = linkArtifactsOr.getValue();
    if (options_.keepLinkerArtifacts) {
      mlir::emitRemark(targetOp.getLoc())
          << "Linker artifacts for " << targetOp.getName() << " preserved:\n"
          << "    " << linkArtifacts.libraryFile.path;
      linkArtifacts.keepAllFiles();
    }

    // Embed debug symbols at the end of the flatbuffer by adding first in the
    // bottoms-up builder.
    FlatbufferBuilder builder;
    flatbuffers_uint8_vec_ref_t debugDatabaseRef = 0;
    flatbuffers_string_ref_t debugDatabaseFilenameRef = 0;
    if (options_.debugSymbols && linkArtifacts.debugFile.outputFile) {
      debugDatabaseRef = builder.streamUint8Vec([&](raw_ostream &stream) {
        return linkArtifacts.debugFile.readInto(stream);
      });
      debugDatabaseFilenameRef = builder.createString(
          llvm::sys::path::filename(linkArtifacts.debugFile.path));
    }

    // Embed entire dynamic library output.
    flatbuffers_uint8_vec_ref_t libraryEmbeddedRef =
        builder.streamUint8Vec([&](raw_ostream &stream) {
          return linkArtifacts.libraryFile.readInto(stream);
        });
    if (!libraryEmbeddedRef) {
      return targetOp.emitError() << "failed to read back dylib temp file at "
                                  << linkArtifacts.libraryFile.path;
    }

    // Entry point names up from.
    // TODO(#3580): these won't be needed in the executable_library world.
    auto entryPointsRef = builder.createStringVec(llvm::map_range(
        targetOp.getBlock().getOps<ExecutableEntryPointOp>(),
        [&](ExecutableEntryPointOp op) { return op.getName(); }));

    iree_DyLibExecutableDef_start_as_root(builder);
    iree_DyLibExecutableDef_entry_points_add(builder, entryPointsRef);
    iree_DyLibExecutableDef_library_embedded_add(builder, libraryEmbeddedRef);
    iree_DyLibExecutableDef_debug_database_filename_add(
        builder, debugDatabaseFilenameRef);
    iree_DyLibExecutableDef_debug_database_embedded_add(builder,
                                                        debugDatabaseRef);
    iree_DyLibExecutableDef_end_as_root(builder);

    // Add the binary data to the target executable.
    executableBuilder.create<IREE::HAL::ExecutableBinaryOp>(
        targetOp.getLoc(),
        static_cast<uint32_t>(IREE::HAL::ExecutableFormat::DyLib),
        builder.getBufferAttr(executableBuilder.getContext()));
    return success();
  }
};

void registerLLVMAOTTargetBackends(
    std::function<LLVMTargetOptions()> queryOptions) {
  getLLVMTargetOptionsFromFlags();
  static TargetBackendRegistration registration("dylib-llvm-aot", [=]() {
#define INIT_LLVM_TARGET(TargetName)        \
  LLVMInitialize##TargetName##Target();     \
  LLVMInitialize##TargetName##TargetMC();   \
  LLVMInitialize##TargetName##TargetInfo(); \
  LLVMInitialize##TargetName##AsmPrinter(); \
  LLVMInitialize##TargetName##AsmParser();
    INIT_LLVM_TARGET(X86)
    INIT_LLVM_TARGET(ARM)
    INIT_LLVM_TARGET(AArch64)
    return std::make_unique<LLVMAOTTargetBackend>(queryOptions());
  });
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<|endoftext|>


<commit_before>/***************************************************************************
                          loader.cpp  -  class Loader
                             -------------------
    begin                : jeu avr 17 2003
    copyright            : (C) 2003 by Michael CATANZARITI
    email                : mcatan@free.fr
 ***************************************************************************/

/***************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.      *
 *                                                                         *
 * This software is published under the terms of the Apache Software       *
 * License version 1.1, a copy of which has been included with this        *
 * distribution in the LICENSE.txt file.                                   *
 ***************************************************************************/

#include <log4cxx/helpers/loader.h>
#include <log4cxx/appender.h>
#include <log4cxx/spi/filter.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/spi/loggerfactory.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/helpers/object.h>
#include <log4cxx/spi/errorhandler.h>
#include <log4cxx/varia/denyallfilter.h>
#include <log4cxx/spi/repositoryselector.h>
#include <log4cxx/spi/appenderattachable.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
using namespace log4cxx::varia;

IMPLEMENT_LOG4CXX_OBJECT(Object)
IMPLEMENT_LOG4CXX_OBJECT(OptionHandler)
IMPLEMENT_LOG4CXX_OBJECT(ErrorHandler)
IMPLEMENT_LOG4CXX_OBJECT(Appender)
IMPLEMENT_LOG4CXX_OBJECT(Filter)
IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachable)
IMPLEMENT_LOG4CXX_OBJECT(LoggerFactory)
IMPLEMENT_LOG4CXX_OBJECT(LoggerRepository)
IMPLEMENT_LOG4CXX_OBJECT(DenyAllFilter)
IMPLEMENT_LOG4CXX_OBJECT(RepositorySelector)

const helpers::Class& Loader::loadClass(const tstring& clazz)
{
	return Class::forName(clazz);
}
<commit_msg>added DOMConfigurator and SMTPAppender helper classes<commit_after>/***************************************************************************
                          loader.cpp  -  class Loader
                             -------------------
    begin                : jeu avr 17 2003
    copyright            : (C) 2003 by Michael CATANZARITI
    email                : mcatan@free.fr
 ***************************************************************************/

/***************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.      *
 *                                                                         *
 * This software is published under the terms of the Apache Software       *
 * License version 1.1, a copy of which has been included with this        *
 * distribution in the LICENSE.txt file.                                   *
 ***************************************************************************/

#include <log4cxx/helpers/loader.h>
#include <log4cxx/appender.h>
#include <log4cxx/spi/filter.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/spi/loggerfactory.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/helpers/object.h>
#include <log4cxx/spi/errorhandler.h>
#include <log4cxx/varia/denyallfilter.h>
#include <log4cxx/spi/repositoryselector.h>
#include <log4cxx/spi/appenderattachable.h>
#include <log4cxx/helpers/xml.h>
#include <log4cxx/spi/triggeringeventevaluator.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
using namespace log4cxx::varia;

IMPLEMENT_LOG4CXX_OBJECT(Object)
IMPLEMENT_LOG4CXX_OBJECT(OptionHandler)
IMPLEMENT_LOG4CXX_OBJECT(ErrorHandler)
IMPLEMENT_LOG4CXX_OBJECT(Appender)
IMPLEMENT_LOG4CXX_OBJECT(Filter)
IMPLEMENT_LOG4CXX_OBJECT(AppenderAttachable)
IMPLEMENT_LOG4CXX_OBJECT(LoggerFactory)
IMPLEMENT_LOG4CXX_OBJECT(LoggerRepository)
IMPLEMENT_LOG4CXX_OBJECT(DenyAllFilter)
IMPLEMENT_LOG4CXX_OBJECT(RepositorySelector)
IMPLEMENT_LOG4CXX_OBJECT(XMLDOMNode)
IMPLEMENT_LOG4CXX_OBJECT(XMLDOMDocument)
IMPLEMENT_LOG4CXX_OBJECT(XMLDOMElement)
IMPLEMENT_LOG4CXX_OBJECT(XMLDOMNodeList)
IMPLEMENT_LOG4CXX_OBJECT(TriggeringEventEvaluator)

const helpers::Class& Loader::loadClass(const tstring& clazz)
{
	return Class::forName(clazz);
}
<|endoftext|>