<commit_before>#include "gru.h"

#include <sstream>
#include <gflags/gflags.h>
#include <boost/algorithm/string.hpp>
#include <vector>
#include "logging.h"

DECLARE_int32(galaxy_deploy_step);
DECLARE_string(minion_path);
DECLARE_string(nexus_server_list);
DECLARE_string(nexus_root_path);
DECLARE_string(master_path);

namespace baidu {
namespace shuttle {

static const int64_t default_additional_map_memory = 1024l * 1024 * 1024;
static const int64_t default_additional_reduce_memory = 2048l * 1024 * 1024;
static const int default_additional_millicores = 0;

int Gru::additional_millicores = default_additional_millicores;
int64_t Gru::additional_map_memory = default_additional_map_memory;
int64_t Gru::additional_reduce_memory = default_additional_reduce_memory;

Gru::Gru(::baidu::galaxy::Galaxy* galaxy, JobDescriptor* job,
         const std::string& job_id, WorkMode mode) :
        galaxy_(galaxy), job_(job), job_id_(job_id), mode_(mode) {
    mode_str_ = ((mode == kReduce) ? "reduce" : "map");
    minion_name_ = job->name() + "_" + mode_str_;
}

Status Gru::Start() {
    ::baidu::galaxy::JobDescription galaxy_job;
    galaxy_job.job_name = minion_name_ + "@minion";
    galaxy_job.type = "kLongRun";
    galaxy_job.priority = "kOnline";
    galaxy_job.replica = (mode_ == kReduce) ? job_->reduce_capacity() : job_->map_capacity();
    galaxy_job.deploy_step = FLAGS_galaxy_deploy_step;
    galaxy_job.pod.version = "1.0.0";
    galaxy_job.pod.requirement.millicores = job_->millicores() + additional_millicores;
    galaxy_job.pod.requirement.memory = job_->memory() +
        ((mode_ == kReduce) ? additional_reduce_memory : additional_map_memory);
    std::string app_package;
    std::vector<std::string> cache_archive_list;
    int file_size = job_->files().size();
    for (int i = 0; i < file_size; ++i) {
        const std::string& file = job_->files(i);
        if (boost::starts_with(file, "hdfs://")) {
            cache_archive_list.push_back(file);
        } else {
            app_package = file;
        }
    }
    std::stringstream ss;
    for (size_t i = 0; i < cache_archive_list.size(); i++) {
        ss << "cache_archive_" << i << "=" << cache_archive_list[i] << " ";
    }
    ss << "app_package=" << app_package
       << " ./minion_boot.sh -jobid=" << job_id_ << " -nexus_addr=" << FLAGS_nexus_server_list
       << " -master_nexus_path=" << FLAGS_nexus_root_path + FLAGS_master_path
       << " -work_mode=" << ((mode_ == kMapOnly) ? "map-only" : mode_str_);
    std::stringstream ss_stop;
    ss_stop << "source hdfs_env.sh; ./minion -jobid=" << job_id_ << " -nexus_addr=" << FLAGS_nexus_server_list
            << " -master_nexus_path=" << FLAGS_nexus_root_path + FLAGS_master_path
            << " -work_mode=" << ((mode_ == kMapOnly) ? "map-only" : mode_str_)
            << " -kill_task";
    ::baidu::galaxy::TaskDescription minion;
    minion.offset = 1;
    minion.binary = FLAGS_minion_path;
    minion.source_type = "kSourceTypeFTP";
    minion.start_cmd = ss.str().c_str();
    minion.stop_cmd = ss_stop.str().c_str();
    minion.requirement = galaxy_job.pod.requirement;
    minion.mem_isolation_type = "kMemIsolationCgroup";
    minion.cpu_isolation_type = "kCpuIsolationSoft";
    galaxy_job.pod.tasks.push_back(minion);
    std::string minion_id;
    if (galaxy_->SubmitJob(galaxy_job, &minion_id)) {
        LOG(INFO, "galaxy job id: %s", minion_id.c_str());
        minion_id_ = minion_id;
        galaxy_job_ = galaxy_job;
        int retry_count = 10;
        while (minion_id_.empty() && retry_count-- > 0 ) {
            std::vector<galaxy::JobInformation> jobs;
            if (galaxy_->ListJobs(&jobs) ) {
                for (size_t i = 0; i < jobs.size(); i++) {
                    const galaxy::JobInformation& job_info = jobs[i];
                    if (job_info.job_name ==  galaxy_job_.job_name) {
                        minion_id_ = job_info.job_id;
                        LOG(INFO, "galaxy job id: %s", minion_id_.c_str());
                        break;
                    }
                }
            }
            sleep(3);
        }
        if (minion_id_.empty()) {
            LOG(INFO, "can not get galaxy job id");
            return kGalaxyError;
        }
        return kOk;
    }
    return kGalaxyError;
}

Status Gru::Kill() {
    LOG(INFO, "kill galaxy job: %s", minion_id_.c_str());
    if (minion_id_.empty()) {
        return kOk;
    }
    if (galaxy_->TerminateJob(minion_id_)) {
        return kOk;
    }
    return kGalaxyError;
}

Status Gru::Update(const std::string& priority,
                   int capacity) {
    ::baidu::galaxy::JobDescription job_desc = galaxy_job_;
    if (!priority.empty()) {
        job_desc.priority = priority;
    }
    if (capacity != -1) {
        job_desc.replica = capacity;
    }
    if (galaxy_->UpdateJob(minion_id_, job_desc)) {
        if (!priority.empty()) {
            galaxy_job_.priority = priority;
        }
        if (capacity != -1) {
            galaxy_job_.replica = capacity;
        }
        return kOk;
    }
    return kGalaxyError;
}

}
}

<commit_msg>use cpu hard limit<commit_after>#include "gru.h"

#include <sstream>
#include <gflags/gflags.h>
#include <boost/algorithm/string.hpp>
#include <vector>
#include "logging.h"

DECLARE_int32(galaxy_deploy_step);
DECLARE_string(minion_path);
DECLARE_string(nexus_server_list);
DECLARE_string(nexus_root_path);
DECLARE_string(master_path);

namespace baidu {
namespace shuttle {

static const int64_t default_additional_map_memory = 1024l * 1024 * 1024;
static const int64_t default_additional_reduce_memory = 2048l * 1024 * 1024;
static const int default_additional_millicores = 0;

int Gru::additional_millicores = default_additional_millicores;
int64_t Gru::additional_map_memory = default_additional_map_memory;
int64_t Gru::additional_reduce_memory = default_additional_reduce_memory;

Gru::Gru(::baidu::galaxy::Galaxy* galaxy, JobDescriptor* job,
         const std::string& job_id, WorkMode mode) :
        galaxy_(galaxy), job_(job), job_id_(job_id), mode_(mode) {
    mode_str_ = ((mode == kReduce) ? "reduce" : "map");
    minion_name_ = job->name() + "_" + mode_str_;
}

Status Gru::Start() {
    ::baidu::galaxy::JobDescription galaxy_job;
    galaxy_job.job_name = minion_name_ + "@minion";
    galaxy_job.type = "kLongRun";
    galaxy_job.priority = "kOnline";
    galaxy_job.replica = (mode_ == kReduce) ? job_->reduce_capacity() : job_->map_capacity();
    galaxy_job.deploy_step = FLAGS_galaxy_deploy_step;
    galaxy_job.pod.version = "1.0.0";
    galaxy_job.pod.requirement.millicores = job_->millicores() + additional_millicores;
    galaxy_job.pod.requirement.memory = job_->memory() +
        ((mode_ == kReduce) ? additional_reduce_memory : additional_map_memory);
    std::string app_package;
    std::vector<std::string> cache_archive_list;
    int file_size = job_->files().size();
    for (int i = 0; i < file_size; ++i) {
        const std::string& file = job_->files(i);
        if (boost::starts_with(file, "hdfs://")) {
            cache_archive_list.push_back(file);
        } else {
            app_package = file;
        }
    }
    std::stringstream ss;
    for (size_t i = 0; i < cache_archive_list.size(); i++) {
        ss << "cache_archive_" << i << "=" << cache_archive_list[i] << " ";
    }
    ss << "app_package=" << app_package
       << " ./minion_boot.sh -jobid=" << job_id_ << " -nexus_addr=" << FLAGS_nexus_server_list
       << " -master_nexus_path=" << FLAGS_nexus_root_path + FLAGS_master_path
       << " -work_mode=" << ((mode_ == kMapOnly) ? "map-only" : mode_str_);
    std::stringstream ss_stop;
    ss_stop << "source hdfs_env.sh; ./minion -jobid=" << job_id_ << " -nexus_addr=" << FLAGS_nexus_server_list
            << " -master_nexus_path=" << FLAGS_nexus_root_path + FLAGS_master_path
            << " -work_mode=" << ((mode_ == kMapOnly) ? "map-only" : mode_str_)
            << " -kill_task";
    ::baidu::galaxy::TaskDescription minion;
    minion.offset = 1;
    minion.binary = FLAGS_minion_path;
    minion.source_type = "kSourceTypeFTP";
    minion.start_cmd = ss.str().c_str();
    minion.stop_cmd = ss_stop.str().c_str();
    minion.requirement = galaxy_job.pod.requirement;
    minion.mem_isolation_type = "kMemIsolationCgroup";
    minion.cpu_isolation_type = "kCpuIsolationHard";
    galaxy_job.pod.tasks.push_back(minion);
    std::string minion_id;
    if (galaxy_->SubmitJob(galaxy_job, &minion_id)) {
        LOG(INFO, "galaxy job id: %s", minion_id.c_str());
        minion_id_ = minion_id;
        galaxy_job_ = galaxy_job;
        int retry_count = 10;
        while (minion_id_.empty() && retry_count-- > 0 ) {
            std::vector<galaxy::JobInformation> jobs;
            if (galaxy_->ListJobs(&jobs) ) {
                for (size_t i = 0; i < jobs.size(); i++) {
                    const galaxy::JobInformation& job_info = jobs[i];
                    if (job_info.job_name ==  galaxy_job_.job_name) {
                        minion_id_ = job_info.job_id;
                        LOG(INFO, "galaxy job id: %s", minion_id_.c_str());
                        break;
                    }
                }
            }
            sleep(3);
        }
        if (minion_id_.empty()) {
            LOG(INFO, "can not get galaxy job id");
            return kGalaxyError;
        }
        return kOk;
    }
    return kGalaxyError;
}

Status Gru::Kill() {
    LOG(INFO, "kill galaxy job: %s", minion_id_.c_str());
    if (minion_id_.empty()) {
        return kOk;
    }
    if (galaxy_->TerminateJob(minion_id_)) {
        return kOk;
    }
    return kGalaxyError;
}

Status Gru::Update(const std::string& priority,
                   int capacity) {
    ::baidu::galaxy::JobDescription job_desc = galaxy_job_;
    if (!priority.empty()) {
        job_desc.priority = priority;
    }
    if (capacity != -1) {
        job_desc.replica = capacity;
    }
    if (galaxy_->UpdateJob(minion_id_, job_desc)) {
        if (!priority.empty()) {
            galaxy_job_.priority = priority;
        }
        if (capacity != -1) {
            galaxy_job_.replica = capacity;
        }
        return kOk;
    }
    return kGalaxyError;
}

}
}

