<commit_before>#include <stdio.h>

int main(int argc, char **argv) {
    int secs, days, hrs, mins;
    const char *uptime = "uptime: 216095, days:2, hrs:12, min:1";
    int matched = sscanf (uptime, "uptime: %d, days:%d, hrs:%d, min:%d", &secs, &days, &hrs, &mins);
    printf("matched:%d, UP D:%d H:%d M:%d", matched, days, hrs, mins);

}<commit_msg>sscanf tests<commit_after>#include <stdio.h>
#include <sys/sysinfo.h>
#include "../src2/HealthStatus.h"

int main(int argc, char **argv) {
    int secs, days, hrs, mins;
    const char *uptime = "uptime: 216095, days:2, hrs:12, min:1";
    int matched = sscanf (uptime, "uptime: %d, days:%d, hrs:%d, min:%d", &secs, &days, &hrs, &mins);
    printf("matched:%d, UP D:%d H:%d M:%d\n", matched, days, hrs, mins);

    Properties statusProps;
    struct sysinfo info;
    char tmp[128];
    sysinfo(&info);
    days = info.uptime / (24*3600);
    hrs = (info.uptime - days * 24*3600) / 3600;
    mins = (info.uptime - days * 24*3600 - hrs*3600) / 60;
    sprintf(tmp, "uptime: %ld, days:%d, hrs:%d, min:%d", info.uptime, days, hrs, mins);
    statusProps["Uptime"] = tmp;
    string uptimeProp = statusProps["Uptime"];
    const char *uptimeStr = uptimeProp.c_str();
    printf("uptimeStr=%s\n", uptimeStr);
    int count = sscanf(uptimeStr, "uptime: %*d, days:%d, hrs:%d, min:%d", &days, &hrs, &mins);
    printf("matched:%d, UP D:%d H:%d M:%d\n", count, days, hrs, mins);
    snprintf(tmp, 20, "UP D:%d H:%d M:%d", days, hrs, mins);
    printf("UP D:%d H:%d M:%d\n", days, hrs, mins);
}<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <string.h>
#include "xcint.hpp"

#ifndef FORTRAN_INT
typedef int fortran_int_t;
#else
typedef FORTRAN_INT fortran_int_t;
#endif

functional_data xcint_funs[XC_NR_FUNCTIONALS];
parameter_data xcint_params[XC_NR_PARAMETERS_AND_FUNCTIONALS];

int xcint_lookup_functional(const char *name)
{
  for (int i=0;i<XC_NR_FUNCTIONALS;i++)
    if (strcasecmp(name,xcint_funs[i].name) == 0)
      return i;
  return -1;
}

int xcint_lookup_parameter(const char *name)
{
  for (int i=XC_NR_FUNCTIONALS;i<XC_NR_PARAMETERS_AND_FUNCTIONALS;i++)
    if (strcasecmp(name,xcint_params[i].name) == 0)
      return i;
  return -1;
}

int xcint_lookup_alias(const char *name)
{
  for (int i=0;i<XC_MAX_ALIASES and xcint_aliases[i].name;i++)
    if (strcasecmp(name,xcint_aliases[i].name) == 0)
      return i;
  return -1;
}

template<int FUN>
void xcint_functional_setup_helper()
{
  if (!(fundat_db<FUN>::symbol[0] == 'X' and fundat_db<FUN>::symbol[1] == 'C' and fundat_db<FUN>::symbol[2] == '_'))
    xcint_die("Functional symbol does not start with XC_",FUN);
  fundat_db<FUN>::d.name = fundat_db<FUN>::symbol + 3;
  fundat_db<FUN>::d.id = (enum xc_functional_id)FUN;
  xcint_funs[FUN] = fundat_db<FUN>::d;
  xcint_functional_setup_helper<FUN+1>();
}

template<> void xcint_functional_setup_helper<XC_NR_FUNCTIONALS>() {  }

template<int P>
void xcint_parameter_setup_helper()
{
  if (!(pardat_db<P>::symbol[0] == 'X' and pardat_db<P>::symbol[1] == 'C' and pardat_db<P>::symbol[2] == '_'))
    xcint_die("Symbol does not start with XC_",P);
  pardat_db<P>::d.name = pardat_db<P>::symbol + 3;
  xcint_params[P] = pardat_db<P>::d;
  xcint_parameter_setup_helper<P+1>();
}

template<>
void xcint_parameter_setup_helper<XC_NR_PARAMETERS_AND_FUNCTIONALS>() {}

