<commit_before>/*-------------------------------------------------------------------------
 *
 * ddl_index.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_index.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <vector>

#include "backend/bridge/ddl/ddl_index.h"
#include "backend/bridge/ddl/bridge.h"
#include "backend/catalog/manager.h"
#include "backend/common/logger.h"
#include "backend/index/index.h"
#include "backend/index/index_factory.h"
#include "backend/storage/data_table.h"
#include "backend/storage/database.h"

#include "nodes/pg_list.h"

namespace peloton {
namespace bridge {

/**
 * @brief Execute the index stmt.
 * @param the parse tree
 * @param the parsetree_stack store parsetree if the table is not created yet
 * @return true if we handled it correctly, false otherwise
 */
bool DDLIndex::ExecIndexStmt(Node* parsetree,
                             std::vector<Node*>& parsetree_stack) {
  IndexStmt* Istmt = (IndexStmt*)parsetree;

  // If table has not been created yet, store it into the parsetree stack
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
  if (nullptr == db->GetTableWithName(Istmt->relation->relname)) {
    parsetree_stack.push_back(parsetree);
    return true;
  }

  IndexInfo* index_info = DDLIndex::ConstructIndexInfoByParsingIndexStmt(Istmt);

  DDLIndex::CreateIndex(*index_info);
  return true;
}

/**
 * @brief Create index.
 * @param index_name Index name
 * @param table_name Table name
 * @param type Type of the index
 * @param unique Index is unique or not ?
 * @param key_column_names column names for the key table
 * @return true if we create the index, false otherwise
 */
bool DDLIndex::CreateIndex(IndexInfo index_info) {
  std::string index_name = index_info.GetIndexName();
  oid_t index_oid = index_info.GetOid();
  std::string table_name = index_info.GetTableName();
  IndexConstraintType index_type = index_info.GetType();
  bool unique_keys = index_info.IsUnique();
  std::vector<std::string> key_column_names = index_info.GetKeyColumnNames();

  if (index_oid == INVALID_OID) return false;
  if (index_name.empty()) return false;
  if (table_name.empty()) return false;
  if (key_column_names.size() <= 0) return false;

  // TODO: We currently only support btree as our index implementation
  // TODO : Support other types based on "type" argument
  IndexType our_index_type = INDEX_TYPE_BTREE;

  // Get the database oid and table oid
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();
  assert(database_oid);

  // Get the table location from db
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);
  storage::DataTable* data_table = db->GetTableWithName(table_name);

  catalog::Schema* tuple_schema = data_table->GetSchema();

  // Construct key schema
  std::vector<oid_t> key_columns;

  // Based on the key column info, get the oid of the given 'key' columns in the
  // tuple schema
  for (auto key_column_name : key_column_names) {
    for (oid_t tuple_schema_column_itr = 0;
         tuple_schema_column_itr < tuple_schema->GetColumnCount();
         tuple_schema_column_itr++) {
      // Get the current column info from tuple schema
      catalog::Column column_info =
          tuple_schema->GetColumn(tuple_schema_column_itr);
      // Compare Key Schema's current column name and Tuple Schema's current
      // column name
      if (key_column_name == column_info.GetName()) {
        key_columns.push_back(tuple_schema_column_itr);

        // NOTE :: Since pg_attribute doesn't have any information about primary
        // key and unique key,
        //         I try to store these information when we create an unique and
        //         primary key index
        if (index_type == INDEX_CONSTRAINT_TYPE_PRIMARY_KEY) {
          catalog::Constraint constraint(CONSTRAINT_TYPE_PRIMARY, index_name);
          tuple_schema->AddConstraint(tuple_schema_column_itr, constraint);
        } else if (index_type == INDEX_CONSTRAINT_TYPE_UNIQUE) {
          catalog::Constraint constraint(CONSTRAINT_TYPE_UNIQUE, index_name);
          constraint.SetUniqueIndexOffset(data_table->GetIndexCount());
          tuple_schema->AddConstraint(tuple_schema_column_itr, constraint);
        }
      }
    }
  }

  auto key_schema = catalog::Schema::CopySchema(tuple_schema, key_columns);
  key_schema->SetIndexedColumns(key_columns);

  // Create index metadata and physical index
  index::IndexMetadata* metadata = new index::IndexMetadata(
      index_name, index_oid, our_index_type, index_type, tuple_schema,
      key_schema, unique_keys);
  index::Index* index = index::IndexFactory::GetInstance(metadata);

  // Record the built index in the table
  data_table->AddIndex(index);

  LOG_INFO("Create index(%u)  %s on %s.", index_oid, index_name.c_str(),
           table_name.c_str());

  return true;
}

/**
 * @brief Construct IndexInfo from a index statement
 * @param Istmt an index statement
 * @return IndexInfo
 */
IndexInfo* DDLIndex::ConstructIndexInfoByParsingIndexStmt(IndexStmt* Istmt) {
  std::string index_name;
  oid_t index_oid = Istmt->index_id;
  std::string table_name;
  IndexType method_type;
  IndexConstraintType type = INDEX_CONSTRAINT_TYPE_DEFAULT;
  std::vector<std::string> key_column_names;

  // Table name
  table_name = Istmt->relation->relname;

  // Key column names
  ListCell* entry;
  foreach (entry, Istmt->indexParams) {
    IndexElem* indexElem = static_cast<IndexElem*>(lfirst(entry));
    if (indexElem->name != NULL) {
      key_column_names.push_back(indexElem->name);
    }
  }

  // Index name and index type
  if (Istmt->idxname == NULL) {
    if (Istmt->isconstraint) {
      if (Istmt->primary) {
        index_name = table_name + "_pkey";
        type = INDEX_CONSTRAINT_TYPE_PRIMARY_KEY;
      } else if (Istmt->unique) {
        index_name = table_name;
        for (auto column_name : key_column_names) {
          index_name += "_" + column_name + "_";
        }
        index_name += "key";
        type = INDEX_CONSTRAINT_TYPE_UNIQUE;
      }
    } else {
      LOG_WARN("No index name");
    }
  } else {
    index_name = Istmt->idxname;
  }

  // Index method type
  // TODO :: More access method types need
  method_type = INDEX_TYPE_BTREE;

  IndexInfo* index_info =
      new IndexInfo(index_name, index_oid, table_name, method_type, type,
                    Istmt->unique, key_column_names);
  return index_info;
}

/**
 * @brief Create the indexes using IndexInfos and add it to the table
 * @param relation_oid relation oid
 * @return true if we create all the indexes, false otherwise
 */
bool DDLIndex::CreateIndexes(std::vector<IndexInfo>& index_infos) {
  for (auto index_info : index_infos) {
    CreateIndex(index_info);
  }
  index_infos.clear();
  return true;
}

}  // namespace bridge
}  // namespace peloton
<commit_msg>Handled the corner case that index name is missing<commit_after>/*-------------------------------------------------------------------------
 *
 * ddl_index.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_index.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <vector>

#include "backend/bridge/ddl/ddl_index.h"
#include "backend/bridge/ddl/bridge.h"
#include "backend/catalog/manager.h"
#include "backend/common/logger.h"
#include "backend/index/index.h"
#include "backend/index/index_factory.h"
#include "backend/storage/data_table.h"
#include "backend/storage/database.h"

#include "nodes/pg_list.h"

namespace peloton {
namespace bridge {

/**
 * @brief Execute the index stmt.
 * @param the parse tree
 * @param the parsetree_stack store parsetree if the table is not created yet
 * @return true if we handled it correctly, false otherwise
 */
bool DDLIndex::ExecIndexStmt(Node* parsetree,
                             std::vector<Node*>& parsetree_stack) {
  IndexStmt* Istmt = (IndexStmt*)parsetree;

  // If table has not been created yet, store it into the parsetree stack
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
  if (nullptr == db->GetTableWithName(Istmt->relation->relname)) {
    parsetree_stack.push_back(parsetree);
    return true;
  }

  IndexInfo* index_info = DDLIndex::ConstructIndexInfoByParsingIndexStmt(Istmt);

  DDLIndex::CreateIndex(*index_info);
  return true;
}

/**
 * @brief Create index.
 * @param index_name Index name
 * @param table_name Table name
 * @param type Type of the index
 * @param unique Index is unique or not ?
 * @param key_column_names column names for the key table
 * @return true if we create the index, false otherwise
 */
bool DDLIndex::CreateIndex(IndexInfo index_info) {
  std::string index_name = index_info.GetIndexName();
  oid_t index_oid = index_info.GetOid();
  std::string table_name = index_info.GetTableName();
  IndexConstraintType index_type = index_info.GetType();
  bool unique_keys = index_info.IsUnique();
  std::vector<std::string> key_column_names = index_info.GetKeyColumnNames();

  if (index_oid == INVALID_OID) return false;
  if (index_name.empty()) return false;
  if (table_name.empty()) return false;
  if (key_column_names.size() <= 0) return false;

  // TODO: We currently only support btree as our index implementation
  // TODO : Support other types based on "type" argument
  IndexType our_index_type = INDEX_TYPE_BTREE;

  // Get the database oid and table oid
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();
  assert(database_oid);

  // Get the table location from db
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);
  storage::DataTable* data_table = db->GetTableWithName(table_name);

  catalog::Schema* tuple_schema = data_table->GetSchema();

  // Construct key schema
  std::vector<oid_t> key_columns;

  // Based on the key column info, get the oid of the given 'key' columns in the
  // tuple schema
  for (auto key_column_name : key_column_names) {
    for (oid_t tuple_schema_column_itr = 0;
         tuple_schema_column_itr < tuple_schema->GetColumnCount();
         tuple_schema_column_itr++) {
      // Get the current column info from tuple schema
      catalog::Column column_info =
          tuple_schema->GetColumn(tuple_schema_column_itr);
      // Compare Key Schema's current column name and Tuple Schema's current
      // column name
      if (key_column_name == column_info.GetName()) {
        key_columns.push_back(tuple_schema_column_itr);

        // NOTE :: Since pg_attribute doesn't have any information about primary
        // key and unique key,
        //         I try to store these information when we create an unique and
        //         primary key index
        if (index_type == INDEX_CONSTRAINT_TYPE_PRIMARY_KEY) {
          catalog::Constraint constraint(CONSTRAINT_TYPE_PRIMARY, index_name);
          tuple_schema->AddConstraint(tuple_schema_column_itr, constraint);
        } else if (index_type == INDEX_CONSTRAINT_TYPE_UNIQUE) {
          catalog::Constraint constraint(CONSTRAINT_TYPE_UNIQUE, index_name);
          constraint.SetUniqueIndexOffset(data_table->GetIndexCount());
          tuple_schema->AddConstraint(tuple_schema_column_itr, constraint);
        }
      }
    }
  }

  auto key_schema = catalog::Schema::CopySchema(tuple_schema, key_columns);
  key_schema->SetIndexedColumns(key_columns);

  // Create index metadata and physical index
  index::IndexMetadata* metadata = new index::IndexMetadata(
      index_name, index_oid, our_index_type, index_type, tuple_schema,
      key_schema, unique_keys);
  index::Index* index = index::IndexFactory::GetInstance(metadata);

  // Record the built index in the table
  data_table->AddIndex(index);

  LOG_INFO("Create index(%u)  %s on %s.", index_oid, index_name.c_str(),
           table_name.c_str());

  return true;
}