<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_FLOAT_CMP_HH
#define DUNE_STUFF_COMMON_FLOAT_CMP_HH

#include <type_traits>
#include <complex>

#include <dune/common/float_cmp.hh>

namespace Dune {
namespace Stuff {
namespace Common {

namespace internal {

template< class Tt >
struct is_complex_helper
{
  DSC_has_typedef_initialize_once(value_type)

  static const bool is_candidate = DSC_has_typedef(value_type)< Tt >::value;
}; // class is_complex_helper

} // namespace internal

template< class T, bool candidate = internal::is_complex_helper< T >::is_candidate >
struct is_complex
  : public std::is_base_of< std::complex< typename T::value_type >, T >
{};

template< class T >
struct is_complex< T, false >
  : public std::false_type
{};

// forwards (include is below)
template< class VecType >
struct VectorAbstraction;

template< class VectorType >
struct is_vector;

namespace FloatCmp {

enum class Style {
  numpy,
  relativeWeak,
  relativeStrong,
  absolute,
  defaultStyle = numpy
};

namespace internal {

template< Style style >
struct ConvertStyle;

template<>
struct ConvertStyle< Style::relativeWeak >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::relativeWeak;
};

template<>
struct ConvertStyle< Style::relativeStrong >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::relativeStrong;
};

template<>
struct ConvertStyle< Style::absolute >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::absolute;
};

} // namespace internal

template< class T, Style style = Style::defaultStyle >
struct DefaultEpsilon
{
  static typename Dune::FloatCmp::EpsilonType< T >::Type value()
  {
    return Dune::FloatCmp::DefaultEpsilon< T, internal::ConvertStyle< style >::value >::value();
  }
};

template< class T >
struct DefaultEpsilon< T, Style::numpy >
{
  static typename Dune::FloatCmp::EpsilonType< T >::Type value()
  {
    return Dune::FloatCmp::DefaultEpsilon< T, Dune::FloatCmp::relativeStrong >::value();
  }
};

namespace internal {

/**
 * Taken from http://docs.pymor.org/en/latest/_modules/pymor/tools/floatcmp.html#float_cmp,
 *            https://github.com/numpy/numpy/blob/v1.9.1/numpy/core/numeric.py#L2238
 */
template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
float_cmp(const T& xx, const T& yy, const T& rtol, const T& atol)
{
  return std::abs(xx - yy) <= atol + std::abs(yy)*rtol;
}

template< class T >
    typename std::enable_if< is_complex< T >::value, bool >::type
float_cmp(const T& xx, const T& yy, const typename T::value_type& rtol, const typename T::value_type& atol )
{
  return (float_cmp(std::real(xx), std::real(yy), rtol, atol) && float_cmp(std::imag(xx), std::imag(yy), rtol, atol));
}

template< class XType, class YType, class TolType >
    typename std::enable_if<    is_vector< XType >::value
                             && is_vector< YType >::value
                             && std::is_arithmetic< TolType >::value
                             && std::is_same< typename VectorAbstraction< XType >::R, TolType >::value
                             && std::is_same< typename VectorAbstraction< YType >::R, TolType >::value
                           , bool >::type
float_cmp(const XType& xx, const YType& yy, const TolType& rtol, const TolType& atol)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!float_cmp(xx[ii], yy[ii], rtol, atol))
      return false;
  return true;
} // ... float_cmp(...)

template< Dune::FloatCmp::CmpStyle style, class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
dune_float_cmp(const T& xx, const T& yy, const T& eps)
{
  return Dune::FloatCmp::eq< T, style >(xx, yy, eps);
}

template< Dune::FloatCmp::CmpStyle style, class XType, class YType, class EpsType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_arithmetic< EpsType >::value
                         && std::is_same< typename VectorAbstraction< XType >::R, EpsType >::value
                         && std::is_same< typename VectorAbstraction< YType >::R, EpsType >::value
                       , bool >::type
dune_float_cmp(const XType& xx, const YType& yy, const EpsType& eps)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!dune_float_cmp< style >(xx[ii], yy[ii], eps))
      return false;
  return true;
} // ... dune_float_cmp(...)

template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
cmp_gt(const T& xx, const T& yy)
{
  return xx > yy;
}

template< class XType, class YType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_same< typename VectorAbstraction< XType >::S
                                        , typename VectorAbstraction< YType >::S >::value
                       , bool >::type
cmp_gt(const XType& xx, const YType& yy)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!(xx[ii] > yy[ii]))
      return false;
  return true;
} // ... cmp_gt(...)

template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
cmp_lt(const T& xx, const T& yy)
{
  return xx < yy;
}

template< class XType, class YType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_same< typename VectorAbstraction< XType >::S
                                        , typename VectorAbstraction< YType >::S >::value
                       , bool >::type
cmp_lt(const XType& xx, const YType& yy)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!(xx[ii] < yy[ii]))
      return false;
  return true;
} // ... cmp_lt(...)

template< class FirstType, class SecondType, class ToleranceType, Style style >
struct Call
{
  static bool eq(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol);
  }

  static bool ne(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol);
  }

  static bool gt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) && cmp_gt(first, second);
  }

  static bool lt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) && cmp_lt(first, second);
  }

  static bool ge(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) || cmp_gt(first, second);
  }

  static bool le(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) || cmp_lt(first, second);
  }
};

template< class FirstType, class SecondType, class ToleranceType >
struct Call< FirstType, SecondType, ToleranceType, Style::numpy >
{
  static bool eq(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol);
  }

  static bool ne(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol);
  }

  static bool gt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol) && cmp_gt(first, second);
  }

  static bool lt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol) && cmp_lt(first, second);
  }

  static bool ge(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol) || cmp_gt(first, second);
  }

  static bool le(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol) || cmp_lt(first, second);
  }
};

} // namespace internal

#define DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(id) \
  template< Style style, class FirstType, class SecondType, class ToleranceType = typename VectorAbstraction< FirstType >::R > \
      typename std::enable_if<    (   std::is_arithmetic< FirstType >::value \
                                   && std::is_same< FirstType, SecondType >::value) \
                               || (std::is_arithmetic< ToleranceType >::value \
                                   && is_vector< FirstType >::value \
                                   && is_vector< SecondType >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< FirstType >::R >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< SecondType >::R >::value) \
                             , bool >::type \
  id (const FirstType& first, \
      const SecondType& second, \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& rtol \
        = DefaultEpsilon< ToleranceType, style >::value(), \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& atol \
        = DefaultEpsilon< ToleranceType, style >::value()) \
  { \
    return internal::Call< FirstType, \
                           SecondType, \
                           typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type, \
                           style >:: id (first, second, rtol, atol); \
  } \
  \
  template< class FirstType, class SecondType, class ToleranceType = typename VectorAbstraction< FirstType >::R > \
      typename std::enable_if<    (   std::is_arithmetic< FirstType >::value \
                                   && std::is_same< FirstType, SecondType >::value) \
                               || (std::is_arithmetic< ToleranceType >::value \
                                   && is_vector< FirstType >::value \
                                   && is_vector< SecondType >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< FirstType >::R >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< SecondType >::R >::value) \
                             , bool >::type \
  id (const FirstType& first, \
      const SecondType& second, \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& rtol \
        = DefaultEpsilon< ToleranceType, Style::defaultStyle >::value(), \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& atol \
        = DefaultEpsilon< ToleranceType, Style::defaultStyle >::value()) \
  { \
    return id < Style::defaultStyle >(first, second, rtol, atol); \
  }

DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(eq)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(ne)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(gt)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(lt)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(ge)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(le)
#undef DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR

} // namespace FloatCmp
} // namespace Common
} // namespace Stuff
} // namespace Dune

#include <dune/stuff/common/vector.hh>

#endif // DUNE_STUFF_COMMON_FLOAT_CMP_HH
<commit_msg>change VectorAbstraction::RealType to VectorAbstraction::ScalarType in dune_float_cmp as this is not (yet) implemented for complex<commit_after>// This file is part of the dune-stuff project:
//   https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_COMMON_FLOAT_CMP_HH
#define DUNE_STUFF_COMMON_FLOAT_CMP_HH

#include <type_traits>
#include <complex>

#include <dune/common/float_cmp.hh>

namespace Dune {
namespace Stuff {
namespace Common {

namespace internal {

template< class Tt >
struct is_complex_helper
{
  DSC_has_typedef_initialize_once(value_type)

  static const bool is_candidate = DSC_has_typedef(value_type)< Tt >::value;
}; // class is_complex_helper

} // namespace internal

template< class T, bool candidate = internal::is_complex_helper< T >::is_candidate >
struct is_complex
  : public std::is_base_of< std::complex< typename T::value_type >, T >
{};

template< class T >
struct is_complex< T, false >
  : public std::false_type
{};

// forwards (include is below)
template< class VecType >
struct VectorAbstraction;

template< class VectorType >
struct is_vector;

namespace FloatCmp {

enum class Style {
  numpy,
  relativeWeak,
  relativeStrong,
  absolute,
  defaultStyle = numpy
};

namespace internal {

template< Style style >
struct ConvertStyle;

template<>
struct ConvertStyle< Style::relativeWeak >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::relativeWeak;
};

template<>
struct ConvertStyle< Style::relativeStrong >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::relativeStrong;
};

template<>
struct ConvertStyle< Style::absolute >
{
  static const Dune::FloatCmp::CmpStyle value = Dune::FloatCmp::CmpStyle::absolute;
};

} // namespace internal

template< class T, Style style = Style::defaultStyle >
struct DefaultEpsilon
{
  static typename Dune::FloatCmp::EpsilonType< T >::Type value()
  {
    return Dune::FloatCmp::DefaultEpsilon< T, internal::ConvertStyle< style >::value >::value();
  }
};

template< class T >
struct DefaultEpsilon< T, Style::numpy >
{
  static typename Dune::FloatCmp::EpsilonType< T >::Type value()
  {
    return Dune::FloatCmp::DefaultEpsilon< T, Dune::FloatCmp::relativeStrong >::value();
  }
};

namespace internal {

/**
 * Taken from http://docs.pymor.org/en/latest/_modules/pymor/tools/floatcmp.html#float_cmp,
 *            https://github.com/numpy/numpy/blob/v1.9.1/numpy/core/numeric.py#L2238
 */
template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
float_cmp(const T& xx, const T& yy, const T& rtol, const T& atol)
{
  return std::abs(xx - yy) <= atol + std::abs(yy)*rtol;
}

template< class T >
    typename std::enable_if< is_complex< T >::value, bool >::type
float_cmp(const T& xx, const T& yy, const typename T::value_type& rtol, const typename T::value_type& atol )
{
  return (float_cmp(std::real(xx), std::real(yy), rtol, atol) && float_cmp(std::imag(xx), std::imag(yy), rtol, atol));
}

template< class XType, class YType, class TolType >
    typename std::enable_if<    is_vector< XType >::value
                             && is_vector< YType >::value
                             && std::is_arithmetic< TolType >::value
                             && std::is_same< typename VectorAbstraction< XType >::R, TolType >::value
                             && std::is_same< typename VectorAbstraction< YType >::R, TolType >::value
                           , bool >::type
float_cmp(const XType& xx, const YType& yy, const TolType& rtol, const TolType& atol)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!float_cmp(xx[ii], yy[ii], rtol, atol))
      return false;
  return true;
} // ... float_cmp(...)

template< Dune::FloatCmp::CmpStyle style, class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
dune_float_cmp(const T& xx, const T& yy, const T& eps)
{
  return Dune::FloatCmp::eq< T, style >(xx, yy, eps);
}

template< Dune::FloatCmp::CmpStyle style, class XType, class YType, class EpsType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_arithmetic< EpsType >::value
                         && std::is_same< typename VectorAbstraction< XType >::S, EpsType >::value
                         && std::is_same< typename VectorAbstraction< YType >::S, EpsType >::value
                       , bool >::type
dune_float_cmp(const XType& xx, const YType& yy, const EpsType& eps)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!dune_float_cmp< style >(xx[ii], yy[ii], eps))
      return false;
  return true;
} // ... dune_float_cmp(...)