vars_data xcint_vars[XC_NR_VARS] =
  {
    {"XC_A", 1, XC_DENSITY},
    {"XC_N", 1, XC_DENSITY},
    {"XC_A_B", 2, XC_DENSITY},
    {"XC_N_S", 2, XC_DENSITY},
    {"XC_A_GAA", 2, XC_DENSITY | XC_GRADIENT},
    {"XC_N_GNN", 2, XC_DENSITY | XC_GRADIENT},
    {"XC_A_B_GAA_GAB_GBB", 5, XC_DENSITY | XC_GRADIENT},
    {"XC_N_S_GNN_GNS_GSS", 5, XC_DENSITY | XC_GRADIENT},
    {"XC_A_GAA_LAPA", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_GAA_TAUA", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_GNN_LAPN", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_GNN_TAUN", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_GAA_GAB_GBB_LAPA_LAPB",7, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_GAA_GAB_GBB_TAUA_TAUB",7, XC_DENSITY | XC_GRADIENT | XC_KINETIC},
    {"XC_N_S_GNN_GNS_GSS_LAPN_LAPS",7, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_S_GNN_GNS_GSS_TAUN_TAUS",7, XC_DENSITY | XC_GRADIENT | XC_KINETIC},
    {"XC_A_AX_AY_AZ",4, XC_DENSITY | XC_GRADIENT},
    {"XC_A_B_AX_AY_AZ_BZ_BY_BZ", 8, XC_DENSITY | XC_GRADIENT},
    {"XC_N_NX_NY_NZ",4, XC_DENSITY | XC_GRADIENT},
    {"XC_N_S_NX_NY_NZ_SX_SY_SZ",8, XC_DENSITY | XC_GRADIENT},
    {"XC_A_2ND_TAYLOR", 10, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_2ND_TAYLOR", 20, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_2ND_TAYLOR", 10, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_S_2ND_TAYLOR", 20, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
  };

void xcint_assure_setup()
{
  static bool is_setup = false;
  if (!is_setup)
    {
      xcint_functional_setup_helper<0>();
      xcint_parameter_setup_helper<XC_NR_FUNCTIONALS>();
      is_setup = true;
    }
}

void xcint_die(const char *message, int code)
{
  fprintf(stderr,"XCFun fatal error %i: ",code);
  fprintf(stderr,"%s",message);
  fprintf(stderr,"\n");
  exit(-1);
}

int xcint_write_fortran_module()
{
  xcint_assure_setup();
  FILE *dst = fopen("fortran/xcfun_autogen.F90","w");
  int i;
  if (!dst)
    {
      perror("Open fortran/xcfun_autogen.F90 for writing failed");
      return -1;
    }
  fprintf(dst,"! Autogenerated file, do not edit\n"
	  "module xcfun_autogen\n");
  fprintf(dst,"  integer, parameter :: XCFUN_CHECKSUM = %i\n",
	  XCFUN_CHECKSUM);
  fprintf(dst,"  integer, parameter :: XCFUN_FORTRAN_INT_SIZE = %lu\n",
	  sizeof(fortran_int_t));
  fprintf(dst,"  integer, parameter :: XC_MAX_ORDER = %i\n",
	  XC_MAX_ORDER);
  fprintf(dst,"  integer, parameter :: XC_NR_FUNCTIONALS = %i\n",
	  XC_NR_FUNCTIONALS);
  fprintf(dst,"  integer, parameter :: XC_NR_PARAMETERS_AND_FUNCTIONALS = %i\n",
	  XC_NR_PARAMETERS_AND_FUNCTIONALS);
  fprintf(dst,"  integer, parameter :: XC_NR_VARS = %i\n",
	  XC_NR_VARS);
  fprintf(dst,"\n");
  fprintf(dst,"!Functionals\n");
  for (i=0;i<XC_NR_FUNCTIONALS;i++)
    fprintf(dst,"  integer, parameter :: XC_%s = %i\n",
	    xcint_funs[i].name,i);
  fprintf(dst,"\n");
  fprintf(dst,"!Parameters\n");
  for (i=XC_NR_FUNCTIONALS;i<XC_NR_PARAMETERS_AND_FUNCTIONALS;i++)
    fprintf(dst,"  integer, parameter :: XC_%s = %i\n",
	    xcint_params[i].name,i);
  fprintf(dst,"\n");
  for (i=0;i<XC_NR_VARS;i++)
    fprintf(dst,"  integer, parameter :: %s = %i\n",
	    xcint_vars[i].symbol,i);
  fprintf(dst,"end module\n");
  fclose(dst);
  return 0;
}

<commit_msg>Fix typo BZ_BY_BZ -> BX_BY_BZ, reported by Michal Repisky.<commit_after>#include <cstdio>
#include <cstdlib>
#include <string.h>
#include "xcint.hpp"

#ifndef FORTRAN_INT
typedef int fortran_int_t;
#else
typedef FORTRAN_INT fortran_int_t;
#endif

functional_data xcint_funs[XC_NR_FUNCTIONALS];
parameter_data xcint_params[XC_NR_PARAMETERS_AND_FUNCTIONALS];

int xcint_lookup_functional(const char *name)
{
  for (int i=0;i<XC_NR_FUNCTIONALS;i++)
    if (strcasecmp(name,xcint_funs[i].name) == 0)
      return i;
  return -1;
}

int xcint_lookup_parameter(const char *name)
{
  for (int i=XC_NR_FUNCTIONALS;i<XC_NR_PARAMETERS_AND_FUNCTIONALS;i++)
    if (strcasecmp(name,xcint_params[i].name) == 0)
      return i;
  return -1;
}

int xcint_lookup_alias(const char *name)
{
  for (int i=0;i<XC_MAX_ALIASES and xcint_aliases[i].name;i++)
    if (strcasecmp(name,xcint_aliases[i].name) == 0)
      return i;
  return -1;
}

template<int FUN>
void xcint_functional_setup_helper()
{
  if (!(fundat_db<FUN>::symbol[0] == 'X' and fundat_db<FUN>::symbol[1] == 'C' and fundat_db<FUN>::symbol[2] == '_'))
    xcint_die("Functional symbol does not start with XC_",FUN);
  fundat_db<FUN>::d.name = fundat_db<FUN>::symbol + 3;
  fundat_db<FUN>::d.id = (enum xc_functional_id)FUN;
  xcint_funs[FUN] = fundat_db<FUN>::d;
  xcint_functional_setup_helper<FUN+1>();
}

template<> void xcint_functional_setup_helper<XC_NR_FUNCTIONALS>() {  }

template<int P>
void xcint_parameter_setup_helper()
{
  if (!(pardat_db<P>::symbol[0] == 'X' and pardat_db<P>::symbol[1] == 'C' and pardat_db<P>::symbol[2] == '_'))
    xcint_die("Symbol does not start with XC_",P);
  pardat_db<P>::d.name = pardat_db<P>::symbol + 3;
  xcint_params[P] = pardat_db<P>::d;
  xcint_parameter_setup_helper<P+1>();
}

template<>
void xcint_parameter_setup_helper<XC_NR_PARAMETERS_AND_FUNCTIONALS>() {}

vars_data xcint_vars[XC_NR_VARS] =
  {
    {"XC_A", 1, XC_DENSITY},
    {"XC_N", 1, XC_DENSITY},
    {"XC_A_B", 2, XC_DENSITY},
    {"XC_N_S", 2, XC_DENSITY},
    {"XC_A_GAA", 2, XC_DENSITY | XC_GRADIENT},
    {"XC_N_GNN", 2, XC_DENSITY | XC_GRADIENT},
    {"XC_A_B_GAA_GAB_GBB", 5, XC_DENSITY | XC_GRADIENT},
    {"XC_N_S_GNN_GNS_GSS", 5, XC_DENSITY | XC_GRADIENT},
    {"XC_A_GAA_LAPA", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_GAA_TAUA", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_GNN_LAPN", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_GNN_TAUN", 3, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_GAA_GAB_GBB_LAPA_LAPB",7, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_GAA_GAB_GBB_TAUA_TAUB",7, XC_DENSITY | XC_GRADIENT | XC_KINETIC},
    {"XC_N_S_GNN_GNS_GSS_LAPN_LAPS",7, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_S_GNN_GNS_GSS_TAUN_TAUS",7, XC_DENSITY | XC_GRADIENT | XC_KINETIC},
    {"XC_A_AX_AY_AZ",4, XC_DENSITY | XC_GRADIENT},
    {"XC_A_B_AX_AY_AZ_BX_BY_BZ", 8, XC_DENSITY | XC_GRADIENT},
    {"XC_N_NX_NY_NZ",4, XC_DENSITY | XC_GRADIENT},
    {"XC_N_S_NX_NY_NZ_SX_SY_SZ",8, XC_DENSITY | XC_GRADIENT},
    {"XC_A_2ND_TAYLOR", 10, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_A_B_2ND_TAYLOR", 20, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_2ND_TAYLOR", 10, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
    {"XC_N_S_2ND_TAYLOR", 20, XC_DENSITY | XC_GRADIENT | XC_LAPLACIAN},
  };

void xcint_assure_setup()
{
  static bool is_setup = false;
  if (!is_setup)
    {
      xcint_functional_setup_helper<0>();
      xcint_parameter_setup_helper<XC_NR_FUNCTIONALS>();
      is_setup = true;
    }
}

void xcint_die(const char *message, int code)
{
  fprintf(stderr,"XCFun fatal error %i: ",code);
  fprintf(stderr,"%s",message);
  fprintf(stderr,"\n");
  exit(-1);
}

int xcint_write_fortran_module()
{
  xcint_assure_setup();
  FILE *dst = fopen("fortran/xcfun_autogen.F90","w");
  int i;
  if (!dst)
    {
      perror("Open fortran/xcfun_autogen.F90 for writing failed");
      return -1;
    }
  fprintf(dst,"! Autogenerated file, do not edit\n"
	  "module xcfun_autogen\n");
  fprintf(dst,"  integer, parameter :: XCFUN_CHECKSUM = %i\n",
	  XCFUN_CHECKSUM);
  fprintf(dst,"  integer, parameter :: XCFUN_FORTRAN_INT_SIZE = %lu\n",
	  sizeof(fortran_int_t));
  fprintf(dst,"  integer, parameter :: XC_MAX_ORDER = %i\n",
	  XC_MAX_ORDER);
  fprintf(dst,"  integer, parameter :: XC_NR_FUNCTIONALS = %i\n",
	  XC_NR_FUNCTIONALS);
  fprintf(dst,"  integer, parameter :: XC_NR_PARAMETERS_AND_FUNCTIONALS = %i\n",
	  XC_NR_PARAMETERS_AND_FUNCTIONALS);
  fprintf(dst,"  integer, parameter :: XC_NR_VARS = %i\n",
	  XC_NR_VARS);
  fprintf(dst,"\n");
  fprintf(dst,"!Functionals\n");
  for (i=0;i<XC_NR_FUNCTIONALS;i++)
    fprintf(dst,"  integer, parameter :: XC_%s = %i\n",
	    xcint_funs[i].name,i);
  fprintf(dst,"\n");
  fprintf(dst,"!Parameters\n");
  for (i=XC_NR_FUNCTIONALS;i<XC_NR_PARAMETERS_AND_FUNCTIONALS;i++)
    fprintf(dst,"  integer, parameter :: XC_%s = %i\n",
	    xcint_params[i].name,i);
  fprintf(dst,"\n");
  for (i=0;i<XC_NR_VARS;i++)
    fprintf(dst,"  integer, parameter :: %s = %i\n",
	    xcint_vars[i].symbol,i);
  fprintf(dst,"end module\n");
  fclose(dst);
  return 0;
}

<|endoftext|>


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

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/bridge/ddl/schema_transformer.h"
#include "backend/planner/projection_node.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Utils
//===--------------------------------------------------------------------===//

const ValueArray PlanTransformer::BuildParams(const ParamListInfo param_list) {
  ValueArray params;
  if (param_list != nullptr) {
    params.Reset(param_list->numParams);
    ParamExternData *postgres_param = param_list->params;
    for (int i = 0; i < params.GetSize(); ++i, ++postgres_param) {
      params[i] = TupleTransformer::GetValue(postgres_param->value,
                                             postgres_param->ptype);
    }
  }

  LOG_INFO("Built %d params: \n%s", params.GetSize(), params.Debug().c_str());
  return params;
}

/**
 * @brief Extract the common things shared by all Scan types:
 * generic predicates and projections.
 *
 * @param[out]  parent  Set to a created projection plan node if one is needed,
 *              or NULL otherwise.
 *
 * @param[out]  predicate   Set to the transformed Expression based on qual. Or NULL if so is qual.
 *
 * @param[out]  out_col_list  Set to the output column list if ps_ProjInfo contains only
 *              direct mapping of attributes. \b Empty if no direct map is presented.
 *
 * @param[in]   sstate  The ScanState from which generic things are extracted.
 *
 * @param[in]   use_projInfo  Parse projInfo or not. Sometimes the projInfo of a Scan may have been
 *              stolen by its parent.
 *
 * @return      Nothing.
 */
void PlanTransformer::GetGenericInfoFromScanState(
    planner::AbstractPlanNode*& parent,
    expression::AbstractExpression*& predicate,
    std::vector<oid_t>& out_col_list,
    const ScanState* sstate,
    bool use_projInfo) {

  List* qual = sstate->ps.qual;
  const ProjectionInfo *pg_proj_info = sstate->ps.ps_ProjInfo;
  oid_t out_column_count = static_cast<oid_t>(sstate->ps.ps_ResultTupleSlot->tts_tupleDescriptor->natts);

  parent = nullptr;
  predicate = nullptr;
  out_col_list.clear();

  /* Transform predicate */
  predicate = BuildPredicateFromQual(qual);

  /* Transform project info */
  std::unique_ptr<const planner::ProjectInfo> project_info(nullptr);
  if(use_projInfo){
    project_info.reset(BuildProjectInfo(pg_proj_info, out_column_count));
  }

  /*
   * Based on project_info, see whether we should create a functional projection node
   * on top, or simply pushed in an output column list.
   */
  if(nullptr == project_info.get()){  // empty predicate, or ignore projInfo, pass thru
    LOG_INFO("No projections (all pass through)");

    assert(out_col_list.size() == 0);
  }
  else if(project_info->GetTargetList().size() > 0){  // Have non-trivial projection, add a plan node
    LOG_INFO("Non-trivial projections are found. Projection node will be created. \n");

    auto project_schema =
        SchemaTransformer::GetSchemaFromTupleDesc(sstate->ps.ps_ResultTupleSlot->tts_tupleDescriptor);

    parent = new planner::ProjectionNode(project_info.release(), project_schema);

  }

  else {  // Pure direct map
    assert(project_info->GetTargetList().size() == 0);
    assert(project_info->GetDirectMapList().size() > 0);

    LOG_INFO("Pure direct map projection.\n");

    std::vector<oid_t> column_ids;
    column_ids = BuildColumnListFromDirectMap(project_info->GetDirectMapList());
    out_col_list = std::move(column_ids);

    assert(out_col_list.size() == out_column_count);
  }
}

/**
 * @brief Transform a PG ProjectionInfo structure to a Peloton ProjectInfo
 *object.
 *
 * @param pg_proj_info  The PG ProjectionInfo struct to be transformed
 * @param column_count  The valid column count of output. This is used to
 * skip junk attributes in PG.
 * @return  An ProjectInfo object built from the PG ProjectionInfo.
 *          NULL if no valid project info is found.
 *
 * @warning Some projections in PG may be ignored.
 * For example, the "row" projection
 */
const planner::ProjectInfo *PlanTransformer::BuildProjectInfo(
    const ProjectionInfo *pg_pi,
    oid_t column_count) {

  if (pg_pi == nullptr) {
    LOG_INFO("pg proj info is null, no projection");
    return nullptr;
  }

  /*
   * (A) Transform non-trivial target list
   */
  planner::ProjectInfo::TargetList target_list;

  ListCell *tl;

  foreach (tl, pg_pi->pi_targetlist) {
    GenericExprState *gstate = (GenericExprState *)lfirst(tl);
    TargetEntry *tle = (TargetEntry *)gstate->xprstate.expr;
    AttrNumber resind = tle->resno - 1;

    if (!(resind < column_count
          && AttributeNumberIsValid(tle->resno)
          && AttrNumberIsForUserDefinedAttr(tle->resno)
          && !tle->resjunk)){
      LOG_INFO("Invalid / Junk attribute. Skipped. \n");
      continue;  // skip junk attributes
    }

    oid_t col_id = static_cast<oid_t>(resind);

    auto peloton_expr = ExprTransformer::TransformExpr(gstate->arg);

    if(peloton_expr == nullptr){
      LOG_INFO("Seems to be a row value expression. Skipped.\n");
      continue;
    }

    LOG_INFO("Target : column id %u, Expression : \n%s\n", col_id, peloton_expr->DebugInfo().c_str());

    target_list.emplace_back(col_id, peloton_expr);
  }

  /*
   * (B) Transform direct map list
   * Special case:
   * a null constant may be specified in SimpleVars by PG,
   * in case of that, we add a Target to target_list we created above.
   */
  planner::ProjectInfo::DirectMapList direct_map_list;

  if (pg_pi->pi_numSimpleVars > 0) {
    int numSimpleVars = pg_pi->pi_numSimpleVars;
    int *varSlotOffsets = pg_pi->pi_varSlotOffsets;
    int *varNumbers = pg_pi->pi_varNumbers;

    if (pg_pi->pi_directMap)  // Sequential direct map
    {
      /* especially simple case where vars go to output in order */
      for (int i = 0; i < numSimpleVars && i < column_count; i++) {
        oid_t tuple_idx =
            (varSlotOffsets[i] == offsetof(ExprContext, ecxt_innertuple) ? 1
                                                                         : 0);
        int varNumber = varNumbers[i] - 1;
        oid_t in_col_id = static_cast<oid_t>(varNumber);
        oid_t out_col_id = static_cast<oid_t>(i);

        direct_map_list.emplace_back(out_col_id, std::make_pair(tuple_idx, in_col_id));

        LOG_INFO("Input column : %u , Output column : %u \n", in_col_id,
                 out_col_id);
      }
    } else  // Non-sequential direct map
    {
      /* we have to pay attention to varOutputCols[] */
      int *varOutputCols = pg_pi->pi_varOutputCols;

      for (int i = 0; i < numSimpleVars; i++) {
        oid_t tuple_idx =
            (varSlotOffsets[i] == offsetof(ExprContext, ecxt_innertuple) ? 1
                                                                         : 0);
        int varNumber = varNumbers[i] - 1;
        int varOutputCol = varOutputCols[i] - 1;
        oid_t in_col_id = static_cast<oid_t>(varNumber);
        oid_t out_col_id = static_cast<oid_t>(varOutputCol);

        direct_map_list.emplace_back(out_col_id, std::make_pair(tuple_idx, in_col_id));

        LOG_INFO("Input column : %u , Output column : %u \n", in_col_id,
                 out_col_id);
      }
    }
  }

  if(target_list.empty() && direct_map_list.empty())
    return nullptr;

  return new planner::ProjectInfo(std::move(target_list),
                                  std::move(direct_map_list));
}

/**
 * @brief Transform a PG qual list to an expression tree.
 *
 * @return Expression tree, null if empty.
 */
expression::AbstractExpression*
PlanTransformer::BuildPredicateFromQual(List* qual){

  expression::AbstractExpression* predicate =
      ExprTransformer::TransformExpr(
          reinterpret_cast<ExprState*>(qual) );
  LOG_INFO("Predicate:\n%s \n", (nullptr==predicate)? "NULL" : predicate->DebugInfo().c_str());

  return predicate;
}

/**
 * @brief Transform a DirectMapList to a one-dimensional column list.
 * This is intended to incorporate a pure-direct-map projection into a scan.
 * The caller should make sure the direct map list has output columns positions.
 * from 0 ~ N-1
 */
const std::vector<oid_t>
PlanTransformer::BuildColumnListFromDirectMap(planner::ProjectInfo::DirectMapList dmlist){
  std::sort(dmlist.begin(), dmlist.end(),
            [](const planner::ProjectInfo::DirectMap &a,
               const planner::ProjectInfo::DirectMap &b){
                return a.first < b.first; }
            );

  assert(dmlist.front().first == 0);
  assert(dmlist.back().first == dmlist.size()-1 );

  std::vector<oid_t> rv;

  for(auto map : dmlist) {
    assert(map.second.first == 0);
    rv.emplace_back(map.second.second);
  }

  return rv;
}

/**
 * Convet a Postgres JoinType into a Peloton JoinType
 *
 * We may want to have a uniform JoinType enum, instead of a transformation
 */
PelotonJoinType PlanTransformer::TransformJoinType(const JoinType type) {
  switch (type) {
    case JOIN_INNER:
      return JOIN_TYPE_INNER;
    case JOIN_FULL:
      return JOIN_TYPE_OUTER;
    case JOIN_LEFT:
      return JOIN_TYPE_LEFT;
    case JOIN_RIGHT:
      return JOIN_TYPE_RIGHT;
    default:
      return JOIN_TYPE_INVALID;
  }
}

}  // namespace bridge
}  // namespace peloton
<commit_msg>Reduce logging.<commit_after>/*-------------------------------------------------------------------------
 *
 * mapper_utils.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/dml/mapper/mapper_utils.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/bridge/ddl/schema_transformer.h"
#include "backend/planner/projection_node.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Utils
//===--------------------------------------------------------------------===//

const ValueArray PlanTransformer::BuildParams(const ParamListInfo param_list) {
  ValueArray params;
  if (param_list != nullptr) {
    params.Reset(param_list->numParams);
    ParamExternData *postgres_param = param_list->params;
    for (int i = 0; i < params.GetSize(); ++i, ++postgres_param) {
      params[i] = TupleTransformer::GetValue(postgres_param->value,
                                             postgres_param->ptype);
    }
  }

  LOG_TRACE("Built %d params: \n%s", params.GetSize(), params.Debug().c_str());
  return params;
}

/**
 * @brief Extract the common things shared by all Scan types:
 * generic predicates and projections.
 *
 * @param[out]  parent  Set to a created projection plan node if one is needed,
 *              or NULL otherwise.
 *
 * @param[out]  predicate   Set to the transformed Expression based on qual. Or NULL if so is qual.
 *
 * @param[out]  out_col_list  Set to the output column list if ps_ProjInfo contains only
 *              direct mapping of attributes. \b Empty if no direct map is presented.
 *
 * @param[in]   sstate  The ScanState from which generic things are extracted.
 *
 * @param[in]   use_projInfo  Parse projInfo or not. Sometimes the projInfo of a Scan may have been
 *              stolen by its parent.
 *
 * @return      Nothing.
 */
void PlanTransformer::GetGenericInfoFromScanState(
    planner::AbstractPlanNode*& parent,
    expression::AbstractExpression*& predicate,
    std::vector<oid_t>& out_col_list,
    const ScanState* sstate,
    bool use_projInfo) {

  List* qual = sstate->ps.qual;
  const ProjectionInfo *pg_proj_info = sstate->ps.ps_ProjInfo;
  oid_t out_column_count = static_cast<oid_t>(sstate->ps.ps_ResultTupleSlot->tts_tupleDescriptor->natts);

  parent = nullptr;
  predicate = nullptr;
  out_col_list.clear();

  /* Transform predicate */
  predicate = BuildPredicateFromQual(qual);

  /* Transform project info */
  std::unique_ptr<const planner::ProjectInfo> project_info(nullptr);
  if(use_projInfo){
    project_info.reset(BuildProjectInfo(pg_proj_info, out_column_count));
  }

  /*
   * Based on project_info, see whether we should create a functional projection node
   * on top, or simply pushed in an output column list.
   */
  if(nullptr == project_info.get()){  // empty predicate, or ignore projInfo, pass thru
    LOG_TRACE("No projections (all pass through)");

    assert(out_col_list.size() == 0);
  }
  else if(project_info->GetTargetList().size() > 0){  // Have non-trivial projection, add a plan node
    LOG_TRACE("Non-trivial projections are found. Projection node will be created. \n");

    auto project_schema =
        SchemaTransformer::GetSchemaFromTupleDesc(sstate->ps.ps_ResultTupleSlot->tts_tupleDescriptor);

    parent = new planner::ProjectionNode(project_info.release(), project_schema);

  }

  else {  // Pure direct map
    assert(project_info->GetTargetList().size() == 0);
    assert(project_info->GetDirectMapList().size() > 0);

    LOG_TRACE("Pure direct map projection.\n");

    std::vector<oid_t> column_ids;
    column_ids = BuildColumnListFromDirectMap(project_info->GetDirectMapList());
    out_col_list = std::move(column_ids);

    assert(out_col_list.size() == out_column_count);
  }
}

/**
 * @brief Transform a PG ProjectionInfo structure to a Peloton ProjectInfo
 *object.
 *
 * @param pg_proj_info  The PG ProjectionInfo struct to be transformed
 * @param column_count  The valid column count of output. This is used to
 * skip junk attributes in PG.
 * @return  An ProjectInfo object built from the PG ProjectionInfo.
 *          NULL if no valid project info is found.
 *
 * @warning Some projections in PG may be ignored.
 * For example, the "row" projection
 */
const planner::ProjectInfo *PlanTransformer::BuildProjectInfo(
    const ProjectionInfo *pg_pi,
    oid_t column_count) {

  if (pg_pi == nullptr) {
    LOG_TRACE("pg proj info is null, no projection");
    return nullptr;
  }

  /*
   * (A) Transform non-trivial target list
   */
  planner::ProjectInfo::TargetList target_list;

  ListCell *tl;

  foreach (tl, pg_pi->pi_targetlist) {
    GenericExprState *gstate = (GenericExprState *)lfirst(tl);
    TargetEntry *tle = (TargetEntry *)gstate->xprstate.expr;
    AttrNumber resind = tle->resno - 1;

    if (!(resind < column_count
          && AttributeNumberIsValid(tle->resno)
          && AttrNumberIsForUserDefinedAttr(tle->resno)
          && !tle->resjunk)){
      LOG_TRACE("Invalid / Junk attribute. Skipped.");
      continue;  // skip junk attributes
    }

    oid_t col_id = static_cast<oid_t>(resind);

    auto peloton_expr = ExprTransformer::TransformExpr(gstate->arg);

    if(peloton_expr == nullptr){
      LOG_TRACE("Seems to be a row value expression. Skipped.");
      continue;
    }

    LOG_TRACE("Target : column id %u, Expression : \n%s", col_id, peloton_expr->DebugInfo().c_str());

    target_list.emplace_back(col_id, peloton_expr);
  }

  /*
   * (B) Transform direct map list
   * Special case:
   * a null constant may be specified in SimpleVars by PG,
   * in case of that, we add a Target to target_list we created above.
   */
  planner::ProjectInfo::DirectMapList direct_map_list;

  if (pg_pi->pi_numSimpleVars > 0) {
    int numSimpleVars = pg_pi->pi_numSimpleVars;
    int *varSlotOffsets = pg_pi->pi_varSlotOffsets;
    int *varNumbers = pg_pi->pi_varNumbers;

    if (pg_pi->pi_directMap)  // Sequential direct map
    {
      /* especially simple case where vars go to output in order */
      for (int i = 0; i < numSimpleVars && i < column_count; i++) {
        oid_t tuple_idx =
            (varSlotOffsets[i] == offsetof(ExprContext, ecxt_innertuple) ? 1
                                                                         : 0);
        int varNumber = varNumbers[i] - 1;
        oid_t in_col_id = static_cast<oid_t>(varNumber);
        oid_t out_col_id = static_cast<oid_t>(i);

        direct_map_list.emplace_back(out_col_id, std::make_pair(tuple_idx, in_col_id));

        LOG_TRACE("Input column : %u , Output column : %u", in_col_id,
                 out_col_id);
      }
    } else  // Non-sequential direct map
    {
      /* we have to pay attention to varOutputCols[] */
      int *varOutputCols = pg_pi->pi_varOutputCols;

      for (int i = 0; i < numSimpleVars; i++) {
        oid_t tuple_idx =
            (varSlotOffsets[i] == offsetof(ExprContext, ecxt_innertuple) ? 1
                                                                         : 0);
        int varNumber = varNumbers[i] - 1;
        int varOutputCol = varOutputCols[i] - 1;
        oid_t in_col_id = static_cast<oid_t>(varNumber);
        oid_t out_col_id = static_cast<oid_t>(varOutputCol);

        direct_map_list.emplace_back(out_col_id, std::make_pair(tuple_idx, in_col_id));

        LOG_TRACE("Input column : %u , Output column : %u \n", in_col_id,
                 out_col_id);
      }
    }
  }

  if(target_list.empty() && direct_map_list.empty())
    return nullptr;

  return new planner::ProjectInfo(std::move(target_list),
                                  std::move(direct_map_list));
}

/**
 * @brief Transform a PG qual list to an expression tree.
 *
 * @return Expression tree, null if empty.
 */
expression::AbstractExpression*
PlanTransformer::BuildPredicateFromQual(List* qual){

  expression::AbstractExpression* predicate =
      ExprTransformer::TransformExpr(
          reinterpret_cast<ExprState*>(qual) );
  LOG_TRACE("Predicate:\n%s \n", (nullptr==predicate)? "NULL" : predicate->DebugInfo().c_str());

  return predicate;
}

/**
 * @brief Transform a DirectMapList to a one-dimensional column list.
 * This is intended to incorporate a pure-direct-map projection into a scan.
 * The caller should make sure the direct map list has output columns positions.
 * from 0 ~ N-1
 */
const std::vector<oid_t>
PlanTransformer::BuildColumnListFromDirectMap(planner::ProjectInfo::DirectMapList dmlist){
  std::sort(dmlist.begin(), dmlist.end(),
            [](const planner::ProjectInfo::DirectMap &a,
               const planner::ProjectInfo::DirectMap &b){
                return a.first < b.first; }
            );

  assert(dmlist.front().first == 0);
  assert(dmlist.back().first == dmlist.size()-1 );

  std::vector<oid_t> rv;

  for(auto map : dmlist) {
    assert(map.second.first == 0);
    rv.emplace_back(map.second.second);
  }

  return rv;
}

/**
 * Convet a Postgres JoinType into a Peloton JoinType
 *
 * We may want to have a uniform JoinType enum, instead of a transformation
 */
PelotonJoinType PlanTransformer::TransformJoinType(const JoinType type) {
  switch (type) {
    case JOIN_INNER:
      return JOIN_TYPE_INNER;
    case JOIN_FULL:
      return JOIN_TYPE_OUTER;
    case JOIN_LEFT:
      return JOIN_TYPE_LEFT;
    case JOIN_RIGHT:
      return JOIN_TYPE_RIGHT;
    default:
      return JOIN_TYPE_INVALID;
  }
}

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


<commit_before>#include "iopin.h"

#include "schedulerbase.h" //for SchedulerBase::registerExitHandler
#include "common/logging.h"

namespace iodrv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

void IoPin::deactivateAll() {
    LOG("IoPin::deactivateAll()\n");
    for (auto p : livingPins) {
        p->setToDefault();
    }
}

void IoPin::registerExitHandler() {
    //install exit handler to leave pins in a safe state post-execution.
    static bool doOnce(SchedulerBase::registerExitHandler((void(*)())&deactivateAll, SCHED_IO_EXIT_LEVEL));
    (void)doOnce; //destroy 'unused' warning
}

IoPin::~IoPin() {
    setToDefault();
    livingPins.erase(this);
}

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_invertReads = other._invertReads;
    _invertWrites = other._invertWrites;
    _defaultState = other._defaultState;
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}<commit_msg>Added some basic test fixtures<commit_after>#include "iopin.h"

#include "schedulerbase.h" //for SchedulerBase::registerExitHandler
#include "common/logging.h"
#include "catch.hpp" //for the testsuite

namespace iodrv {

std::set<IoPin*> IoPin::livingPins; //allocate storage for static variables.
IoPin::null IoPin::null::_null;

void IoPin::deactivateAll() {
    LOG("IoPin::deactivateAll()\n");
    for (auto p : livingPins) {
        p->setToDefault();
    }
}

void IoPin::registerExitHandler() {
    //install exit handler to leave pins in a safe state post-execution.
    static bool doOnce(SchedulerBase::registerExitHandler((void(*)())&deactivateAll, SCHED_IO_EXIT_LEVEL));
    (void)doOnce; //destroy 'unused' warning
}

IoPin::~IoPin() {
    setToDefault();
    livingPins.erase(this);
}

//move constructor:
IoPin::IoPin(IoPin &&other) : _pin(PrimitiveIoPin::null()) {
	*this = std::move(other);
}

IoPin& IoPin::operator=(IoPin &&other) {
	_invertReads = other._invertReads;
    _invertWrites = other._invertWrites;
    _defaultState = other._defaultState;
	_pin = other._pin;
	other._pin = IoPin::null::ref()._pin;
	livingPins.insert(this);
    livingPins.erase(&other);
    return *this;
}

}

TEST_CASE("IoPins will correctly invert writes", "[iopin]") {
    SECTION("Inverted reads won't invert writes") {
        iodrv::IoPin p(iodrv::INVERT_READS, IoDefaultLow, PrimitiveIoPin::null());
        REQUIRE(p.translateWriteToPrimitive(IoLow) == IoLow);
        REQUIRE(p.translateWriteToPrimitive(IoHigh) == IoHigh);
        REQUIRE(p.translateDutyCycleToPrimitive(0.2) == Approx(0.2));
    }
    SECTION("Inverted pins will invert writes") {
        iodrv::IoPin p(iodrv::INVERT_WRITES, IoDefaultLow, PrimitiveIoPin::null());
        REQUIRE(p.translateWriteToPrimitive(IoLow) == IoHigh);
        REQUIRE(p.translateWriteToPrimitive(IoHigh) == IoLow);
        REQUIRE(p.translateDutyCycleToPrimitive(0.2) == Approx(0.8));
    }
}<|endoftext|>


<commit_before>/*
 * An istream handler which sends data to a socket.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "sink_fd.hxx"
#include "Sink.hxx"
#include "pool.hxx"
#include "direct.hxx"
#include "system/fd-util.h"
#include "event/Event.hxx"
#include "event/Callback.hxx"

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

struct SinkFd final : IstreamSink {
    struct pool *pool;

    int fd;
    FdType fd_type;
    const SinkFdHandler *handler;
    void *handler_ctx;

    Event event;

    /**
     * Set to true each time data was received from the istream.
     */
    bool got_data;

    /**
     * This flag is used to determine if the EV_WRITE event shall be
     * scheduled after a splice().  We need to add the event only if
     * the splice() was triggered by EV_WRITE, because then we're
     * responsible for querying more data.
     */
    bool got_event = false;

#ifndef NDEBUG
    bool valid = true;
#endif

    SinkFd(struct pool &_pool, Istream &_istream,
           int _fd, FdType _fd_type,
           const SinkFdHandler &_handler, void *_handler_ctx)
        :IstreamSink(_istream, istream_direct_mask_to(_fd_type)),
         pool(&_pool),
         fd(_fd), fd_type(_fd_type),
         handler(&_handler), handler_ctx(_handler_ctx) {
        ScheduleWrite();
    }

    bool IsDefined() const {
        return input.IsDefined();
    }

    void Read() {
        input.Read();
    }

    void Close() {
        input.Close();
    }

    void ScheduleWrite() {
        assert(fd >= 0);
        assert(input.IsDefined());

        got_event = false;
        event.Add();
    }

    void EventCallback();

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    ssize_t OnDirect(FdType type, int fd, size_t max_length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

/*
 * istream handler
 *
 */

inline size_t
SinkFd::OnData(const void *data, size_t length)
{
    got_data = true;

    ssize_t nbytes = IsAnySocket(fd_type)
        ? send(fd, data, length, MSG_DONTWAIT|MSG_NOSIGNAL)
        : write(fd, data, length);
    if (nbytes >= 0) {
        ScheduleWrite();
        return nbytes;
    } else if (errno == EAGAIN) {
        ScheduleWrite();
        return 0;
    } else {
        event.Delete();
        if (handler->send_error(errno, handler_ctx))
            input.Close();
        return 0;
    }
}

inline ssize_t
SinkFd::OnDirect(FdType type, gcc_unused int _fd, size_t max_length)
{
    got_data = true;

    ssize_t nbytes = istream_direct_to(fd, type, fd, fd_type,
                                       max_length);
    if (unlikely(nbytes < 0 && errno == EAGAIN)) {
        if (!fd_ready_for_writing(fd)) {
            ScheduleWrite();
            return ISTREAM_RESULT_BLOCKING;
        }

        /* try again, just in case connection->fd has become ready
           between the first istream_direct_to_socket() call and
           fd_ready_for_writing() */
        nbytes = istream_direct_to(fd, type, fd, fd_type, max_length);
    }

    if (likely(nbytes > 0) && (got_event || type == FdType::FD_FILE))
        /* regular files don't have support for EV_READ, and thus the
           sink is responsible for triggering the next splice */
        ScheduleWrite();

    return nbytes;
}

inline void
SinkFd::OnEof()
{
    got_data = true;

#ifndef NDEBUG
    valid = false;
#endif

    event.Delete();

    handler->input_eof(handler_ctx);
}

inline void
SinkFd::OnError(GError *error)
{
    got_data = true;

#ifndef NDEBUG
    valid = false;
#endif

    event.Delete();

    handler->input_error(error, handler_ctx);
}

/*
 * libevent callback
 *
 */

inline void
SinkFd::EventCallback()
{
    pool_ref(pool);

    got_event = true;
    got_data = false;
    input.Read();

    if (!got_data)
        /* the fd is ready for writing, but the istream is blocking -
           don't try again for now */
        event.Delete();

    pool_unref(pool);
    pool_commit();
}

/*
 * constructor
 *
 */

SinkFd *
sink_fd_new(struct pool &pool, Istream &istream,
            int fd, FdType fd_type,
            const SinkFdHandler &handler, void *ctx)
{
    assert(fd >= 0);
    assert(handler.input_eof != nullptr);
    assert(handler.input_error != nullptr);
    assert(handler.send_error != nullptr);

    return NewFromPool<SinkFd>(pool, pool, istream, fd, fd_type,
                               handler, ctx);
}

void
sink_fd_read(SinkFd *ss)
{
    assert(ss != nullptr);
    assert(ss->valid);
    assert(ss->IsDefined());

    ss->Read();
}

void
sink_fd_close(SinkFd *ss)
{
    assert(ss != nullptr);
    assert(ss->valid);
    assert(ss->IsDefined());

#ifndef NDEBUG
    ss->valid = false;
#endif

    ss->event.Delete();
    ss->Close();
}
<commit_msg>istream/sink_fd: initialize event<commit_after>/*
 * An istream handler which sends data to a socket.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "sink_fd.hxx"
#include "Sink.hxx"
#include "pool.hxx"
#include "direct.hxx"
#include "system/fd-util.h"
#include "event/Event.hxx"
#include "event/Callback.hxx"

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

struct SinkFd final : IstreamSink {
    struct pool *pool;

    int fd;
    FdType fd_type;
    const SinkFdHandler *handler;
    void *handler_ctx;

    Event event;

    /**
     * Set to true each time data was received from the istream.
     */
    bool got_data;

    /**
     * This flag is used to determine if the EV_WRITE event shall be
     * scheduled after a splice().  We need to add the event only if
     * the splice() was triggered by EV_WRITE, because then we're
     * responsible for querying more data.
     */
    bool got_event = false;

#ifndef NDEBUG
    bool valid = true;
#endif

    SinkFd(struct pool &_pool, Istream &_istream,
           int _fd, FdType _fd_type,
           const SinkFdHandler &_handler, void *_handler_ctx)
        :IstreamSink(_istream, istream_direct_mask_to(_fd_type)),
         pool(&_pool),
         fd(_fd), fd_type(_fd_type),
         handler(&_handler), handler_ctx(_handler_ctx),
         event(fd, EV_WRITE|EV_PERSIST,
               MakeSimpleEventCallback(SinkFd, EventCallback), this) {
        ScheduleWrite();
    }

    bool IsDefined() const {
        return input.IsDefined();
    }

    void Read() {
        input.Read();
    }

    void Close() {
        input.Close();
    }

    void ScheduleWrite() {
        assert(fd >= 0);
        assert(input.IsDefined());

        got_event = false;
        event.Add();
    }

    void EventCallback();

    /* virtual methods from class IstreamHandler */
    size_t OnData(const void *data, size_t length) override;
    ssize_t OnDirect(FdType type, int fd, size_t max_length) override;
    void OnEof() override;
    void OnError(GError *error) override;
};

/*
 * istream handler
 *
 */

inline size_t
SinkFd::OnData(const void *data, size_t length)
{
    got_data = true;

    ssize_t nbytes = IsAnySocket(fd_type)
        ? send(fd, data, length, MSG_DONTWAIT|MSG_NOSIGNAL)
        : write(fd, data, length);
    if (nbytes >= 0) {
        ScheduleWrite();
        return nbytes;
    } else if (errno == EAGAIN) {
        ScheduleWrite();
        return 0;
    } else {
        event.Delete();
        if (handler->send_error(errno, handler_ctx))
            input.Close();
        return 0;
    }
}

inline ssize_t
SinkFd::OnDirect(FdType type, gcc_unused int _fd, size_t max_length)
{
    got_data = true;

    ssize_t nbytes = istream_direct_to(fd, type, fd, fd_type,
                                       max_length);
    if (unlikely(nbytes < 0 && errno == EAGAIN)) {
        if (!fd_ready_for_writing(fd)) {
            ScheduleWrite();
            return ISTREAM_RESULT_BLOCKING;
        }

        /* try again, just in case connection->fd has become ready
           between the first istream_direct_to_socket() call and
           fd_ready_for_writing() */
        nbytes = istream_direct_to(fd, type, fd, fd_type, max_length);
    }

    if (likely(nbytes > 0) && (got_event || type == FdType::FD_FILE))
        /* regular files don't have support for EV_READ, and thus the
           sink is responsible for triggering the next splice */
        ScheduleWrite();

    return nbytes;
}

inline void
SinkFd::OnEof()
{
    got_data = true;

#ifndef NDEBUG
    valid = false;
#endif

    event.Delete();

    handler->input_eof(handler_ctx);
}

inline void
SinkFd::OnError(GError *error)
{
    got_data = true;

#ifndef NDEBUG
    valid = false;
#endif

    event.Delete();

    handler->input_error(error, handler_ctx);
}

/*
 * libevent callback
 *
 */

inline void
SinkFd::EventCallback()
{
    pool_ref(pool);

    got_event = true;
    got_data = false;
    input.Read();

    if (!got_data)
        /* the fd is ready for writing, but the istream is blocking -
           don't try again for now */
        event.Delete();

    pool_unref(pool);
    pool_commit();
}

/*
 * constructor
 *
 */

SinkFd *
sink_fd_new(struct pool &pool, Istream &istream,
            int fd, FdType fd_type,
            const SinkFdHandler &handler, void *ctx)
{
    assert(fd >= 0);
    assert(handler.input_eof != nullptr);
    assert(handler.input_error != nullptr);
    assert(handler.send_error != nullptr);

    return NewFromPool<SinkFd>(pool, pool, istream, fd, fd_type,
                               handler, ctx);
}

void
sink_fd_read(SinkFd *ss)
{
    assert(ss != nullptr);
    assert(ss->valid);
    assert(ss->IsDefined());

    ss->Read();
}

void
sink_fd_close(SinkFd *ss)
{
    assert(ss != nullptr);
    assert(ss->valid);
    assert(ss->IsDefined());

#ifndef NDEBUG
    ss->valid = false;
#endif

    ss->event.Delete();
    ss->Close();
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * EPGItem.cpp: EPGItem
 ****************************************************************************
 * Copyright © 2009-2010 VideoLAN
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <QTransform>
#include <QFont>
#include <QFontMetrics>
#include <QDateTime>
#include <QFocusEvent>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneHoverEvent>
#include <QStyle>

#include "EPGItem.hpp"
#include "EPGView.hpp"

#include "qt.hpp"

EPGItem::EPGItem( const vlc_epg_event_t *data, EPGView *view, const EPGProgram *prog )
    : QGraphicsItem()
{
    m_view = view;
    program = prog;
    m_id = data->i_id;
    setData( data );
    m_boundingRect.setHeight( TRACKS_HEIGHT );
    setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    setAcceptHoverEvents( true );
}

QRectF EPGItem::boundingRect() const
{
    return m_boundingRect;
}

void EPGItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget*)
{
    QPen pen;
    QColor gradientColor;

    // Draw in view's coordinates
    painter->setWorldMatrixEnabled( false );

    // Draw high-quality items
    //painter->setRenderHint( QPainter::Antialiasing );

    // Get the transformations required to map the text on the viewport
    QTransform viewPortTransform = m_view->viewportTransform();
    QRectF mapped = deviceTransform( viewPortTransform ).mapRect( boundingRect() );

    QLinearGradient gradient( mapped.topLeft(), mapped.bottomLeft() );

    bool b_simultaneous = m_view->liveTime().isValid() && playsAt( m_view->liveTime() );
    if ( program->getCurrent() == this || b_simultaneous )
        gradientColor.setRgb( 244, 125, 0 , b_simultaneous ? 192 : 255 );
    else
        gradientColor.setRgb( 201, 217, 242 );

    gradient.setColorAt( 0.0, gradientColor.lighter( 120 ) );
    gradient.setColorAt( 1.0, gradientColor );

    pen.setColor( option->state & QStyle::State_MouseOver || hasFocus()
                  ? QColor( 0, 0, 0 ) : QColor( 192, 192, 192 ) );

    pen.setStyle( option->state & QStyle::State_MouseOver && !hasFocus()
                  ? Qt::DashLine : Qt::SolidLine );

    painter->setBrush( QBrush( gradient ) );
    painter->setPen( pen );
    mapped.adjust( 1, 2, -1, -2 );
    painter->drawRoundedRect( mapped, 10, 10 );

    /* Draw text */

    // Setup the font
    QFont f = painter->font();

    // Get the font metrics
    QFontMetrics fm = painter->fontMetrics();

    // Adjust the drawing rect
    mapped.adjust( 6, 6, -6, -6 );

    painter->setPen( Qt::black );
    /* Draw the title. */
    painter->drawText( mapped, Qt::AlignTop | Qt::AlignLeft, fm.elidedText( m_name, Qt::ElideRight, mapped.width() ) );

    if ( m_rating > 0 && mapped.width() > 40 )
    {
        QRectF iconsRect = QRectF( mapped.bottomRight(), mapped.bottomRight() );
        iconsRect.adjust( -20, -20, 0, 0 );
        painter->save();
        painter->setBrush( Qt::white );
        f.setPixelSize( 8 );
        painter->setFont( f );
        painter->drawRect( iconsRect );
        painter->drawText( iconsRect, Qt::AlignCenter, QString("%1+").arg( m_rating ) );
        painter->restore();
    }

    mapped.adjust( 0, 20, 0, 0 );

    QDateTime m_end = m_start.addSecs( m_duration );
    f.setPixelSize( 10 );
    f.setItalic( true );
    painter->setFont( f );

    /* Draw the hours. */
    painter->drawText( mapped, Qt::AlignTop | Qt::AlignLeft,
                       fm.elidedText( start().toString( "hh:mm" ) + " - " +
                                      m_end.toString( "hh:mm" ),
                                      Qt::ElideRight, mapped.width() ) );
}

const QDateTime& EPGItem::start() const
{
    return m_start;
}

QDateTime EPGItem::end() const
{
    return QDateTime( m_start ).addSecs( m_duration );
}

uint32_t EPGItem::duration() const
{
    return m_duration;
}

uint16_t EPGItem::eventID() const
{
    return m_id;
}

bool EPGItem::setData( const vlc_epg_event_t *data )
{
    QDateTime newtime = QDateTime::fromTime_t( data->i_start );
    QString newname = qfu( data->psz_name );
    QString newdesc = qfu( data->psz_description );
    QString newshortdesc = qfu( data->psz_short_description );

    if ( m_start != newtime ||
         m_name != newname ||
         m_description != newdesc ||
         m_shortDescription != newshortdesc ||
         m_duration != data->i_duration )
    {
        m_start = newtime;
        m_name = newname;
        setToolTip( newname );
        m_description = newdesc;
        m_shortDescription = newshortdesc;
        setDuration( data->i_duration );
        setRating( data->i_rating );
        updatePos();
        prepareGeometryChange();
        return true;
    }
    return false;
}

bool EPGItem::endsBefore( const QDateTime &ref ) const
{
    return m_start.addSecs( m_duration ) < ref;
}

bool EPGItem::playsAt( const QDateTime & ref ) const
{
    return (m_start <= ref) && !endsBefore( ref );
}

void EPGItem::setDuration( uint32_t duration )
{
    m_duration = duration;
    m_boundingRect.setWidth( duration );
}

void EPGItem::setRating( uint8_t i_rating )
{
    m_rating = i_rating;
}

QString EPGItem::description() const
{
    if( m_description.isEmpty() )
        return m_shortDescription;

    QString text( m_description );
    if( !m_shortDescription.isEmpty() )
        text += QString(" - ") += m_shortDescription;
    return text;
}

void EPGItem::updatePos()
{
    QDateTime overallmin = m_view->startTime();
    if( overallmin.isValid() )
    {
        int x = m_view->startTime().secsTo( m_start );
        setPos( x, program->getPosition() * TRACKS_HEIGHT );
    }
}

void EPGItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
{
    event->accept();
    scene()->update();
}

void EPGItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
{ /* required to redraw our background without flaws */
    hoverEnterEvent( event );
}

void EPGItem::focusInEvent( QFocusEvent * event )
{
    event->accept();
    m_view->focusItem( this );
    update();
}
<commit_msg>Qt: epg: remove time based highlighting<commit_after>/*****************************************************************************
 * EPGItem.cpp: EPGItem
 ****************************************************************************
 * Copyright © 2009-2010 VideoLAN
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <QTransform>
#include <QFont>
#include <QFontMetrics>
#include <QDateTime>
#include <QFocusEvent>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneHoverEvent>
#include <QStyle>

#include "EPGItem.hpp"
#include "EPGView.hpp"

#include "qt.hpp"

EPGItem::EPGItem( const vlc_epg_event_t *data, EPGView *view, const EPGProgram *prog )
    : QGraphicsItem()
{
    m_view = view;
    program = prog;
    m_id = data->i_id;
    setData( data );
    m_boundingRect.setHeight( TRACKS_HEIGHT );
    setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    setAcceptHoverEvents( true );
}

QRectF EPGItem::boundingRect() const
{
    return m_boundingRect;
}

void EPGItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget*)
{
    QPen pen;
    QColor gradientColor;

    // Draw in view's coordinates
    painter->setWorldMatrixEnabled( false );

    // Draw high-quality items
    //painter->setRenderHint( QPainter::Antialiasing );

    // Get the transformations required to map the text on the viewport
    QTransform viewPortTransform = m_view->viewportTransform();
    QRectF mapped = deviceTransform( viewPortTransform ).mapRect( boundingRect() );

    QLinearGradient gradient( mapped.topLeft(), mapped.bottomLeft() );

    if ( program->getCurrent() == this )
        gradientColor.setRgb( 244, 125, 0 , 255 );
    else
        gradientColor.setRgb( 201, 217, 242 );

    gradient.setColorAt( 0.0, gradientColor.lighter( 120 ) );
    gradient.setColorAt( 1.0, gradientColor );

    pen.setColor( option->state & QStyle::State_MouseOver || hasFocus()
                  ? QColor( 0, 0, 0 ) : QColor( 192, 192, 192 ) );

    pen.setStyle( option->state & QStyle::State_MouseOver && !hasFocus()
                  ? Qt::DashLine : Qt::SolidLine );

    painter->setBrush( QBrush( gradient ) );
    painter->setPen( pen );
    mapped.adjust( 1, 2, -1, -2 );
    painter->drawRoundedRect( mapped, 10, 10 );

    /* Draw text */

    // Setup the font
    QFont f = painter->font();

    // Get the font metrics
    QFontMetrics fm = painter->fontMetrics();

    // Adjust the drawing rect
    mapped.adjust( 6, 6, -6, -6 );

    painter->setPen( Qt::black );
    /* Draw the title. */
    painter->drawText( mapped, Qt::AlignTop | Qt::AlignLeft, fm.elidedText( m_name, Qt::ElideRight, mapped.width() ) );

    if ( m_rating > 0 && mapped.width() > 40 )
    {
        QRectF iconsRect = QRectF( mapped.bottomRight(), mapped.bottomRight() );
        iconsRect.adjust( -20, -20, 0, 0 );
        painter->save();
        painter->setBrush( Qt::white );
        f.setPixelSize( 8 );
        painter->setFont( f );
        painter->drawRect( iconsRect );
        painter->drawText( iconsRect, Qt::AlignCenter, QString("%1+").arg( m_rating ) );
        painter->restore();
    }

    mapped.adjust( 0, 20, 0, 0 );

    QDateTime m_end = m_start.addSecs( m_duration );
    f.setPixelSize( 10 );
    f.setItalic( true );
    painter->setFont( f );

    /* Draw the hours. */
    painter->drawText( mapped, Qt::AlignTop | Qt::AlignLeft,
                       fm.elidedText( start().toString( "hh:mm" ) + " - " +
                                      m_end.toString( "hh:mm" ),
                                      Qt::ElideRight, mapped.width() ) );
}

const QDateTime& EPGItem::start() const
{
    return m_start;
}

QDateTime EPGItem::end() const
{
    return QDateTime( m_start ).addSecs( m_duration );
}

uint32_t EPGItem::duration() const
{
    return m_duration;
}

uint16_t EPGItem::eventID() const
{
    return m_id;
}

bool EPGItem::setData( const vlc_epg_event_t *data )
{
    QDateTime newtime = QDateTime::fromTime_t( data->i_start );
    QString newname = qfu( data->psz_name );
    QString newdesc = qfu( data->psz_description );
    QString newshortdesc = qfu( data->psz_short_description );

    if ( m_start != newtime ||
         m_name != newname ||
         m_description != newdesc ||
         m_shortDescription != newshortdesc ||
         m_duration != data->i_duration )
    {
        m_start = newtime;
        m_name = newname;
        setToolTip( newname );
        m_description = newdesc;
        m_shortDescription = newshortdesc;
        setDuration( data->i_duration );
        setRating( data->i_rating );
        updatePos();
        prepareGeometryChange();
        return true;
    }
    return false;
}

bool EPGItem::endsBefore( const QDateTime &ref ) const
{
    return m_start.addSecs( m_duration ) < ref;
}

bool EPGItem::playsAt( const QDateTime & ref ) const
{
    return (m_start <= ref) && !endsBefore( ref );
}

void EPGItem::setDuration( uint32_t duration )
{
    m_duration = duration;
    m_boundingRect.setWidth( duration );
}

void EPGItem::setRating( uint8_t i_rating )
{
    m_rating = i_rating;
}

QString EPGItem::description() const
{
    if( m_description.isEmpty() )
        return m_shortDescription;

    QString text( m_description );
    if( !m_shortDescription.isEmpty() )
        text += QString(" - ") += m_shortDescription;
    return text;
}

void EPGItem::updatePos()
{
    QDateTime overallmin = m_view->startTime();
    if( overallmin.isValid() )
    {
        int x = m_view->startTime().secsTo( m_start );
        setPos( x, program->getPosition() * TRACKS_HEIGHT );
    }
}

void EPGItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
{
    event->accept();
    scene()->update();
}

void EPGItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
{ /* required to redraw our background without flaws */
    hoverEnterEvent( event );
}

void EPGItem::focusInEvent( QFocusEvent * event )
{
    event->accept();
    m_view->focusItem( this );
    update();
}
<|endoftext|>


<commit_before>#include <tansa/mocap.h>
#include <tansa/gazebo.h>
#include <zconf.h>
#include <tansa/control.h>
#include "tansa/jocsPlayer.h"
#include <unistd.h>
#include <sys/signal.h>

namespace tansa {

	/**
	 * Begin to play the choreography
	 */
	void JocsPlayer::play() {

	}

	/**
	 * Pause the choreography
	 */
	void JocsPlayer::pause() {
		JocsPlayer::pauseRequested = true;
	}

	/**
	 * Rewind the chreography by a number of 'steps'
	 * @param steps How far back in the choreography to rewind
	 */
	void JocsPlayer::rewind(int steps) {

	}

	/**
	 * Reset the choreography back to the initial position (ie: plans[0])
	 */
	void JocsPlayer::reset() {
		JocsPlayer::resetMode = true;
	}

    /**
     * Load JOCS data from a specified path
     */
    void JocsPlayer::loadJocs(string jocsPath) {
		// TODO: Clear all these if they already have data.
		JocsPlayer::jocsData = Jocs::Parse(jocsPath);
		JocsPlayer::homes = jocsData.GetHomes();
		JocsPlayer::actions = jocsData.GetActions();
		JocsPlayer::breakpoints = jocsData.GetBreakpoints();
    }

	// *******
	// Helper methods
	// *******

	double JocsPlayer::getNextBreakpointTime(double lastTime) {

	}
	double JocsPlayer::getBreakpointTime(unsigned breakpointNumber) {

	}
	double JocsPlayer::getBreakpointTime(std::string breakpointName) {

	}
	unsigned JocsPlayer::getBreakpointNumber(double startTime) {

	}
	Point JocsPlayer::getDroneLocationAtTime(double startTime, unsigned droneId) {

	}
}
<commit_msg>Fill in bodies for helper methods in jocsPlayer<commit_after>#include <tansa/mocap.h>
#include <tansa/gazebo.h>
#include <zconf.h>
#include <tansa/control.h>
#include "tansa/jocsPlayer.h"
#include <unistd.h>
#include <sys/signal.h>

namespace tansa {

	/**
	 * Begin to play the choreography
	 */
	void JocsPlayer::play() {

	}

	/**
	 * Pause the choreography
	 */
	void JocsPlayer::pause() {
		JocsPlayer::pauseRequested = true;
	}

	/**
	 * Rewind the chreography by a number of 'steps'
	 * @param steps How far back in the choreography to rewind
	 */
	void JocsPlayer::rewind(int steps) {

	}

	/**
	 * Reset the choreography back to the initial position (ie: plans[0])
	 */
	void JocsPlayer::reset() {
		JocsPlayer::resetMode = true;
	}

    /**
     * Load JOCS data from a specified path
     */
    void JocsPlayer::loadJocs(string jocsPath) {
		// TODO: Clear all these if they already have data.
		JocsPlayer::jocsData = Jocs::Parse(jocsPath);
		JocsPlayer::homes = jocsData.GetHomes();
		JocsPlayer::actions = jocsData.GetActions();
		JocsPlayer::breakpoints = jocsData.GetBreakpoints();
    }

	/**
     * Helper methods
     * TODO: write test cases (especially since the code doesn't use them yet)
     */

	double JocsPlayer::getNextBreakpointTime(double lastTime) {
		unsigned breakpointsLength = breakpoints.size();

		// Cycles all breakpoints
		// Assumes list of breakpoints is in time-ascending order
		for (int i = 0; i < breakpointsLength - 1; i++) {
			double ret = breakpoints[i].GetStartTime();
			if (ret >= lastTime) {
				// Return the first breakpoint whose starttime hasn't passed yet
				// or is currently happening
				return ret;
			}
		}

		return -1;
	}
	double JocsPlayer::getBreakpointTime(unsigned breakpointNumber) {
		unsigned breakpointsLength = breakpoints.size();

		// Cycles all breakpoints
		for (int i = 1; i < breakpointsLength - 1; i++) {
			unsigned ret = breakpoints[i].GetNumber();
			if (ret == breakpointNumber) {
				return breakpoints[i].GetStartTime();
			}
		}

		return -1;
	}
	double JocsPlayer::getBreakpointTime(std::string breakpointName) {
		unsigned breakpointsLength = breakpoints.size();

		// Cycles all breakpoints
		for (int i = 1; i < breakpointsLength - 1; i++) {
			std::string name = breakpoints[i].GetName();
			if (name.compare(breakpointName) == 0) {
				return breakpoints[i].GetStartTime();
			}
		}

		return -1;
	}
	unsigned JocsPlayer::getBreakpointNumber(double startTime) {
		unsigned breakpointsLength = breakpoints.size();

		// Cycles all breakpoints
		for (int i = 1; i < breakpointsLength - 1; i++) {
			double ret = breakpoints[i].GetStartTime();
			if (ret > startTime) {
				// Return the breakpoint that the given time is a part of
				// Also works for given times that are within a breakpoint
				// not just the start time of a breakpoint
				return breakpoints[i-1].GetNumber();
			}
		}

		return -1;
	}
	Point JocsPlayer::getDroneLocationAtTime(double startTime, unsigned droneId) {
		// This one only works if the startTime is a startTime of an action
		// Returns negative value if startTime is either between actions or out of scope

		unsigned breakpointsLength = breakpoints.size();
		unsigned actionsLength = actions[droneId].size();

		// Assume droneId is valid and use it to choose which list of actions we need to parse
		for (int j = 0; j < actionsLength; j++) {
			double actionStartTime = actions[droneId][j]->GetStartTime();
			bool isMotionAction = true; // TODO: actually check if it's a motion. For now, they're all motions.
			if (actionStartTime == startTime && isMotionAction) {
				return ((MotionAction*)actions[droneId][j])->GetStartPoint(); // TODO: check if this cast works...
			}
		}
	}
}
<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2020 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

RD_TEST(VK_Imageless_Framebuffer, VulkanGraphicsTest)
{
  static constexpr const char *Description =
      "Test using VK_KHR_imageless_framebuffer to specify image views at the last second";

  std::string common = R"EOSHADER(

#version 420 core

struct v2f
{
	vec4 pos;
	vec4 col;
	vec4 uv;
};

)EOSHADER";

  const std::string vertex = R"EOSHADER(

layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV;

layout(location = 0) out v2f vertOut;

void main()
{
	vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
	gl_Position = vertOut.pos;
	vertOut.col = Color;
	vertOut.uv = vec4(UV.xy, 0, 1);
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

layout(location = 0) in v2f vertIn;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
	Color = vec4(1, 0, 0, 1);
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    devExts.push_back(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME);

    // dependencies of VK_EXT_descriptor_indexing
    devExts.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
    devExts.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);

    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    static VkPhysicalDeviceImagelessFramebufferFeaturesKHR imageless = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR,
    };

    getPhysFeatures2(&imageless);

    if(!imageless.imagelessFramebuffer)
      Avail = "feature 'imagelessFramebuffer' not available";

    devInfoNext = &imageless;
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = mainWindow->rp;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    AllocatedBuffer vb(
        this, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                            VK_BUFFER_USAGE_TRANSFER_DST_BIT),
        VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(DefaultTri);

    int lastWidth = -1;
    VkFramebuffer fb = VK_NULL_HANDLE;

    while(Running())
    {
      if(lastWidth != (int)mainWindow->scissor.extent.width)
      {
        lastWidth = (int)mainWindow->scissor.extent.width;
        if(fb != VK_NULL_HANDLE)
        {
          // be lazy, hard sync
          vkDeviceWaitIdle(device);
          vkDestroyFramebuffer(device, fb, NULL);
        }

        VkFramebufferAttachmentImageInfoKHR imageInfo = {
            VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,
        };

        imageInfo.width = mainWindow->scissor.extent.width;
        imageInfo.height = mainWindow->scissor.extent.height;
        imageInfo.layerCount = 1;
        imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
        imageInfo.viewFormatCount = 1;
        imageInfo.pViewFormats = &mainWindow->format;

        VkFramebufferAttachmentsCreateInfoKHR viewsInfo = {
            VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR, NULL, 1, &imageInfo,
        };

        CHECK_VKR(vkCreateFramebuffer(
            device,
            vkh::FramebufferCreateInfo(mainWindow->rp, {VK_NULL_HANDLE}, mainWindow->scissor.extent,
                                       1, VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)
                .next(&viewsInfo),
            NULL, &fb));
      }

      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      VkImageView curView = mainWindow->GetView();
      VkRenderPassAttachmentBeginInfoKHR usedView = {
          VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, NULL, 1, &curView,
      };

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(mainWindow->rp, fb, mainWindow->scissor).next(&usedView),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<commit_msg>Test that imageless framebuffer parameters are properly ignored<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2019-2020 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

RD_TEST(VK_Imageless_Framebuffer, VulkanGraphicsTest)
{
  static constexpr const char *Description =
      "Test using VK_KHR_imageless_framebuffer to specify image views at the last second";

  std::string common = R"EOSHADER(

#version 420 core

struct v2f
{
	vec4 pos;
	vec4 col;
	vec4 uv;
};

)EOSHADER";

  const std::string vertex = R"EOSHADER(

layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV;

layout(location = 0) out v2f vertOut;

void main()
{
	vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
	gl_Position = vertOut.pos;
	vertOut.col = Color;
	vertOut.uv = vec4(UV.xy, 0, 1);
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

layout(location = 0) in v2f vertIn;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
	Color = vec4(1, 0, 0, 1);
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    devExts.push_back(VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME);

    // dependencies of VK_EXT_descriptor_indexing
    devExts.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
    devExts.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);

    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    static VkPhysicalDeviceImagelessFramebufferFeaturesKHR imageless = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR,
    };

    getPhysFeatures2(&imageless);

    if(!imageless.imagelessFramebuffer)
      Avail = "feature 'imagelessFramebuffer' not available";

    devInfoNext = &imageless;
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo());

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = mainWindow->rp;

    pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
    pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
        vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
        vkh::vertexAttr(2, 0, DefaultA2V, uv),
    };

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    AllocatedBuffer vb(
        this, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
                                                            VK_BUFFER_USAGE_TRANSFER_DST_BIT),
        VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    vb.upload(DefaultTri);

    int lastWidth = -1;
    VkFramebuffer fb = VK_NULL_HANDLE;

    while(Running())
    {
      if(lastWidth != (int)mainWindow->scissor.extent.width)
      {
        lastWidth = (int)mainWindow->scissor.extent.width;
        if(fb != VK_NULL_HANDLE)
        {
          // be lazy, hard sync
          vkDeviceWaitIdle(device);
          vkDestroyFramebuffer(device, fb, NULL);
        }

        VkFramebufferAttachmentImageInfoKHR imageInfo = {
            VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR,
        };

        imageInfo.width = mainWindow->scissor.extent.width;
        imageInfo.height = mainWindow->scissor.extent.height;
        imageInfo.layerCount = 1;
        imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
        imageInfo.viewFormatCount = 1;
        imageInfo.pViewFormats = &mainWindow->format;

        VkFramebufferAttachmentsCreateInfoKHR viewsInfo = {
            VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR, NULL, 1, &imageInfo,
        };

        CHECK_VKR(vkCreateFramebuffer(
            device, vkh::FramebufferCreateInfo(mainWindow->rp, {(VkImageView)0x1234},
                                               mainWindow->scissor.extent, 1,
                                               VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)
                        .next(&viewsInfo),
            NULL, &fb));
      }

      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      VkImageView curView = mainWindow->GetView();
      VkRenderPassAttachmentBeginInfoKHR usedView = {
          VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR, NULL, 1, &curView,
      };

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(mainWindow->rp, fb, mainWindow->scissor).next(&usedView),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
      vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
      vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();
    }

    return 0;
  }
};

