<commit_before>#include "authoring/qt4_widget_opengl_authoring.h"

using namespace std;
using namespace qt4;
using namespace state;
using namespace opengl;
using namespace authoring;

Qt4_Widget_OpenGL_Authoring::
Qt4_Widget_OpenGL_Authoring( const string& xmlString,
                              QWidget * parent ) : Qt4_Widget_OpenGL( parent ),
                                                  _opengl_object_affordance_collection(),
                                                  _opengl_object_affordance_collection_ghost(),
                                                  _opengl_object_robot_plan(),
                                                  _opengl_object_gfe( xmlString ),
                                                  _opengl_object_gfe_ghost( xmlString ),
                                                  _opengl_object_constraint_visualizer(),
                                                  _timer_update( new QTimer( this ) ) {
  setMinimumSize( 800, 400 );

  _opengl_object_affordance_collection.set_visible( false );
  _opengl_object_affordance_collection_ghost.set_visible( false );
  _opengl_object_affordance_collection_ghost.set_transparency( 0.1 );
  _opengl_object_robot_plan.set_visible( false );
  _opengl_object_robot_plan.set_transparency( 0.1 );
  _opengl_object_gfe.set_visible( false );
  _opengl_object_gfe_ghost.set_visible( false );
  _opengl_object_gfe_ghost.set_transparency( 0.1 );

  _opengl_object_constraint_visualizer.set_color( Eigen::Vector3f(1.0, 0.0, 0.0) );
  _opengl_object_constraint_visualizer.set_transparency( 0.5 );
  _opengl_object_constraint_visualizer.set_visible( false );

//_opengl_object_constraint_visualizer.set_visible( false )

  opengl_scene().add_object( _opengl_object_affordance_collection );
  opengl_scene().add_object( _opengl_object_affordance_collection_ghost );
  opengl_scene().add_object( _opengl_object_robot_plan );
  opengl_scene().add_object( _opengl_object_gfe );
  opengl_scene().add_object( _opengl_object_gfe_ghost );
  opengl_scene().add_object( _opengl_object_constraint_visualizer);
  _timer_update->start( 100 );

  connect( _timer_update, SIGNAL( timeout() ), this, SLOT( _timer_update_callback() ) );
}

Qt4_Widget_OpenGL_Authoring::
~Qt4_Widget_OpenGL_Authoring() {

}

Qt4_Widget_OpenGL_Authoring::
Qt4_Widget_OpenGL_Authoring( const Qt4_Widget_OpenGL_Authoring& other ) {

}