template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
cmp_gt(const T& xx, const T& yy)
{
  return xx > yy;
}

template< class XType, class YType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_same< typename VectorAbstraction< XType >::S
                                        , typename VectorAbstraction< YType >::S >::value
                       , bool >::type
cmp_gt(const XType& xx, const YType& yy)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!(xx[ii] > yy[ii]))
      return false;
  return true;
} // ... cmp_gt(...)

template< class T >
    typename std::enable_if< std::is_arithmetic< T >::value, bool >::type
cmp_lt(const T& xx, const T& yy)
{
  return xx < yy;
}

template< class XType, class YType >
typename std::enable_if<    is_vector< XType >::value
                         && is_vector< YType >::value
                         && std::is_same< typename VectorAbstraction< XType >::S
                                        , typename VectorAbstraction< YType >::S >::value
                       , bool >::type
cmp_lt(const XType& xx, const YType& yy)
{
  const auto sz = xx.size();
  if (yy.size() != sz)
    return false;
  for (size_t ii = 0; ii < sz; ++ii)
    if (!(xx[ii] < yy[ii]))
      return false;
  return true;
} // ... cmp_lt(...)

template< class FirstType, class SecondType, class ToleranceType, Style style >
struct Call
{
  static bool eq(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol);
  }

  static bool ne(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol);
  }

  static bool gt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) && cmp_gt(first, second);
  }

  static bool lt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return !dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) && cmp_lt(first, second);
  }

  static bool ge(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) || cmp_gt(first, second);
  }

  static bool le(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& /**/)
  {
    return dune_float_cmp< internal::ConvertStyle< style >::value >(first, second, rtol) || cmp_lt(first, second);
  }
};

template< class FirstType, class SecondType, class ToleranceType >
struct Call< FirstType, SecondType, ToleranceType, Style::numpy >
{
  static bool eq(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol);
  }

  static bool ne(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol);
  }

  static bool gt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol) && cmp_gt(first, second);
  }

  static bool lt(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return !float_cmp(first, second, rtol, atol) && cmp_lt(first, second);
  }

  static bool ge(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol) || cmp_gt(first, second);
  }

  static bool le(const FirstType& first, const SecondType& second, const ToleranceType& rtol, const ToleranceType& atol)
  {
    return float_cmp(first, second, rtol, atol) || cmp_lt(first, second);
  }
};

} // namespace internal

#define DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(id) \
  template< Style style, class FirstType, class SecondType, class ToleranceType = typename VectorAbstraction< FirstType >::R > \
      typename std::enable_if<    (   std::is_arithmetic< FirstType >::value \
                                   && std::is_same< FirstType, SecondType >::value) \
                               || (std::is_arithmetic< ToleranceType >::value \
                                   && is_vector< FirstType >::value \
                                   && is_vector< SecondType >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< FirstType >::R >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< SecondType >::R >::value) \
                             , bool >::type \
  id (const FirstType& first, \
      const SecondType& second, \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& rtol \
        = DefaultEpsilon< ToleranceType, style >::value(), \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& atol \
        = DefaultEpsilon< ToleranceType, style >::value()) \
  { \
    return internal::Call< FirstType, \
                           SecondType, \
                           typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type, \
                           style >:: id (first, second, rtol, atol); \
  } \
  \
  template< class FirstType, class SecondType, class ToleranceType = typename VectorAbstraction< FirstType >::R > \
      typename std::enable_if<    (   std::is_arithmetic< FirstType >::value \
                                   && std::is_same< FirstType, SecondType >::value) \
                               || (std::is_arithmetic< ToleranceType >::value \
                                   && is_vector< FirstType >::value \
                                   && is_vector< SecondType >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< FirstType >::R >::value \
                                   && std::is_same< ToleranceType \
                                                  , typename VectorAbstraction< SecondType >::R >::value) \
                             , bool >::type \
  id (const FirstType& first, \
      const SecondType& second, \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& rtol \
        = DefaultEpsilon< ToleranceType, Style::defaultStyle >::value(), \
      const typename Dune::FloatCmp::EpsilonType< ToleranceType >::Type& atol \
        = DefaultEpsilon< ToleranceType, Style::defaultStyle >::value()) \
  { \
    return id < Style::defaultStyle >(first, second, rtol, atol); \
  }

DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(eq)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(ne)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(gt)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(lt)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(ge)
DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR(le)
#undef DUNE_STUFF_COMMON_FLOAT_CMP_GENERATOR

} // namespace FloatCmp
} // namespace Common
} // namespace Stuff
} // namespace Dune

#include <dune/stuff/common/vector.hh>

#endif // DUNE_STUFF_COMMON_FLOAT_CMP_HH
<|endoftext|>


<commit_before>//! \file rno2roff.cc
//!
//! \breif Filter to convert DSR (Digital Standard Runoff) to roff.
//!
//! This filter will read in a rno file,
//! and convert it into [ntg]roff format.
//!
//! Use it asy, March 2016
//! rno2roff < source > dest
//!
//! \author Kevin Hand

#include <iostream>
#include <string>

#include <cctype>

//
// Prototypes
//
std::string parse_text(const std::string &src, int &ptr);
int rno_filter(std::istream &in);

//
// Global values
//
static int uc_flag = 0;		//!< Upper case flag (0 = lc everything,
				//! 1 = retain case.
static int uc1_flag = 0;	//!< Upper case next character (^)?
static int uc2_flag = 0;	//!< Upper case characters (\^)?

//! \brief Main function.
//!
//! Main function.
//! Handles all user options,
//! and runs filter.
//!
int main(int argc, char **argv)
{

	rno_filter(std::cin);
}

//! \brief Main filter
//!
//! Main filter program
//!
int rno_filter(std::istream &in)
{
	std::string buffer;
	int ptr;

	while (getline(in, buffer))
	{
		ptr = 0;
		std::cout << parse_text(buffer, ptr) <<std::endl;
	}
}

//! \brief Translate text line
//!
//! Converts a text line in RNO format to roff.
//!
//! \return filtered string.
//!
std::string parse_text(
	const std::string &src,	//!< String to convert
	int &ptr)		//!< Pointer into string
{
	std::string result;	//!< Result string being built.
	char ch;		//< For looking at characters.

	while (ptr < src.size())
	{

		switch (src[ptr])
		{
		// &  Ampersand     Underscoring
		case '&':
			break;

		// #  Number Sign   Explicit space
		case '#':
			result.append("\\ ");
			break;

		// _  Underline     Quote next character
		case '_':
			// roff special characters don't match RNO specials
			ch += src[++ptr];	// hope they aren't lying
			if (ch == '\\')
			{
				result += "\\\\";
			}
			else
			{
				result += ch;
			}
			break;

		// ^  Circumflex    Upper-case shift or mode lock
		case '^':
			//
			// Try for mode lock
			//
			ch = src[ptr+1];
			switch(ch)
			{
			case '^':
				uc2_flag = 1;
				ptr++;
				break;
			default:
				uc1_flag = 1;
				break;
			}
			break;

		// \   Backslash    Lower-case shift or mode unlock
		case '\\':
			//
			// Try for mode lock
			//
			ch = src[ptr+1];
			switch(ch)
			{
			case '\\':
				uc2_flag = 0;
				ptr++;
				break;
			default:
				uc1_flag = 2;
				break;
			}
			break;
			break;

		// <  Less-than     Capitalize next word
		case '<':
			result += src[ptr];
			break;

		// =  Equals-sign   Hypenation disable
		case '=':
			break;

		default:
			ch = src[ptr];

			//
			// Is the file set to .LOWER CASE
			//
			if (uc_flag == 0)
			{
				ch = tolower(ch);
			}
			//
			// Is ther a single upper case flag set (^)?
			//
			if (uc1_flag == 1)
			{
				ch =toupper(ch);
				uc1_flag = 0;
			}
			//
			// Is ther a single lower case flag set (^)?
			//
			if (uc1_flag == 2)
			{
				ch =tolower(ch);
				uc1_flag = 0;
			}
			//
			// Is ther a long upper case flag set (^^)?
			//
			if (uc2_flag == 1)
			{
				ch =toupper(ch);
			}
			//
			// Is ther a long upper case flag set (^^)?
			//
			if (uc2_flag == 2)
			{
				ch =tolower(ch);
			}
			result += ch;
			break;
		}

		ptr++;
	}
	return result;
}

//! \brief Structure to handle list of RNO commands
//!
//! This structure lists all of the dor commands defined in the
//! RSTS/E RNO manual.
//!
struct rno_commands
{
	const char *text;	//!< RNO command
	int opcode;		//!< Option decode value. 0 = undefined
	const char *value;	//!< Replacement text, 0 = undefined
};