REGISTER_TEST();
<|endoftext|>


<commit_before>#include <QtGui/QVBoxLayout>

#include "listWidget.h"

using namespace qReal;

ListWidget::ListWidget(QWidget *parent)
	: QWidget(parent)
	, mListWidget(new QListWidget())
	, mOkButton(new QPushButton(tr("&OK")))
{
	mOkButton->setDisabled(true);
	mOkButton->setMinimumHeight(mOkButtonMinimumHeight);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(mListWidget);
	mainLayout->addWidget(mOkButton);

	setLayout(mainLayout);

	connect(mListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(okActivate()));
	connect(mOkButton, SIGNAL(clicked()), this, SLOT(okButtonHandler()));
	connect(mListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*))
			, this, SLOT(doubleClickHandler(QListWidgetItem*)));
}

void ListWidget::addItem(QString const &text, QString const &userData, QString const &toolTip)
{
	QListWidgetItem *currentItem = new QListWidgetItem(text, mListWidget);
	currentItem->setData(Qt::UserRole, userData);
	currentItem->setToolTip(toolTip);
	mListWidget->addItem(currentItem);
}

int ListWidget::count()
{
	return mListWidget->count();
}

void ListWidget::highlightFirstItem()
{
	if (count() == 0) {
		return;
	}
	mListWidget->setCurrentRow(0);
}