Qt4_Widget_OpenGL_Authoring&
Qt4_Widget_OpenGL_Authoring::
operator=( const Qt4_Widget_OpenGL_Authoring& other ) {

  return (*this);
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_affordance_collection( vector< affordance::AffordanceState >& affordanceCollection ){
  _opengl_object_affordance_collection.set_visible( true );
  _opengl_object_affordance_collection.set( affordanceCollection );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_affordance_collection_ghost( vector< affordance::AffordanceState >& affordanceCollection ){
  _opengl_object_affordance_collection_ghost.set_visible( true );
  _opengl_object_affordance_collection_ghost.set( affordanceCollection );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan( vector< State_GFE >& robotPlan ){
  _opengl_object_robot_plan.set_visible( true );
  _opengl_object_robot_plan.set( robotPlan );
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_gfe( State_GFE& stateGFE ){
  _opengl_object_gfe.set_visible( true );
  _opengl_object_gfe.set( stateGFE );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_gfe_ghost( State_GFE& stateGFE ){
  _opengl_object_gfe_ghost.set_visible( true );
  _opengl_object_gfe_ghost.set( stateGFE );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_current_index( int currentIndex ){
  _opengl_object_robot_plan.set_current_index( currentIndex );
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_current_index( int visibleCurrentIndex ){
  if( visibleCurrentIndex == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_current_index( true );
  } else {
    _opengl_object_robot_plan.set_visible_current_index( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_trajectory( int visibleTrajectory ){
  if( visibleTrajectory == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_trajectory( true );
  } else {
    _opengl_object_robot_plan.set_visible_trajectory( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_trajectory_wrist( int visibleTrajectoryWrist ){
  if( visibleTrajectoryWrist == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_trajectory_wrist( true );
  } else {
    _opengl_object_robot_plan.set_visible_trajectory_wrist( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_constraint_visualizer( Constraint* constraint) {
  // update the box from the constraint
    if ( constraint->type() == CONSTRAINT_TASK_SPACE_REGION_TYPE ) {
        Constraint_Task_Space_Region* _tsr_constraint = dynamic_cast <Constraint_Task_Space_Region*>(constraint);
        double h = _tsr_constraint->ranges()[0].second - _tsr_constraint->ranges()[0].first;
        double w = _tsr_constraint->ranges()[1].second - _tsr_constraint->ranges()[1].first;
        double l = _tsr_constraint->ranges()[2].second - _tsr_constraint->ranges()[2].first;

        _opengl_object_constraint_visualizer.set_visible( true );
        _opengl_object_constraint_visualizer.set(Eigen::Vector3f(h, w, l));
    }
    update();
    return;
}

void
Qt4_Widget_OpenGL_Authoring::
_timer_update_callback( void ){
  update();
  return;
}

namespace authoring {
  ostream&
  operator<<( ostream& out,
              const Qt4_Widget_OpenGL_Authoring& other ) {
    return out;
  }

}
<commit_msg>move constraint visual to child frame<commit_after>#include "authoring/qt4_widget_opengl_authoring.h"

using namespace std;
using namespace qt4;
using namespace state;
using namespace opengl;
using namespace authoring;

Qt4_Widget_OpenGL_Authoring::
Qt4_Widget_OpenGL_Authoring( const string& xmlString,
                              QWidget * parent ) : Qt4_Widget_OpenGL( parent ),
                                                  _opengl_object_affordance_collection(),
                                                  _opengl_object_affordance_collection_ghost(),
                                                  _opengl_object_robot_plan(),
                                                  _opengl_object_gfe( xmlString ),
                                                  _opengl_object_gfe_ghost( xmlString ),
                                                  _opengl_object_constraint_visualizer(),
                                                  _timer_update( new QTimer( this ) ) {
  setMinimumSize( 800, 400 );

  _opengl_object_affordance_collection.set_visible( false );
  _opengl_object_affordance_collection_ghost.set_visible( false );
  _opengl_object_affordance_collection_ghost.set_transparency( 0.1 );
  _opengl_object_robot_plan.set_visible( false );
  _opengl_object_robot_plan.set_transparency( 0.1 );
  _opengl_object_gfe.set_visible( false );
  _opengl_object_gfe_ghost.set_visible( false );
  _opengl_object_gfe_ghost.set_transparency( 0.1 );

  _opengl_object_constraint_visualizer.set_color( Eigen::Vector3f(1.0, 0.0, 0.0) );
  _opengl_object_constraint_visualizer.set_transparency( 0.5 );
  _opengl_object_constraint_visualizer.set_visible( false );

//_opengl_object_constraint_visualizer.set_visible( false )

  opengl_scene().add_object( _opengl_object_affordance_collection );
  opengl_scene().add_object( _opengl_object_affordance_collection_ghost );
  opengl_scene().add_object( _opengl_object_robot_plan );
  opengl_scene().add_object( _opengl_object_gfe );
  opengl_scene().add_object( _opengl_object_gfe_ghost );
  opengl_scene().add_object( _opengl_object_constraint_visualizer);
  _timer_update->start( 100 );

  connect( _timer_update, SIGNAL( timeout() ), this, SLOT( _timer_update_callback() ) );
}

Qt4_Widget_OpenGL_Authoring::
~Qt4_Widget_OpenGL_Authoring() {

}

Qt4_Widget_OpenGL_Authoring::
Qt4_Widget_OpenGL_Authoring( const Qt4_Widget_OpenGL_Authoring& other ) {

}

Qt4_Widget_OpenGL_Authoring&
Qt4_Widget_OpenGL_Authoring::
operator=( const Qt4_Widget_OpenGL_Authoring& other ) {

  return (*this);
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_affordance_collection( vector< affordance::AffordanceState >& affordanceCollection ){
  _opengl_object_affordance_collection.set_visible( true );
  _opengl_object_affordance_collection.set( affordanceCollection );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_affordance_collection_ghost( vector< affordance::AffordanceState >& affordanceCollection ){
  _opengl_object_affordance_collection_ghost.set_visible( true );
  _opengl_object_affordance_collection_ghost.set( affordanceCollection );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan( vector< State_GFE >& robotPlan ){
  _opengl_object_robot_plan.set_visible( true );
  _opengl_object_robot_plan.set( robotPlan );
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_gfe( State_GFE& stateGFE ){
  _opengl_object_gfe.set_visible( true );
  _opengl_object_gfe.set( stateGFE );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_gfe_ghost( State_GFE& stateGFE ){
  _opengl_object_gfe_ghost.set_visible( true );
  _opengl_object_gfe_ghost.set( stateGFE );
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_current_index( int currentIndex ){
  _opengl_object_robot_plan.set_current_index( currentIndex );
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_current_index( int visibleCurrentIndex ){
  if( visibleCurrentIndex == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_current_index( true );
  } else {
    _opengl_object_robot_plan.set_visible_current_index( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_trajectory( int visibleTrajectory ){
  if( visibleTrajectory == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_trajectory( true );
  } else {
    _opengl_object_robot_plan.set_visible_trajectory( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_opengl_object_robot_plan_visible_trajectory_wrist( int visibleTrajectoryWrist ){
  if( visibleTrajectoryWrist == Qt::Checked ){
    _opengl_object_robot_plan.set_visible_trajectory_wrist( true );
  } else {
    _opengl_object_robot_plan.set_visible_trajectory_wrist( false );
  }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
update_constraint_visualizer( Constraint* constraint) {
  // update the box from the constraint
  if ( constraint->type() == CONSTRAINT_TASK_SPACE_REGION_TYPE ) {
      Constraint_Task_Space_Region* _tsr_constraint = dynamic_cast <Constraint_Task_Space_Region*>(constraint);
      if ( _tsr_constraint->child() != NULL) {
        double h = _tsr_constraint->ranges()[0].second - _tsr_constraint->ranges()[0].first;
        double w = _tsr_constraint->ranges()[1].second - _tsr_constraint->ranges()[1].first;
        double l = _tsr_constraint->ranges()[2].second - _tsr_constraint->ranges()[2].first;

        _opengl_object_constraint_visualizer.set_visible( true );
        // Use the frame of the child link; also, add a small constant offset
        // makes it easier to visualize the TSRs when they have very few
        // constraints
        _opengl_object_constraint_visualizer.set(_tsr_constraint->child()->getOriginFrame(),
                                                 Eigen::Vector3f(h + 0.01, w + 0.01, l + 0.01));
      }
    }
  update();
  return;
}

void
Qt4_Widget_OpenGL_Authoring::
_timer_update_callback( void ){
  update();
  return;
}

namespace authoring {
  ostream&
  operator<<( ostream& out,
              const Qt4_Widget_OpenGL_Authoring& other ) {
    return out;
  }

}
<|endoftext|>


<commit_before>/*
** Copyright 2009-2012 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <locale.h>
#include <QCoreApplication>
#include <QLibraryInfo>
#include "com/centreon/broker/config/applier/endpoint.hh"
#include "com/centreon/broker/config/applier/init.hh"
#include "com/centreon/broker/config/applier/logger.hh"
#include "com/centreon/broker/config/applier/modules.hh"
#include "com/centreon/broker/config/applier/state.hh"
#include "com/centreon/broker/config/logger.hh"
#include "com/centreon/broker/config/parser.hh"
#include "com/centreon/broker/config/state.hh"
#include "com/centreon/broker/logging/logging.hh"

using namespace com::centreon::broker;

/**************************************
*                                     *
*           Static Objects            *
*                                     *
**************************************/

// Main config file.
static QString gl_mainconfigfile;

/**
 *  Function called when updating configuration (when program receives
 *  SIGHUP).
 *
 *  @param[in] signum Signal number.
 */
static void hup_handler(int signum) {
  (void)signum;

  // Log message.
  logging::config(logging::high)
    << "main: configuration update requested";

  // Parse configuration file.
  config::parser parsr;
  config::state conf;
  parsr.parse(gl_mainconfigfile, conf);

  // Apply resulting configuration.
  config::applier::state::instance().apply(conf);

  return ;
}

/**
 *  Function called on termination request (when program receives
 *  SIGTERM).
 *
 *  @param[in] signum Signal number.
 */
static void term_handler(int signum) {
  (void)signum;

  // Log message.
  logging::info(logging::high)
    << "main: termination request received";

  // Reset original signal handler.
  signal(SIGTERM, SIG_DFL);

  // Ask event loop to quit.
  QCoreApplication::exit(0);

  return ;
}

/**************************************
*                                     *
*          Public Functions           *
*                                     *
**************************************/

/**
 *  @brief Program entry point.
 *
 *  main() is the first function called when the program starts.
 *
 *  @param[in] argc Number of arguments received on the command line.
 *  @param[in] argv Arguments received on the command line, stored in an
 *                  array.
 *
 *  @return 0 on normal termination, any other value on failure.
 */
int main(int argc, char* argv[]) {
  // Initialization.
  config::applier::init();

  // Return value.
  int retval(0);

  // Qt application object.
  QCoreApplication app(argc, argv);

  try {
    // Check the command line.
    bool check(false);
    bool debug(false);
    bool help(false);
    bool version(false);
    if (argc >= 2) {
      for (int i(1); i < argc; ++i)
        if (!strcmp(argv[i], "-c"))
          check = true;
        else if (!strcmp(argv[i], "-d"))
          debug = true;
        else if (!strcmp(argv[i], "-h"))
          help = true;
        else if (!strcmp(argv[i], "-v"))
          version = true;
        else
          gl_mainconfigfile = argv[i];
    }

    // Apply default configuration.
    config::state default_state;
    {
      // Logging object.
      config::logger default_log;
      default_log.config(!help);
      default_log.debug(debug);
      default_log.error(!help);
      default_log.info(true);
      logging::level level;
      if (debug)
        level = logging::low;
      else if (check)
        level = logging::medium;
      else
        level = logging::high;
      default_log.level(level);
      default_log.name((check || version) ? "stdout" : "stderr");
      default_log.type(config::logger::standard);

      // Configuration object.
      default_state.loggers().push_back(default_log);

      // Apply configuration.
      config::applier::state::instance().apply(default_state, false);
    }

    // Check parameters requirements.
    if (help) {
      logging::info(logging::high) << "USAGE: " << argv[0]
        << " [-c] [-d] [-h] [-v] [<configfile>]";
      logging::info(logging::high) << "  -c  Check configuration file.";
      logging::info(logging::high) << "  -d  Enable debug mode.";
      logging::info(logging::high) << "  -h  Print this help.";
      logging::info(logging::high)
        << "  -v  Print Centreon Broker version.";
      logging::info(logging::high) << "Centreon Broker "
        << CENTREON_BROKER_VERSION;
      logging::info(logging::high) << "Copyright 2009-2012 Merethis";
      logging::info(logging::high) << "License GNU GPL " \
        "version 2 <http://gnu.org/licenses/gpl.html>";
      retval = 0;
    }
    else if (version) {
      logging::info(logging::high) << "Centreon Broker "
        << CENTREON_BROKER_VERSION;
      retval = 0;
    }
    else if (gl_mainconfigfile.isEmpty()) {
      logging::error(logging::high) << "USAGE: " << argv[0]
        << " [-c] [-d] [-h] [-v] [<configfile>]";
      retval = 1;
    }
    else {
      app.setApplicationName("Centreon Broker");
#if QT_VERSION >= 0x040400
      app.setApplicationVersion(CENTREON_BROKER_VERSION);
#endif // Qt >= 4.4.0
      app.setOrganizationDomain("merethis.com");
      app.setOrganizationName("Merethis");
      logging::info(logging::medium)
        << "Centreon Broker " << CENTREON_BROKER_VERSION;
      logging::info(logging::medium) << "Copyright 2009-2012 Merethis";
      logging::info(logging::medium) << "License GNU GPL " \
        "version 2 <http://gnu.org/licenses/gpl.html>";
#if QT_VERSION >= 0x040400
      logging::info(logging::low) << "PID: " << app.applicationPid();
#endif // Qt >= 4.4.0
      logging::info(logging::medium)
        << "Qt compilation version " << QT_VERSION_STR;
      logging::info(logging::medium)
        << "Qt runtime version " << qVersion();
      logging::info(logging::medium) << "  Build Key: "
        << QLibraryInfo::buildKey();
      logging::info(logging::medium) << "  Licensee: "
        << QLibraryInfo::licensee();
      logging::info(logging::medium) << "  Licensed Products: "
        << QLibraryInfo::licensedProducts();

      // Reset locale.
      setlocale(LC_NUMERIC, "C");

      {
        // Parse configuration file.
        config::parser parsr;
        config::state conf;
        parsr.parse(gl_mainconfigfile, conf);

        // Verification modifications.
        if (check) {
          // Loggers.
          for (QList<config::logger>::iterator
                 it(conf.loggers().begin()),
                 end(conf.loggers().end());
               it != end;
               ++it)
            it->types(0);
          conf.loggers().push_back(default_state.loggers().front());
        }

        // Apply resulting configuration totally or partially.
        config::applier::state::instance().apply(conf, !check);
      }

      // Set configuration update handler.
      if (signal(SIGHUP, hup_handler) == SIG_ERR) {
        char const* err(strerror(errno));
        logging::info(logging::high)
          << "main: could not register configuration update handler: "
          << err;
      }

      // Set termination handler.
      if (signal(SIGTERM, term_handler) == SIG_ERR) {
        char const* err(strerror(errno));
        logging::info(logging::high)
          << "main: could not register termination handler: "
          << err;
      }

      // Launch event loop.
      if (!check)
        retval = app.exec();
      else
        retval = EXIT_SUCCESS;
    }
  }
  // Standard exception.
  catch (std::exception const& e) {
    logging::error(logging::high) << e.what();
    retval = EXIT_FAILURE;
  }
  // Unknown exception.
  catch (...) {
    logging::error(logging::high)
      << "main: unknown error, aborting execution";
    retval = EXIT_FAILURE;
  }

  // Unload endpoints.
  config::applier::deinit();

  return (retval);
}
<commit_msg>Disable SIGHUP handler during handler execution.<commit_after>/*
** Copyright 2009-2012 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <cerrno>
#include <csignal>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <locale.h>
#include <QCoreApplication>
#include <QLibraryInfo>
#include "com/centreon/broker/config/applier/endpoint.hh"
#include "com/centreon/broker/config/applier/init.hh"
#include "com/centreon/broker/config/applier/logger.hh"
#include "com/centreon/broker/config/applier/modules.hh"
#include "com/centreon/broker/config/applier/state.hh"
#include "com/centreon/broker/config/logger.hh"
#include "com/centreon/broker/config/parser.hh"
#include "com/centreon/broker/config/state.hh"
#include "com/centreon/broker/logging/logging.hh"

using namespace com::centreon::broker;

/**************************************
*                                     *
*           Static Objects            *
*                                     *
**************************************/

// Main config file.
static QString gl_mainconfigfile;

/**
 *  Function called when updating configuration (when program receives
 *  SIGHUP).
 *
 *  @param[in] signum Signal number.
 */
static void hup_handler(int signum) {
  (void)signum;

  // Disable SIGHUP handling during handler execution.
  signal(SIGHUP, SIG_IGN);

  // Log message.
  logging::config(logging::high)
    << "main: configuration update requested";

  // Parse configuration file.
  config::parser parsr;
  config::state conf;
  parsr.parse(gl_mainconfigfile, conf);

  // Apply resulting configuration.
  config::applier::state::instance().apply(conf);

  // Reenable SIGHUP handler.
  signal(SIGHUP, &hup_handler);

  return ;
}

/**
 *  Function called on termination request (when program receives
 *  SIGTERM).
 *
 *  @param[in] signum Signal number.
 */
static void term_handler(int signum) {
  (void)signum;

  // Log message.
  logging::info(logging::high)
    << "main: termination request received";

  // Reset original signal handler.
  signal(SIGTERM, SIG_DFL);

  // Ask event loop to quit.
  QCoreApplication::exit(0);

  return ;
}

/**************************************
*                                     *
*          Public Functions           *
*                                     *
**************************************/

/**
 *  @brief Program entry point.
 *
 *  main() is the first function called when the program starts.
 *
 *  @param[in] argc Number of arguments received on the command line.
 *  @param[in] argv Arguments received on the command line, stored in an
 *                  array.
 *
 *  @return 0 on normal termination, any other value on failure.
 */
int main(int argc, char* argv[]) {
  // Initialization.
  config::applier::init();

  // Return value.
  int retval(0);

  // Qt application object.
  QCoreApplication app(argc, argv);

  try {
    // Check the command line.
    bool check(false);
    bool debug(false);
    bool help(false);
    bool version(false);
    if (argc >= 2) {
      for (int i(1); i < argc; ++i)
        if (!strcmp(argv[i], "-c"))
          check = true;
        else if (!strcmp(argv[i], "-d"))
          debug = true;
        else if (!strcmp(argv[i], "-h"))
          help = true;
        else if (!strcmp(argv[i], "-v"))
          version = true;
        else
          gl_mainconfigfile = argv[i];
    }

    // Apply default configuration.
    config::state default_state;
    {
      // Logging object.
      config::logger default_log;
      default_log.config(!help);
      default_log.debug(debug);
      default_log.error(!help);
      default_log.info(true);
      logging::level level;
      if (debug)
        level = logging::low;
      else if (check)
        level = logging::medium;
      else
        level = logging::high;
      default_log.level(level);
      default_log.name((check || version) ? "stdout" : "stderr");
      default_log.type(config::logger::standard);

      // Configuration object.
      default_state.loggers().push_back(default_log);

      // Apply configuration.
      config::applier::state::instance().apply(default_state, false);
    }

    // Check parameters requirements.
    if (help) {
      logging::info(logging::high) << "USAGE: " << argv[0]
        << " [-c] [-d] [-h] [-v] [<configfile>]";
      logging::info(logging::high) << "  -c  Check configuration file.";
      logging::info(logging::high) << "  -d  Enable debug mode.";
      logging::info(logging::high) << "  -h  Print this help.";
      logging::info(logging::high)
        << "  -v  Print Centreon Broker version.";
      logging::info(logging::high) << "Centreon Broker "
        << CENTREON_BROKER_VERSION;
      logging::info(logging::high) << "Copyright 2009-2012 Merethis";
      logging::info(logging::high) << "License GNU GPL " \
        "version 2 <http://gnu.org/licenses/gpl.html>";
      retval = 0;
    }
    else if (version) {
      logging::info(logging::high) << "Centreon Broker "
        << CENTREON_BROKER_VERSION;
      retval = 0;
    }
    else if (gl_mainconfigfile.isEmpty()) {
      logging::error(logging::high) << "USAGE: " << argv[0]
        << " [-c] [-d] [-h] [-v] [<configfile>]";
      retval = 1;
    }
    else {
      app.setApplicationName("Centreon Broker");
#if QT_VERSION >= 0x040400
      app.setApplicationVersion(CENTREON_BROKER_VERSION);
#endif // Qt >= 4.4.0
      app.setOrganizationDomain("merethis.com");
      app.setOrganizationName("Merethis");
      logging::info(logging::medium)
        << "Centreon Broker " << CENTREON_BROKER_VERSION;
      logging::info(logging::medium) << "Copyright 2009-2012 Merethis";
      logging::info(logging::medium) << "License GNU GPL " \
        "version 2 <http://gnu.org/licenses/gpl.html>";
#if QT_VERSION >= 0x040400
      logging::info(logging::low) << "PID: " << app.applicationPid();
#endif // Qt >= 4.4.0
      logging::info(logging::medium)
        << "Qt compilation version " << QT_VERSION_STR;
      logging::info(logging::medium)
        << "Qt runtime version " << qVersion();
      logging::info(logging::medium) << "  Build Key: "
        << QLibraryInfo::buildKey();
      logging::info(logging::medium) << "  Licensee: "
        << QLibraryInfo::licensee();
      logging::info(logging::medium) << "  Licensed Products: "
        << QLibraryInfo::licensedProducts();

      // Reset locale.
      setlocale(LC_NUMERIC, "C");

      {
        // Parse configuration file.
        config::parser parsr;
        config::state conf;
        parsr.parse(gl_mainconfigfile, conf);

        // Verification modifications.
        if (check) {
          // Loggers.
          for (QList<config::logger>::iterator
                 it(conf.loggers().begin()),
                 end(conf.loggers().end());
               it != end;
               ++it)
            it->types(0);
          conf.loggers().push_back(default_state.loggers().front());
        }

        // Apply resulting configuration totally or partially.
        config::applier::state::instance().apply(conf, !check);
      }

      // Set configuration update handler.
      if (signal(SIGHUP, hup_handler) == SIG_ERR) {
        char const* err(strerror(errno));
        logging::info(logging::high)
          << "main: could not register configuration update handler: "
          << err;
      }

      // Set termination handler.
      if (signal(SIGTERM, term_handler) == SIG_ERR) {
        char const* err(strerror(errno));
        logging::info(logging::high)
          << "main: could not register termination handler: "
          << err;
      }

      // Launch event loop.
      if (!check)
        retval = app.exec();
      else
        retval = EXIT_SUCCESS;
    }
  }
  // Standard exception.
  catch (std::exception const& e) {
    logging::error(logging::high) << e.what();
    retval = EXIT_FAILURE;
  }
  // Unknown exception.
  catch (...) {
    logging::error(logging::high)
      << "main: unknown error, aborting execution";
    retval = EXIT_FAILURE;
  }

  // Unload endpoints.
  config::applier::deinit();

  return (retval);
}
<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#include "precompiled.hpp"
#include "utils.hpp"

namespace poseidon {

cow_string
ascii_uppercase(cow_string text)
  {
    // Only modify the string when it really has to modified.
    for(size_t k = 0;  k != text.size();  ++k) {
      char32_t ch = static_cast<uint8_t>(text[k]);
      if(('a' <= ch) && (ch <= 'z'))
        text.mut(k) = static_cast<char>(ch - 0x20);
    }
    return ::std::move(text);
  }

cow_string
ascii_lowercase(cow_string text)
  {
    // Only modify the string when it really has to modified.
    for(size_t k = 0;  k != text.size();  ++k) {
      char32_t ch = static_cast<uint8_t>(text[k]);
      if(('A' <= ch) && (ch <= 'Z'))
        text.mut(k) = static_cast<char>(ch + 0x20);
    }
    return ::std::move(text);
  }

cow_string
ascii_trim(cow_string text)
  {
    // Remove leading blank characters.
    // Return an empty string if all characters are blank.
    size_t k = cow_string::npos;
    for(;;) {
      if(++k == text.size())
        return { };

      char32_t ch = static_cast<uint8_t>(text[k]);
      if((ch != ' ') && (ch != '\t'))
        break;
    }
    if(k != 0)
      text.erase(0, k);

    // Remove trailing blank characters.
    k = text.size();
    for(;;) {
      if(--k == 0)
        break;

      char32_t ch = static_cast<uint8_t>(text[k]);
      if((ch != ' ') && (ch != '\t'))
        break;
    }
    if(++k != text.size())
      text.erase(k);

    return ::std::move(text);
  }

bool
ascii_ci_has_token(const cow_string& text, char delim, const char* tok, size_t len)
  {
    size_t epos = 0;
    while(epos < text.size()) {
      // Get a token.
      size_t bpos = epos;
      epos = ::std::min(text.find(bpos, delim), text.size()) + 1;
      size_t mpos = epos - 1;

      // Skip leading and trailing blank characters, if any.
      while((bpos != mpos) && ::rocket::is_any_of(text[bpos], {' ', '\t'}))
        bpos++;

      while((bpos != mpos) && ::rocket::is_any_of(text[mpos-1], {' ', '\t'}))
        mpos--;

      // If the token matches `close`, the connection shall be closed.
      if(::rocket::ascii_ci_equal(text.data() + bpos, mpos - bpos, tok, len))
        return true;
    }
    return false;
  }

size_t
explode(cow_vstrings& segments, const cow_string& text, char delim, size_t limit)
  {
    segments.clear();
    size_t epos = 0;
    while(epos < text.size()) {
      // Get a token.
      size_t bpos = epos;
      epos = (segments.size() + 1 >= limit) ? text.size()
                 : ::std::min(text.find(bpos, delim), text.size()) + 1;
      size_t mpos = epos - 1;

      // Skip leading and trailing blank characters, if any.
      while((bpos != mpos) && ::rocket::is_any_of(text[bpos], {' ', '\t'}))
        bpos++;

      while((bpos != mpos) && ::rocket::is_any_of(text[mpos-1], {' ', '\t'}))
        mpos--;

      // Push this token.
      segments.emplace_back(text.data() + bpos, mpos - bpos);
    }
    return segments.size();
  }

size_t
implode(cow_string& text, const cow_vstrings& segments, char delim)
  {
    text.clear();
    if(segments.size()) {
      // Write the first token.
      text << segments[0];

      // Write the other tokens, each of which is preceded by a delimiter.
      for(size_t k = 1;  k < segments.size();  ++k)
        text << delim << ' ' << segments[k];
    }
    return segments.size();
  }

}  // namespace poseidon
<commit_msg>utils: Cleanup<commit_after>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#include "precompiled.hpp"
#include "utils.hpp"

namespace poseidon {

cow_string
ascii_uppercase(cow_string text)
  {
    // Only modify the string when it really has to modified.
    for(size_t k = 0;  k != text.size();  ++k) {
      char32_t ch = static_cast<uint8_t>(text[k]);
      if(('a' <= ch) && (ch <= 'z'))
        text.mut(k) = static_cast<char>(ch - 0x20);
    }
    return ::std::move(text);
  }

cow_string
ascii_lowercase(cow_string text)
  {
    // Only modify the string when it really has to modified.
    for(size_t k = 0;  k != text.size();  ++k) {
      char32_t ch = static_cast<uint8_t>(text[k]);
      if(('A' <= ch) && (ch <= 'Z'))
        text.mut(k) = static_cast<char>(ch + 0x20);
    }
    return ::std::move(text);
  }

cow_string
ascii_trim(cow_string text)
  {
    // Remove leading blank characters.
    // Return an empty string if all characters are blank.
    size_t k = cow_string::npos;
    for(;;) {
      if(++k == text.size())
        return { };

      char32_t ch = static_cast<uint8_t>(text[k]);
      if((ch != ' ') && (ch != '\t'))
        break;
    }
    if(k != 0)
      text.erase(0, k);

    // Remove trailing blank characters.
    k = text.size();
    for(;;) {
      if(--k == 0)
        break;

      char32_t ch = static_cast<uint8_t>(text[k]);
      if((ch != ' ') && (ch != '\t'))
        break;
    }
    if(++k != text.size())
      text.erase(k);

    return ::std::move(text);
  }

bool
ascii_ci_has_token(const cow_string& text, char delim, const char* tok, size_t len)
  {
    size_t bpos = text.find_first_not_of(" \t");
    while(bpos < text.size()) {
      // Get the end of this segment.
      // If the delimiter is not found, make sure `epos` is reasonably large
      // and incrementing it will not overflow.
      size_t epos = text.find(bpos, delim) * 2 / 2;

      // Skip trailing blank characters, if any.
      size_t mpos = text.find_last_not_of(epos - 1, " \t");
      ROCKET_ASSERT(mpos != text.npos);
      if(::rocket::ascii_ci_equal(text.data() + bpos, mpos + 1 - bpos, tok, len))
        return true;

      // Skip the delimiter and blank characters that follow it.
      bpos = text.find_first_not_of(epos + 1, " \t");
    }
    return false;
  }

size_t
explode(cow_vstrings& segments, const cow_string& text, char delim, size_t limit)
  {
    segments.clear();
    size_t bpos = text.find_first_not_of(" \t");
    while(bpos < text.size()) {
      // Get the end of this segment.
      // If the delimiter is not found, make sure `epos` is reasonably large
      // and incrementing it will not overflow.
      size_t epos = text.npos / 2;
      if(segments.size() + 1 < limit)
        epos = text.find(bpos, delim) * 2 / 2;

      // Skip trailing blank characters, if any.
      size_t mpos = text.find_last_not_of(epos - 1, " \t");
      ROCKET_ASSERT(mpos != text.npos);
      segments.emplace_back(text.data() + bpos, mpos + 1 - bpos);

      // Skip the delimiter and blank characters that follow it.
      bpos = text.find_first_not_of(epos + 1, " \t");
    }
    return segments.size();
  }

size_t
implode(cow_string& text, const cow_vstrings& segments, char delim)
  {
    text.clear();
    if(segments.size()) {
      // Write the first token.
      text << segments[0];

      // Write the other tokens, each of which is preceded by a delimiter.
      for(size_t k = 1;  k < segments.size();  ++k)
        text << delim << ' ' << segments[k];
    }
    return segments.size();
  }

}  // namespace poseidon
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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                                */
/*                                                                        */
/*     http://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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mcbist_workarounds.C
/// @brief Workarounds for the MCBISt engine
/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/dimm/kind.H>
#include <lib/workarounds/mcbist_workarounds.H>
#include <lib/mcbist/mcbist.H>
#include <lib/fir/fir.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace workarounds
{

namespace mcbist
{

///
/// @brief Replace reads with displays in the passed in MCBIST program
/// @param[in,out] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
{
    using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;

    io_program.change_maint_broadcast_mode(mss::OFF);
    io_program.change_end_boundary(mss::mcbist::end_boundary::STOP_AFTER_ADDRESS);

    for (auto& st : io_program.iv_subtests)
    {
        uint64_t l_op = 0;
        st.iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op);

        if (l_op == mss::mcbist::op_type::READ)
        {
            l_op = mss::mcbist::op_type::DISPLAY;
        }

        st.iv_mcbmr.insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op);
    }
}

///
/// @brief End of rank work around
/// For Nimbus DD1 the MCBIST engine doesn't detect the end of rank properly
/// for a 1R DIMM during a super-fast read. To work around this, we check the
/// MCBIST to see if any port has a 1R DIMM on it and if so we change our stop
/// conditions to immediate. However, because that doesn't work (by design) with
/// read, we also must change all reads to displays (slow read.)
/// @param[in] i_target the fapi2 target of the mcbist
/// @param[in,out] io_program the mcbist program to check
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                               mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program )
{
    using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;

    // If we don't need the mcbist work-around, we're done.
    if (! mss::chip_ec_feature_mcbist_end_of_rank(i_target) )
    {
        return FAPI2_RC_SUCCESS;
    }

    // First things first - lets find out if we have an 1R DIMM on our side of the chip.
    const auto l_dimm_kinds = dimm::kind::vector( mss::find_targets<TARGET_TYPE_DIMM>(i_target) );
    const auto l_kind = std::find_if(l_dimm_kinds.begin(), l_dimm_kinds.end(), [](const dimm::kind & k) -> bool
    {
        // If total ranks are 1, we have a 1R DIMM, SDP. This is the fellow of concern
        return k.iv_total_ranks == 1;
    });

    // If we don't find the fellow of concern, we can get outta here
    if (l_kind == l_dimm_kinds.end())
    {
        FAPI_INF("no 1R SDP DIMM on this MCBIST (%s), we're ok", mss::c_str(i_target));
        return FAPI2_RC_SUCCESS;
    }

    // Keep in mind that pause-on-error-mode is two bits and it doesn't encode master/slave. The
    // end_boundary enums are constructed such that STOP_AFTER_MASTER_RANK is really stop on
    // either master or slave for the purposes of this field. So, checking stop-after-master-rank
    // will catch both master and slave pauses which is correct for this work-around.
    uint64_t l_pause_mode = 0;
    io_program.iv_config.extractToRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(l_pause_mode);

    if( l_pause_mode != mss::mcbist::end_boundary::STOP_AFTER_MASTER_RANK )
    {
        FAPI_INF("not checking rank boundaries on this MCBIST (%s), we're ok", mss::c_str(i_target));
        return FAPI2_RC_SUCCESS;
    }

    // If we're here, we need to fix up our program. We need to set our stop to stop immediate, which implies
    // we don't do broadcasts and we can't do read, we have to do display.
    FAPI_INF("%s replacing reads and changing broadcast mode due to a chip bug", mss::c_str(i_target));
    replace_read_helper(io_program);

    return fapi2::FAPI2_RC_SUCCESS;
}

///
/// @brief WAT debug attention
/// For Nimbus DD1 the MCBIST engine uses the WAT debug bit as a workaround
/// @param[in] i_target the fapi2 target of the mcbist
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode wat_debug_attention( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
{
    // MCBIST attentions are already special attention
    if (mss::chip_ec_feature_mss_wat_debug_attn(i_target))
    {
        fapi2::ReturnCode l_rc;
        fir::reg<MCBIST_MCBISTFIRQ> mcbist_fir_register(i_target, l_rc);
        FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ);

        FAPI_TRY(mcbist_fir_register.attention<MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN>().write());
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief BROADCAST OUT OF SYNC workaround
/// A UE noise window is triggered by UE/AUEs causing an out of sync error
/// @param[in] i_target the fapi2 target of the mcbist
/// @param[in] i_value value to enable or disable workaround
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode broadcast_out_of_sync( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
        const mss::states i_value )
{
    fapi2::ReturnCode l_rc;
    fapi2::buffer<uint64_t> recr_buffer;

    fir::reg<MCBIST_MCBISTFIRQ> l_mcbist_fir_reg(i_target, l_rc);
    FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ);

    // Check for enabled (post memdiag) or disbaled (pre memdiag) workaround
    if ( i_value )
    {
        // Initialize Broadcast of out sync to checkstop post workaround
        l_mcbist_fir_reg.checkstop<MCBIST_MCBISTFIRQ_MCBIST_BRODCAST_OUT_OF_SYNC>();
    }
    else
    {
        // Initialize Broadcast of out sync to recoverable pre workaround
        l_mcbist_fir_reg.recoverable_error<MCBIST_MCBISTFIRQ_MCBIST_BRODCAST_OUT_OF_SYNC>();
    }

    FAPI_TRY(l_mcbist_fir_reg.write(), "unable to write fir::reg %d", MCBIST_MCBISTFIRQ);

    for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
    {
        // Set UE noise window for workaround
        mss::read_recr_register(p, recr_buffer);
        mss::set_enable_ue_noise_window(recr_buffer, i_value);
        mss::write_recr_register(p, recr_buffer);
    }

fapi_try_exit:
    return fapi2::current_err;
}

} // close namespace mcbist
} // close namespace workarounds
} // close namespace mss
<commit_msg>Fixed unmasking of BRODCAST_OUT_OF_SYNC fir after memdiags handling<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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                                */
/*                                                                        */
/*     http://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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mcbist_workarounds.C
/// @brief Workarounds for the MCBISt engine
/// Workarounds are very device specific, so there is no attempt to generalize
/// this code in any way.
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/dimm/kind.H>
#include <lib/workarounds/mcbist_workarounds.H>
#include <lib/mcbist/mcbist.H>
#include <lib/fir/fir.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace workarounds
{

namespace mcbist
{

///
/// @brief Replace reads with displays in the passed in MCBIST program
/// @param[in,out] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
{
    using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;

    io_program.change_maint_broadcast_mode(mss::OFF);
    io_program.change_end_boundary(mss::mcbist::end_boundary::STOP_AFTER_ADDRESS);

    for (auto& st : io_program.iv_subtests)
    {
        uint64_t l_op = 0;
        st.iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op);

        if (l_op == mss::mcbist::op_type::READ)
        {
            l_op = mss::mcbist::op_type::DISPLAY;
        }

        st.iv_mcbmr.insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op);
    }
}

///
/// @brief End of rank work around
/// For Nimbus DD1 the MCBIST engine doesn't detect the end of rank properly
/// for a 1R DIMM during a super-fast read. To work around this, we check the
/// MCBIST to see if any port has a 1R DIMM on it and if so we change our stop
/// conditions to immediate. However, because that doesn't work (by design) with
/// read, we also must change all reads to displays (slow read.)
/// @param[in] i_target the fapi2 target of the mcbist
/// @param[in,out] io_program the mcbist program to check
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
                               mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program )
{
    using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;

    // If we don't need the mcbist work-around, we're done.
    if (! mss::chip_ec_feature_mcbist_end_of_rank(i_target) )
    {
        return FAPI2_RC_SUCCESS;
    }

    // First things first - lets find out if we have an 1R DIMM on our side of the chip.
    const auto l_dimm_kinds = dimm::kind::vector( mss::find_targets<TARGET_TYPE_DIMM>(i_target) );
    const auto l_kind = std::find_if(l_dimm_kinds.begin(), l_dimm_kinds.end(), [](const dimm::kind & k) -> bool
    {
        // If total ranks are 1, we have a 1R DIMM, SDP. This is the fellow of concern
        return k.iv_total_ranks == 1;
    });

    // If we don't find the fellow of concern, we can get outta here
    if (l_kind == l_dimm_kinds.end())
    {
        FAPI_INF("no 1R SDP DIMM on this MCBIST (%s), we're ok", mss::c_str(i_target));
        return FAPI2_RC_SUCCESS;
    }

    // Keep in mind that pause-on-error-mode is two bits and it doesn't encode master/slave. The
    // end_boundary enums are constructed such that STOP_AFTER_MASTER_RANK is really stop on
    // either master or slave for the purposes of this field. So, checking stop-after-master-rank
    // will catch both master and slave pauses which is correct for this work-around.
    uint64_t l_pause_mode = 0;
    io_program.iv_config.extractToRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(l_pause_mode);

    if( l_pause_mode != mss::mcbist::end_boundary::STOP_AFTER_MASTER_RANK )
    {
        FAPI_INF("not checking rank boundaries on this MCBIST (%s), we're ok", mss::c_str(i_target));
        return FAPI2_RC_SUCCESS;
    }

    // If we're here, we need to fix up our program. We need to set our stop to stop immediate, which implies
    // we don't do broadcasts and we can't do read, we have to do display.
    FAPI_INF("%s replacing reads and changing broadcast mode due to a chip bug", mss::c_str(i_target));
    replace_read_helper(io_program);

    return fapi2::FAPI2_RC_SUCCESS;
}

///
/// @brief WAT debug attention
/// For Nimbus DD1 the MCBIST engine uses the WAT debug bit as a workaround
/// @param[in] i_target the fapi2 target of the mcbist
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode wat_debug_attention( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
{
    // MCBIST attentions are already special attention
    if (mss::chip_ec_feature_mss_wat_debug_attn(i_target))
    {
        fapi2::ReturnCode l_rc;
        fir::reg<MCBIST_MCBISTFIRQ> mcbist_fir_register(i_target, l_rc);
        FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ);

        FAPI_TRY(mcbist_fir_register.attention<MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN>().write());
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief BROADCAST OUT OF SYNC workaround
/// A UE noise window is triggered by UE/AUEs causing an out of sync error
/// @param[in] i_target the fapi2 target of the mcbist
/// @param[in] i_value value to enable or disable workaround
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode broadcast_out_of_sync( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
        const mss::states i_value )
{
    // Check for enabled (post memdiag) or disabled (pre memdiag) workaround
    if ( i_value == mss::ON )
    {
        fapi2::buffer<uint64_t> l_mcbist_action_buffer;

        // Change Broadcast of out sync to checkstop post workaround
        // Current FIR register API resets FIR mask registers when setting up FIR
        // This can result in FIRs being incorrectly unmasked after being handled in memdiags
        // The scoms below set the mask to checkstop while preserving the current mask state
        FAPI_TRY( mss::getScom(i_target, MCBIST_MCBISTFIRACT1, l_mcbist_action_buffer) );
        l_mcbist_action_buffer.clearBit<MCBIST_MCBISTFIRQ_MCBIST_BRODCAST_OUT_OF_SYNC>();
        FAPI_TRY( mss::putScom(i_target, MCBIST_MCBISTFIRACT1, l_mcbist_action_buffer) );
    }
    else
    {
        fapi2::ReturnCode l_rc;
        fir::reg<MCBIST_MCBISTFIRQ> l_mcbist_fir_reg(i_target, l_rc);
        FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCBIST_MCBISTFIRQ);

        // Initialize Broadcast out of sync to recoverable pre workaround
        l_mcbist_fir_reg.recoverable_error<MCBIST_MCBISTFIRQ_MCBIST_BRODCAST_OUT_OF_SYNC>();
        FAPI_TRY(l_mcbist_fir_reg.write(), "unable to write fir::reg %d", MCBIST_MCBISTFIRQ);
    }

    for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
    {
        fapi2::buffer<uint64_t> l_recr_buffer;

        // Set UE noise window for workaround
        mss::read_recr_register(p, l_recr_buffer);
        mss::set_enable_ue_noise_window(l_recr_buffer, i_value);
        mss::write_recr_register(p, l_recr_buffer);
    }

fapi_try_exit:
    return fapi2::current_err;
}

} // close namespace mcbist
} // close namespace workarounds
} // close namespace mss
<|endoftext|>


<commit_before>//
//    Copyright (C) 2014 Haruki Hasegawa
//
//    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
//
//        http://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.
//

#ifndef ANDROID_HELPER_HPP_
#define ANDROID_HELPER_HPP_

#include <jni.h>
#include <unistd.h>

namespace oslmp {
namespace impl {

class AndroidHelper {

    AndroidHelper() = delete;

public:
    static bool setThreadPriority(JavaVM *vm, pid_t tid, int prio) noexcept;
    static bool setCurrentThreadName(const char *name) noexcept;
};

// sync. with android.os.Process
enum AndroidThreadPriority {
    ANDROID_THREAD_PRIORITY_LOWEST = 19,
    ANDROID_THREAD_PRIORITY_BACKGROUND = 10,
    ANDROID_THREAD_PRIORITY_DEFAULT = 0,
    ANDROID_THREAD_PRIORITY_MORE_FAVORABLE = -1,
    ANDROID_THREAD_PRIORITY_LESS_FAVORABLE = -2,
    ANDROID_THREAD_PRIORITY_FOREGROUND = -4,
    ANDROID_THREAD_PRIORITY_URGENT_DISPLAY = -8,
    ANDROID_THREAD_PRIORITY_AUDIO = -16,
    ANDROID_THREAD_PRIORITY_URGENT_AUDIO = -19
};

} // namespace impl
} // namespace oslmp

#endif // ANDROID_HELPER_HPP_
<commit_msg>Fix wrong ANDROID_THREAD_PRIORITY_LESS_FAVORABLE thread priority<commit_after>//
//    Copyright (C) 2014 Haruki Hasegawa
//
//    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
//
//        http://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.
//

#ifndef ANDROID_HELPER_HPP_
#define ANDROID_HELPER_HPP_

#include <jni.h>
#include <unistd.h>

namespace oslmp {
namespace impl {

class AndroidHelper {

    AndroidHelper() = delete;

public:
    static bool setThreadPriority(JavaVM *vm, pid_t tid, int prio) noexcept;
    static bool setCurrentThreadName(const char *name) noexcept;
};

// sync. with android.os.Process
enum AndroidThreadPriority {
    ANDROID_THREAD_PRIORITY_LOWEST = 19,
    ANDROID_THREAD_PRIORITY_BACKGROUND = 10,
    ANDROID_THREAD_PRIORITY_LESS_FAVORABLE = 1,
    ANDROID_THREAD_PRIORITY_DEFAULT = 0,
    ANDROID_THREAD_PRIORITY_MORE_FAVORABLE = -1,
    ANDROID_THREAD_PRIORITY_FOREGROUND = -4,
    ANDROID_THREAD_PRIORITY_URGENT_DISPLAY = -8,
    ANDROID_THREAD_PRIORITY_AUDIO = -16,
    ANDROID_THREAD_PRIORITY_URGENT_AUDIO = -19
};

} // namespace impl
} // namespace oslmp

#endif // ANDROID_HELPER_HPP_
<|endoftext|>


<commit_before>#ifndef AX_BASIC_OBJ_MODEL_HPP
#define AX_BASIC_OBJ_MODEL_HPP

#include <vector>
#include <string>
#include <iosfwd>

#include "math.hpp"
#include "option.hpp"
#include "basic_buffer.hpp"

namespace ax
{
    struct basic_vertex
    {
        ax::v3 vertex;
        ax::v3 normal;
        ax::v2 uv;
    };

    struct basic_obj_model
    {
    public:

        basic_obj_model(const char *file_path);
        ~basic_obj_model();

        int get_vertex_count() const;
        int get_face_count() const;
        ax::v3 get_normal(int iface, int nthvert) const;
        ax::v3 get_normal(ax::v2 uv) const;
        ax::v3 get_vertex(int i) const;
        ax::v3 get_vertex(int iface, int nthvert) const;
        ax::v2 get_uv(int iface, int nthvert) const;
        ax::color get_color_diffuse(ax::v2 uv) const;
        float get_specularity(ax::v2 uv) const;
        std::vector<int> get_face(int idx) const;

    private:

        bool try_load_texture(std::string file_path, const char *suffix, ax::basic_buffer &img);

        std::vector<std::vector<ax::v3i>> faces; // NOTE: this v3i means vertex/uv/normal. TODO: make it mean vertex/normal/uv instead.
        std::vector<ax::v3> vertices;
        std::vector<ax::v3> normals;
        std::vector<ax::v2> uvs;
        ax::option<std::vector<ax::basic_vertex>> stream_opt;
        ax::basic_buffer diffuse_map;
        ax::basic_buffer normal_map;
        ax::basic_buffer specular_map;
    };
}

#endif
<commit_msg>Exposed model maps and added TODOs to decouple operations from basic_obj_model.<commit_after>#ifndef AX_BASIC_OBJ_MODEL_HPP
#define AX_BASIC_OBJ_MODEL_HPP

#include <vector>
#include <string>
#include <iosfwd>

#include "math.hpp"
#include "option.hpp"
#include "basic_buffer.hpp"

namespace ax
{
    struct basic_vertex
    {
        ax::v3 vertex;
        ax::v3 normal;
        ax::v2 uv;
    };

    struct basic_obj_model
    {
    public:

        basic_obj_model(const char *file_path);
        ~basic_obj_model();

        int get_vertex_count() const;
        int get_face_count() const;
        ax::v3 get_normal(int iface, int nthvert) const; // TODO: move this to math.hpp?
        ax::v3 get_normal(ax::v2 uv) const; // TODO: move this to math.hpp?
        ax::v3 get_vertex(int i) const;
        ax::v3 get_vertex(int iface, int nthvert) const; // TODO: move this to math.hpp?
        ax::v2 get_uv(int iface, int nthvert) const; // TODO: move this to math.hpp?
        ax::color get_color_diffuse(ax::v2 uv) const; // TODO: move this to math.hpp
        float get_specularity(ax::v2 uv) const; // TODO: move this to math.hpp
        std::vector<int> get_face(int idx) const;
		const ax::basic_buffer& get_diffuse_map() const { return diffuse_map; }
		const ax::basic_buffer& get_normal_map() const { return normal_map; }
		const ax::basic_buffer& get_specular_map() const { return specular_map; }

    private:

        bool try_load_texture(std::string file_path, const char *suffix, ax::basic_buffer &img);

        std::vector<std::vector<ax::v3i>> faces; // NOTE: this v3i means vertex/uv/normal. TODO: make it mean vertex/normal/uv instead.
        std::vector<ax::v3> vertices;
        std::vector<ax::v3> normals;
        std::vector<ax::v2> uvs;
        ax::option<std::vector<ax::basic_vertex>> stream_opt;
        ax::basic_buffer diffuse_map;
        ax::basic_buffer normal_map;
        ax::basic_buffer specular_map;
    };
}

#endif
<|endoftext|>


<commit_before>#ifndef K3_RUNTIME_BASETYPES_H
#define K3_RUNTIME_BASETYPES_H

#include <tuple>
#include <functional>

#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/functional/hash.hpp>

#include "serialization/yaml.hpp"

// Basic types needed by our builtin libraries

class unit_t {
  public:
  template <class archive>
  void serialize(archive&, const unsigned int) {}

  template <class archive>
  void serialize(archive&) {}

  bool operator==(const unit_t&) const { return true; }
  bool operator!=(const unit_t&) const { return false; }
  bool operator<(const unit_t&) const { return false; }
  bool operator>(const unit_t&) const { return false; }
};

namespace YAML {
  template <>
  struct convert<unit_t> {
    public:
        static Node encode(const unit_t&)  {
          Node node;
          return node;
        }
        static bool decode(const Node&, unit_t&)  {
          return true;
        }
  };
}

#ifndef K3_R_addr
#define K3_R_addr
template <class _T0>
class R_addr {
    public:
        R_addr() {}
        R_addr(_T0 _addr): addr(_addr) {}
        bool operator==(const R_addr& _r) const {
            if (addr == _r.addr)
                return true;
            return false;
        }
        bool operator!=(const R_addr& _r) const {
            return !(*this == _r);
        }
        bool operator<(const R_addr& _r) const {
          return addr < _r.addr;
        }
        template <class archive>
        void serialize(archive& _archive,const unsigned int) {
            _archive & BOOST_SERIALIZATION_NVP(addr);
        }
        template <class archive>
        void serialize(archive& _archive) {
            _archive & addr;
        }
        _T0 addr;
};
#endif // K3_R_addr

#ifndef K3_R_addr_srimpl_lvl
#define K3_R_addr_srimpl_lvl
// Turn off class information tracking in boost serialization for above types.
namespace boost {
  namespace serialization {
    template <class _T0>
    class implementation_level<R_addr<_T0>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_addr_srimpl_lvl

#ifndef K3_R_addr_hash_value
#define K3_R_addr_hash_value
template <class T>
  std::size_t hash_value(R_addr<T> const& b) {
    boost::hash<T> hasher;
    return hasher(b.addr);
}
#endif // K3_R_addr_hash_value

#ifndef K3_R_elem
#define K3_R_elem

template <class _T0>
class R_elem {
    public:
        R_elem() {}
        R_elem(_T0 _elem): elem(_elem) {}
        bool operator==(const R_elem& _r) const {
            if (elem == _r.elem)
                return true;
            return false;
        }
        // TODO, beter implementation?
        bool operator!=(const R_elem& _r) const {
            return !(*this == _r);
        }
        bool operator<(const R_elem& _r) const {
            return elem < _r.elem;
        }
        template <class archive>
        void serialize(archive& _archive,const unsigned int) {
            _archive & BOOST_SERIALIZATION_NVP(elem);
        }
        template <class archive>
        void serialize(archive& _archive) {
            _archive & elem;
        }
        _T0 elem;
};
#endif // K3_R_elem

#ifndef K3_R_elem_srimpl_lvl
#define K3_R_elem_srimpl_lvl
namespace boost {
  namespace serialization {
    template <class _T0>
    class implementation_level<R_elem<_T0>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_elem_srimpl_lvl

#ifndef K3_R_elem_hash_value
#define K3_R_elem_hash_value
template <class T>
  std::size_t hash_value(R_elem<T> const& b) {
    boost::hash<T> hasher;
    return hasher(b.elem);
}
#endif // K3_R_elem_hash_value

#ifndef K3_R_key_value
#define K3_R_key_value

template <class _T0, class _T1>
class R_key_value {
  public:
      typedef _T0 KeyType;
      typedef _T1 ValueType;
      R_key_value(): key(), value()  {}
      template <class __T0, class __T1>
      R_key_value(__T0&& _key, __T1&& _value): key(std::forward<__T0>(_key)), value(std::forward<__T1>(_value))  {}
      template <class archive>
      void serialize(archive& _archive, const unsigned int)  {
        _archive & BOOST_SERIALIZATION_NVP(key);
        _archive & BOOST_SERIALIZATION_NVP(value);
      }
      template <class archive>
      void serialize(archive& _archive)  {
        _archive & key;
        _archive & value;
      }
      bool operator==(const R_key_value<_T0, _T1>& __other) const {
        return key == (__other.key) && value == (__other.value);
      }
      bool operator!=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) != std::tie(__other.key, __other.value);
      }
      bool operator<(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) < std::tie(__other.key, __other.value);
      }
      bool operator>(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) > std::tie(__other.key, __other.value);
      }
      bool operator<=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) <= std::tie(__other.key, __other.value);
      }
      bool operator>=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) >= std::tie(__other.key, __other.value);
      }
      _T0 key;
      _T1 value;
};
#endif // K3_R_key_value

#ifndef K3_R_key_value_srimpl_lvl
#define K3_R_key_value_srimpl_lvl
namespace boost {
  namespace serialization {
    template <class _T0, class _T1>
    class implementation_level<R_key_value<_T0, _T1>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_key_value_srimpl_lvl

#ifndef K3_R_key_value_hash_value
#define K3_R_key_value_hash_value
template <class K,class V>
  std::size_t hash_value(R_key_value<K,V> const& b) {
    boost::hash<std::tuple<K,V>> hasher;
    return hasher(std::tie(b.key, b.value));
}
#endif // K3_R_key_value_hash_value

#endif // K3_RUNTIME_BASETYPES_H
<commit_msg>Add missing hash overload for unit_t.<commit_after>#ifndef K3_RUNTIME_BASETYPES_H
#define K3_RUNTIME_BASETYPES_H

#include <tuple>
#include <functional>

#include <boost/serialization/level.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/functional/hash.hpp>

#include "serialization/yaml.hpp"

// Basic types needed by our builtin libraries

class unit_t {
  public:
  template <class archive>
  void serialize(archive&, const unsigned int) {}

  template <class archive>
  void serialize(archive&) {}

  bool operator==(const unit_t&) const { return true; }
  bool operator!=(const unit_t&) const { return false; }
  bool operator<(const unit_t&) const { return false; }
  bool operator>(const unit_t&) const { return false; }
};

namespace YAML {
  template <>
  struct convert<unit_t> {
    public:
        static Node encode(const unit_t&)  {
          Node node;
          return node;
        }
        static bool decode(const Node&, unit_t&)  {
          return true;
        }
  };
}

#ifndef unit_t_hash_value
#define unit_t_hash_value
namespace K3 {
  inline std::size_t hash_value(unit_t const&) {
    return 0;
  }
}
#endif

#ifndef K3_R_addr
#define K3_R_addr
template <class _T0>
class R_addr {
    public:
        R_addr() {}
        R_addr(_T0 _addr): addr(_addr) {}
        bool operator==(const R_addr& _r) const {
            if (addr == _r.addr)
                return true;
            return false;
        }
        bool operator!=(const R_addr& _r) const {
            return !(*this == _r);
        }
        bool operator<(const R_addr& _r) const {
          return addr < _r.addr;
        }
        template <class archive>
        void serialize(archive& _archive,const unsigned int) {
            _archive & BOOST_SERIALIZATION_NVP(addr);
        }
        template <class archive>
        void serialize(archive& _archive) {
            _archive & addr;
        }
        _T0 addr;
};
#endif // K3_R_addr

#ifndef K3_R_addr_srimpl_lvl
#define K3_R_addr_srimpl_lvl
// Turn off class information tracking in boost serialization for above types.
namespace boost {
  namespace serialization {
    template <class _T0>
    class implementation_level<R_addr<_T0>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_addr_srimpl_lvl

#ifndef K3_R_addr_hash_value
#define K3_R_addr_hash_value
template <class T>
  std::size_t hash_value(R_addr<T> const& b) {
    boost::hash<T> hasher;
    return hasher(b.addr);
}
#endif // K3_R_addr_hash_value

#ifndef K3_R_elem
#define K3_R_elem

template <class _T0>
class R_elem {
    public:
        R_elem() {}
        R_elem(_T0 _elem): elem(_elem) {}
        bool operator==(const R_elem& _r) const {
            if (elem == _r.elem)
                return true;
            return false;
        }
        // TODO, beter implementation?
        bool operator!=(const R_elem& _r) const {
            return !(*this == _r);
        }
        bool operator<(const R_elem& _r) const {
            return elem < _r.elem;
        }
        template <class archive>
        void serialize(archive& _archive,const unsigned int) {
            _archive & BOOST_SERIALIZATION_NVP(elem);
        }
        template <class archive>
        void serialize(archive& _archive) {
            _archive & elem;
        }
        _T0 elem;
};
#endif // K3_R_elem

#ifndef K3_R_elem_srimpl_lvl
#define K3_R_elem_srimpl_lvl
namespace boost {
  namespace serialization {
    template <class _T0>
    class implementation_level<R_elem<_T0>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_elem_srimpl_lvl

#ifndef K3_R_elem_hash_value
#define K3_R_elem_hash_value
template <class T>
  std::size_t hash_value(R_elem<T> const& b) {
    boost::hash<T> hasher;
    return hasher(b.elem);
}
#endif // K3_R_elem_hash_value

#ifndef K3_R_key_value
#define K3_R_key_value

template <class _T0, class _T1>
class R_key_value {
  public:
      typedef _T0 KeyType;
      typedef _T1 ValueType;
      R_key_value(): key(), value()  {}
      template <class __T0, class __T1>
      R_key_value(__T0&& _key, __T1&& _value): key(std::forward<__T0>(_key)), value(std::forward<__T1>(_value))  {}
      template <class archive>
      void serialize(archive& _archive, const unsigned int)  {
        _archive & BOOST_SERIALIZATION_NVP(key);
        _archive & BOOST_SERIALIZATION_NVP(value);
      }
      template <class archive>
      void serialize(archive& _archive)  {
        _archive & key;
        _archive & value;
      }
      bool operator==(const R_key_value<_T0, _T1>& __other) const {
        return key == (__other.key) && value == (__other.value);
      }
      bool operator!=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) != std::tie(__other.key, __other.value);
      }
      bool operator<(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) < std::tie(__other.key, __other.value);
      }
      bool operator>(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) > std::tie(__other.key, __other.value);
      }
      bool operator<=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) <= std::tie(__other.key, __other.value);
      }
      bool operator>=(const R_key_value<_T0, _T1>& __other) const {
        return std::tie(key, value) >= std::tie(__other.key, __other.value);
      }
      _T0 key;
      _T1 value;
};
#endif // K3_R_key_value

#ifndef K3_R_key_value_srimpl_lvl
#define K3_R_key_value_srimpl_lvl
namespace boost {
  namespace serialization {
    template <class _T0, class _T1>
    class implementation_level<R_key_value<_T0, _T1>> {
      public:
          typedef  mpl::integral_c_tag tag;
          typedef  mpl::int_<object_serializable> type;
          BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value);
    };
  }
}
#endif // K3_R_key_value_srimpl_lvl

#ifndef K3_R_key_value_hash_value
#define K3_R_key_value_hash_value
template <class K,class V>
std::size_t hash_value(R_key_value<K,V> const& b) {
    boost::hash<std::tuple<K,V>> hasher;
    return hasher(std::tie(b.key, b.value));
}
#endif // K3_R_key_value_hash_value

#endif // K3_RUNTIME_BASETYPES_H
<|endoftext|>


<commit_before>// Message.cpp
// Implements the Message class.

#include "Message.h"

#include "Communicator.h"
#include "Model.h"
#include "MarketModel.h"

#include "Resource.h"
#include "Logger.h"
#include "Timer.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::constructBase(Communicator* sender) {
  sender_ = sender;
  curr_owner_ = sender;
  receiver_ = NULL;
  trans_ = NULL;
  dead_ = false;
  needs_next_dest_ = true;
  dir_ = UP_MSG;

  sender->trackMessage(msg_ptr(this));
  makeRealParticipant(sender);

  MLOG(LEV_DEBUG4) << "Message " << this << " created.";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender) {
  constructBase(sender);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender, Communicator* receiver) {
  constructBase(sender);
  receiver_ = receiver;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender, Communicator* receiver,
                 Transaction& trans) {
  constructBase(sender);
  receiver_ = receiver;
  trans_ = new Transaction(trans);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::~Message() {
  if (trans_ != NULL) {
    delete trans_;
  }
  MLOG(LEV_DEBUG4) << "Message " << this << " deleted.";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
msg_ptr Message::clone() {
  CLOG(LEV_DEBUG3) << "Message " << this << "was cloned.";

  msg_ptr new_msg(new Message(*this));
  try {
    new_msg->trans_ = trans_->clone();
  } catch(CycNullMsgParamException) { }
  return new_msg;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::sendOn() {
  if (dead_) {return;}

  if (needs_next_dest_) {
    autoSetNextDest();
    needs_next_dest_ = true;
  }

  validateForSend();
  msg_ptr me = msg_ptr(this);

  if (dir_ == DOWN_MSG) {
    path_stack_.back()->untrackMessage(me);
    path_stack_.pop_back();
  } else {
    path_stack_.back()->trackMessage(me);
  }

  Communicator* next_stop = path_stack_.back();
  makeRealParticipant(next_stop);
  curr_owner_ = next_stop;

  CLOG(LEV_DEBUG1) << "Message " << this << " going to comm "
                   << next_stop << " {";

  next_stop->receiveMessage(me);

  CLOG(LEV_DEBUG1) << "} Message " << this << " send to comm "
                   << next_stop << " completed";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::autoSetNextDest() {
  Model* next_model = dynamic_cast<Model*>(curr_owner_)->parent();
  Communicator* next_dest = dynamic_cast<Communicator*>(next_model);
  if (next_dest == curr_owner_) {
    next_dest = receiver_;
  }
  setNextDest(next_dest);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::validateForSend() {
  int next_stop_i = -1;
  bool has_receiver = false;
  Communicator* next_stop;

  if (dir_ == UP_MSG) {
    has_receiver = (path_stack_.size() > 0);
    next_stop_i = path_stack_.size() - 1;
  } else if (dir_ == DOWN_MSG) {
    has_receiver = (path_stack_.size() > 1);
    next_stop_i = path_stack_.size() - 2;
  }

  if (!has_receiver) {
    throw CycNoMsgReceiverException();
  }

  next_stop = path_stack_[next_stop_i];
  if (next_stop == curr_owner_) {
    throw CycCircularMsgException();
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::makeRealParticipant(Communicator* who) {
  Model* model = NULL;
  model = dynamic_cast<Model*>(who);
  if (model != NULL) {model->setIsTemplate(false);}
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::setNextDest(Communicator* next_stop) {
  if (dir_ == DOWN_MSG) {
    CLOG(LEV_DEBUG4) << "Message " << this
                     << " next stop set attempt ignored";
    return;
  }

  if (path_stack_.size() == 0) {
    path_stack_.push_back(sender_);
  }
  path_stack_.push_back(next_stop);

  needs_next_dest_ = false;

  CLOG(LEV_DEBUG4) << "Message " << this << " set next stop to comm "
                   << next_stop;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::kill() {
  MLOG(LEV_DEBUG5) << "Message " << this << " was killed.";
  dead_ = true;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Message::isDead() {
  return dead_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MessageDir Message::dir() const {
  return dir_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::setDir(MessageDir new_dir) {
  CLOG(LEV_DEBUG4) << "Message " << this << " direction manually set to "
                   << new_dir << ".";

  dir_ = new_dir;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Communicator* Message::sender() const {
  return sender_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Communicator* Message::receiver() const {
  if (receiver_ == NULL) {
    string err_msg = "Uninitilized message receiver.";
    throw CycNullMsgParamException(err_msg);
  }
  return receiver_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Transaction& Message::trans() const {
  if (trans_ == NULL) {
    throw CycNullMsgParamException("Uninitialized transaction parameter.");
  }
  return *trans_;
}

<commit_msg>fixes improper exception handling for NULL parent.  I thought root model nodes had themselves as their parent - apparently, they now have been changed to hold a NULL parent.<commit_after>// Message.cpp
// Implements the Message class.

#include "Message.h"

#include "Communicator.h"
#include "Model.h"
#include "MarketModel.h"

#include "Resource.h"
#include "Logger.h"
#include "Timer.h"

using namespace std;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::constructBase(Communicator* sender) {
  sender_ = sender;
  curr_owner_ = sender;
  receiver_ = NULL;
  trans_ = NULL;
  dead_ = false;
  needs_next_dest_ = true;
  dir_ = UP_MSG;

  sender->trackMessage(msg_ptr(this));
  makeRealParticipant(sender);

  MLOG(LEV_DEBUG4) << "Message " << this << " created.";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender) {
  constructBase(sender);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender, Communicator* receiver) {
  constructBase(sender);
  receiver_ = receiver;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::Message(Communicator* sender, Communicator* receiver,
                 Transaction& trans) {
  constructBase(sender);
  receiver_ = receiver;
  trans_ = new Transaction(trans);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Message::~Message() {
  if (trans_ != NULL) {
    delete trans_;
  }
  MLOG(LEV_DEBUG4) << "Message " << this << " deleted.";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
msg_ptr Message::clone() {
  CLOG(LEV_DEBUG3) << "Message " << this << "was cloned.";

  msg_ptr new_msg(new Message(*this));
  try {
    new_msg->trans_ = trans_->clone();
  } catch(CycNullMsgParamException) { }
  return new_msg;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::sendOn() {
  if (dead_) {return;}

  if (needs_next_dest_) {
    autoSetNextDest();
    needs_next_dest_ = true;
  }

  validateForSend();
  msg_ptr me = msg_ptr(this);

  if (dir_ == DOWN_MSG) {
    path_stack_.back()->untrackMessage(me);
    path_stack_.pop_back();
  } else {
    path_stack_.back()->trackMessage(me);
  }

  Communicator* next_stop = path_stack_.back();
  makeRealParticipant(next_stop);
  curr_owner_ = next_stop;

  CLOG(LEV_DEBUG1) << "Message " << this << " going to comm "
                   << next_stop << " {";

  next_stop->receiveMessage(me);

  CLOG(LEV_DEBUG1) << "} Message " << this << " send to comm "
                   << next_stop << " completed";
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::autoSetNextDest() {
  Model* next_model;
  Communicator* next_dest;
  try {
    next_model = dynamic_cast<Model*>(curr_owner_)->parent();
    next_dest = dynamic_cast<Communicator*>(next_model);
  } catch (CycIndexException err) {
    next_dest = receiver_;
  }
  setNextDest(next_dest);
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::validateForSend() {
  int next_stop_i = -1;
  bool has_receiver = false;
  Communicator* next_stop;

  if (dir_ == UP_MSG) {
    has_receiver = (path_stack_.size() > 0);
    next_stop_i = path_stack_.size() - 1;
  } else if (dir_ == DOWN_MSG) {
    has_receiver = (path_stack_.size() > 1);
    next_stop_i = path_stack_.size() - 2;
  }

  if (!has_receiver) {
    throw CycNoMsgReceiverException();
  }

  next_stop = path_stack_[next_stop_i];
  if (next_stop == curr_owner_) {
    throw CycCircularMsgException();
  }
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::makeRealParticipant(Communicator* who) {
  Model* model = NULL;
  model = dynamic_cast<Model*>(who);
  if (model != NULL) {model->setIsTemplate(false);}
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::setNextDest(Communicator* next_stop) {
  if (dir_ == DOWN_MSG) {
    CLOG(LEV_DEBUG4) << "Message " << this
                     << " next stop set attempt ignored";
    return;
  }

  if (path_stack_.size() == 0) {
    path_stack_.push_back(sender_);
  }
  path_stack_.push_back(next_stop);

  needs_next_dest_ = false;

  CLOG(LEV_DEBUG4) << "Message " << this << " set next stop to comm "
                   << next_stop;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::kill() {
  MLOG(LEV_DEBUG5) << "Message " << this << " was killed.";
  dead_ = true;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Message::isDead() {
  return dead_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MessageDir Message::dir() const {
  return dir_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Message::setDir(MessageDir new_dir) {
  CLOG(LEV_DEBUG4) << "Message " << this << " direction manually set to "
                   << new_dir << ".";

  dir_ = new_dir;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Communicator* Message::sender() const {
  return sender_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Communicator* Message::receiver() const {
  if (receiver_ == NULL) {
    string err_msg = "Uninitilized message receiver.";
    throw CycNullMsgParamException(err_msg);
  }
  return receiver_;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Transaction& Message::trans() const {
  if (trans_ == NULL) {
    throw CycNullMsgParamException("Uninitialized transaction parameter.");
  }
  return *trans_;
}

<|endoftext|>


<commit_before>//
// Created by Michael on 12/19/2016.
//

#include "Molecule.h"
#include <cmath>

Molecule::Molecule()
{
    Branch b;
    b.branchSMILES= "l";
}

Molecule::Molecule(std::string simpleSMILES): SMILES(simpleSMILES)
{
    convertToMolecule(SMILES);
}
void Molecule::convertToMolecule(std::string SMILES)
{
    std::vector<Branch> branches;
    branches = filterBranching(SMILES);

    if(atomList.size() == 0)
    {
        simpleSMLIESconverter(branches[0].branchSMILES);
        branches.erase(branches.begin());
    }

    int i = 0;
    while(i < branches.size())
    {
        if(isSimple(branches[i].branchSMILES))
        {
            simpleSMLIESconverter(branches[i].branchSMILES);
            //manually attach
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - branches[i].branchPoint);
        }
        else
        {
            convertToMolecule(branches[i].branchSMILES);
            //manually attach
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - branches[i].branchPoint);
        }
        i++;
    }
    fillInHydrogens();
}
bool Molecule::isSimple(std::string simpleSMILES)
{
    for(size_t i = 0; i < simpleSMILES.length(); i++)
        if(simpleSMILES[i] == '(')
            return false;
    return true;
}
void Molecule::simpleSMLIESconverter(std::string simpleSMILES)
{
    std::string tmpAtom;
    char step;

    for(int i = 0; i < simpleSMILES.size(); i++)
    {
        tmpAtom = "";
        step = simpleSMILES[i];
        if(isalpha(step))
        {
            if(i+1 < simpleSMILES.size())
            {
                if(simpleSMILES[i+1] == 'l' || simpleSMILES[i+1] == 'r')
                {
                    tmpAtom = simpleSMILES[i];
                    tmpAtom += simpleSMILES[i+1];
                }
                else
                    tmpAtom = simpleSMILES[i];
            }
            else
                    tmpAtom = simpleSMILES[i];
            if(isOrganic(tmpAtom))
            {
                Atom a(tmpAtom, atomList.size(), 3, 0);
                atomList.push_back(a);
                bonds.addPoint();
                if(atomList.size() > 0)
                    bonds.formBond(atomList.size() - 1, atomList.size() - 2);
            }
            else
                throw notAnAtom();
            if(tmpAtom.size() > 1)
                i++;
        }
        else if(step == '[') //[NH2+]
        {
            tmpAtom = simpleSMILES[i+1];
            i++;
            int charge = 0;
            while(simpleSMILES[i+1] != ']')
            {
                if(simpleSMILES[i+1] == '+' || simpleSMILES[i+1] == '-')
                {
                    if(isdigit(simpleSMILES[i+2]))
                        charge = simpleSMILES[i+2] - '0';
                    else
                        charge = 1;
                    if(simpleSMILES[i+1] == '-')
                        charge *= -1;
                }
                if(simpleSMILES[i+1] == 'H' && simpleSMILES[i+2] != 'o')
                {
                    //do nothing for now
                }
                else if(isalpha(simpleSMILES[i+1]))
                    tmpAtom += simpleSMILES[i+1];
                i++;
            }
            Atom a(tmpAtom, atomList.size(), 3, charge);
            atomList.push_back(a);
            bonds.addPoint();
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - 2);
        }
    }
}
std::vector<Branch> Molecule::filterBranching(std::string molecule)
{
    std::vector<Branch> tmp;
    tmp.push_back(Branch());
    tmp[0].branchPoint = -1;
    tmp[0].branchSMILES = "CC(=O)C";
    return tmp;
}
void Molecule::fillInHydrogens()
{
    for(size_t i = 0; i < atomList.size(); i++)
    {
        //the hybrid stored in the atom is the hybrid it is supposed to be while the bonds store what it currently is
        if(bonds.checkHybrid(i) < atomList[i].getHybrid())
        {
            double numH = atomList[i].getHybrid() - bonds.checkHybrid(i) + std::abs(atomList[i].getFormalCharge());
            for(int j = 0; j < numH; j++)
            {
                Atom a("H", atomList.size(), 0, 0);
                atomList.push_back(a);
                bonds.addPoint();
                bonds.formBond(i, atomList.size() - 1);
            }
        }
    }
}
double Molecule::calculateMolecularWeight()
{
    return 0;
}

bool Molecule::isOrganic(std::string a)
{
    return true;
}
<commit_msg>Implemented isOrgainic and added bond functionality<commit_after>//
// Created by Michael on 12/19/2016.
//

#include "Molecule.h"
#include <cmath>

Molecule::Molecule()
{
    Branch b;
    b.branchSMILES= "l";
}

Molecule::Molecule(std::string simpleSMILES): SMILES(simpleSMILES)
{
    convertToMolecule(SMILES);
}
void Molecule::convertToMolecule(std::string SMILES)
{
    std::vector<Branch> branches;
    branches = filterBranching(SMILES);

    if(atomList.size() == 0)
    {
        simpleSMLIESconverter(branches[0].branchSMILES);
        branches.erase(branches.begin());
    }

    int i = 0;
    while(i < branches.size())
    {
        if(isSimple(branches[i].branchSMILES))
        {
            simpleSMLIESconverter(branches[i].branchSMILES);
            //manually attach
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - branches[i].branchPoint);
        }
        else
        {
            convertToMolecule(branches[i].branchSMILES);
            //manually attach
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - branches[i].branchPoint);
        }
        i++;
    }
    fillInHydrogens();
}
bool Molecule::isSimple(std::string simpleSMILES)
{
    for(size_t i = 0; i < simpleSMILES.length(); i++)
        if(simpleSMILES[i] == '(')
            return false;
    return true;
}
void Molecule::simpleSMLIESconverter(std::string simpleSMILES)
{
    std::string tmpAtom;
    char step;
    std::vector<size_t> doubles, triples, aromatics; // stores the locations of double,
    // triple, and aromatic bonds respectively

    for(int i = 0; i < simpleSMILES.size(); i++)
    {
        tmpAtom = "";
        step = simpleSMILES[i];
        if(isalpha(step))
        {
            if(i+1 < simpleSMILES.size())
            {
                if(simpleSMILES[i+1] == 'l' || simpleSMILES[i+1] == 'r')
                {
                    tmpAtom = simpleSMILES[i];
                    tmpAtom += simpleSMILES[i+1];
                }
                else
                    tmpAtom = simpleSMILES[i];
            }
            else
                    tmpAtom = simpleSMILES[i];
            if(isOrganic(tmpAtom))
            {
                Atom a(tmpAtom, atomList.size(), 3, 0);
                atomList.push_back(a);
                bonds.addPoint();
                if(atomList.size() > 0)
                    bonds.formBond(atomList.size() - 1, atomList.size() - 2);
            }
            else
                throw notAnAtom();
            if(tmpAtom.size() > 1)
                i++;
        }
        else if(step == '=' || step == '#' || step == ':')
        {
            if(step == '=')
                doubles.push_back(atomList.size() - 1);
            else if(step == '#')
                triples.push_back(atomList.size() - 1);
            else
                aromatics.push_back(atomList.size() - 1);
        }
        else if(step == '[') //[NH2+]
        {
            tmpAtom = simpleSMILES[i+1];
            i++;
            int charge = 0;
            while(simpleSMILES[i+1] != ']')
            {
                if(simpleSMILES[i+1] == '+' || simpleSMILES[i+1] == '-')
                {
                    if(isdigit(simpleSMILES[i+2]))
                        charge = simpleSMILES[i+2] - '0';
                    else
                        charge = 1;
                    if(simpleSMILES[i+1] == '-')
                        charge *= -1;
                }
                if(simpleSMILES[i+1] == 'H' && simpleSMILES[i+2] != 'o')
                {
                    //do nothing for now
                }
                else if(isalpha(simpleSMILES[i+1]))
                    tmpAtom += simpleSMILES[i+1];
                i++;
            }
            Atom a(tmpAtom, atomList.size(), 3, charge);
            atomList.push_back(a);
            bonds.addPoint();
            if(atomList.size() > 0)
                bonds.formBond(atomList.size() - 1, atomList.size() - 2);
        }
    }
    for(int i = 0; i < doubles.size(); i++)
        bonds.alterBondValue(doubles[i], doubles[i] + 1, 2);
    for(int i = 0; i < triples.size(); i++)
        bonds.alterBondValue(triples[i], triples[i] + 1, 3);
    for(int i = 0; i < aromatics.size(); i++)
        bonds.alterBondValue(aromatics[i], aromatics[i] + 1, 4);
}
std::vector<Branch> Molecule::filterBranching(std::string molecule)
{
    std::vector<Branch> tmp;
    tmp.push_back(Branch());
    tmp[0].branchPoint = -1;
    tmp[0].branchSMILES = "CC(=O)C";
    return tmp;
}
void Molecule::fillInHydrogens()
{
    for(size_t i = 0; i < atomList.size(); i++)
    {
        //the hybrid stored in the atom is the hybrid it is supposed to be while the bonds store what it currently is
        if(bonds.checkHybrid(i) < atomList[i].getHybrid())
        {
            double numH = atomList[i].getHybrid() - bonds.checkHybrid(i) + std::abs(atomList[i].getFormalCharge());
            for(int j = 0; j < numH; j++)
            {
                Atom a("H", atomList.size(), 0, 0);
                atomList.push_back(a);
                bonds.addPoint();
                bonds.formBond(i, atomList.size() - 1);
            }
        }
    }
}
double Molecule::calculateMolecularWeight()
{
    return 0;
}

bool Molecule::isOrganic(std::string a)
{
    return a == "C" || a == "N" || a == "O" || a == "Br" || a == "Cl" || a == "F" || a == "I" || a == "S" || a =="P";
}
<|endoftext|>