//! \brief Fill in the table
//!
//! Lists all of the commands in the RSTS/E dsr manual
//!
struct rno_commands rnoc[] =
{
	"BREAK", 0, 0,
	"BR", 0, 0,
	"SKIP", 0, 0,
	"S", 0, 0,
	"BLANK", 0, 0,
	"B", 0, 0,
	"FIGURE", 0, 0,
	"FG", 0, 0,
	"INDENT", 0, 0,
	"I", 0, 0,
	"PARAGRAPH", 0, 0,
	"P", 0, 0,
	"CENTER", 0, 0,
	"CENTRE", 0, 0,
	"C", 0, 0,
	"FOOTNOTE", 0, 0,
	"FN", 0, 0,
	"NOTE text", 0, 0,
	"NT text", 0, 0,
	"END NOTE", 0, 0,
	"EN", 0, 0,
	"LIST", 0, 0,
	"LS", 0, 0,
	"LIST ELEMENT", 0, 0,
	"LE", 0, 0,
	"END LIST", 0, 0,
	"ELS", 0, 0,
	"COMMENT text", 0, 0,
	"PAGE", 0, 0,
	"PG", 0, 0,
	"TEST PAGE", 0, 0,
	"TP", 0, 0,
	"NUMBER", 0, 0,
	"NM", 0, 0,
	"NONUMBER", 0, 0,
	"NNM", 0, 0,
	"CHAPTER text", 0, 0,
	"CH text", 0, 0,
	"NUMBER CHAPTER", 0, 0,
	"HEADERLEVEL", 0, 0,
	"HL", 0, 0,
	"TITLE text", 0, 0,
	"T text", 0, 0,
	"FIRST TITLE text", 0, 0,
	"FT text", 0, 0,
	"SUBTITLE text", 0, 0,
	"ST text", 0, 0,
	"INDEX text", 0, 0,
	"X text", 0, 0,
	"DO INDEX text", 0, 0,
	"DX", 0, 0,
	"PRINT INDEX", 0, 0,
	"PX", 0, 0,
	"SUBPAGE", 0, 0,
	"END SUBPAGE", 0, 0,
	"APPENDIX text", 0, 0,
	"AX", 0, 0,
	"NUMBER APPENDIX a", 0, 0,
	"HEADER arg", 0, 0,
	"HD", 0, 0,
	"NOHEADER", 0, 0,
	"NHD", 0, 0,
	"JUSTIFY", 0, 0,
	"J", 0, 0,
	"NOJUSTIFY", 0, 0,
	"NJ", 0, 0,
	"FILL", 0, 0,
	"F", 0, 0,
	"NOFILL", 0, 0,
	"NF", 0, 0,
	"UPPER CASE", 0, 0,
	"UC", 0, 0,
	"LOWER CASE", 0, 0,
	"LC", 0, 0,
	"FLAGS CAPITALIZE", 0, 0,
	"FL CAPITALIZE", 0, 0,
	"NO FLAGS CAPITALIZE", 0, 0,
	"NFL", 0, 0,
	"HYPHENATION", 0, 0,
	"HY", 0, 0,
	"NO HYPHENATION", 0, 0,
	"NHY", 0, 0,
	"FLAGS HYPHENATE", 0, 0,
	"PERIOD", 0, 0,
	"PR", 0, 0,
	"NOPERIOD", 0, 0,
	"NPR", 0, 0,
	"LITERAL", 0, 0,
	"LIT", 0, 0,
	"END LITERAL", 0, 0,
	"ELI", 0, 0,
	"LEFT MARGIN", 0, 0,
	"LM", 0, 0,
	"RIGHT MARGIN", 0, 0,
	"RM", 0, 0,
	"PAPER SIZE", 0, 0,
	"PAGE SIZE", 0, 0,
	"PS", 0, 0,
	"SPACING", 0, 0,
	"SP", 0, 0,
	"STANDARD", 0, 0,
	"SD", 0, 0,
	"TAB STOPS", 0, 0,
	"TS", 0, 0,
	"AUTOPARAGRAPH", 0, 0,
	"AP", 0, 0,
	"NOAUTOPARAGRAPH", 0, 0,
	"NAP", 0, 0,
	0, 0, 0
};

<commit_msg>Handle first command [COMMENT]<commit_after>//! \file rno2roff.cc
//!
//! \breif Filter to convert DSR (Digital Standard Runoff) to roff.
//!
//! This filter will read in a rno file,
//! and convert it into [ntg]roff format.
//!
//! Use it asy, March 2016
//! rno2roff < source > dest
//!
//! \author Kevin Hand

#include <iostream>
#include <string>

#include <cctype>

//
// Prototypes
//
int rno_filter(std::istream &in);
std::string parse_text(const std::string &src, int &ptr);
std::string parse_dot(const std::string &src, int &ptr);
int search_dot(const std::string &src, int &ptr);
int dot_match(const char *match, const std::string src, int &ptr);

//
// Global values
//
static int uc_flag = 0;		//!< Upper case flag (0 = lc everything,
				//! 1 = retain case.
static int uc1_flag = 0;	//!< Upper case next character (^)?
static int uc2_flag = 0;	//!< Upper case characters (\^)?

//! \brief Main function.
//!
//! Main function.
//! Handles all user options,
//! and runs filter.
//!
int main(int argc, char **argv)
{

	rno_filter(std::cin);
}

//! \brief Main filter
//!
//! Main filter program
//!
int rno_filter(std::istream &in)
{
	std::string buffer;
	int ptr;

	while (getline(in, buffer))
	{
		ptr = 0;
		std::cout << parse_text(buffer, ptr) <<std::endl;
	}
}

//! \brief Translate text line
//!
//! Converts a text line in RNO format to roff.
//!
//! \return filtered string.
//!
std::string parse_text(
	const std::string &src,	//!< String to convert
	int &ptr)		//!< Pointer into string
{
	std::string result;	//!< Result string being built.
	char ch;		//< For looking at characters.

	//
	// Handle any dor commands
	//
	while (ptr < src.size() && src[ptr] == '.')
	{
		result += parse_dot(src, ptr);
	}

	//
	// Handle ordinary text
	//
	while (ptr < src.size())
	{

		switch (src[ptr])
		{
		// &  Ampersand     Underscoring
		case '&':
			break;

		// #  Number Sign   Explicit space
		case '#':
			result.append("\\ ");
			break;

		// _  Underline     Quote next character
		case '_':
			// roff special characters don't match RNO specials
			ch += src[++ptr];	// hope they aren't lying
			if (ch == '\\')
			{
				result += "\\\\";
			}
			else
			{
				result += ch;
			}
			break;

		// ^  Circumflex    Upper-case shift or mode lock
		case '^':
			//
			// Try for mode lock
			//
			ch = src[ptr+1];
			switch(ch)
			{
			case '^':
				uc2_flag = 1;
				ptr++;
				break;
			default:
				uc1_flag = 1;
				break;
			}
			break;

		// \   Backslash    Lower-case shift or mode unlock
		case '\\':
			//
			// Try for mode lock
			//
			ch = src[ptr+1];
			switch(ch)
			{
			case '\\':
				uc2_flag = 0;
				ptr++;
				break;
			default:
				uc1_flag = 2;
				break;
			}
			break;
			break;

		// <  Less-than     Capitalize next word
		case '<':
			result += src[ptr];
			break;

		// =  Equals-sign   Hypenation disable
		case '=':
			break;

		default:
			ch = src[ptr];

			//
			// Is the file set to .LOWER CASE
			//
			if (uc_flag == 0)
			{
				ch = tolower(ch);
			}
			//
			// Is ther a single upper case flag set (^)?
			//
			if (uc1_flag == 1)
			{
				ch =toupper(ch);
				uc1_flag = 0;
			}
			//
			// Is ther a single lower case flag set (^)?
			//
			if (uc1_flag == 2)
			{
				ch =tolower(ch);
				uc1_flag = 0;
			}
			//
			// Is ther a long upper case flag set (^^)?
			//
			if (uc2_flag == 1)
			{
				ch =toupper(ch);
			}
			//
			// Is ther a long upper case flag set (^^)?
			//
			if (uc2_flag == 2)
			{
				ch =tolower(ch);
			}
			result += ch;
			break;
		}

		ptr++;
	}
#if 0
	if (*(result.rbegin()) == '\n')
	{
		return result.substr(0, result.size() -1);
	}
	else
	{
		return result;
	}
#else
	if (*(result.rbegin()) == '\n')
	{
		result.erase(result.size() - 1, 1);
	}
	return result;
#endif
}

//! \brief parsing option numbers
//!
//! These numbers are used to handle determining what to do with
//! the dot commands
//!
enum dotopt
{
	OP_COMMENT = 100
};
//! \brief Structure to handle list of RNO commands
//!
//! This structure lists all of the dor commands defined in the
//! RSTS/E RNO manual.
//!
struct rno_commands
{
	const char *text;	//!< RNO command
	int opcode;		//!< Option decode value. 0 = undefined
	const char *value;	//!< Replacement text, 0 = undefined
};

//! \brief Fill in the table
//!
//! Lists all of the commands in the RSTS/E dsr manual
//!
struct rno_commands rnoc[] =
{
	"BREAK", 0, 0,
	"BR", 0, 0,
	"SKIP", 0, 0,
	"S", 0, 0,
	"BLANK", 0, 0,
	"B", 0, 0,
	"FIGURE", 0, 0,
	"FG", 0, 0,
	"INDENT", 0, 0,
	"I", 0, 0,
	"PARAGRAPH", 0, 0,
	"P", 0, 0,
	"CENTER", 0, 0,
	"CENTRE", 0, 0,
	"C", 0, 0,
	"FOOTNOTE", 0, 0,
	"FN", 0, 0,
	"NOTE", 0, 0,
	"NT", 0, 0,
	"END NOTE", 0, 0,
	"EN", 0, 0,
	"LIST", 0, 0,
	"LS", 0, 0,
	"LIST ELEMENT", 0, 0,
	"LE", 0, 0,
	"END LIST", 0, 0,
	"ELS", 0, 0,
	"COMMENT", OP_COMMENT, ".\\\"",
	"PAGE", 0, 0,
	"PG", 0, 0,
	"TEST PAGE", 0, 0,
	"TP", 0, 0,
	"NUMBER", 0, 0,
	"NM", 0, 0,
	"NONUMBER", 0, 0,
	"NNM", 0, 0,
	"CHAPTER", 0, 0,
	"CH", 0, 0,
	"NUMBER CHAPTER", 0, 0,
	"HEADERLEVEL", 0, 0,
	"HL", 0, 0,
	"TITLE", 0, 0,
	"T", 0, 0,
	"FIRST TITLE", 0, 0,
	"FT", 0, 0,
	"SUBTITLE", 0, 0,
	"ST", 0, 0,
	"INDEX", 0, 0,
	"X", 0, 0,
	"DO INDEX", 0, 0,
	"DX", 0, 0,
	"PRINT INDEX", 0, 0,
	"PX", 0, 0,
	"SUBPAGE", 0, 0,
	"END SUBPAGE", 0, 0,
	"APPENDIX", 0, 0,
	"AX", 0, 0,
	"NUMBER APPENDIX a", 0, 0,
	"HEADER arg", 0, 0,
	"HD", 0, 0,
	"NOHEADER", 0, 0,
	"NHD", 0, 0,
	"JUSTIFY", 0, 0,
	"J", 0, 0,
	"NOJUSTIFY", 0, 0,
	"NJ", 0, 0,
	"FILL", 0, 0,
	"F", 0, 0,
	"NOFILL", 0, 0,
	"NF", 0, 0,
	"UPPER CASE", 0, 0,
	"UC", 0, 0,
	"LOWER CASE", 0, 0,
	"LC", 0, 0,
	"FLAGS CAPITALIZE", 0, 0,
	"FL CAPITALIZE", 0, 0,
	"NO FLAGS CAPITALIZE", 0, 0,
	"NFL", 0, 0,
	"HYPHENATION", 0, 0,
	"HY", 0, 0,
	"NO HYPHENATION", 0, 0,
	"NHY", 0, 0,
	"FLAGS HYPHENATE", 0, 0,
	"PERIOD", 0, 0,
	"PR", 0, 0,
	"NOPERIOD", 0, 0,
	"NPR", 0, 0,
	"LITERAL", 0, 0,
	"LIT", 0, 0,
	"END LITERAL", 0, 0,
	"ELI", 0, 0,
	"LEFT MARGIN", 0, 0,
	"LM", 0, 0,
	"RIGHT MARGIN", 0, 0,
	"RM", 0, 0,
	"PAPER SIZE", 0, 0,
	"PAGE SIZE", 0, 0,
	"PS", 0, 0,
	"SPACING", 0, 0,
	"SP", 0, 0,
	"STANDARD", 0, 0,
	"SD", 0, 0,
	"TAB STOPS", 0, 0,
	"TS", 0, 0,
	"AUTOPARAGRAPH", 0, 0,
	"AP", 0, 0,
	"NOAUTOPARAGRAPH", 0, 0,
	"NAP", 0, 0,
	0, 0, 0
};