/**
 * @brief Construct IndexInfo from a index statement
 * @param Istmt an index statement
 * @return IndexInfo
 */
IndexInfo* DDLIndex::ConstructIndexInfoByParsingIndexStmt(IndexStmt* Istmt) {
  std::string index_name;
  oid_t index_oid = Istmt->index_id;
  std::string table_name;
  IndexType method_type;
  IndexConstraintType type = INDEX_CONSTRAINT_TYPE_DEFAULT;
  std::vector<std::string> key_column_names;

  // Table name
  table_name = Istmt->relation->relname;

  // Key column names
  ListCell* entry;
  foreach (entry, Istmt->indexParams) {
    IndexElem* indexElem = static_cast<IndexElem*>(lfirst(entry));
    if (indexElem->name != NULL) {
      key_column_names.push_back(indexElem->name);
    }
  }

  // Index name and index type
  if (Istmt->idxname == NULL) {
    if (Istmt->isconstraint) {
      if (Istmt->primary) {
        index_name = table_name + "_pkey";
        type = INDEX_CONSTRAINT_TYPE_PRIMARY_KEY;
      } else if (Istmt->unique) {
        index_name = table_name;
        for (auto column_name : key_column_names) {
          index_name += "_" + column_name + "_";
        }
        index_name += "key";
        type = INDEX_CONSTRAINT_TYPE_UNIQUE;
      }
    } else {
      index_name = table_name;
      for (auto column_name : key_column_names) {
        index_name += "_" + column_name + "_";
      }
      index_name += "idx";
    }
  } else {
    index_name = Istmt->idxname;
  }

  // Index method type
  // TODO :: More access method types need
  method_type = INDEX_TYPE_BTREE;

  IndexInfo* index_info =
      new IndexInfo(index_name, index_oid, table_name, method_type, type,
                    Istmt->unique, key_column_names);
  return index_info;
}

/**
 * @brief Create the indexes using IndexInfos and add it to the table
 * @param relation_oid relation oid
 * @return true if we create all the indexes, false otherwise
 */
bool DDLIndex::CreateIndexes(std::vector<IndexInfo>& index_infos) {
  for (auto index_info : index_infos) {
    CreateIndex(index_info);
  }
  index_infos.clear();
  return true;
}

}  // namespace bridge
}  // namespace peloton
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/process.h>
#include <vistk/pipeline/process_exception.h>
#include <vistk/pipeline/process_registry.h>
#include <vistk/pipeline/process_registry_exception.h>
#include <vistk/pipeline/types.h>

#include <boost/foreach.hpp>

#include <exception>
#include <iostream>