void ListWidget::okButtonHandler()
{
	emit userDataSelected(userData(mListWidget->currentItem()));
}

void ListWidget::doubleClickHandler(QListWidgetItem *item)
{
	emit userDataSelected(userData(item));
}

QString ListWidget::userData(QListWidgetItem *item)
{
	return item->data(Qt::UserRole).toString();
}

void ListWidget::okActivate()
{
	mOkButton->setEnabled(true);
	mOkButton->setDefault(true);
}
<commit_msg>jenkins test<commit_after>#include <QtGui/QVBoxLayout>

#include "listWidget.h"

using namespace qReal;

ListWidget::ListWidget(QWidget *parent)
	: QWidget(parent)
	, mListWidget(new QListWidget())
	, mOkButton(new QPushButton(tr("&OK")))
{
	mOkButton->setMinimumHeight(mOkButtonMinimumHeight);
	mOkButton->setDisabled(true);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addWidget(mListWidget);
	mainLayout->addWidget(mOkButton);

	setLayout(mainLayout);

	connect(mListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(okActivate()));
	connect(mOkButton, SIGNAL(clicked()), this, SLOT(okButtonHandler()));
	connect(mListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*))
			, this, SLOT(doubleClickHandler(QListWidgetItem*)));
}

void ListWidget::addItem(QString const &text, QString const &userData, QString const &toolTip)
{
	QListWidgetItem *currentItem = new QListWidgetItem(text, mListWidget);
	currentItem->setData(Qt::UserRole, userData);
	currentItem->setToolTip(toolTip);
	mListWidget->addItem(currentItem);
}