//! \brief Translate dot command
//!
//! Converts a dot command to roff command
//!
//! \return filtered string.
//!
std::string parse_dot(
	const std::string &src,	//!< String to convert
	int &ptr)		//!< Pointer into string
{
	std::string result;	//!< Result string being built.
	int cmd;		//!< Used to search for dot command

	//
	// Skip over the dot
	//
	ptr++;

	//
	// Tryto find match
	//
	cmd = search_dot(src, ptr);

	if (cmd)
	{
		switch(rnoc[cmd].opcode)
		{
		//
		// .COMMENT.
		// Copy everything to end of line
		//
		case OP_COMMENT:
			result =  std::string(rnoc[cmd].value) +
				" " + src.substr(ptr)  + "\n";
			ptr = src.size();
			return result;
		//
		// Unknown command
		//
		default:
			result =  std::string(".\\\" Unhandled .") +
				rnoc[cmd].text + " " + src.substr(ptr)  + "\n";
			ptr = src.size();
			return result;
		}
	}
	else
	{
	//
	// If we cannot handle this command
	//
		result =  std::string(".\\\" Unknown .") + src.substr(ptr)  + "\n";
		ptr = src.size();
		return result;
	}
}

//! \brief Search for dot command in ist
//!
//! Tries to find command in command list.
//!
//! \return Item number in command list.
//!
int search_dot(
	const std::string &src,	//!< String to convert
	int &ptr)		//!< Pointer into string
{
	int cmd;		//!< Loop to scan for a command

	//
	// Scan through possible commands
	//
	for (cmd = 0; rnoc[cmd].text != 0; cmd++)
	{
		if (dot_match(rnoc[cmd].text, src, ptr))
		{
			return cmd;
		}
	}

	//
	// Not found
	//
	return 0;
}

//! \brief try to match a dot command
//!
//! Try to match a simgle dot command.
//! This is made fun because:
//! - Case is not important.
//! - Spaces are not important.
//! - The src string must not continue after match.
//! Assumes that the first character after the dot is non-space.
//!
//! It will adjust ptr if there was a match
//!
//!
//! \return 0 for no match, 1 got match.
//!
int dot_match(const char *match, const std::string src, int &ptr)
{
	int sptr = ptr;		//!< pointer in source text
	int mptr = 0;		//!< pointer to string being matched

	while (sptr <= src.size() && match[mptr] != 0)
	{
		//
		// Point to next non-space source character
		//
		while (sptr < src.size() && src[sptr] == ' ')
		{
			sptr++;
		}

		//
		// Point to next non-space match character
		//
		while (match[mptr] == ' ')
		{
			mptr++;
		}

		//
		// Check characters
		//
		if (match[mptr] != toupper(src[sptr]))
		{
			return 0;
		}

		sptr++;
		mptr++;
	}

	if (match[mptr] != 0)
	{
		//
		// We didn't match to end of match string
		//
		return 0;
	}
	if (sptr < src.size())
	{
		switch (src[sptr])
		{
		case ' ':
			sptr++;
			ptr = sptr;
			return 1;
		default:
			return 0;
		}
	}
	else
	{
		//
		// Matched to the end of the line
		//
		ptr = sptr;
		return 1;
	}
}

<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(h)

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * This method will be invoked first, you should design your own algorithm
     * to serialize a binary tree which denote by a root node to a string which
     * can be easily deserialized by your own "deserialize" method later.
     */
    string serialize(TreeNode *root) {
        string output;
        serializeHelper(root, &output);
        return output;
    }

    /**
     * This method will be invoked second, the argument data is what exactly
     * you serialized at method "serialize", that means the data is not given by
     * system, it's given by your own serialize method. So the format of data is
     * designed by yourself, and deserialize it here as you serialize it in
     * "serialize" method.
     */
    TreeNode *deserialize(string data) {
        TreeNode *root = nullptr;
        int start = 0;
        deserializeHelper(data, &start, &root);
        return root;
    }

private:
    bool getNumber(const string &data, int *start, int *num) {
        int sign = 1;
        if (data[*start] == '#') {
            *start += 2;  // Skip "# ".
            return false;
        } else if (data[*start] == '-') {
            sign = -1;
            ++(*start);
        }

        for (*num = 0; isdigit(data[*start]); ++(*start)) {
            *num = *num * 10 + data[*start] - '0';
        }
        *num *= sign;
        ++(*start);  // Skip " ".

        return true;
    }

    void deserializeHelper(const string& data,
                           int *start,  TreeNode **root) {
        int num;
        if (!getNumber(data, start, &num)) {
            *root = nullptr;
        } else {
            *root = new TreeNode(num);
            deserializeHelper(data, start, &((*root)->left));
            deserializeHelper(data, start, &((*root)->right));
        }
    }

    void serializeHelper(const TreeNode *root, string *prev) {
        if (!root)  {
            prev->append("# ");
        } else {
            prev->append(to_string(root->val).append(" "));
            serializeHelper(root->left, prev);
            serializeHelper(root->right, prev);
        }
    }
};
<commit_msg>Update binary-tree-serialization.cpp<commit_after>// Time:  O(n)
// Space: O(h)

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * This method will be invoked first, you should design your own algorithm
     * to serialize a binary tree which denote by a root node to a string which
     * can be easily deserialized by your own "deserialize" method later.
     */
    string serialize(TreeNode *root) {
        ostringstream out;
        serializeHelper(root, out);
        return out.str();
    }

    /**
     * This method will be invoked second, the argument data is what exactly
     * you serialized at method "serialize", that means the data is not given by
     * system, it's given by your own serialize method. So the format of data is
     * designed by yourself, and deserialize it here as you serialize it in
     * "serialize" method.
     */
    TreeNode *deserialize(string data) {
        istringstream in(data);
        return deserializeHelper(in);
    }

private:
    void serializeHelper(const TreeNode *root, ostringstream& out) {
        if (!root)  {
            out << "# ";
        } else {
            out << root->val << " ";
            serializeHelper(root->left, out);
            serializeHelper(root->right, out);
        }
    }

    TreeNode *deserializeHelper(istringstream& in) {
        string val;
        in >> val;
        if (val != "#") {
            TreeNode* root = new TreeNode(stoi(val));
            root->left = deserializeHelper(in);
            root->right = deserializeHelper(in);
            return root;
        }
        return nullptr;
    }
};
<|endoftext|>


<commit_before>/*******************************************************************************
 *    ALMA - Atacama Large Millimiter Array
 *    (c) European Southern Observatory, 2002
 *    Copyright by ESO (in the framework of the ALMA collaboration),
 *    All rights reserved
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * "@(#) $Id: baciTestAlarmClient.cpp,v 1.3 2008/10/01 02:26:45 cparedes Exp $"
 *
 * who       when      what
 * --------  --------  ----------------------------------------------
 * oat      2008-02-02 created
 */

static char *rcsId="@(#) $Id: baciTestAlarmClient.cpp,v 1.3 2008/10/01 02:26:45 cparedes Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

#include <tao/corba.h>
#include <ace/Read_Buffer.h>

#include <string>

#include <baci.h>
#include <baciCORBA.h>
#include <baciC.h>
#include <baciS.h>
#include <baciTestC.h>
#include <logging.h>
#include <baciTest.h>
#include <baciTestUtils.h>

#include <acsThread.h>

#include <ace/SString.h>

using namespace ACS;
using namespace baci;
using namespace BACI_TEST;

/**
 * Used to provide common functionality for the implementations of BACI
 * callbacks and alarms.  Really all this class does is keep track of the number
 * of done invocations as well as the name of the BACI property it's monitoring, receiving
 * an asynchronous value from, etc.
 *
 * @version "@(#) $Id: baciTestAlarmClient.cpp,v 1.3 2008/10/01 02:26:45 cparedes Exp $"
 */
class CommonCallback
{
  public:
    /**
     * Standard constructor
     */
    CommonCallback() {}

  protected:
    /**
     * 99% of the time, callback are used in conjunction with BACI properties.
     * This member is just the name of that property.
     */
    ACE_CString prop;

    /**
     * To keep the acsexmpl modular test deterministic, we keep track of the number
     * of times the done method is invoked.  From this value the logging priority
     * is dynamically changed under some circumstances.
     */
    unsigned int m_count;

  private:
    /**
     * ALMA C++ coding standards state copy operators should be disabled.
     */
    void operator=(const CommonCallback&);
};

/////////////////////////////////////////////////////////////////////////
/**
 * This class is the implementation of the AlarmPattern IDL interface defined in baci.idl.
 * It is used so that we may create a local alarm for the value of a remote BACI
 * property.  There are only two useful methods: alarm_raised and alarm_cleared.  They
 * do just what their names imply.
 *
 * @version "@(#) $Id: baciTestAlarmClient.cpp,v 1.3 2008/10/01 02:26:45 cparedes Exp $"
 */