int
main()
{
  vistk::process_registry_t reg = vistk::process_registry::self();

  try
  {
    vistk::load_known_modules();
  }
  catch (vistk::process_type_already_exists_exception& e)
  {
    std::cerr << "Error: Duplicate process names: " << e.what() << std::endl;
  }
  catch (vistk::pipeline_exception& e)
  {
    std::cerr << "Error: Failed to load modules: " << e.what() << std::endl;
  }
  catch (std::exception& e)
  {
    std::cerr << "Error: Unexpected exception when loading modules: " << e.what() << std::endl;

    return 1;
  }

  vistk::process::name_t const expected_name = vistk::process::name_t("expected_name");

  vistk::process_registry::types_t const types = reg->types();

  vistk::config_t config = vistk::config::empty_config();
  config->set_value(vistk::process::config_name, expected_name);

  BOOST_FOREACH (vistk::process_registry::type_t const& type, types)
  {
    vistk::process_t process;

    try
    {
      process = reg->create_process(type, config);
    }
    catch (vistk::no_such_process_type_exception& e)
    {
      std::cerr << "Error: Failed to create process: " << e.what() << std::endl;

      continue;
    }
    catch (std::exception& e)
    {
      std::cerr << "Error: Unexpected exception when creating process: " << e.what() << std::endl;
    }

    if (!process)
    {
      std::cerr << "Error: Received NULL process (" << type << ")" << std::endl;

      continue;
    }

    if (process->name() != expected_name)
    {
      std::cerr << "Error: Name (" << process->name() << ") "
                << "does not match expected name: " << expected_name << std::endl;
    }

    vistk::config::keys_t const keys = process->available_config();

    BOOST_FOREACH (vistk::config::key_t const& key, keys)
    {
      try
      {
        process->config_default(key);
      }
      catch (vistk::unknown_configuration_value_exception& e)
      {
        std::cerr << "Error: Failed to get a default for "
                  << type << vistk::config::block_sep << key
                  << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for default "
                  << "(" << type << vistk::config::block_sep
                  << key << "): " << e.what() << std::endl;
      }

      try
      {
        process->config_description(key);
      }
      catch (vistk::unknown_configuration_value_exception& e)
      {
        std::cerr << "Error: Failed to get a description for "
                  << type << vistk::config::block_sep << key
                  << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for description "
                  << "(" << type << vistk::config::block_sep
                  << key << "): " << e.what() << std::endl;
      }
    }

    vistk::process::ports_t const iports = process->input_ports();

    BOOST_FOREACH (vistk::process::port_t const& port, iports)
    {
      try
      {
        process->input_port_type(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a type for input port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for input port type "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }

      try
      {
        process->input_port_description(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a description for input port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for input port description "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }
    }

    vistk::process::ports_t const oports = process->output_ports();

    BOOST_FOREACH (vistk::process::port_t const& port, oports)
    {
      try
      {
        process->output_port_type(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a type for output port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for output port type "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }

      try
      {
        process->output_port_description(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a description for output port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for output port description "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }
    }
  }

  return 0;
}
<commit_msg>Test that the process description is non-empty<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/process.h>
#include <vistk/pipeline/process_exception.h>
#include <vistk/pipeline/process_registry.h>
#include <vistk/pipeline/process_registry_exception.h>
#include <vistk/pipeline/types.h>

#include <boost/foreach.hpp>

#include <exception>
#include <iostream>

int
main()
{
  vistk::process_registry_t reg = vistk::process_registry::self();

  try
  {
    vistk::load_known_modules();
  }
  catch (vistk::process_type_already_exists_exception& e)
  {
    std::cerr << "Error: Duplicate process names: " << e.what() << std::endl;
  }
  catch (vistk::pipeline_exception& e)
  {
    std::cerr << "Error: Failed to load modules: " << e.what() << std::endl;
  }
  catch (std::exception& e)
  {
    std::cerr << "Error: Unexpected exception when loading modules: " << e.what() << std::endl;

    return 1;
  }

  vistk::process::name_t const expected_name = vistk::process::name_t("expected_name");

  vistk::process_registry::types_t const types = reg->types();

  vistk::config_t config = vistk::config::empty_config();
  config->set_value(vistk::process::config_name, expected_name);

  BOOST_FOREACH (vistk::process_registry::type_t const& type, types)
  {
    vistk::process_t process;

    try
    {
      process = reg->create_process(type, config);
    }
    catch (vistk::no_such_process_type_exception& e)
    {
      std::cerr << "Error: Failed to create process: " << e.what() << std::endl;

      continue;
    }
    catch (std::exception& e)
    {
      std::cerr << "Error: Unexpected exception when creating process: " << e.what() << std::endl;
    }

    if (!process)
    {
      std::cerr << "Error: Received NULL process (" << type << ")" << std::endl;

      continue;
    }

    if (reg->description(type).empty())
    {
      std::cerr << "Error: The description is empty" << std::endl;
    }

    if (process->name() != expected_name)
    {
      std::cerr << "Error: Name (" << process->name() << ") "
                << "does not match expected name: " << expected_name << std::endl;
    }

    vistk::config::keys_t const keys = process->available_config();

    BOOST_FOREACH (vistk::config::key_t const& key, keys)
    {
      try
      {
        process->config_default(key);
      }
      catch (vistk::unknown_configuration_value_exception& e)
      {
        std::cerr << "Error: Failed to get a default for "
                  << type << vistk::config::block_sep << key
                  << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for default "
                  << "(" << type << vistk::config::block_sep
                  << key << "): " << e.what() << std::endl;
      }

      try
      {
        process->config_description(key);
      }
      catch (vistk::unknown_configuration_value_exception& e)
      {
        std::cerr << "Error: Failed to get a description for "
                  << type << vistk::config::block_sep << key
                  << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for description "
                  << "(" << type << vistk::config::block_sep
                  << key << "): " << e.what() << std::endl;
      }
    }

    vistk::process::ports_t const iports = process->input_ports();

    BOOST_FOREACH (vistk::process::port_t const& port, iports)
    {
      try
      {
        process->input_port_type(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a type for input port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for input port type "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }

      try
      {
        process->input_port_description(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a description for input port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for input port description "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }
    }

    vistk::process::ports_t const oports = process->output_ports();

    BOOST_FOREACH (vistk::process::port_t const& port, oports)
    {
      try
      {
        process->output_port_type(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a type for output port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for output port type "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }

      try
      {
        process->output_port_description(port);
      }
      catch (vistk::no_such_port_exception& e)
      {
        std::cerr << "Error: Failed to get a description for output port "
                  << type << "." << port << ": " << e.what() << std::endl;
      }
      catch (std::exception& e)
      {
        std::cerr << "Error: Unexpected exception when querying for output port description "
                  << "(" << type << "." << port << "): " << e.what() << std::endl;
      }
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libone project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <string>
#include <librevenge-stream/librevenge-stream.h>
#include <unordered_map>
#include <iostream>
#include <iostream>
#include <iomanip>
#include "StringInStorageBuffer.h"
#include "libone_utils.h"

namespace libone {

  void StringInStorageBuffer::parse(librevenge::RVNGInputStream *input) {
    std::stringstream stream;
    length = readU32(input);
    std::vector<char> string;
    char *buf = (char *) readNBytes(input, length*2);
    string.assign(buf, buf+length*2);
    ustring = librevenge::RVNGString((char *) &string[0]);

    ONE_DEBUG_MSG(("read length1 %lu length2 %lu string1 %s string2 %s end\n", length, ustring.len(), &string[0], ustring.cstr()));
  }

  std::string StringInStorageBuffer::to_string() {
    return ustring.cstr();
  }

}

<commit_msg>Fix some more debugging fallout<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libone project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <string>
#include <librevenge-stream/librevenge-stream.h>
#include <unordered_map>
#include <iostream>
#include <iostream>
#include <iomanip>
#include "StringInStorageBuffer.h"
#include "libone_utils.h"

namespace libone {

  void StringInStorageBuffer::parse(librevenge::RVNGInputStream *input) {
    std::stringstream stream;
    length = readU32(input);
    std::vector<char> string;
    char *buf = (char *) readNBytes(input, length*2);
    string.assign(buf, buf+length*2);
    ustring = librevenge::RVNGString((char *) &string[0]);

    ONE_DEBUG_MSG(("read length1 %u length2 %u string1 %s string2 %s end\n", length, ustring.len(), &string[0], ustring.cstr()));
  }

  std::string StringInStorageBuffer::to_string() {
    return ustring.cstr();
  }

}

<|endoftext|>


<commit_before>#include "tidyup_state_creators/goalCreatorDefineGoal.h"
#include <pluginlib/class_list_macros.h>
#include <ros/ros.h>

PLUGINLIB_EXPORT_CLASS(tidyup_state_creators::GoalCreatorDefineGoal, continual_planning_executive::GoalCreator)

namespace tidyup_state_creators
{

    GoalCreatorDefineGoal::GoalCreatorDefineGoal()
    {
    }

    GoalCreatorDefineGoal::~GoalCreatorDefineGoal()
    {
    }

    void GoalCreatorDefineGoal::initialize(const std::deque<std::string> & arguments)
    {
    }

    bool GoalCreatorDefineGoal::fillStateAndGoal(SymbolicState & currentState, SymbolicState & goal)
    {
    	goal.setForEachGoalStatement("manipulation_location", "location-inspected", true);
    	goal.setForEachGoalStatement("movable_object", "object-inspected", true);
    	goal.setForEachGoalStatement("arm", "hand-free", true); // derived predicate
        return true;
    }

};

<commit_msg>changed manipulation_location-inspected to table-inspected - todo delete definegoalGrounding<commit_after>#include "tidyup_state_creators/goalCreatorDefineGoal.h"
#include <pluginlib/class_list_macros.h>
#include <ros/ros.h>

PLUGINLIB_EXPORT_CLASS(tidyup_state_creators::GoalCreatorDefineGoal, continual_planning_executive::GoalCreator)

namespace tidyup_state_creators
{

    GoalCreatorDefineGoal::GoalCreatorDefineGoal()
    {
    }

    GoalCreatorDefineGoal::~GoalCreatorDefineGoal()
    {
    }

    void GoalCreatorDefineGoal::initialize(const std::deque<std::string> & arguments)
    {
    }

    bool GoalCreatorDefineGoal::fillStateAndGoal(SymbolicState & currentState, SymbolicState & goal)
    {
    	goal.setForEachGoalStatement("table", "table-inspected", true);
    	goal.setForEachGoalStatement("movable_object", "object-inspected", true);
    	goal.setForEachGoalStatement("arm", "hand-free", true); // derived predicate
        return true;
    }

};

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "CeTcpSyncConnection.h"
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo>

static const QString ceTcpSyncProgram = ceTcpSyncProgram + "";
extern void debugOutput(const QString& text, int level);

CeTcpSyncConnection::CeTcpSyncConnection()
        : AbstractRemoteConnection()
        , connected(false)
{
}

CeTcpSyncConnection::~CeTcpSyncConnection()
{
    if (isConnected())
        disconnect();
}

bool CeTcpSyncConnection::connect(QVariantList&)
{
    // We connect with each command, so this is always true
    // The command itself will fail then
    if (system(ceTcpSyncProgram + " noop") != 0)
        return false;
    connected = true;
    return true;
}

void CeTcpSyncConnection::disconnect()
{
    connected = false;
}

bool CeTcpSyncConnection::isConnected() const
{
    return connected;
}

inline QString boolToString(bool b)
{
    return b ? "true" : "false";
}

static bool fileTimeFromString(FILETIME& ft, const QString& str)
{
    int idx = str.indexOf("*");
    if (idx <= 0)
        return false;
    bool ok;
    ft.dwLowDateTime = str.left(idx).toULong(&ok);
    if (!ok)
        return false;
    ft.dwHighDateTime = str.mid(idx+1).toULong(&ok);
    return ok;
}

static QString fileTimeToString(FILETIME& ft)
{
    return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime);
}

bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory,
                                        bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::deleteFile(const QString &fileName)
{
    QString cmd = ceTcpSyncProgram + " deleteFile \"" + fileName + "\"";
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists)
{
    QString cmd = ceTcpSyncProgram + " deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue)
{
    QString cmd = ceTcpSyncProgram + " execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout);
    int exitCode = system(qPrintable(cmd));
    if (returnValue)
        *returnValue = exitCode;
    return true;
}

bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore)
{
    QString cmd = ceTcpSyncProgram + " createDirectory \"" + path + "\" " + boolToString(deleteBefore);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const
{
    QString cmd = ceTcpSyncProgram + " timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >qt_cetcpsyncdata.txt";
    if (system(qPrintable(cmd)) != 0)
        return false;

    QFile file("qt_cetcpsyncdata.txt");
    if (!file.open(QIODevice::ReadOnly))
        return false;

    bool result = fileTimeFromString(*fTime, file.readLine());
    file.close();
    file.remove();
    return result;
}

bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const
{
    QString cmd = ceTcpSyncProgram + " fileCreationTime \"" + fileName + "\" >qt_cetcpsyncdata.txt";
    if (system(qPrintable(cmd)) != 0)
        return false;

    QFile file("qt_cetcpsyncdata.txt");
    if (!file.open(QIODevice::ReadOnly))
        return false;

    bool result = fileTimeFromString(*deviceCreationTime, file.readLine());
    file.close();
    file.remove();
    return result;
}
<commit_msg>cetest compile fix<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "CeTcpSyncConnection.h"
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo>

static const QString ceTcpSyncProgram = "cetcpsync";
extern void debugOutput(const QString& text, int level);

CeTcpSyncConnection::CeTcpSyncConnection()
        : AbstractRemoteConnection()
        , connected(false)
{
}

CeTcpSyncConnection::~CeTcpSyncConnection()
{
    if (isConnected())
        disconnect();
}

bool CeTcpSyncConnection::connect(QVariantList&)
{
    // We connect with each command, so this is always true
    // The command itself will fail then
    const QString cmd = ceTcpSyncProgram + " noop";
    if (system(qPrintable(cmd)) != 0)
        return false;
    connected = true;
    return true;
}

void CeTcpSyncConnection::disconnect()
{
    connected = false;
}

bool CeTcpSyncConnection::isConnected() const
{
    return connected;
}

inline QString boolToString(bool b)
{
    return b ? "true" : "false";
}

static bool fileTimeFromString(FILETIME& ft, const QString& str)
{
    int idx = str.indexOf("*");
    if (idx <= 0)
        return false;
    bool ok;
    ft.dwLowDateTime = str.left(idx).toULong(&ok);
    if (!ok)
        return false;
    ft.dwHighDateTime = str.mid(idx+1).toULong(&ok);
    return ok;
}

static QString fileTimeToString(FILETIME& ft)
{
    return QString::number(ft.dwLowDateTime) + "*" + QString::number(ft.dwHighDateTime);
}

bool CeTcpSyncConnection::copyFileToDevice(const QString &localSource, const QString &deviceDest, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFileToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectoryToDevice(const QString &localSource, const QString &deviceDest, bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectoryToDevice \"" + localSource + "\" \"" + deviceDest + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyFileFromDevice(const QString &deviceSource, const QString &localDest, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFileFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectoryFromDevice(const QString &deviceSource, const QString &localDest, bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectoryFromDevice \"" + deviceSource + "\" \"" + localDest + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyFile(const QString &srcFile, const QString &destFile, bool failIfExists)
{
    QString cmd = ceTcpSyncProgram + " copyFile \"" + srcFile + "\" \"" + destFile + "\" " + boolToString(failIfExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::copyDirectory(const QString &srcDirectory, const QString &destDirectory,
                                        bool recursive)
{
    QString cmd = ceTcpSyncProgram + " copyDirectory \"" + srcDirectory + "\" \"" + destDirectory + "\" " + boolToString(recursive);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::deleteFile(const QString &fileName)
{
    QString cmd = ceTcpSyncProgram + " deleteFile \"" + fileName + "\"";
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::deleteDirectory(const QString &directory, bool recursive, bool failIfContentExists)
{
    QString cmd = ceTcpSyncProgram + " deleteDirectory \"" + directory + "\" " + boolToString(recursive) + " " + boolToString(failIfContentExists);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::execute(QString program, QString arguments, int timeout, int *returnValue)
{
    QString cmd = ceTcpSyncProgram + " execute \"" + program + "\" \"" + arguments + "\" " + QString::number(timeout);
    int exitCode = system(qPrintable(cmd));
    if (returnValue)
        *returnValue = exitCode;
    return true;
}

bool CeTcpSyncConnection::createDirectory(const QString &path, bool deleteBefore)
{
    QString cmd = ceTcpSyncProgram + " createDirectory \"" + path + "\" " + boolToString(deleteBefore);
    return system(qPrintable(cmd)) == 0;
}

bool CeTcpSyncConnection::timeStampForLocalFileTime(FILETIME* fTime) const
{
    QString cmd = ceTcpSyncProgram + " timeStampForLocalFileTime " + fileTimeToString(*fTime) + " >qt_cetcpsyncdata.txt";
    if (system(qPrintable(cmd)) != 0)
        return false;

    QFile file("qt_cetcpsyncdata.txt");
    if (!file.open(QIODevice::ReadOnly))
        return false;

    bool result = fileTimeFromString(*fTime, file.readLine());
    file.close();
    file.remove();
    return result;
}

bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* deviceCreationTime) const
{
    QString cmd = ceTcpSyncProgram + " fileCreationTime \"" + fileName + "\" >qt_cetcpsyncdata.txt";
    if (system(qPrintable(cmd)) != 0)
        return false;

    QFile file("qt_cetcpsyncdata.txt");
    if (!file.open(QIODevice::ReadOnly))
        return false;

    bool result = fileTimeFromString(*deviceCreationTime, file.readLine());
    file.close();
    file.remove();
    return result;
}
<|endoftext|>


<commit_before>#include "TRandom.h"
#include "ROOT/TDataFrame.hxx"
#include "ROOT/TSeq.hxx"
#include "gtest/gtest.h"

using namespace ROOT::Experimental;

TEST(TDataFrameReport, AnalyseCuts)
{
   // Full coverage :) ?
   TDataFrame d(128);
   TRandom r(1);
   auto gen = [&r]() { return r.Gaus(0, 1); };
   auto cut0 = [](double x) { return x > 0; };
   auto cut1 = [](double x) { return x > 0.1; };
   auto cut2 = [](double x) { return x > 0.2; };
   auto colName = "col0";
   auto dd = d.Define(colName, gen)
                .Filter(cut0, {colName}, "cut0")
                .Filter(cut1, {colName}, "cut1")
                .Filter(cut2, {colName}, "cut2");

   testing::internal::CaptureStdout();
   auto rep = dd.Report();
   std::string output = testing::internal::GetCapturedStdout();
   auto expOut = "cut0      : pass=67         all=128        --   52.344 %\n"
                 "cut1      : pass=59         all=67         --   88.060 %\n"
                 "cut2      : pass=50         all=59         --   84.746 %\n";

   EXPECT_STREQ(output.c_str(), expOut);

   std::vector<const char *> cutNames{"cut0", "cut1", "cut2"};
   std::vector<ULong64_t> allEvts{128, 67, 59};
   std::vector<ULong64_t> passEvts{67, 59, 50};
   std::vector<float> effs{52.34375, 88.0597, 84.745766};
   unsigned int i = 0;

   for (auto &&cut : rep) {
      EXPECT_STREQ(cut.GetName().c_str(), cutNames[i]);
      EXPECT_EQ(cut.GetAll(), allEvts[i]);
      EXPECT_EQ(cut.GetPass(), passEvts[i]);
      ASSERT_FLOAT_EQ(cut.GetEff(), effs[i]);
      i++;
   }

   std::vector<TDF::TCutInfo> cutis{rep["cut0"], rep["cut1"], rep["cut2"]};

   for (auto j : ROOT::TSeqI(3)) {
      EXPECT_STREQ(cutis[j].GetName().c_str(), cutNames[j]);
      EXPECT_EQ(cutis[j].GetAll(), allEvts[j]);
      EXPECT_EQ(cutis[j].GetPass(), passEvts[j]);
      ASSERT_FLOAT_EQ(cutis[j].GetEff(), effs[j]);
   }

   int ret = 1;
   try {
      rep["NonExisting"];
   } catch (...) {
      ret = 0;
   }
   ASSERT_EQ(0, ret) << "No exception thrown when trying to get a non-existing cut.\n";

   ret = 1;
   try {
      rep[""];
   } catch (...) {
      ret = 0;
   }
   ASSERT_EQ(0, ret) << "No exception thrown when trying to get an unnamed cut.\n";
}

TEST(TDataFrameReport, Printing)
{
   // Full coverage :) ?
   TDataFrame d(8);
   TRandom r(1);
   auto gen = [&r]() { return r.Gaus(0, 1); };
   auto cut0 = [](double x) { return x > 0; };
   auto colName = "col0";
   auto dd = d.Define(colName, gen).Filter(cut0, {colName}, "cut0");

   testing::internal::CaptureStdout();
   dd.Report();
   std::string output0 = testing::internal::GetCapturedStdout();
   EXPECT_FALSE(output0.empty());

   testing::internal::CaptureStdout();
   auto rep = dd.Report(false);
   std::string output1 = testing::internal::GetCapturedStdout();
   EXPECT_TRUE(output1.empty());

   testing::internal::CaptureStdout();
   rep.Print();
   output1 = testing::internal::GetCapturedStdout();
   EXPECT_STREQ(output1.c_str(), output0.c_str());
}
<commit_msg>[TDF] Be more precise with types to fix test on Windows<commit_after>#include "TRandom.h"
#include "ROOT/TDataFrame.hxx"
#include "ROOT/TSeq.hxx"
#include "gtest/gtest.h"

using namespace ROOT::Experimental;

TEST(TDataFrameReport, AnalyseCuts)
{
   // Full coverage :) ?
   TDataFrame d(128);
   TRandom r(1);
   auto gen = [&r]() { return r.Gaus(0, 1); };
   auto cut0 = [](double x) { return x > 0; };
   auto cut1 = [](double x) { return x > 0.1; };
   auto cut2 = [](double x) { return x > 0.2; };
   auto colName = "col0";
   auto dd = d.Define(colName, gen)
                .Filter(cut0, {colName}, "cut0")
                .Filter(cut1, {colName}, "cut1")
                .Filter(cut2, {colName}, "cut2");

   testing::internal::CaptureStdout();
   auto rep = dd.Report();
   std::string output = testing::internal::GetCapturedStdout();
   auto expOut = "cut0      : pass=67         all=128        --   52.344 %\n"
                 "cut1      : pass=59         all=67         --   88.060 %\n"
                 "cut2      : pass=50         all=59         --   84.746 %\n";

   EXPECT_STREQ(output.c_str(), expOut);

   std::vector<const char *> cutNames{"cut0", "cut1", "cut2"};
   std::vector<ULong64_t> allEvts{128, 67, 59};
   std::vector<ULong64_t> passEvts{67, 59, 50};
   std::vector<float> effs{52.34375f, 88.0597f, 84.745766f};
   unsigned int i = 0;

   for (auto &&cut : rep) {
      EXPECT_STREQ(cut.GetName().c_str(), cutNames[i]);
      EXPECT_EQ(cut.GetAll(), allEvts[i]);
      EXPECT_EQ(cut.GetPass(), passEvts[i]);
      ASSERT_FLOAT_EQ(cut.GetEff(), effs[i]);
      i++;
   }

   std::vector<TDF::TCutInfo> cutis{rep["cut0"], rep["cut1"], rep["cut2"]};

   for (auto j : ROOT::TSeqI(3)) {
      EXPECT_STREQ(cutis[j].GetName().c_str(), cutNames[j]);
      EXPECT_EQ(cutis[j].GetAll(), allEvts[j]);
      EXPECT_EQ(cutis[j].GetPass(), passEvts[j]);
      ASSERT_FLOAT_EQ(cutis[j].GetEff(), effs[j]);
   }

   int ret = 1;
   try {
      rep["NonExisting"];
   } catch (...) {
      ret = 0;
   }
   ASSERT_EQ(0, ret) << "No exception thrown when trying to get a non-existing cut.\n";

   ret = 1;
   try {
      rep[""];
   } catch (...) {
      ret = 0;
   }
   ASSERT_EQ(0, ret) << "No exception thrown when trying to get an unnamed cut.\n";
}

TEST(TDataFrameReport, Printing)
{
   // Full coverage :) ?
   TDataFrame d(8);
   TRandom r(1);
   auto gen = [&r]() { return r.Gaus(0, 1); };
   auto cut0 = [](double x) { return x > 0; };
   auto colName = "col0";
   auto dd = d.Define(colName, gen).Filter(cut0, {colName}, "cut0");

   testing::internal::CaptureStdout();
   dd.Report();
   std::string output0 = testing::internal::GetCapturedStdout();
   EXPECT_FALSE(output0.empty());

   testing::internal::CaptureStdout();
   auto rep = dd.Report(false);
   std::string output1 = testing::internal::GetCapturedStdout();
   EXPECT_TRUE(output1.empty());

   testing::internal::CaptureStdout();
   rep.Print();
   output1 = testing::internal::GetCapturedStdout();
   EXPECT_STREQ(output1.c_str(), output0.c_str());
}
<|endoftext|>


<commit_before>#include <Windows.h>
#include <DXGI.h>
#include <D3D10.h>
#include <hexus.h>

#include "dxgihook.h"

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d10.lib")

typedef HRESULT (__stdcall* TYPE_IDXGISwapChain_Present) (
    IDXGISwapChain *SwapChain,
    UINT SyncInterval,
    UINT Flags
    );

typedef HRESULT(__stdcall* TYPE_IDXGISwapChain_ResizeBuffers) (
    IDXGISwapChain *SwapChain,
    UINT BufferCount,
    UINT Width,
    UINT Height,
    DXGI_FORMAT NewFormat,
    UINT SwapChainFlags
    );

TYPE_IDXGISwapChain_Present         HkIDXGISwapChain_Present;
TYPE_IDXGISwapChain_ResizeBuffers   HkIDXGISwapChain_ResizeBuffers;

typedef VOID (*HK_IDXGISWAPCHAIN_CALLBACK)(
IDXGISwapChain* SwapChain
);
HK_IDXGISWAPCHAIN_CALLBACK HkIDXGISwapChain_PresentCallback;
HK_IDXGISWAPCHAIN_CALLBACK HkIDXGISwapChain_ResizeBuffersCallback;

VOID OvLog(const wchar_t* Format, ...);
DWORD FindPattern(WCHAR* Module, char pattern[], char mask[]);
DWORD64 FindPattern64(WCHAR* Module, char pattern[], char mask[]);
void ReplaceVirtualMethod(void **VTable, int Function, void *Detour);

HRESULT __stdcall IDXGISwapChain_PresentHook(
    IDXGISwapChain* SwapChain,
    UINT SyncInterval,
    UINT Flags
    )
{
    static BOOLEAN init = FALSE;

    if (!init)
    {
        init = TRUE;

        OvLog(L"Hook called @ IDXGISwapChain_Present");
    }

    if (HkIDXGISwapChain_PresentCallback)
    {
        HkIDXGISwapChain_PresentCallback(SwapChain);
    }

    return HkIDXGISwapChain_Present(SwapChain, SyncInterval, Flags);
}

HRESULT __stdcall IDXGISwapChain_ResizeBuffersHook(
    IDXGISwapChain *SwapChain,
    UINT BufferCount,
    UINT Width,
    UINT Height,
    DXGI_FORMAT NewFormat,
    UINT SwapChainFlags
    )
{
    if (HkIDXGISwapChain_ResizeBuffersCallback)
    {
        HkIDXGISwapChain_ResizeBuffersCallback(SwapChain);
    }

    return HkIDXGISwapChain_ResizeBuffers(
        SwapChain,
        BufferCount,
        Width,
        Height,
        NewFormat,
        SwapChainFlags
        );
}

LRESULT
CALLBACK
FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}

#define PATT_DXGIPRESENT_X86            "\x8B\xFF\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x24\xA1\x00\x00\x00\x00\x33\xC4\x89\x44\x24\x20\x8B\x45\x10\x53"
#define MASK_DXGIPRESENT_X86            "xxxxxxxxxxxx????xxxxxxxxxx"
#define PATT_DXGIPRESENT_X64            "\x40\x55\x53\x56\x57\x41\x56\x48\x8D\x6C\x24\xC9"
#define MASK_DXGIPRESENT_X64            "xxxxxxxxxxxx"
#define PATT_IDXGISwapChain1_x86 "jhggh"

IDXGISwapChain* BuildDevice()
{
    IDXGIFactory* factory;
    IDXGIAdapter *pAdapter;
    IDXGISwapChain* swapChain;
    ID3D10Device *pDevice;
    UINT CreateFlags = 0;
    DXGI_MODE_DESC requestedMode;
    DXGI_SWAP_CHAIN_DESC scDesc;
    HWND windowHandle;
    HRESULT hr;

    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
    factory->EnumAdapters(0, &pAdapter);

    D3D10CreateDevice(
        pAdapter,
        D3D10_DRIVER_TYPE_HARDWARE,
        NULL,
        CreateFlags,
        D3D10_SDK_VERSION,
        &pDevice
        );

    requestedMode.Width = 500;
    requestedMode.Height = 500;
    requestedMode.RefreshRate.Numerator = 0;
    requestedMode.RefreshRate.Denominator = 0;
    requestedMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
    requestedMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    requestedMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    // Create fake window

    WNDCLASSEX windowClass = { 0 };

    windowClass.lpfnWndProc = FakeWndProc;
    windowClass.lpszClassName = L"JustGimmeADamnWindow";
    windowClass.cbSize = sizeof(WNDCLASSEX);

    ATOM classy = RegisterClassExW(&windowClass);

    if (!classy)
    {
        OvLog(L"RegisterClassExW failed with 0x%i", GetLastError());
        return NULL;
    }

    windowHandle = CreateWindowExW(
        0,
        L"JustGimmeADamnWindow",
        L"HwBtYouJustGimmeMyDamnWindow?",
        WS_SYSMENU,
        CW_USEDEFAULT,
        NULL,
        300,
        300,
        0, 0, 0, 0
        );

    if (!windowHandle)
    {
        OvLog(L"CreateWindowExW failed with 0x%i", GetLastError());
        return NULL;
    }

    // Now create the thing

    scDesc.BufferDesc = requestedMode;
    scDesc.SampleDesc.Count = 1;
    scDesc.SampleDesc.Quality = 0;
    scDesc.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scDesc.BufferCount = 2;
    scDesc.OutputWindow = windowHandle;
    scDesc.Windowed = TRUE;
    scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

    hr = factory->CreateSwapChain(pDevice, &scDesc, &swapChain);

    if (FAILED(hr))
    {
        OvLog(L"IDXGIFactory::CreateSwapChain failed! hr=0x%X",hr);
        return NULL;
    }

    // Destroy window
    DestroyWindow(windowHandle);
    UnregisterClassW(L"JustGimmeADamnWindow", GetModuleHandleW(NULL));

    return swapChain;
}

VOID* FindDevice()
{
#ifdef _M_IX86
    DWORD base = (DWORD)LoadLibraryW(L"dxgi.dll");
    DWORD swapchainvftable = base + 0x5070;

    return (VOID*)swapchainvftable;
#else
    VOID **vmt;
    DWORD64 pattern;
    DWORD64 base = (DWORD64)LoadLibraryW(L"dxgi.dll");

    pattern = base + 0x5AE0;
    OvLog(L"pattern 0x%llX", pattern);
    vmt = (VOID**)pattern;
    OvLog(L"vmt[8].new 0x%llX", vmt[8]);
    return (VOID*)pattern;
#endif
}

DETOUR_PROPERTIES DetourDXGIPresent;
DETOUR_PROPERTIES DetourDXGIResizeBuffers;

VOID DxgiHook_Initialize( IDXGISWAPCHAIN_HOOK* HookParameters )
{
    IDXGISwapChain* swapChain;
    VOID **vmt;

    HkIDXGISwapChain_PresentCallback = (HK_IDXGISWAPCHAIN_CALLBACK) HookParameters->PresentCallback;
    HkIDXGISwapChain_ResizeBuffersCallback = (HK_IDXGISWAPCHAIN_CALLBACK) HookParameters->ResizeBuffersCallback;

    swapChain = BuildDevice();

    if (!swapChain)
        return;

    vmt = (VOID**) swapChain;
    vmt = (VOID**) vmt[0];

    if (!HkIDXGISwapChain_Present)
    {
        DetourCreate(vmt[8], IDXGISwapChain_PresentHook, &DetourDXGIPresent);
        HkIDXGISwapChain_Present = (TYPE_IDXGISwapChain_Present)DetourDXGIPresent.Trampoline;

        DetourCreate(vmt[13], IDXGISwapChain_ResizeBuffersHook, &DetourDXGIResizeBuffers);
        HkIDXGISwapChain_ResizeBuffers = (TYPE_IDXGISwapChain_ResizeBuffers)DetourDXGIResizeBuffers.Trampoline;
    }

	swapChain->Release();
}

VOID DxgiHook_Destroy()
{
    if (DetourDXGIPresent.Trampoline)
        DetourDestroy(&DetourDXGIPresent);

    if (DetourDXGIResizeBuffers.Trampoline)
        DetourDestroy(&DetourDXGIResizeBuffers);
}<commit_msg>remove obsolete function<commit_after>#include <Windows.h>
#include <DXGI.h>
#include <D3D10.h>
#include <hexus.h>

#include "dxgihook.h"

#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d10.lib")

typedef HRESULT (__stdcall* TYPE_IDXGISwapChain_Present) (
    IDXGISwapChain *SwapChain,
    UINT SyncInterval,
    UINT Flags
    );

typedef HRESULT(__stdcall* TYPE_IDXGISwapChain_ResizeBuffers) (
    IDXGISwapChain *SwapChain,
    UINT BufferCount,
    UINT Width,
    UINT Height,
    DXGI_FORMAT NewFormat,
    UINT SwapChainFlags
    );

TYPE_IDXGISwapChain_Present         HkIDXGISwapChain_Present;
TYPE_IDXGISwapChain_ResizeBuffers   HkIDXGISwapChain_ResizeBuffers;

typedef VOID (*HK_IDXGISWAPCHAIN_CALLBACK)(
IDXGISwapChain* SwapChain
);
HK_IDXGISWAPCHAIN_CALLBACK HkIDXGISwapChain_PresentCallback;
HK_IDXGISWAPCHAIN_CALLBACK HkIDXGISwapChain_ResizeBuffersCallback;

VOID OvLog(const wchar_t* Format, ...);
DWORD FindPattern(WCHAR* Module, char pattern[], char mask[]);
DWORD64 FindPattern64(WCHAR* Module, char pattern[], char mask[]);
void ReplaceVirtualMethod(void **VTable, int Function, void *Detour);

HRESULT __stdcall IDXGISwapChain_PresentHook(
    IDXGISwapChain* SwapChain,
    UINT SyncInterval,
    UINT Flags
    )
{
    static BOOLEAN init = FALSE;

    if (!init)
    {
        init = TRUE;

        OvLog(L"Hook called @ IDXGISwapChain_Present");
    }

    if (HkIDXGISwapChain_PresentCallback)
    {
        HkIDXGISwapChain_PresentCallback(SwapChain);
    }

    return HkIDXGISwapChain_Present(SwapChain, SyncInterval, Flags);
}

HRESULT __stdcall IDXGISwapChain_ResizeBuffersHook(
    IDXGISwapChain *SwapChain,
    UINT BufferCount,
    UINT Width,
    UINT Height,
    DXGI_FORMAT NewFormat,
    UINT SwapChainFlags
    )
{
    if (HkIDXGISwapChain_ResizeBuffersCallback)
    {
        HkIDXGISwapChain_ResizeBuffersCallback(SwapChain);
    }

    return HkIDXGISwapChain_ResizeBuffers(
        SwapChain,
        BufferCount,
        Width,
        Height,
        NewFormat,
        SwapChainFlags
        );
}

LRESULT
CALLBACK
FakeWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}

IDXGISwapChain* BuildDevice()
{
    IDXGIFactory* factory;
    IDXGIAdapter *pAdapter;
    IDXGISwapChain* swapChain;
    ID3D10Device *pDevice;
    UINT CreateFlags = 0;
    DXGI_MODE_DESC requestedMode;
    DXGI_SWAP_CHAIN_DESC scDesc;
    HWND windowHandle;
    HRESULT hr;

    CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
    factory->EnumAdapters(0, &pAdapter);

    D3D10CreateDevice(
        pAdapter,
        D3D10_DRIVER_TYPE_HARDWARE,
        NULL,
        CreateFlags,
        D3D10_SDK_VERSION,
        &pDevice
        );

    requestedMode.Width = 500;
    requestedMode.Height = 500;
    requestedMode.RefreshRate.Numerator = 0;
    requestedMode.RefreshRate.Denominator = 0;
    requestedMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
    requestedMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    requestedMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    // Create fake window

    WNDCLASSEX windowClass = { 0 };

    windowClass.lpfnWndProc = FakeWndProc;
    windowClass.lpszClassName = L"JustGimmeADamnWindow";
    windowClass.cbSize = sizeof(WNDCLASSEX);

    ATOM classy = RegisterClassExW(&windowClass);

    if (!classy)
    {
        OvLog(L"RegisterClassExW failed with 0x%i", GetLastError());
        return NULL;
    }

    windowHandle = CreateWindowExW(
        0,
        L"JustGimmeADamnWindow",
        L"HwBtYouJustGimmeMyDamnWindow?",
        WS_SYSMENU,
        CW_USEDEFAULT,
        NULL,
        300,
        300,
        0, 0, 0, 0
        );

    if (!windowHandle)
    {
        OvLog(L"CreateWindowExW failed with 0x%i", GetLastError());
        return NULL;
    }

    // Now create the thing

    scDesc.BufferDesc = requestedMode;
    scDesc.SampleDesc.Count = 1;
    scDesc.SampleDesc.Quality = 0;
    scDesc.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scDesc.BufferCount = 2;
    scDesc.OutputWindow = windowHandle;
    scDesc.Windowed = TRUE;
    scDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

    hr = factory->CreateSwapChain(pDevice, &scDesc, &swapChain);

    if (FAILED(hr))
    {
        OvLog(L"IDXGIFactory::CreateSwapChain failed! hr=0x%X",hr);
        return NULL;
    }

    // Destroy window
    DestroyWindow(windowHandle);
    UnregisterClassW(L"JustGimmeADamnWindow", GetModuleHandleW(NULL));

    return swapChain;
}

DETOUR_PROPERTIES DetourDXGIPresent;
DETOUR_PROPERTIES DetourDXGIResizeBuffers;

VOID DxgiHook_Initialize( IDXGISWAPCHAIN_HOOK* HookParameters )
{
    IDXGISwapChain* swapChain;
    VOID **vmt;

    HkIDXGISwapChain_PresentCallback = (HK_IDXGISWAPCHAIN_CALLBACK) HookParameters->PresentCallback;
    HkIDXGISwapChain_ResizeBuffersCallback = (HK_IDXGISWAPCHAIN_CALLBACK) HookParameters->ResizeBuffersCallback;

    swapChain = BuildDevice();

    if (!swapChain)
        return;

    vmt = (VOID**) swapChain;
    vmt = (VOID**) vmt[0];

    if (!HkIDXGISwapChain_Present)
    {
        DetourCreate(vmt[8], IDXGISwapChain_PresentHook, &DetourDXGIPresent);
        HkIDXGISwapChain_Present = (TYPE_IDXGISwapChain_Present)DetourDXGIPresent.Trampoline;

        DetourCreate(vmt[13], IDXGISwapChain_ResizeBuffersHook, &DetourDXGIResizeBuffers);
        HkIDXGISwapChain_ResizeBuffers = (TYPE_IDXGISwapChain_ResizeBuffers)DetourDXGIResizeBuffers.Trampoline;
    }

	swapChain->Release();
}

VOID DxgiHook_Destroy()
{
    if (DetourDXGIPresent.Trampoline)
        DetourDestroy(&DetourDXGIPresent);

    if (DetourDXGIResizeBuffers.Trampoline)
        DetourDestroy(&DetourDXGIResizeBuffers);
}<|endoftext|>


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

// -----------------------------------------------------------------------------
// This is a copy of the matmul strategy infrastructure existing in mlir_edge.
// This version will be removed once this gets upstreamed to common mlir.
// Please try to limit changes in this code only minor changes or make sure the
// changes are applied in mlir_edge as well.

#include "iree/compiler/Conversion/CodegenUtils/MatmulCodegenStrategy.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/Transforms/Hoisting.h"
#include "mlir/Dialect/Linalg/Transforms/Transforms.h"
#include "mlir/Dialect/Linalg/Utils/Utils.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/Dialect/SCF/Utils.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Vector/EDSC/Intrinsics.h"
#include "mlir/Dialect/Vector/VectorOps.h"
#include "mlir/Dialect/Vector/VectorTransforms.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Dominance.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Value.h"
#include "mlir/IR/Visitors.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/LoopUtils.h"
#include "mlir/Transforms/Passes.h"

using namespace mlir;          // NOLINT
using namespace mlir::linalg;  // NOLINT

#define DEBUG_TYPE "matmul-codegen-strategy"

//===----------------------------------------------------------------------===//
// TODO: Cleanup and upstream these to go into core. Please ignore for now !
//===----------------------------------------------------------------------===//
static void hoistRedundantCopies(FuncOp func) {
  bool changed = true;
  while (changed) {
    changed = false;
    func.walk([&](linalg::FillOp op) {
      auto loop = op.getParentOfType<scf::ForOp>();
      if (!loop) return;

      for (auto operand : op.getOperands())
        if (!loop.isDefinedOutsideOfLoop(operand)) return;

      // Hoist fill before.
      op.getOperation()->moveBefore(loop);
      changed = true;
    });

    func.walk([&](linalg::CopyOp op) {
      auto loop = op.getParentOfType<scf::ForOp>();
      if (!loop) return;

      for (auto operand : op.getOperands())
        if (!loop.isDefinedOutsideOfLoop(operand)) return;

      Value sourceView = op.getInput(0);
      while (auto subViewOp = sourceView.getDefiningOp<SubViewOp>())
        sourceView = subViewOp.getViewSource();

      // Source traces back to a block argument.
      if (sourceView.isa<BlockArgument>()) {
        op.getOperation()->moveBefore(loop);
      } else {
        assert(sourceView.getDefiningOp<ViewOp>() ||
               sourceView.getDefiningOp<AllocOp>() ||
               sourceView.getDefiningOp<AllocaOp>());
        op.getOperation()->moveAfter(loop);
      }
      changed = true;
    });
  }
}

/// Substitute scf.for = %lb to %ub step %step by an AffineExpr expressing:
///   `%lb + %step * new_dim` where
/// 1. the AffineExpr for %lb is either an AffineConstantExpr or an
/// AffineDimExpr depending on whether the value is constant or not.
/// 2. the AffineExpr for %step is either an AffineConstantExpr or an
/// AffineSymbolExpr depending on whether the value is constant or not.
///
static void substitute(scf::ForOp forOp, SmallVectorImpl<AffineExpr> &exprs,
                       SmallVectorImpl<Value> &dims,
                       SmallVectorImpl<Value> &symbols) {
  MLIRContext *ctx = forOp.getContext();
  auto lbConstant = forOp.lowerBound().getDefiningOp<ConstantIndexOp>();
  AffineExpr lb = lbConstant ? getAffineConstantExpr(lbConstant.getValue(), ctx)
                             : getAffineDimExpr(dims.size(), ctx);

  auto stepConstant = forOp.step().getDefiningOp<ConstantIndexOp>();
  AffineExpr step = stepConstant
                        ? getAffineConstantExpr(stepConstant.getValue(), ctx)
                        : getAffineSymbolExpr(symbols.size(), ctx);

  if (!lbConstant) dims.push_back(forOp.lowerBound());
  if (!stepConstant) symbols.push_back(forOp.step());
  exprs.push_back(lb + step * getAffineDimExpr(dims.size(), ctx));

  auto ubConstant = forOp.upperBound().getDefiningOp<ConstantIndexOp>();
  AffineExpr ub = ubConstant ? getAffineConstantExpr(ubConstant.getValue(), ctx)
                             : getAffineDimExpr(dims.size(), ctx);
  if (!ubConstant) dims.push_back(forOp.upperBound());
  exprs.push_back(ub);

  dims.push_back(forOp.getInductionVar());
}

/// Traverse the .
static void substitute(AffineMinOp minOp, SmallVectorImpl<AffineExpr> &exprs,
                       SmallVectorImpl<Value> &dims,
                       SmallVectorImpl<Value> &symbols) {
  MLIRContext *ctx = minOp.getContext();
  for (Value v : minOp.getDimOperands()) {
    if (auto forOp = scf::getForInductionVarOwner(v)) {
      substitute(forOp, exprs, dims, symbols);
      continue;
    }
    if (auto parentMinOp = v.getDefiningOp<AffineMinOp>()) {
      substitute(parentMinOp, exprs, dims, symbols);
      continue;
    }
    exprs.push_back(getAffineDimExpr(dims.size(), ctx));
    dims.push_back(v);
  }
}

/// Perform folding of chains of AffineMinOp.
struct AffineMinCanonicalizationPattern : public OpRewritePattern<AffineMinOp> {
  using OpRewritePattern<AffineMinOp>::OpRewritePattern;

  LogicalResult matchAndRewrite(AffineMinOp minOp,
                                PatternRewriter &rewriter) const override;
};

LogicalResult AffineMinCanonicalizationPattern::matchAndRewrite(
    AffineMinOp minOp, PatternRewriter &rewriter) const {
  LLVM_DEBUG(llvm::dbgs() << "\nCanonicalize AffineMin: "
                          << *minOp.getOperation() << "\n");

  int64_t min = std::numeric_limits<int64_t>::max();
  for (auto e : minOp.map().getResults())
    if (auto cstExpr = e.dyn_cast<AffineConstantExpr>())
      min = std::min(min, cstExpr.getValue());
  if (min == std::numeric_limits<int64_t>::max()) return failure();

  SmallVector<AffineExpr, 4> exprs;
  SmallVector<Value, 4> dims, symbols;
  substitute(minOp, exprs, dims, symbols);

  SmallVector<Value, 4> operands = dims;
  operands.append(symbols.begin(), symbols.end());

  MLIRContext *ctx = minOp.getContext();
  auto map = AffineMap::get(dims.size(), symbols.size(), exprs, ctx);
  LLVM_DEBUG(llvm::dbgs() << "Substitution map: " << map << "\n");

  SmallVector<AffineExpr, 4> modExprs;
  for (unsigned idx = 0, e = map.getNumResults(); idx < e; ++idx)
    modExprs.push_back(getAffineDimExpr(idx, ctx) % min);
  map = AffineMap::get(map.getNumResults(), 0, modExprs, ctx).compose(map);
  canonicalizeMapAndOperands(&map, &operands);
  map = simplifyAffineMap(map);

  LLVM_DEBUG(llvm::dbgs() << "Post mod: " << map << "\n";
             llvm::interleaveComma(operands, llvm::dbgs()));

  if (!llvm::all_of(map.getResults(), [](AffineExpr e) {
        if (auto cst = e.dyn_cast<AffineConstantExpr>())
          return cst.getValue() == 0;
        return false;
      }))
    return failure();

  rewriter.replaceOpWithNewOp<ConstantIndexOp>(minOp, min);
  return success();
}
//===----------------------------------------------------------------------===//
// END TODO
//===----------------------------------------------------------------------===//

void MatmulCodegenStrategy::transform(FuncOp func) const {
  MLIRContext *context = func.getContext();
  // Emplace patterns one at a time while also maintaining a simple chained
  // state transition.
  unsigned stepCount = 0;
  SmallVector<OwningRewritePatternList, 4> stage1Patterns;
  auto zeroState = Identifier::get(std::to_string(stepCount), context);
  auto currentState = zeroState;
  for (auto &t : transformationSequence) {
    auto nextState = Identifier::get(std::to_string(++stepCount), context);
    auto marker = (currentState == zeroState)
                      ? linalg::LinalgMarker({}, nextState)
                      : linalg::LinalgMarker(currentState, nextState);
    stage1Patterns.emplace_back(t->buildRewritePatterns(context, marker));
    currentState = nextState;
  }

  OwningRewritePatternList stage2Patterns =
      linalg::getLinalgTilingCanonicalizationPatterns(context);
  stage2Patterns.insert<AffineMinCanonicalizationPattern>(context);

  auto stage3Transforms = [](Operation *op) {
    promoteSingleIterationLoops(cast<FuncOp>(op));
    return success();
  };
  linalg::applyStagedPatterns(func, stage1Patterns, stage2Patterns,
                              stage3Transforms);

  auto postStageTransforms = [this](Operation *op) {
    // Run LICM and hoisting patterns after all the stages as we want to
    // unrolling before moving transfer ops out of the loop.
    if (hoistInvariantCode) {
      PassManager pm(op->getContext());
      pm.addPass(createLoopInvariantCodeMotionPass());
      if (failed(pm.run(op->getParentOfType<ModuleOp>())))
        llvm_unreachable("Unexpected failure in cleanup pass pipeline.");
      hoistViewAllocOps(cast<FuncOp>(op));
      hoistRedundantVectorTransfers(cast<FuncOp>(op));
      hoistRedundantCopies(cast<FuncOp>(op));
    }
  };
  postStageTransforms(func);
  if (lowering != nullptr) lowering(func);
}

// Parametric lowering of vector contract for CPU target.
static void cpuLowering(
    FuncOp func, const vector::VectorTransformsOptions &vectorTransformsOptions,
    const VectorTransferToSCFOptions &vectorToSCFOptions) {
  // Programmatic controlled lowering of vector.contract only.
  MLIRContext *context = func.getContext();
  OwningRewritePatternList vectorContractLoweringPatterns;
  vectorContractLoweringPatterns
      .insert<ContractionOpToOuterProductOpLowering,
              ContractionOpToMatmulOpLowering, ContractionOpLowering>(
          vectorTransformsOptions, context);

  applyPatternsAndFoldGreedily(func, vectorContractLoweringPatterns);

  // Programmatic controlled lowering of vector.transfer only.
  OwningRewritePatternList vectorToLoopsPatterns;
  populateVectorToSCFConversionPatterns(vectorToLoopsPatterns, context,
                                        vectorToSCFOptions);
  applyPatternsAndFoldGreedily(func, vectorToLoopsPatterns);
}

MatmulCodegenStrategy &MatmulCodegenStrategy::setDefaultCPULowering() {
  auto lowering = [this](FuncOp func) {
    cpuLowering(func, vectorTransformsOptions, vectorToSCFOptions);
  };
  return setLoweringFunction(lowering);
}
<commit_msg>Improve AffineMinCanonicalization in MatmulCodegen strategy. (#2901)<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// -----------------------------------------------------------------------------
// This is a copy of the matmul strategy infrastructure existing in mlir_edge.
// This version will be removed once this gets upstreamed to common mlir.
// Please try to limit changes in this code only minor changes or make sure the
// changes are applied in mlir_edge as well.

#include "iree/compiler/Conversion/CodegenUtils/MatmulCodegenStrategy.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/Transforms/Hoisting.h"
#include "mlir/Dialect/Linalg/Transforms/Transforms.h"
#include "mlir/Dialect/Linalg/Utils/Utils.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/Dialect/SCF/Utils.h"
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Vector/EDSC/Intrinsics.h"
#include "mlir/Dialect/Vector/VectorOps.h"
#include "mlir/Dialect/Vector/VectorTransforms.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Dominance.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/IR/Value.h"
#include "mlir/IR/Visitors.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/LoopUtils.h"
#include "mlir/Transforms/Passes.h"

using namespace mlir;          // NOLINT
using namespace mlir::linalg;  // NOLINT

#define DEBUG_TYPE "matmul-codegen-strategy"

//===----------------------------------------------------------------------===//
// TODO: Cleanup and upstream these to go into core. Please ignore for now !
//===----------------------------------------------------------------------===//
static void hoistRedundantCopies(FuncOp func) {
  bool changed = true;
  while (changed) {
    changed = false;
    func.walk([&](linalg::FillOp op) {
      auto loop = op.getParentOfType<scf::ForOp>();
      if (!loop) return;

      for (auto operand : op.getOperands())
        if (!loop.isDefinedOutsideOfLoop(operand)) return;

      // Hoist fill before.
      op.getOperation()->moveBefore(loop);
      changed = true;
    });

    func.walk([&](linalg::CopyOp op) {
      auto loop = op.getParentOfType<scf::ForOp>();
      if (!loop) return;

      for (auto operand : op.getOperands())
        if (!loop.isDefinedOutsideOfLoop(operand)) return;

      Value sourceView = op.getInput(0);
      while (auto subViewOp = sourceView.getDefiningOp<SubViewOp>())
        sourceView = subViewOp.getViewSource();

      // Source traces back to a block argument.
      if (sourceView.isa<BlockArgument>()) {
        op.getOperation()->moveBefore(loop);
      } else {
        assert(sourceView.getDefiningOp<ViewOp>() ||
               sourceView.getDefiningOp<AllocOp>() ||
               sourceView.getDefiningOp<AllocaOp>());
        op.getOperation()->moveAfter(loop);
      }
      changed = true;
    });
  }
}

/// Substitute scf.for = %lb to %ub step %step by an AffineExpr expressing:
///   `%lb + %step * new_dim` where
/// 1. the AffineExpr for %lb is either an AffineConstantExpr or an
/// AffineDimExpr depending on whether the value is constant or not.
/// 2. the AffineExpr for %step is either an AffineConstantExpr or an
/// AffineSymbolExpr depending on whether the value is constant or not.
///
static void substitute(scf::ForOp forOp, SmallVectorImpl<AffineExpr> &exprs,
                       SmallVectorImpl<Value> &dims,
                       SmallVectorImpl<Value> &symbols) {
  MLIRContext *ctx = forOp.getContext();
  auto lbConstant = forOp.lowerBound().getDefiningOp<ConstantIndexOp>();
  AffineExpr lb = lbConstant ? getAffineConstantExpr(lbConstant.getValue(), ctx)
                             : getAffineDimExpr(dims.size(), ctx);

  auto stepConstant = forOp.step().getDefiningOp<ConstantIndexOp>();
  AffineExpr step = stepConstant
                        ? getAffineConstantExpr(stepConstant.getValue(), ctx)
                        : getAffineSymbolExpr(symbols.size(), ctx);

  if (!lbConstant) dims.push_back(forOp.lowerBound());
  if (!stepConstant) symbols.push_back(forOp.step());
  exprs.push_back(lb + step * getAffineDimExpr(dims.size(), ctx));

  auto ubConstant = forOp.upperBound().getDefiningOp<ConstantIndexOp>();
  AffineExpr ub = ubConstant ? getAffineConstantExpr(ubConstant.getValue(), ctx)
                             : getAffineDimExpr(dims.size(), ctx);
  if (!ubConstant) dims.push_back(forOp.upperBound());
  exprs.push_back(ub);

  dims.push_back(forOp.getInductionVar());
}

/// Substitue dimensions coming from forOp or AffineMin. Return false if it has
/// unknown dimension operands.
static bool substitute(AffineMinOp minOp, SmallVectorImpl<AffineExpr> &exprs,
                       SmallVectorImpl<Value> &dims,
                       SmallVectorImpl<Value> &symbols) {
  if (minOp.getDimOperands().empty()) return false;
  for (Value v : minOp.getDimOperands()) {
    if (auto forOp = scf::getForInductionVarOwner(v)) {
      substitute(forOp, exprs, dims, symbols);
      continue;
    }
    if (auto parentMinOp = v.getDefiningOp<AffineMinOp>()) {
      substitute(parentMinOp, exprs, dims, symbols);
      continue;
    }
    // If couldn't substitue the dimension give up and use the original map.
    return false;
  }
  return true;
}

/// Perform folding of chains of AffineMinOp.
struct AffineMinCanonicalizationPattern : public OpRewritePattern<AffineMinOp> {
  using OpRewritePattern<AffineMinOp>::OpRewritePattern;

  LogicalResult matchAndRewrite(AffineMinOp minOp,
                                PatternRewriter &rewriter) const override;
};

LogicalResult AffineMinCanonicalizationPattern::matchAndRewrite(
    AffineMinOp minOp, PatternRewriter &rewriter) const {
  LLVM_DEBUG(llvm::dbgs() << "\nCanonicalize AffineMin: "
                          << *minOp.getOperation() << "\n");

  int64_t min = std::numeric_limits<int64_t>::max();
  for (auto e : minOp.map().getResults())
    if (auto cstExpr = e.dyn_cast<AffineConstantExpr>())
      min = std::min(min, cstExpr.getValue());
  if (min == std::numeric_limits<int64_t>::max()) return failure();

  MLIRContext *ctx = minOp.getContext();
  AffineMap map;
  SmallVector<Value, 4> operands;
  SmallVector<AffineExpr, 4> exprs;
  SmallVector<Value, 4> dims, symbols;
  if (substitute(minOp, exprs, dims, symbols)) {
    operands = dims;
    operands.append(symbols.begin(), symbols.end());

    map = AffineMap::get(dims.size(), symbols.size(), exprs, ctx);
    LLVM_DEBUG(llvm::dbgs() << "Substitution map: " << map << "\n");
  } else {
    map = minOp.getAffineMap();
    operands = minOp.getDimOperands();
    operands.append(minOp.getSymbolOperands().begin(),
                    minOp.getSymbolOperands().end());
  }
  SmallVector<AffineExpr, 4> modExprs;
  for (unsigned idx = 0, e = map.getNumResults(); idx < e; ++idx)
    modExprs.push_back(getAffineDimExpr(idx, ctx) % min);
  map = AffineMap::get(map.getNumResults(), 0, modExprs, ctx).compose(map);
  canonicalizeMapAndOperands(&map, &operands);
  map = simplifyAffineMap(map);

  LLVM_DEBUG(llvm::dbgs() << "Post mod: " << map << "\n";
             llvm::interleaveComma(operands, llvm::dbgs()));

  if (!llvm::all_of(map.getResults(), [](AffineExpr e) {
        if (auto cst = e.dyn_cast<AffineConstantExpr>())
          return cst.getValue() == 0;
        return false;
      }))
    return failure();

  rewriter.replaceOpWithNewOp<ConstantIndexOp>(minOp, min);
  return success();
}
//===----------------------------------------------------------------------===//
// END TODO
//===----------------------------------------------------------------------===//

void MatmulCodegenStrategy::transform(FuncOp func) const {
  MLIRContext *context = func.getContext();
  // Emplace patterns one at a time while also maintaining a simple chained
  // state transition.
  unsigned stepCount = 0;
  SmallVector<OwningRewritePatternList, 4> stage1Patterns;
  auto zeroState = Identifier::get(std::to_string(stepCount), context);
  auto currentState = zeroState;
  for (auto &t : transformationSequence) {
    auto nextState = Identifier::get(std::to_string(++stepCount), context);
    auto marker = (currentState == zeroState)
                      ? linalg::LinalgMarker({}, nextState)
                      : linalg::LinalgMarker(currentState, nextState);
    stage1Patterns.emplace_back(t->buildRewritePatterns(context, marker));
    currentState = nextState;
  }

  OwningRewritePatternList stage2Patterns =
      linalg::getLinalgTilingCanonicalizationPatterns(context);
  // Add extra patterns to canonicalize AffineMin in combination with scf loops
  // operations after tiling.
  stage2Patterns.insert<AffineMinCanonicalizationPattern,
                        AffineMinSCFCanonicalizationPattern>(context);

  auto stage3Transforms = [](Operation *op) {
    promoteSingleIterationLoops(cast<FuncOp>(op));
    return success();
  };
  linalg::applyStagedPatterns(func, stage1Patterns, stage2Patterns,
                              stage3Transforms);

  auto postStageTransforms = [this](Operation *op) {
    // Run LICM and hoisting patterns after all the stages as we want to
    // unrolling before moving transfer ops out of the loop.
    if (hoistInvariantCode) {
      PassManager pm(op->getContext());
      pm.addPass(createLoopInvariantCodeMotionPass());
      if (failed(pm.run(op->getParentOfType<ModuleOp>())))
        llvm_unreachable("Unexpected failure in cleanup pass pipeline.");
      hoistViewAllocOps(cast<FuncOp>(op));
      hoistRedundantVectorTransfers(cast<FuncOp>(op));
      hoistRedundantCopies(cast<FuncOp>(op));
    }
  };
  postStageTransforms(func);
  if (lowering != nullptr) lowering(func);
}

// Parametric lowering of vector contract for CPU target.
static void cpuLowering(
    FuncOp func, const vector::VectorTransformsOptions &vectorTransformsOptions,
    const VectorTransferToSCFOptions &vectorToSCFOptions) {
  // Programmatic controlled lowering of vector.contract only.
  MLIRContext *context = func.getContext();
  OwningRewritePatternList vectorContractLoweringPatterns;
  vectorContractLoweringPatterns
      .insert<ContractionOpToOuterProductOpLowering,
              ContractionOpToMatmulOpLowering, ContractionOpLowering>(
          vectorTransformsOptions, context);

  applyPatternsAndFoldGreedily(func, vectorContractLoweringPatterns);

  // Programmatic controlled lowering of vector.transfer only.
  OwningRewritePatternList vectorToLoopsPatterns;
  populateVectorToSCFConversionPatterns(vectorToLoopsPatterns, context,
                                        vectorToSCFOptions);
  applyPatternsAndFoldGreedily(func, vectorToLoopsPatterns);
}

MatmulCodegenStrategy &MatmulCodegenStrategy::setDefaultCPULowering() {
  auto lowering = [this](FuncOp func) {
    cpuLowering(func, vectorTransformsOptions, vectorToSCFOptions);
  };
  return setLoweringFunction(lowering);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <stdlib.h>

#include "parada.h"

using namespace std;

int main(void){	// l do arquivo paradas.csv e guarda cada coluna em sua respectiva variavel (int,float ou char)

    ifstream arq;

	string str;
	char *tokchar;
	char *cstr;
	int tokcount=1;

	int idparada,i=0;
	float latitude, longitude;
	float codigo;
	char *terminal;

    parada* stop;
    parada* lst;

    arq.open("paradas.csv", ios::in);

    arq >> str;

    while(!arq.fail()){
    i++;
    arq >> str;
    if (str.c_str() == NULL)
        break;
    }

    lst = new parada[i-1];
	i=0;	//vetor com lista de parada ja inicializado no tamanho do numero de linhas com variaveis

    arq.close();

    arq.open("paradas.csv", ios::in);

    arq >> str;

    while(!arq.eof()){
   	stop = new parada();
		arq >> str;
		cstr = new char[str.length()+1];
		strcpy(cstr, str.c_str());

		tokchar = strtok(cstr,";");

			while(tokchar != NULL){
//              cout << tokchar << "\n"<< endl;

				switch(tokcount){
					case 1:tokcount++;
							stop -> set_ID(atoi(tokchar));  //idparada = atoi(tokchar); //preencher no objeto nesta linha
							break;
					case 2:tokcount++;
							tokchar[0]=tokchar[5]=' ' ;
							codigo = atof(tokchar);	//XXXX -- useless
							break;
					case 3:tokcount++;
							for(int k=0; k<= 5;k++)
								if(tokchar[k]==',')
									tokchar[k]='.';
							stop -> set_longitude(atof(tokchar));	//longitude = atof(tokchar);  //preencher no objeto nesta linha
							break;
					case 4:tokcount++;
							for(int k=0; k<= 5;k++)
								if(tokchar[k]==',')
									tokchar[k]='.';
							stop -> set_latitude(atof(tokchar)); //latitude = atof(tokchar);	//preencher no objeto nesta linha
							break;
					default:tokcount = 1;
							tokchar[0] = tokchar[2] = ' ';
							terminal = tokchar;		//S ou N -- useless
							break;
				}
				tokchar = strtok(NULL, ";");
			}
	lst[i] = *stop;
	i++;
	}
    arq.close();

	cout <<"idparada = "<< stop -> get_ID() << endl;
	cout <<"codigo = "<< codigo << endl;    //codigo nao esta no obj
	cout <<"longitude = "<< stop -> get_longitude() << endl;
	cout <<"latitude = "<< stop -> get_latitude() << endl;
	cout <<"terminal = "<< terminal << endl; //terminal nao esta no obj
    cout << lst[1].get_ID() << endl;
    cout << lst[1].get_latitude() << endl;
    cout << lst[1].get_longitude() << endl;

	//ISTA LST CRIADA COM i(5765) POSICOES ARMAZENANDO OBJETOS parada

    return 0;
}
<commit_msg>Add files via upload<commit_after>#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include <stdlib.h>

#include "parada.h"
#include "veiculo.h"

using namespace std;

int main(void){
    ifstream arq;
	string str;
	char *tokchar;
	char *cstr;
	int tokcount=1;

	int i=0;
	float codigo;
	char *terminal;

    parada* stop;
    parada* lst;

    arq.open("paradas.csv", ios::in); // lr do arquivo paradas.csv e guardar cada coluna em sua respectiva variavel (int,float ou char)

    arq >> str;			//leitura da 1 linha(cabecalho)

    while(!arq.eof()){
    i++;
    arq >> str;
    if (str.c_str() == NULL)
        break;
    }

    lst = new parada[i-1];
	i=0;	//vetor com lista de parada ja inicializado no tamanho do numero de linhas com variaveis

    arq.close();

    arq.open("paradas.csv", ios::in);

    arq >> str;			//leitura da 1 linha(cabecalho)

    while(!arq.eof()){
   	stop = new parada();
		arq >> str;
		cstr = new char[str.length()+1];
		strcpy(cstr, str.c_str());

		tokchar = strtok(cstr,";");

			while(tokchar != NULL){
//              cout << tokchar << "\n"<< endl;

				switch(tokcount){
					case 1:tokcount++;
							stop -> set_ID(atoi(tokchar));  //idparada = atoi(tokchar);
							break;
					case 2:tokcount++;
							tokchar[0]=tokchar[5]=' ' ;
							codigo = atof(tokchar);	//XXXX -- useless
							break;
					case 3:tokcount++;
							for(int k=0; k<= 5;k++)
								if(tokchar[k]==',')
									tokchar[k]='.';
							stop -> set_longitude(atof(tokchar));	//longitude = atof(tokchar);
							break;
					case 4:tokcount++;
							for(int k=0; k<= 5;k++)
								if(tokchar[k]==',')
									tokchar[k]='.';
							stop -> set_latitude(atof(tokchar)); //latitude = atof(tokchar);
							break;
					default:tokcount = 1;
							tokchar[0] = tokchar[2] = ' ';
							terminal = tokchar;		//S ou N -- useless
							break;
				}
				tokchar = strtok(NULL, ";");
			}
	lst[i] = *stop;
	i++;
	}
    arq.close();

	cout <<"idparada = "<< stop -> get_ID() << endl;
	cout <<"codigo = "<< codigo << endl;    //codigo nao esta no obj
	cout <<"longitude = "<< stop -> get_longitude() << endl;
	cout <<"latitude = "<< stop -> get_latitude() << endl;
	cout <<"terminal = "<< terminal << endl; //terminal nao esta no obj
    cout << lst[1].get_ID() << endl;
    cout << lst[1].get_latitude() << endl;
    cout << lst[1].get_longitude() << endl;

	//LISTA LST CRIADA COM i(5765) POSICOES ARMAZENANDO OBJETOS parada
    i = 0;
    tokcount =1;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

cout << "/*****************************************************/" <<endl;

    //variaveis utilizadas a partir desta parte do codigo//
    //int i=0;
	//char *tokchar;
	//char *cstr;
	//int tokcount=1;
    //string str

    ifstream file;

	veiculo* carro;
	veiculo* lstcarro;

	file.open("linhas.csv",ios::in);
	//iniciar leitura dos dados do veiculo

	file >> str;					//leitura da 1 linha(cabecalho)

    while(!file.eof()){			//tratar i maior que numero de linhas do arquivo /////////////////////////////<<<--------------------------
    i++;
    file >> str;
    if (str.c_str() == NULL)
        break;
    }
	cout << i-1 << endl;
    lstcarro = new veiculo[i-1];

	i=0;	//vetor com lista de parada ja inicializado no tamanho do numero de linhas com variaveis

    file.close();

    file.open("linhas.csv", ios::in);

    file >> str;		//leitura da 1 linha(cabecalho)

    while(!file.eof()){
   	carro = new veiculo();
		file >> str;

		cstr = new char[str.length()+1];
		strcpy(cstr, str.c_str());

		tokchar = strtok(cstr,";");

			while(tokchar != NULL){

				switch(tokcount){
					case 1:tokcount++;
							carro -> set_ID(atoi(tokchar));  //idcarro = atoi(tokchar);
							break;
					case 2:tokcount++;
						  	str = tokchar;
							carro -> set_nome(str);	//nome do carro  uma string e tokchar e char
							break;
					case 3:tokcount++;	//codigo --useless
							break;

					default:tokcount = 1;
							carro -> set_tipo(tokchar[1]);		//"L" ou "O"
							break;
				}
				tokchar = strtok(NULL, ";");
			}
	lstcarro[i] = *carro;
	i++;
	}
    file.close();

	cout <<"idlinha = "<< carro -> get_ID() << endl;
	cout <<"nome = "<< carro -> get_nome() << endl;
	cout <<"tipo = "<< carro -> get_tipo() << endl;
    cout<<"/*******************************************/"<<endl;
    cout << lstcarro[1].get_ID() << endl;
    cout << lstcarro[1].get_nome() << endl;
    cout << lstcarro[1].get_tipo() << endl;

    return 0;
}
<|endoftext|>