int ListWidget::count()
{
	return mListWidget->count();
}

void ListWidget::highlightFirstItem()
{
	if (count() == 0) {
		return;
	}
	mListWidget->setCurrentRow(0);
}

void ListWidget::okButtonHandler()
{
	emit userDataSelected(userData(mListWidget->currentItem()));
}

void ListWidget::doubleClickHandler(QListWidgetItem *item)
{
	emit userDataSelected(userData(item));
}

QString ListWidget::userData(QListWidgetItem *item)
{
	return item->data(Qt::UserRole).toString();
}

void ListWidget::okActivate()
{
	mOkButton->setEnabled(true);
	mOkButton->setDefault(true);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>

#include <MultiRegions/ExpList.h>

using namespace Nektar;

bool CheckTetRotation(Array<OneD, NekDouble> &xc, Array<OneD, NekDouble> &yc,
                      Array<OneD, NekDouble> &xz,
                      std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator &tetIter,
                      int id);

int main(int argc, char *argv[])
{
    Array<OneD,NekDouble>  fce;
    Array<OneD,NekDouble>  xc0,xc1,xc2;

    if(argc != 2)
    {
        fprintf(stderr,"Usage: CheckXmlFile  meshfile.xml\n");
        exit(1);
    }

    LibUtilities::SessionReaderSharedPtr vSession
            = LibUtilities::SessionReader::CreateInstance(argc, argv);

    //----------------------------------------------
    // Read in mesh from input file
    string meshfile(argv[argc-1]);
    SpatialDomains::MeshGraphSharedPtr mesh  = SpatialDomains::MeshGraph::Read(vSession);
    //----------------------------------------------

    //----------------------------------------------
    // Define Expansion
    int expdim   = mesh->GetMeshDimension();

    switch(expdim)
    {
    case 1:
        ASSERTL0(false,"1D not set up");
        break;
    case 2:
        {
            NekDouble x,y,z;
            string   outname(strtok(argv[argc-1],"."));
            outname += ".dat";
            FILE *fp = fopen(outname.c_str(),"w");

            SpatialDomains::TriGeomMap trigeom = mesh->GetAllTriGeoms();
            SpatialDomains::QuadGeomMap quadgeom = mesh->GetAllQuadGeoms();

            int nverts = mesh->GetNvertices();

            Array<OneD, NekDouble> xc(nverts),yc(nverts),zc(nverts);

            for(int i = 0; i < nverts; ++i)
            {
                mesh->GetVertex(i)->GetCoords(x,y,z);
                xc[i] = x;
                yc[i] = y;
                zc[i] = z;
            }

            std::map<int,SpatialDomains::TriGeomSharedPtr>::iterator triIter;
            for(triIter = trigeom.begin(); triIter != trigeom.end(); ++triIter)
            {
                fprintf(fp,"%d %d %d %d\n",(triIter->second)->GetVid(0)+1,(triIter->second)->GetVid(1)+1,(triIter->second)->GetVid(2)+1,(triIter->second)->GetVid(2)+1);
            }

            std::map<int,SpatialDomains::QuadGeomSharedPtr>::iterator quadIter;
            for(quadIter = quadgeom.begin(); quadIter != quadgeom.end(); ++quadIter)
            {
                fprintf(fp,"%d %d %d %d\n",(quadIter->second)->GetVid(0)+1,(quadIter->second)->GetVid(1)+1,(quadIter->second)->GetVid(2)+1,(quadIter->second)->GetVid(3)+1);
            }
        }
        break;
    case 3:
        {
            NekDouble x,y,z;
            string   outname(strtok(argv[argc-1],"."));
            outname += ".dat";

            SpatialDomains::TetGeomMap   tetgeom   = mesh->GetAllTetGeoms();
            SpatialDomains::PyrGeomMap   pyrgeom   = mesh->GetAllPyrGeoms();
            SpatialDomains::PrismGeomMap prismgeom = mesh->GetAllPrismGeoms();
            SpatialDomains::HexGeomMap   hexgeom   = mesh->GetAllHexGeoms();

            int nverts = mesh->GetNvertices();

            Array<OneD, NekDouble> xc(nverts),yc(nverts),zc(nverts);

            for(int i = 0; i < nverts; ++i)
            {
                // Check element roation
                mesh->GetVertex(i)->GetCoords(x,y,z);
                xc[i] = x;
                yc[i] = y;
                zc[i] = z;

            }

            std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator tetIter;
            int cnt = 0;
            bool NoRotateIssues = true;
            bool NoOrientationIssues = true;
            for(tetIter = tetgeom.begin(); tetIter != tetgeom.end(); ++tetIter)
            {
                // check rotation and dump
                NoOrientationIssues = CheckTetRotation(xc,yc,zc,tetIter,cnt++);

                // Check face rotation
                if((tetIter->second)->GetFace(0)->GetVid(2) != (tetIter->second)->GetVid(2))
                {
                    cout << "ERROR: Face " << tetIter->second->GetFid(0) << " (vert "<< (tetIter->second)->GetFace(0)->GetVid(2) << ") is not aligned with base vertex of Tet " << (tetIter->second)->GetGlobalID() << " (vert "<< (tetIter->second)->GetVid(2) <<")" << endl;
                    NoRotateIssues = false;
                }

                for(int i = 1; i < 4; ++i)

                {
                    if((tetIter->second)->GetFace(i)->GetVid(2) != (tetIter->second)->GetVid(3))
                    {
                        cout << "ERROR: Face " << tetIter->second->GetFid(i) << " is not aligned with top Vertex of Tet " << (tetIter->second)->GetGlobalID() << endl;
                        NoRotateIssues = false;
                    }
                }

            }
            if(NoOrientationIssues)
            {
                cout << "All Tet have correct ordering for anticlockwise rotation" << endl;
            }

            if(NoRotateIssues)
            {
                cout << "All Tet faces are correctly aligned" << endl;
            }

            std::map<int,SpatialDomains::PyrGeomSharedPtr>::iterator pyrIter;
            for(pyrIter = pyrgeom.begin(); pyrIter != pyrgeom.end(); ++pyrIter)
            {
                // Put pyramid checks in here
            }

            // Put prism checks in here
            std::map<int,SpatialDomains::PrismGeomSharedPtr>::iterator Iter;
            NoRotateIssues = true;
            NoOrientationIssues = true;
            for(Iter = prismgeom.begin(); Iter != prismgeom.end(); ++Iter)
            {

                // Check face rotation
                if((Iter->second)->GetFace(1)->GetVid(2) != (Iter->second)->GetVid(4))
                {
                    cout << "ERROR: Face " << Iter->second->GetFid(1) << " (vert "<< (Iter->second)->GetFace(1)->GetVid(2) << ") not aligned to face 1 singular vert of Prism " << (Iter->second)->GetGlobalID() << " (vert "<< (Iter->second)->GetVid(4) <<")" << endl;
                    NoRotateIssues = false;
                }

                // Check face rotation
                if((Iter->second)->GetFace(3)->GetVid(2) != (Iter->second)->GetVid(5))
                {
                    cout << "ERROR: Face " << Iter->second->GetFid(3) << " (vert "<< (Iter->second)->GetFace(3)->GetVid(2) << ") not aligned to face 3 singular vert of Prism " << (Iter->second)->GetGlobalID() << " (vert "<< (Iter->second)->GetVid(5) <<")" << endl;
                    NoRotateIssues = false;
                }

            }

            if(NoRotateIssues)
            {
                cout << "All Prism Tri faces are correctly aligned" << endl;
            }

            std::map<int,SpatialDomains::HexGeomSharedPtr>::iterator hexIter;
            for(hexIter = hexgeom.begin(); hexIter != hexgeom.end(); ++hexIter)
            {
                // PUt Hex checks in here
            }

        }

        break;
    default:
        ASSERTL0(false,"Expansion dimension not recognised");
        break;
    }

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

    return 0;
}

class Ord
{
public:
    double x;
    double y;
    double z;
};

bool CheckTetRotation(Array<OneD, NekDouble> &xc, Array<OneD, NekDouble> &yc, Array<OneD, NekDouble> &zc, std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator &tetIter, int id)
{
    bool      RotationOK = true;
    Ord       v[4];
    NekDouble abx,aby,abz;

    v[0].x = xc[(tetIter->second)->GetVid(0)];
    v[0].y = yc[(tetIter->second)->GetVid(0)];
    v[0].z = zc[(tetIter->second)->GetVid(0)];

    v[1].x = xc[(tetIter->second)->GetVid(1)];
    v[1].y = yc[(tetIter->second)->GetVid(1)];
    v[1].z = zc[(tetIter->second)->GetVid(1)];

    v[2].x = xc[(tetIter->second)->GetVid(2)];
    v[2].y = yc[(tetIter->second)->GetVid(2)];
    v[2].z = zc[(tetIter->second)->GetVid(2)];

    v[3].x = xc[(tetIter->second)->GetVid(3)];
    v[3].y = yc[(tetIter->second)->GetVid(3)];
    v[3].z = zc[(tetIter->second)->GetVid(3)];

    // cross product of edge 0 and 2
    abx = (v[1].y-v[0].y)*(v[2].z-v[0].z) -
        (v[1].z-v[0].z)*(v[2].y-v[0].y);
    aby = (v[1].z-v[0].z)*(v[2].x-v[0].x) -
        (v[1].x-v[0].x)*(v[2].z-v[0].z);
    abz = (v[1].x-v[0].x)*(v[2].y-v[0].y) -
        (v[1].y-v[0].y)*(v[2].x-v[0].x);

    // inner product of cross product with respect to edge 3 should be positive
    if(((v[3].x-v[0].x)*abx + (v[3].y-v[0].y)*aby +
        (v[3].z-v[0].z)*abz)<0.0)
    {
        cerr << "ERROR: Element " << id + 1 << "is NOT counter-clockwise\n" << endl;
        RotationOK = false;
    }
    return RotationOK;
}
<commit_msg>Added duplicate vertex check to CheckXmlFile.<commit_after>#include <cstdio>
#include <cstdlib>

#include <MultiRegions/ExpList.h>

using namespace Nektar;

bool CheckTetRotation(Array<OneD, NekDouble> &xc, Array<OneD, NekDouble> &yc,
                      Array<OneD, NekDouble> &xz,
                      std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator &tetIter,
                      int id);

int main(int argc, char *argv[])
{
    Array<OneD,NekDouble>  fce;
    Array<OneD,NekDouble>  xc0,xc1,xc2;

    if(argc != 2)
    {
        fprintf(stderr,"Usage: CheckXmlFile  meshfile.xml\n");
        exit(1);
    }

    LibUtilities::SessionReaderSharedPtr vSession
            = LibUtilities::SessionReader::CreateInstance(argc, argv);

    //----------------------------------------------
    // Read in mesh from input file
    string meshfile(argv[argc-1]);
    SpatialDomains::MeshGraphSharedPtr mesh  = SpatialDomains::MeshGraph::Read(vSession);
    //----------------------------------------------

    //----------------------------------------------
    // Define Expansion
    int expdim   = mesh->GetMeshDimension();

    switch(expdim)
    {
    case 1:
        ASSERTL0(false,"1D not set up");
        break;
    case 2:
        {
            NekDouble x,y,z;
            string   outname(strtok(argv[argc-1],"."));
            outname += ".dat";
            FILE *fp = fopen(outname.c_str(),"w");

            SpatialDomains::TriGeomMap trigeom = mesh->GetAllTriGeoms();
            SpatialDomains::QuadGeomMap quadgeom = mesh->GetAllQuadGeoms();

            int nverts = mesh->GetNvertices();

            Array<OneD, NekDouble> xc(nverts),yc(nverts),zc(nverts);

            for(int i = 0; i < nverts; ++i)
            {
                mesh->GetVertex(i)->GetCoords(x,y,z);
                xc[i] = x;
                yc[i] = y;
                zc[i] = z;
            }

            std::map<int,SpatialDomains::TriGeomSharedPtr>::iterator triIter;
            for(triIter = trigeom.begin(); triIter != trigeom.end(); ++triIter)
            {
                fprintf(fp,"%d %d %d %d\n",(triIter->second)->GetVid(0)+1,(triIter->second)->GetVid(1)+1,(triIter->second)->GetVid(2)+1,(triIter->second)->GetVid(2)+1);
            }

            std::map<int,SpatialDomains::QuadGeomSharedPtr>::iterator quadIter;
            for(quadIter = quadgeom.begin(); quadIter != quadgeom.end(); ++quadIter)
            {
                fprintf(fp,"%d %d %d %d\n",(quadIter->second)->GetVid(0)+1,(quadIter->second)->GetVid(1)+1,(quadIter->second)->GetVid(2)+1,(quadIter->second)->GetVid(3)+1);
            }
        }
        break;
    case 3:
        {
            NekDouble x,y,z;
            string   outname(strtok(argv[argc-1],"."));
            outname += ".dat";

            SpatialDomains::TetGeomMap   tetgeom   = mesh->GetAllTetGeoms();
            SpatialDomains::PyrGeomMap   pyrgeom   = mesh->GetAllPyrGeoms();
            SpatialDomains::PrismGeomMap prismgeom = mesh->GetAllPrismGeoms();
            SpatialDomains::HexGeomMap   hexgeom   = mesh->GetAllHexGeoms();

            int nverts = mesh->GetNvertices();

            Array<OneD, NekDouble> xc(nverts),yc(nverts),zc(nverts);

            for(int i = 0; i < nverts; ++i)
            {
                // Check element roation
                mesh->GetVertex(i)->GetCoords(x,y,z);
                xc[i] = x;
                yc[i] = y;
                zc[i] = z;

            }

            for (int i = 0; i < nverts; ++i)
            {
                for (int j = i+1; j < nverts; ++j)
                {
                    if ((xc[i]-xc[j])*(xc[i]-xc[j]) +
                        (yc[i]-yc[j])*(yc[i]-yc[j]) +
                        (zc[i]-zc[j])*(zc[i]-zc[j]) < 1e-10)
                    {
                        cout << "Duplicate vertices: " << i << " " << j << endl;
                    }
                }
            }

            std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator tetIter;
            int cnt = 0;
            bool NoRotateIssues = true;
            bool NoOrientationIssues = true;
            for(tetIter = tetgeom.begin(); tetIter != tetgeom.end(); ++tetIter)
            {
                // check rotation and dump
                NoOrientationIssues = CheckTetRotation(xc,yc,zc,tetIter,cnt++);

                // Check face rotation
                if((tetIter->second)->GetFace(0)->GetVid(2) != (tetIter->second)->GetVid(2))
                {
                    cout << "ERROR: Face " << tetIter->second->GetFid(0) << " (vert "<< (tetIter->second)->GetFace(0)->GetVid(2) << ") is not aligned with base vertex of Tet " << (tetIter->second)->GetGlobalID() << " (vert "<< (tetIter->second)->GetVid(2) <<")" << endl;
                    NoRotateIssues = false;
                }

                for(int i = 1; i < 4; ++i)

                {
                    if((tetIter->second)->GetFace(i)->GetVid(2) != (tetIter->second)->GetVid(3))
                    {
                        cout << "ERROR: Face " << tetIter->second->GetFid(i) << " is not aligned with top Vertex of Tet " << (tetIter->second)->GetGlobalID() << endl;
                        NoRotateIssues = false;
                    }
                }

            }
            if(NoOrientationIssues)
            {
                cout << "All Tet have correct ordering for anticlockwise rotation" << endl;
            }

            if(NoRotateIssues)
            {
                cout << "All Tet faces are correctly aligned" << endl;
            }

            std::map<int,SpatialDomains::PyrGeomSharedPtr>::iterator pyrIter;
            for(pyrIter = pyrgeom.begin(); pyrIter != pyrgeom.end(); ++pyrIter)
            {
                // Put pyramid checks in here
            }

            // Put prism checks in here
            std::map<int,SpatialDomains::PrismGeomSharedPtr>::iterator Iter;
            NoRotateIssues = true;
            NoOrientationIssues = true;
            for(Iter = prismgeom.begin(); Iter != prismgeom.end(); ++Iter)
            {

                // Check face rotation
                if((Iter->second)->GetFace(1)->GetVid(2) != (Iter->second)->GetVid(4))
                {
                    cout << "ERROR: Face " << Iter->second->GetFid(1) << " (vert "<< (Iter->second)->GetFace(1)->GetVid(2) << ") not aligned to face 1 singular vert of Prism " << (Iter->second)->GetGlobalID() << " (vert "<< (Iter->second)->GetVid(4) <<")" << endl;
                    NoRotateIssues = false;
                }

                // Check face rotation
                if((Iter->second)->GetFace(3)->GetVid(2) != (Iter->second)->GetVid(5))
                {
                    cout << "ERROR: Face " << Iter->second->GetFid(3) << " (vert "<< (Iter->second)->GetFace(3)->GetVid(2) << ") not aligned to face 3 singular vert of Prism " << (Iter->second)->GetGlobalID() << " (vert "<< (Iter->second)->GetVid(5) <<")" << endl;
                    NoRotateIssues = false;
                }

            }

            if(NoRotateIssues)
            {
                cout << "All Prism Tri faces are correctly aligned" << endl;
            }

            std::map<int,SpatialDomains::HexGeomSharedPtr>::iterator hexIter;
            for(hexIter = hexgeom.begin(); hexIter != hexgeom.end(); ++hexIter)
            {
                // PUt Hex checks in here
            }

        }

        break;
    default:
        ASSERTL0(false,"Expansion dimension not recognised");
        break;
    }

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

    return 0;
}

class Ord
{
public:
    double x;
    double y;
    double z;
};

bool CheckTetRotation(Array<OneD, NekDouble> &xc, Array<OneD, NekDouble> &yc, Array<OneD, NekDouble> &zc, std::map<int,SpatialDomains::TetGeomSharedPtr>::iterator &tetIter, int id)
{
    bool      RotationOK = true;
    Ord       v[4];
    NekDouble abx,aby,abz;

    v[0].x = xc[(tetIter->second)->GetVid(0)];
    v[0].y = yc[(tetIter->second)->GetVid(0)];
    v[0].z = zc[(tetIter->second)->GetVid(0)];

    v[1].x = xc[(tetIter->second)->GetVid(1)];
    v[1].y = yc[(tetIter->second)->GetVid(1)];
    v[1].z = zc[(tetIter->second)->GetVid(1)];

    v[2].x = xc[(tetIter->second)->GetVid(2)];
    v[2].y = yc[(tetIter->second)->GetVid(2)];
    v[2].z = zc[(tetIter->second)->GetVid(2)];

    v[3].x = xc[(tetIter->second)->GetVid(3)];
    v[3].y = yc[(tetIter->second)->GetVid(3)];
    v[3].z = zc[(tetIter->second)->GetVid(3)];

    // cross product of edge 0 and 2
    abx = (v[1].y-v[0].y)*(v[2].z-v[0].z) -
        (v[1].z-v[0].z)*(v[2].y-v[0].y);
    aby = (v[1].z-v[0].z)*(v[2].x-v[0].x) -
        (v[1].x-v[0].x)*(v[2].z-v[0].z);
    abz = (v[1].x-v[0].x)*(v[2].y-v[0].y) -
        (v[1].y-v[0].y)*(v[2].x-v[0].x);

    // inner product of cross product with respect to edge 3 should be positive
    if(((v[3].x-v[0].x)*abx + (v[3].y-v[0].y)*aby +
        (v[3].z-v[0].z)*abz)<0.0)
    {
        cerr << "ERROR: Element " << id + 1 << "is NOT counter-clockwise\n" << endl;
        RotationOK = false;
    }
    return RotationOK;
}
<|endoftext|>


<commit_before>/**
 * Elk Application
 */

#include "Elk.h"
//Moose Includes
#include "MooseInit.h"
#include "ElkTestApp.h"

// libMesh includes
#include "perf_log.h"

// Create a performance log
PerfLog Moose::perf_log("Elk");

 // Begin the main program.
int main (int argc, char** argv)
{
  MooseInit init (argc, argv);
  ElkTestApp app(argc, argv);

  app.setCheckUnusedFlag( true );
  app.setSortAlpha( true );
  app.run();

  return 0;
}
<commit_msg>Fixing the build on linux (#1319)<commit_after>/**
 * Elk Application
 */

#include "Elk.h"
//Moose Includes
#include "MooseInit.h"
#include "Moose.h"
#include "ElkTestApp.h"
// libMesh includes
#include "perf_log.h"

// Create a performance log
PerfLog Moose::perf_log("Elk");

 // Begin the main program.
int main (int argc, char** argv)
{
  MooseInit init (argc, argv);
  ElkTestApp app(argc, argv);

  app.setCheckUnusedFlag( true );
  app.setSortAlpha( true );
  app.run();

  return 0;
}
<|endoftext|>