class MyAlarmpattern : public virtual POA_ACS::Alarmpattern,    //CORBA servant stub
		       protected CommonCallback
{
  public:
    /**
     * Constructor
     * @param _prop Name of this Alarmdouble instance
     */
    MyAlarmpattern(ACE_CString _prop)
	{
	    prop = _prop;
	}

    /**
     * Destructor - nothing to delete.
     */
    ~MyAlarmpattern() {}

    /**
     * Method invoked when the double value goes out of range.
     * @param value The double's current (i.e., out of range) value
     * @param c Error handing structure.
     * @param desc Callback descriptor
     * @return void
     * @htmlonly

     @endhtmlonly
    */
    void
    alarm_raised (ACS::pattern value,
		  const ACSErr::Completion &c,
		  const ACS::CBDescOut &desc)
	{
	    ACS_SHORT_LOG ((LM_INFO, "(%s::Alarmpattern::alarm_raised) Value: %d", prop.c_str(), value));
	}

    /**
     * Method invoked when the double value goes back into the acceptable range.
     * @param value The double's new value
     * @param c Error handing structure.
     * @param desc Callback descriptor
     * @return void
     * @htmlonly

     @endhtmlonly
    */
    void
    alarm_cleared (ACS::pattern value,
		   const ACSErr::Completion &c,
		   const ACS::CBDescOut &desc)
	{
	    ACS_SHORT_LOG ((LM_INFO, "(%s::Alarmpattern::alarm_cleared) Value: %d", prop.c_str(), value));
	}

    /**
     * Method used so that client and servant can agree
     * upon the time it takes to transmit data (generally invocations
     * of the done method). A smart callback implementation would analize
     * the value of time_to_transmit and decide whether the value is acceptable,
     * but we just return true regardless in this simplistic example.
     * @param time_to_transmit Time to transmit data.
     * @param desc Callback descriptor
     * @return True regardless of parameter values.
     * @htmlonly

     @endhtmlonly
    */
    CORBA::Boolean
    negotiate (ACS::TimeInterval time_to_transmit, const ACS::CBDescOut &desc)
	{
	    return true;
	}

};

class WorkerThreadPattern : public ACS::Thread
{
  public:
    WorkerThreadPattern(const ACE_CString& name,
			ACS::RWpattern_var rwPattern,
			const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime,
			const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime) :
	ACS::Thread(name, responseTime, sleepTime)
	{
	    ACS_TRACE("WorkerThreadPattern::WorkerThreadPattern");
	    rwPattern_m = rwPattern;
	    count = 0;
	    numValues = 8;
	    values = new int[8];
	                    // 1011 - alarm_mask read from the CDB (decimal 11), three bits considered
                            // 1101 - alarm_trigger read from the CDB (decimal 13)
                            // 0010 - default value read from the CDB (decimal 2), no alarm raised
	    values[0] = 10; // 0110 - 1 bit present in alarm_trigger, 1 alarm raised
	    values[1] = 2;  // 0010 - no bit present in alarm_trigger, alarm cleared
	    values[2] = 1;  // 0001 - 2 bits present in alarm_trigger, 2 alarms raised
	    values[3] = 3;  // 0011 - 1 bit present in alarm_trigger, 1 alarm cleared
	    values[4] = 2;  // 0010 - no bit present in alarm_trigger, the other alarm cleared
	    values[5] = 9;  // 1001 - 3 bits present in alarm_trigger, 3 alarms raised
	    values[6] = 2;  // 0010 - no bit present in alarm_trigger, all 3 alarms cleared
	    values[7] = 6;  // 0110 - the bit present in alarm_trigger is not present in alarm_mask, no alarm raised

	    ACS_SHORT_LOG((LM_INFO, "%s: Created thread", getName().c_str()));
	}

    ~WorkerThreadPattern()
	{
	    ACS_TRACE("WorkerThreadPattern::~WorkerThreadPattern");
	    if(NULL != values)
		{
		delete[] values;
		}
	}

    virtual void runLoop()
	{
	    if(0 == count) {
	    ACS_SHORT_LOG((LM_INFO, "%s: Started runLoop for thread", getName().c_str()));
	    }
	    //while there are still values that need to be set...
	    if(count < numValues)
		{
		try
		    {

		    //change the BACI property's value synchronously
		    ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), values[count]));
		    rwPattern_m->set_sync(values[count]);
		    count++;

		    ACSErr::Completion_var completion;
		    prop_m = rwPattern_m->get_sync(completion.out());
		    cout << "rwPatternProperty: " << prop_m << endl;

		    ACE_OS::sleep(1);

		    }
		catch(...)
		    {
		    ACS_SHORT_LOG((LM_ERROR,"Error!"));
		    }
		}
	    else {
	    setStopped();
	    ACS_SHORT_LOG((LM_INFO, "%s: Stopped thread", getName().c_str()));
	    }
	}

  private:
    ACS::RWpattern_var rwPattern_m;
    int count;
    int numValues;
    //Ranges in the CDB for roPattern are:
    // alarm low  on : 5
    // alarm high on : 80
    int * values;
    ACS::pattern prop_m;
};

unsigned int sleep(unsigned int);

#ifdef MAKE_VXWORKS
////////////////////////////int startBaciTestClient (int argc,  char **argv)
#else
int main (int argc, char **argv)
#endif
{

    try
	{
	// create logging proxy
	LoggingProxy *m_logger = new LoggingProxy(0, 0, 31, 0);
	LoggingProxy::init(m_logger);
	LoggingProxy::ProcessName(argv[0]);
	LoggingProxy::ThreadName("main");
	ACS_TEST_INIT_LOGGING;

	//
	// Initialysation of CORBA, POA and related CORBA internals
	//
	ACE_CString g_strCmdLn;
	for (int i=argc-1; i>=0; i--)
	    g_strCmdLn = ACE_CString(argv[i])+ " " + g_strCmdLn;

	if (g_strCmdLn.find("-ORBDottedDecimalAddresses")==ACE_CString::npos)
	    g_strCmdLn += " -ORBDottedDecimalAddresses 1";

	ACE_TCHAR **m_argv = argv;
	int m_argc = argc;
	ACE_OS::string_to_argv((ACE_TCHAR*)g_strCmdLn.c_str(),
			       m_argc,
			       m_argv);

	BACI_CORBA::InitCORBA(m_argc, m_argv);

	std::string readIOR;

	int result = read_IOR_from_file ("BACIALARM", readIOR);
	if (result != 0)
	    {
	    ACS_SHORT_LOG((LM_ERROR, "Cannot read IOR from file"));
	    return -1;
	    }

	// Get an object reference from the argument string.
	CORBA::Object_var object =
	    BACI_CORBA::getORB()->string_to_object (readIOR.c_str());

	if (CORBA::is_nil(object.in()))
	    {
	    ACS_SHORT_LOG ((LM_DEBUG, "Cannot create OBJ from IOR"));
	    return -1;
	    }

	// Try to narrow the object reference to a BaciTestAlarmClass reference.
	BACI_TEST::BaciTestAlarmClass_var comp = BACI_TEST::BaciTestAlarmClass::_narrow(object.in());

	CORBA::String_var ior =
	    BACI_CORBA::getORB()->object_to_string (comp.in());

        ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: Connecting to: %s", ior.in()));

	/********************* pattern alarm subscription ******************/

	ACS::ROpattern_var roPattern = comp->roPatternProperty();
	ACS::RWpattern_var rwPattern = comp->rwPatternProperty();

	//create an instance of our alarm class
	MyAlarmpattern macb("roPatternProperty");
	//activate it as a CORBA object
	ACS::Alarmpattern_var acb = macb._this();
	//create the actual BACI double alarm
	ACS::CBDescIn desc;
	ACS::Subscription_var alarmSub = roPattern->new_subscription_Alarm(acb.in(), desc);
	ACS_SHORT_LOG((LM_INFO,"Alarmpattern subscription created"));

	// create the thread
	WorkerThreadPattern threadPattern_p /*threadManager.create<WorkerThreadPattern,ACS::RWpattern_var>*/ ("actionThreadPattern", rwPattern, ThreadBase::defaultResponseTime, ThreadBase::defaultSleepTime*10 /*=1s*/);
	// by default threads that are not created using a thread manager are creatd suspended so we have to resume them!!
	threadPattern_p.resume();

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

	//Enter main loop and stays there for a fixed amount of time.  Really we are
	//just allowing the thread we just created to run for awhile before exiting out
	//of this example.
	ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: main thread, entering ORB loop to sleep..."));

	ACE_Time_Value tv(20);

	BACI_CORBA::getORB()->run(tv);

	//Must cleanly destroy the alarm
	ACS_SHORT_LOG((LM_INFO,"Alarm subscriptions deleted"));
	alarmSub->destroy();

	ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: main thread, shutting down..."));

	comp->shutdown();

	sleep(10);

	BACI_CORBA::DoneCORBA();

	// Delete the logger last.
	delete m_logger;

	}
    catch(CORBA::Exception &ex)
	{
        ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"Error!");
        return -1;
	}
    ACE_CHECK_RETURN (-1);

    // Wait for the servant to complete cleanup before exiting.
    sleep(2);
    return 0;

} /* end main() */

<commit_msg>added cases to test changing of FF/FM<commit_after>/*******************************************************************************
 *    ALMA - Atacama Large Millimiter Array
 *    (c) European Southern Observatory, 2002
 *    Copyright by ESO (in the framework of the ALMA collaboration),
 *    All rights reserved
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 * "@(#) $Id: baciTestAlarmClient.cpp,v 1.4 2009/09/25 13:59:26 bjeram Exp $"
 *
 * who       when      what
 * --------  --------  ----------------------------------------------
 * oat      2008-02-02 created
 */

static char *rcsId="@(#) $Id: baciTestAlarmClient.cpp,v 1.4 2009/09/25 13:59:26 bjeram Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

#include <tao/corba.h>
#include <ace/Read_Buffer.h>

#include <string>

#include <baci.h>
#include <baciCORBA.h>
#include <baciC.h>
#include <baciS.h>
#include <baciTestC.h>
#include <logging.h>
#include <baciTest.h>
#include <baciTestUtils.h>

#include <acsThread.h>

#include <ace/SString.h>

using namespace ACS;
using namespace baci;
using namespace BACI_TEST;

/**
 * Used to provide common functionality for the implementations of BACI
 * callbacks and alarms.  Really all this class does is keep track of the number
 * of done invocations as well as the name of the BACI property it's monitoring, receiving
 * an asynchronous value from, etc.
 *
 * @version "@(#) $Id: baciTestAlarmClient.cpp,v 1.4 2009/09/25 13:59:26 bjeram Exp $"
 */
class CommonCallback
{
  public:
    /**
     * Standard constructor
     */
    CommonCallback() {}

  protected:
    /**
     * 99% of the time, callback are used in conjunction with BACI properties.
     * This member is just the name of that property.
     */
    ACE_CString prop;

    /**
     * To keep the acsexmpl modular test deterministic, we keep track of the number
     * of times the done method is invoked.  From this value the logging priority
     * is dynamically changed under some circumstances.
     */
    unsigned int m_count;

  private:
    /**
     * ALMA C++ coding standards state copy operators should be disabled.
     */
    void operator=(const CommonCallback&);
};

/////////////////////////////////////////////////////////////////////////
/**
 * This class is the implementation of the AlarmPattern IDL interface defined in baci.idl.
 * It is used so that we may create a local alarm for the value of a remote BACI
 * property.  There are only two useful methods: alarm_raised and alarm_cleared.  They
 * do just what their names imply.
 *
 * @version "@(#) $Id: baciTestAlarmClient.cpp,v 1.4 2009/09/25 13:59:26 bjeram Exp $"
 */
class MyAlarmpattern : public virtual POA_ACS::Alarmpattern,    //CORBA servant stub
		       protected CommonCallback
{
  public:
    /**
     * Constructor
     * @param _prop Name of this Alarmdouble instance
     */
    MyAlarmpattern(ACE_CString _prop)
	{
	    prop = _prop;
	}

    /**
     * Destructor - nothing to delete.
     */
    ~MyAlarmpattern() {}

    /**
     * Method invoked when the double value goes out of range.
     * @param value The double's current (i.e., out of range) value
     * @param c Error handing structure.
     * @param desc Callback descriptor
     * @return void
     * @htmlonly

     @endhtmlonly
    */
    void
    alarm_raised (ACS::pattern value,
		  const ACSErr::Completion &c,
		  const ACS::CBDescOut &desc)
	{
	    ACS_SHORT_LOG ((LM_INFO, "(%s::Alarmpattern::alarm_raised) Value: %d", prop.c_str(), value));
	}

    /**
     * Method invoked when the double value goes back into the acceptable range.
     * @param value The double's new value
     * @param c Error handing structure.
     * @param desc Callback descriptor
     * @return void
     * @htmlonly

     @endhtmlonly
    */
    void
    alarm_cleared (ACS::pattern value,
		   const ACSErr::Completion &c,
		   const ACS::CBDescOut &desc)
	{
	    ACS_SHORT_LOG ((LM_INFO, "(%s::Alarmpattern::alarm_cleared) Value: %d", prop.c_str(), value));
	}

    /**
     * Method used so that client and servant can agree
     * upon the time it takes to transmit data (generally invocations
     * of the done method). A smart callback implementation would analize
     * the value of time_to_transmit and decide whether the value is acceptable,
     * but we just return true regardless in this simplistic example.
     * @param time_to_transmit Time to transmit data.
     * @param desc Callback descriptor
     * @return True regardless of parameter values.
     * @htmlonly

     @endhtmlonly
    */
    CORBA::Boolean
    negotiate (ACS::TimeInterval time_to_transmit, const ACS::CBDescOut &desc)
	{
	    return true;
	}

};

class WorkerThreadPattern : public ACS::Thread
{
  public:
    WorkerThreadPattern(const ACE_CString& name,
    		BACI_TEST::BaciTestAlarmClass* comp,
			const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime,
			const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime) :
	ACS::Thread(name, responseTime, sleepTime)
	{
	    ACS_TRACE("WorkerThreadPattern::WorkerThreadPattern");
	    comp_m = BACI_TEST::BaciTestAlarmClass::_duplicate(comp);
	    rwPattern_m = comp_m->rwPatternProperty();
	    count = 0;
	    numValues = 9;
	    values = new int[numValues];
	                    // 1011 - alarm_mask read from the CDB (decimal 11), three bits considered
                            // 1101 - alarm_trigger read from the CDB (decimal 13)
                            // 0010 - default value read from the CDB (decimal 2), no alarm raised
	    values[0] = 10; // 0110 - 1 bit present in alarm_trigger, 1 alarm raised
	    values[1] = 2;  // 0010 - no bit present in alarm_trigger, alarm cleared
	    values[2] = 1;  // 0001 - 2 bits present in alarm_trigger, 2 alarms raised
	    values[3] = 3;  // 0011 - 1 bit present in alarm_trigger, 1 alarm cleared
	    values[4] = 2;  // 0010 - no bit present in alarm_trigger, the other alarm cleared
	    values[5] = 9;  // 1001 - 3 bits present in alarm_trigger, 3 alarms raised
	    values[6] = 2;  // 0010 - no bit present in alarm_trigger, all 3 alarms cleared
	    values[7] = 6;  // 0110 - the bit present in alarm_trigger is not present in alarm_mask, no alarm raised
	    //we added this that we have an alarm before we change FF and FM
	    values[8] = 1;  // 0001 - 2 bits present in alarm_trigger, 2 alarms raised

	    ACS_SHORT_LOG((LM_INFO, "%s: Created thread", getName().c_str()));
	}

    ~WorkerThreadPattern()
	{
	    ACS_TRACE("WorkerThreadPattern::~WorkerThreadPattern");
	    if(NULL != values)
		{
		delete[] values;
		}
	}

    virtual void runLoop()
	{
	    if(0 == count) {
	    ACS_SHORT_LOG((LM_INFO, "%s: Started runLoop for thread", getName().c_str()));
	    }
	    //while there are still values that need to be set...
	    if(count < numValues)
		{
		try
		    {

		    //change the BACI property's value synchronously
		    ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), values[count]));
		    rwPattern_m->set_sync(values[count]);
		    count++;

		    ACSErr::Completion_var completion;
		    prop_m = rwPattern_m->get_sync(completion.out());
		    cout << "rwPatternProperty: " << prop_m << endl;

		    ACE_OS::sleep(1);

		    }
		catch(...)
		    {
		    ACS_SHORT_LOG((LM_ERROR,"Error!"));
		    }
		}
	    else {
	    	ACS_SHORT_LOG((LM_INFO, "==> Going to test changing of FF and FM if we have a previous alarm."));
	    	// first heaving an alarm
	    	comp_m->changeAlarmFFFM("UserDefinedFF", "UserDefinedFM");

	    	// reset all alarms
	    	ACS_SHORT_LOG((LM_INFO, "==> Going to test changing of FF and FM if we do not have a previous alarm."));
	    	ACS_SHORT_LOG((LM_INFO, "==> First we reset all alarms an wait that are actaully cleared."));
	    	ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), 2));
			rwPattern_m->set_sync(2);
			ACE_OS::sleep(2); //we have to wait that alarm is actually cleaned
			ACS_SHORT_LOG((LM_INFO, "==> After resting alarms  we set new FF FM"));
			comp_m->changeAlarmFFFM("AnotherUserDefinedFF", "AnotherUserDefinedFM");

			ACS_SHORT_LOG((LM_INFO, "==>  Generate an alarm after we have changed FF, FM."));
	    	ACS_SHORT_LOG((LM_INFO, "%s: Setting rwPattern to %d", getName().c_str(), 1));
			rwPattern_m->set_sync(1);

	    	setStopped();
	    	ACS_SHORT_LOG((LM_INFO, "%s: Stopped thread", getName().c_str()));
	    }
	}

  private:
    ACS::RWpattern_var rwPattern_m;
    int count;
    int numValues;
    //Ranges in the CDB for roPattern are:
    // alarm low  on : 5
    // alarm high on : 80
    int * values;
    ACS::pattern prop_m;
    BACI_TEST::BaciTestAlarmClass_var comp_m;
};

unsigned int sleep(unsigned int);

#ifdef MAKE_VXWORKS
////////////////////////////int startBaciTestClient (int argc,  char **argv)
#else
int main (int argc, char **argv)
#endif
{

    try
	{
	// create logging proxy
	LoggingProxy *m_logger = new LoggingProxy(0, 0, 31, 0);
	LoggingProxy::init(m_logger);
	LoggingProxy::ProcessName(argv[0]);
	LoggingProxy::ThreadName("main");
	ACS_TEST_INIT_LOGGING;

	//
	// Initialysation of CORBA, POA and related CORBA internals
	//
	ACE_CString g_strCmdLn;
	for (int i=argc-1; i>=0; i--)
	    g_strCmdLn = ACE_CString(argv[i])+ " " + g_strCmdLn;

	if (g_strCmdLn.find("-ORBDottedDecimalAddresses")==ACE_CString::npos)
	    g_strCmdLn += " -ORBDottedDecimalAddresses 1";

	ACE_TCHAR **m_argv = argv;
	int m_argc = argc;
	ACE_OS::string_to_argv((ACE_TCHAR*)g_strCmdLn.c_str(),
			       m_argc,
			       m_argv);

	BACI_CORBA::InitCORBA(m_argc, m_argv);

	std::string readIOR;

	int result = read_IOR_from_file ("BACIALARM", readIOR);
	if (result != 0)
	    {
	    ACS_SHORT_LOG((LM_ERROR, "Cannot read IOR from file"));
	    return -1;
	    }

	// Get an object reference from the argument string.
	CORBA::Object_var object =
	    BACI_CORBA::getORB()->string_to_object (readIOR.c_str());

	if (CORBA::is_nil(object.in()))
	    {
	    ACS_SHORT_LOG ((LM_DEBUG, "Cannot create OBJ from IOR"));
	    return -1;
	    }

	// Try to narrow the object reference to a BaciTestAlarmClass reference.
	BACI_TEST::BaciTestAlarmClass_var comp = BACI_TEST::BaciTestAlarmClass::_narrow(object.in());

	CORBA::String_var ior =
	    BACI_CORBA::getORB()->object_to_string (comp.in());

        ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: Connecting to: %s", ior.in()));

	/********************* pattern alarm subscription ******************/

	ACS::ROpattern_var roPattern = comp->roPatternProperty();
	ACS::RWpattern_var rwPattern = comp->rwPatternProperty();

	//create an instance of our alarm class
	MyAlarmpattern macb("roPatternProperty");
	//activate it as a CORBA object
	ACS::Alarmpattern_var acb = macb._this();
	//create the actual BACI double alarm
	ACS::CBDescIn desc;
	ACS::Subscription_var alarmSub = roPattern->new_subscription_Alarm(acb.in(), desc);
	ACS_SHORT_LOG((LM_INFO,"Alarmpattern subscription created"));

	// create the thread
	WorkerThreadPattern threadPattern_p ("actionThreadPattern", comp, ThreadBase::defaultResponseTime, ThreadBase::defaultSleepTime*10 /*=1s*/);
	// by default threads that are not created using a thread manager are creatd suspended so we have to resume them!!
	threadPattern_p.resume();

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

	//Enter main loop and stays there for a fixed amount of time.  Really we are
	//just allowing the thread we just created to run for awhile before exiting out
	//of this example.
	ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: main thread, entering ORB loop to sleep..."));

	ACE_Time_Value tv(25);

	BACI_CORBA::getORB()->run(tv);

	//Must cleanly destroy the alarm
	ACS_SHORT_LOG((LM_INFO,"Alarm subscriptions deleted"));
	alarmSub->destroy();

	ACS_SHORT_LOG((LM_INFO,"baciTestAlarmClient: main thread, shutting down..."));

	comp->shutdown();

	sleep(10);

	BACI_CORBA::DoneCORBA();

	// Delete the logger last.
	delete m_logger;

	}
    catch(CORBA::Exception &ex)
	{
        ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,"Error!");
        return -1;
	}
    ACE_CHECK_RETURN (-1);

    // Wait for the servant to complete cleanup before exiting.
    sleep(2);
    return 0;

} /* end main() */

<|endoftext|>


<commit_before>AliAnalysisTaskESDfilter *AddTaskESDFilter(Bool_t useKineFilter=kTRUE)
{
// Creates a filter task and adds it to the analysis manager.

   // Get the pointer to the existing analysis manager via the static access method.
   //==============================================================================
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskESDFilter", "No analysis manager to connect to.");
      return NULL;
   }

   // This task requires an ESD input handler and an AOD output handler.
   // Check this using the analysis manager.
   //===============================================================================
   TString type = mgr->GetInputEventHandler()->GetDataType();
   if (!type.Contains("ESD")) {
      ::Error("AddTaskESDFilter", "ESD filtering task needs the manager to have an ESD input handler.");
      return NULL;
   }
   // Check if AOD output handler exist.
   AliAODHandler *aod_h = (AliAODHandler*)mgr->GetOutputEventHandler();
   if (!aod_h) {
      ::Error("AddTaskESDFilter", "ESD filtering task needs the manager to have an AOD output handler.");
      return NULL;
   }
   // Check if MC handler is connected in case kine filter requested
   AliMCEventHandler *mcH = (AliMCEventHandler*)mgr->GetMCtruthEventHandler();
   if (!mcH && useKineFilter) {
      ::Error("AddTaskESDFilter", "No MC handler connected while kine filtering requested");
      return NULL;
   }

   // Filtering of MC particles (decays conversions etc)
   // this task is also needed to set the MCEventHandler
   // to the AODHandler, this will not be needed when
   // AODHandler goes to ANALYSISalice
   if (useKineFilter) {
      AliAnalysisTaskMCParticleFilter *kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Kine Filter");
      mgr->AddTask(kinefilter);
   }

   // Create the task, add it to the manager and configure it.
   //===========================================================================
   // Barrel tracks filter
   AliAnalysisTaskESDfilter *esdfilter = new AliAnalysisTaskESDfilter("ESD Filter");
   mgr->AddTask(esdfilter);
   // Muons
   AliAnalysisTaskESDMuonFilter *esdmuonfilter = new AliAnalysisTaskESDMuonFilter("ESD Muon Filter");
   mgr->AddTask(esdmuonfilter);

   // Cuts on primary tracks
   AliESDtrackCuts* esdTrackCutsL = new AliESDtrackCuts("AliESDtrackCuts", "Standard");
   esdTrackCutsL->SetMinNClustersTPC(50);
   esdTrackCutsL->SetMaxChi2PerClusterTPC(3.5);
   esdTrackCutsL->SetRequireTPCRefit(kTRUE);
   esdTrackCutsL->SetMaxDCAToVertexXY(2.4);
   esdTrackCutsL->SetMaxDCAToVertexZ(3.2);
   esdTrackCutsL->SetDCAToVertex2D(kTRUE);
   esdTrackCutsL->SetRequireSigmaToVertex(kFALSE);
   esdTrackCutsL->SetAcceptKinkDaughters(kFALSE);
   // ITS stand-alone tracks
   AliESDtrackCuts* esdTrackCutsITSsa = new AliESDtrackCuts("AliESDtrackCuts", "ITS stand-alone");
   esdTrackCutsITSsa->SetRequireITSStandAlone(kTRUE);

   AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
   trackFilter->AddCuts(esdTrackCutsL);
   trackFilter->AddCuts(esdTrackCutsITSsa);

   // Cuts on V0s
   AliESDv0Cuts*   esdV0Cuts = new AliESDv0Cuts("AliESDv0Cuts", "Standard pp");
   esdV0Cuts->SetMinRadius(0.2);
   esdV0Cuts->SetMaxRadius(100);
   esdV0Cuts->SetMinDcaPosToVertex(0.05);
   esdV0Cuts->SetMinDcaNegToVertex(0.05);
   esdV0Cuts->SetMaxDcaV0Daughters(0.5);
   esdV0Cuts->SetMinCosinePointingAngle(0.99);
   AliAnalysisFilter* v0Filter = new AliAnalysisFilter("v0Filter");
   v0Filter->AddCuts(esdV0Cuts);

   esdfilter->SetTrackFilter(trackFilter);
   esdfilter->SetV0Filter(v0Filter);

   // Create ONLY the output containers for the data produced by the task.
   // Get and connect other common input/output containers via the manager as below
   //==============================================================================
   mgr->ConnectInput  (esdfilter,  0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput (esdfilter,  0, mgr->GetCommonOutputContainer());
   mgr->ConnectInput  (esdmuonfilter, 0, mgr->GetCommonInputContainer());
   if (useKineFilter) {
      mgr->ConnectInput  (kinefilter,  0, mgr->GetCommonInputContainer());
      mgr->ConnectOutput (kinefilter,  0, mgr->GetCommonOutputContainer());
      AliAnalysisDataContainer *coutputEx = mgr->CreateContainer("cFilterList", TList::Class(),
								   AliAnalysisManager::kOutputContainer,"pyxsec_hists.root");
   }
   return esdfilter;
}
<commit_msg>add output list for the kinefilter<commit_after>AliAnalysisTaskESDfilter *AddTaskESDFilter(Bool_t useKineFilter=kTRUE)
{
// Creates a filter task and adds it to the analysis manager.

   // Get the pointer to the existing analysis manager via the static access method.
   //==============================================================================
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskESDFilter", "No analysis manager to connect to.");
      return NULL;
   }

   // This task requires an ESD input handler and an AOD output handler.
   // Check this using the analysis manager.
   //===============================================================================
   TString type = mgr->GetInputEventHandler()->GetDataType();
   if (!type.Contains("ESD")) {
      ::Error("AddTaskESDFilter", "ESD filtering task needs the manager to have an ESD input handler.");
      return NULL;
   }
   // Check if AOD output handler exist.
   AliAODHandler *aod_h = (AliAODHandler*)mgr->GetOutputEventHandler();
   if (!aod_h) {
      ::Error("AddTaskESDFilter", "ESD filtering task needs the manager to have an AOD output handler.");
      return NULL;
   }
   // Check if MC handler is connected in case kine filter requested
   AliMCEventHandler *mcH = (AliMCEventHandler*)mgr->GetMCtruthEventHandler();
   if (!mcH && useKineFilter) {
      ::Error("AddTaskESDFilter", "No MC handler connected while kine filtering requested");
      return NULL;
   }

   // Filtering of MC particles (decays conversions etc)
   // this task is also needed to set the MCEventHandler
   // to the AODHandler, this will not be needed when
   // AODHandler goes to ANALYSISalice
   if (useKineFilter) {
      AliAnalysisTaskMCParticleFilter *kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Kine Filter");
      mgr->AddTask(kinefilter);
   }

   // Create the task, add it to the manager and configure it.
   //===========================================================================
   // Barrel tracks filter
   AliAnalysisTaskESDfilter *esdfilter = new AliAnalysisTaskESDfilter("ESD Filter");
   mgr->AddTask(esdfilter);
   // Muons
   AliAnalysisTaskESDMuonFilter *esdmuonfilter = new AliAnalysisTaskESDMuonFilter("ESD Muon Filter");
   mgr->AddTask(esdmuonfilter);

   // Cuts on primary tracks
   AliESDtrackCuts* esdTrackCutsL = new AliESDtrackCuts("AliESDtrackCuts", "Standard");
   esdTrackCutsL->SetMinNClustersTPC(50);
   esdTrackCutsL->SetMaxChi2PerClusterTPC(3.5);
   esdTrackCutsL->SetRequireTPCRefit(kTRUE);
   esdTrackCutsL->SetMaxDCAToVertexXY(2.4);
   esdTrackCutsL->SetMaxDCAToVertexZ(3.2);
   esdTrackCutsL->SetDCAToVertex2D(kTRUE);
   esdTrackCutsL->SetRequireSigmaToVertex(kFALSE);
   esdTrackCutsL->SetAcceptKinkDaughters(kFALSE);
   // ITS stand-alone tracks
   AliESDtrackCuts* esdTrackCutsITSsa = new AliESDtrackCuts("AliESDtrackCuts", "ITS stand-alone");
   esdTrackCutsITSsa->SetRequireITSStandAlone(kTRUE);

   AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
   trackFilter->AddCuts(esdTrackCutsL);
   trackFilter->AddCuts(esdTrackCutsITSsa);

   // Cuts on V0s
   AliESDv0Cuts*   esdV0Cuts = new AliESDv0Cuts("AliESDv0Cuts", "Standard pp");
   esdV0Cuts->SetMinRadius(0.2);
   esdV0Cuts->SetMaxRadius(100);
   esdV0Cuts->SetMinDcaPosToVertex(0.05);
   esdV0Cuts->SetMinDcaNegToVertex(0.05);
   esdV0Cuts->SetMaxDcaV0Daughters(0.5);
   esdV0Cuts->SetMinCosinePointingAngle(0.99);
   AliAnalysisFilter* v0Filter = new AliAnalysisFilter("v0Filter");
   v0Filter->AddCuts(esdV0Cuts);

   esdfilter->SetTrackFilter(trackFilter);
   esdfilter->SetV0Filter(v0Filter);

   // Create ONLY the output containers for the data produced by the task.
   // Get and connect other common input/output containers via the manager as below
   //==============================================================================
   mgr->ConnectInput  (esdfilter,  0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput (esdfilter,  0, mgr->GetCommonOutputContainer());
   mgr->ConnectInput  (esdmuonfilter, 0, mgr->GetCommonInputContainer());
   if (useKineFilter) {
      mgr->ConnectInput  (kinefilter,  0, mgr->GetCommonInputContainer());
      mgr->ConnectOutput (kinefilter,  0, mgr->GetCommonOutputContainer());
      AliAnalysisDataContainer *coutputEx = mgr->CreateContainer("cFilterList", TList::Class(),
								   AliAnalysisManager::kOutputContainer,"pyxsec_hists.root");
      mgr->ConnectOutput (kinefilter,  1,coutputEx);
   }
   return esdfilter;
}
<|endoftext|>